forked from darktable-org/darktable
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontrol.h
More file actions
325 lines (273 loc) · 10.5 KB
/
Copy pathcontrol.h
File metadata and controls
325 lines (273 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
/*
This file is part of darktable,
copyright (c) 2009--2010 johannes hanika.
copyright (c) 2011 henrik andersson.
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DT_CONTROL_H
#define DT_CONTROL_H
#include "common/darktable.h"
#include "common/dtpthread.h"
#include "control/settings.h"
#include <inttypes.h>
#include <gtk/gtk.h>
#ifdef _OPENMP
# include <omp.h>
#endif
#include <gtk/gtk.h>
#include "libs/lib.h"
// #include "control/job.def"
#define DT_CONTROL_MAX_JOBS 30
#define DT_CONTROL_JOB_DEBUG
#define DT_CONTROL_DESCRIPTION_LEN 256
// reserved workers
#define DT_CTL_WORKER_RESERVED 8
#define DT_CTL_WORKER_1 0 // dev load raw
#define DT_CTL_WORKER_2 1 // dev zoom 1
#define DT_CTL_WORKER_3 2 // dev zoom fill
#define DT_CTL_WORKER_4 3 // dev zoom fit
#define DT_CTL_WORKER_5 4 // dev small prev
#define DT_CTL_WORKER_6 5 // dev prefetch
#define DT_CTL_WORKER_7 6 // scheduled jobs nice level
// A mask to strip out the Ctrl, Shift, and Alt mod keys for shortcuts
#define KEY_STATE_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK)
typedef GdkCursorType dt_cursor_t;
// called from gui
void *dt_control_expose(void *voidptr);
gboolean dt_control_expose_endmarker(GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
void dt_control_button_pressed(double x, double y, int which, int type, uint32_t state);
void dt_control_button_released(double x, double y, int which, uint32_t state);
void dt_control_mouse_moved(double x, double y, int which);
void dt_control_mouse_leave();
void dt_control_mouse_enter();
int dt_control_key_pressed(guint key, guint state);
int dt_control_key_released(guint key, guint state);
int dt_control_key_pressed_override(guint key, guint state);
gboolean dt_control_configure (GtkWidget *da, GdkEventConfigure *event, gpointer user_data);
void dt_control_log(const char* msg, ...);
void dt_control_log_busy_enter();
void dt_control_log_busy_leave();
void dt_control_change_cursor(dt_cursor_t cursor);
void dt_control_write_sidecar_files();
void dt_control_delete_images();
void dt_ctl_get_display_profile(GtkWidget *widget, guint8 **buffer, gint *buffer_size);
/** \brief request redraw of the workspace.
This redraws the whole workspace within a gdk critical
section to prevent several threads to carry out a redraw
which will end up in crashes.
*/
void dt_control_queue_redraw();
/** \brief request redraw of center window.
This redraws the center view within a gdk critical section
to prevent several thrads to carry out the redraw.
*/
void dt_control_queue_redraw_center();
/** \brief threadsafe request of redraw of specific widget.
Use this function if you need to redraw a specific widget
if your current thread context is not gtk main thread.
*/
void dt_control_queue_redraw_widget(GtkWidget *widget);
/** \brief smart wrapper for entering gdk critical section.
This wrapper check is current thread context already have
entered a gdk criical section to prevent entering the critical
section that will reduce a application lock.
\return true if current call have the lock, see usage in note.
\note It's very importent that dt_control_gdk_unlock()
not is called if its locked on current thread in another place
so its very important to use the following code semantics:
\code
gboolean i_have_lock = dt_control_gdk_lock();
gtk_widget_queue_redraw();
if(i_have_lock) dt_control_gdk_unlock();
\endcode
*/
gboolean dt_control_gdk_lock();
/** \brief smart wrapper for leaving a gdk critical section */
void dt_control_gdk_unlock();
void dt_ctl_switch_mode();
void dt_ctl_switch_mode_to(dt_ctl_gui_mode_t mode);
struct dt_control_t;
struct dt_job_t;
/* backgroundjobs proxy funcs */
/** creates a background job and returns hash id reference */
const guint *dt_control_backgroundjobs_create(const struct dt_control_t *s,guint type,const gchar *message);
/** destroys a backgroundjob using hash id reference */
void dt_control_backgroundjobs_destroy(const struct dt_control_t *s, const guint *key);
/** sets the progress of a backgroundjob using hash id reference */
void dt_control_backgroundjobs_progress(const struct dt_control_t *s, const guint *key, double progress);
/** assign a dt_job_t to a bgjob which makes it cancellable thru ui interaction */
void dt_control_backgroundjobs_set_cancellable(const struct dt_control_t *s, const guint *key,struct dt_job_t *job);
/** sets the hinter message */
void dt_control_hinter_message(const struct dt_control_t *s, const char *message);
/** turn the use of key accelerators on */
void dt_control_key_accelerators_on(struct dt_control_t *s);
/** turn the use of key accelerators on */
void dt_control_key_accelerators_off(struct dt_control_t *s);
int dt_control_is_key_accelerators_on(struct dt_control_t *s);
/**
* smallest unit of work.
*/
struct dt_job_t;
typedef void (*dt_job_state_change_callback)(struct dt_job_t*,int state);
#define DT_JOB_STATE_INITIALIZED 0
#define DT_JOB_STATE_QUEUED 1
#define DT_JOB_STATE_RUNNING 2
#define DT_JOB_STATE_FINISHED 3
#define DT_JOB_STATE_CANCELLED 4
#define DT_JOB_STATE_DISCARDED 5
typedef struct dt_job_t
{
int32_t (*execute) (struct dt_job_t *job);
int32_t result;
/* timestamp of job added to queue */
time_t ts_added;
/* if job is a delayed job it will be run as a backgroundjob
and ts_execute will be the timestamp of when to start job */
time_t ts_execute;
dt_pthread_mutex_t state_mutex;
dt_pthread_mutex_t wait_mutex;
int32_t state;
dt_job_state_change_callback state_changed_cb;
void *user_data;
int32_t param[32];
#ifdef DT_CONTROL_JOB_DEBUG
char description[DT_CONTROL_DESCRIPTION_LEN];
#endif
}
dt_job_t;
/** intializes a job */
void dt_control_job_init(dt_job_t *j, const char *msg, ...);
/** setup a state callback for job. */
void dt_control_job_set_state_callback(dt_job_t *j,dt_job_state_change_callback cb,void *user_data);
void dt_control_job_print(dt_job_t *j);
/** cancel a job, running or in queue. */
void dt_control_job_cancel(dt_job_t *j);
int dt_control_job_get_state(dt_job_t *j);
/** wait for a job to finish execution. */
void dt_control_job_wait(dt_job_t *j);
//z All the accelerator keys for the key_pressed style shortcuts
typedef struct dt_control_accels_t
{
GtkAccelKey
filmstrip_forward, filmstrip_back,
lighttable_up, lighttable_down, lighttable_right,
lighttable_left, lighttable_center, lighttable_preview,
global_sideborders, global_header;
} dt_control_accels_t;
#define DT_CTL_LOG_SIZE 10
#define DT_CTL_LOG_MSG_SIZE 200
#define DT_CTL_LOG_TIMEOUT 20000
/**
* this manages everything time-consuming.
* distributes the jobs on all processors,
* performs scheduling.
*/
typedef struct dt_control_t
{
// Keyboard accelerator groups
GtkAccelGroup *accelerators;
// Accelerator group path lists
GSList *accelerator_list;
// Cached accelerator keys for key_pressed shortcuts
dt_control_accels_t accels;
// Accel remapping data
gchar *accel_remap_str;
GtkTreePath *accel_remap_path;
char vimkey[256];
int vimkey_cnt;
// gui related stuff
double tabborder;
int32_t width, height;
float progress;
pthread_t gui_thread;
int button_down, button_down_which, button_type;
double button_x, button_y;
int history_start;
// message log
int log_pos, log_ack;
char log_message[DT_CTL_LOG_SIZE][DT_CTL_LOG_MSG_SIZE];
guint log_message_timeout_id;
int log_busy;
dt_pthread_mutex_t log_mutex;
// gui settings
dt_ctl_settings_t global_settings, global_defaults;
dt_pthread_mutex_t global_mutex, image_mutex;
double last_expose_time;
int key_accelerators_on;
// xatom color profile:
uint8_t *xprofile_data;
int xprofile_size;
// job management
int32_t running;
dt_pthread_mutex_t queue_mutex, cond_mutex, run_mutex;
pthread_cond_t cond;
int32_t num_threads;
pthread_t *thread,kick_on_workers_thread;
GList *queue;
dt_job_t job_res[DT_CTL_WORKER_RESERVED];
uint8_t new_res[DT_CTL_WORKER_RESERVED];
pthread_t thread_res[DT_CTL_WORKER_RESERVED];
/* proxy */
struct {
/* proxy functions for backgroundjobs ui*/
struct {
dt_lib_module_t *module;
const guint *(*create)(dt_lib_module_t *self, int type, const gchar *message);
void (*destroy)(dt_lib_module_t *self, const guint *key);
void (*progress)(dt_lib_module_t *self, const guint *key, double progress);
void (*set_cancellable)(dt_lib_module_t *self, const guint *key, dt_job_t *job);
} backgroundjobs;
struct {
dt_lib_module_t *module;
void (*set_message)(dt_lib_module_t *self, const gchar *message);
} hinter;
} proxy;
}
dt_control_t;
void dt_control_init(dt_control_t *s);
void dt_control_create_database_schema();
// join all worker threads.
void dt_control_shutdown(dt_control_t *s);
void dt_control_cleanup(dt_control_t *s);
// call this to quit dt
void dt_control_quit();
int dt_control_load_config(dt_control_t *c);
int dt_control_write_config(dt_control_t *c);
int32_t dt_control_run_job(dt_control_t *s);
int32_t dt_control_add_job(dt_control_t *s, dt_job_t *job);
/** adds a job to queue tagged as background job and with a delay */
int32_t dt_control_add_background_job(dt_control_t *s, dt_job_t *job, time_t delay);
int32_t dt_control_revive_job(dt_control_t *s, dt_job_t *job);
int32_t dt_control_run_job_res(dt_control_t *s, int32_t res);
int32_t dt_control_add_job_res(dt_control_t *s, dt_job_t *job, int32_t res);
/** get threadsafe running state. */
int dt_control_running();
void *dt_control_work(void *ptr);
void *dt_control_work_res(void *ptr);
int32_t dt_control_get_threadid();
int32_t dt_control_get_threadid_res();
static inline int32_t dt_ctl_get_num_procs()
{
#ifdef _OPENMP
return omp_get_num_procs();
#else
#ifdef _SC_NPROCESSORS_ONLN
return sysconf (_SC_NPROCESSORS_ONLN);
#else
return 1;
#endif
#endif
}
#endif
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
// vim: shiftwidth=2 expandtab tabstop=2 cindent
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-space on;