73#include <gdk/gdkkeysyms.h>
74#include <glib/gstdio.h>
115 pthread_cond_init(&s->
cond, NULL);
136 gchar *shape_str = NULL;
139 case GDK_X_CURSOR: shape_str = g_strdup(
"GDK_X_CURSOR");
break;
140 case GDK_ARROW: shape_str = g_strdup(
"GDK_ARROW");
break;
141 case GDK_BASED_ARROW_DOWN: shape_str = g_strdup(
"GDK_BASED_ARROW_DOWN");
break;
142 case GDK_BASED_ARROW_UP: shape_str = g_strdup(
"GDK_BASED_ARROW_UP");
break;
143 case GDK_BOAT: shape_str = g_strdup(
"GDK_BOAT");
break;
144 case GDK_BOGOSITY: shape_str = g_strdup(
"GDK_BOGOSITY");
break;
145 case GDK_BOTTOM_LEFT_CORNER: shape_str = g_strdup(
"GDK_BOTTOM_LEFT_CORNER");
break;
146 case GDK_BOTTOM_RIGHT_CORNER: shape_str = g_strdup(
"GDK_BOTTOM_RIGHT_CORNER");
break;
147 case GDK_BOTTOM_SIDE: shape_str = g_strdup(
"GDK_BOTTOM_SIDE");
break;
148 case GDK_BOTTOM_TEE: shape_str = g_strdup(
"GDK_BOTTOM_TEE");
break;
149 case GDK_BOX_SPIRAL: shape_str = g_strdup(
"GDK_BOX_SPIRAL");
break;
150 case GDK_CENTER_PTR: shape_str = g_strdup(
"GDK_CENTER_PTR");
break;
151 case GDK_CIRCLE: shape_str = g_strdup(
"GDK_CIRCLE");
break;
152 case GDK_CLOCK: shape_str = g_strdup(
"GDK_CLOCK");
break;
153 case GDK_COFFEE_MUG: shape_str = g_strdup(
"GDK_COFFEE_MUG");
break;
154 case GDK_CROSS: shape_str = g_strdup(
"GDK_CROSS");
break;
155 case GDK_CROSS_REVERSE: shape_str = g_strdup(
"GDK_CROSS_REVERSE");
break;
156 case GDK_CROSSHAIR: shape_str = g_strdup(
"GDK_CROSSHAIR");
break;
157 case GDK_DIAMOND_CROSS: shape_str = g_strdup(
"GDK_DIAMOND_CROSS");
break;
158 case GDK_DOT: shape_str = g_strdup(
"GDK_DOT");
break;
159 case GDK_DOTBOX: shape_str = g_strdup(
"GDK_DOTBOX");
break;
160 case GDK_DOUBLE_ARROW: shape_str = g_strdup(
"GDK_DOUBLE_ARROW");
break;
161 case GDK_DRAFT_LARGE: shape_str = g_strdup(
"GDK_DRAFT_LARGE");
break;
162 case GDK_DRAFT_SMALL: shape_str = g_strdup(
"GDK_DRAFT_SMALL");
break;
163 case GDK_DRAPED_BOX: shape_str = g_strdup(
"GDK_DRAPED_BOX");
break;
164 case GDK_EXCHANGE: shape_str = g_strdup(
"GDK_EXCHANGE");
break;
165 case GDK_FLEUR: shape_str = g_strdup(
"GDK_FLEUR");
break;
166 case GDK_GOBBLER: shape_str = g_strdup(
"GDK_GOBBLER");
break;
167 case GDK_GUMBY: shape_str = g_strdup(
"GDK_GUMBY");
break;
168 case GDK_HAND1: shape_str = g_strdup(
"GDK_HAND1");
break;
169 case GDK_HAND2: shape_str = g_strdup(
"GDK_HAND2");
break;
170 case GDK_HEART: shape_str = g_strdup(
"GDK_HEART");
break;
171 case GDK_ICON: shape_str = g_strdup(
"GDK_ICON");
break;
172 case GDK_IRON_CROSS: shape_str = g_strdup(
"GDK_IRON_CROSS");
break;
173 case GDK_LEFT_PTR: shape_str = g_strdup(
"GDK_LEFT_PTR");
break;
174 case GDK_LEFT_SIDE: shape_str = g_strdup(
"GDK_LEFT_SIDE");
break;
175 case GDK_LEFT_TEE: shape_str = g_strdup(
"GDK_LEFT_TEE");
break;
176 case GDK_LEFTBUTTON: shape_str = g_strdup(
"GDK_LEFTBUTTON");
break;
177 case GDK_LL_ANGLE: shape_str = g_strdup(
"GDK_LL_ANGLE");
break;
178 case GDK_LR_ANGLE: shape_str = g_strdup(
"GDK_LR_ANGLE");
break;
179 case GDK_MAN: shape_str = g_strdup(
"GDK_MAN");
break;
180 case GDK_MIDDLEBUTTON: shape_str = g_strdup(
"GDK_MIDDLEBUTTON");
break;
181 case GDK_MOUSE: shape_str = g_strdup(
"GDK_MOUSE");
break;
182 case GDK_PENCIL: shape_str = g_strdup(
"GDK_PENCIL");
break;
183 case GDK_PIRATE: shape_str = g_strdup(
"GDK_PIRATE");
break;
184 case GDK_PLUS: shape_str = g_strdup(
"GDK_PLUS");
break;
185 case GDK_QUESTION_ARROW: shape_str = g_strdup(
"GDK_QUESTION_ARROW");
break;
186 case GDK_RIGHT_PTR: shape_str = g_strdup(
"GDK_RIGHT_PTR");
break;
187 case GDK_RIGHT_SIDE: shape_str = g_strdup(
"GDK_RIGHT_SIDE");
break;
188 case GDK_RIGHT_TEE: shape_str = g_strdup(
"GDK_RIGHT_TEE");
break;
189 case GDK_RIGHTBUTTON: shape_str = g_strdup(
"GDK_RIGHTBUTTON");
break;
190 case GDK_RTL_LOGO: shape_str = g_strdup(
"GDK_RTL_LOGO");
break;
191 case GDK_SAILBOAT: shape_str = g_strdup(
"GDK_SAILBOAT");
break;
192 case GDK_SB_DOWN_ARROW: shape_str = g_strdup(
"GDK_SB_DOWN_ARROW");
break;
193 case GDK_SB_H_DOUBLE_ARROW: shape_str = g_strdup(
"GDK_SB_H_DOUBLE_ARROW");
break;
194 case GDK_SB_LEFT_ARROW: shape_str = g_strdup(
"GDK_SB_LEFT_ARROW");
break;
195 case GDK_SB_RIGHT_ARROW: shape_str = g_strdup(
"GDK_SB_RIGHT_ARROW");
break;
196 case GDK_SB_UP_ARROW: shape_str = g_strdup(
"GDK_SB_UP_ARROW");
break;
197 case GDK_SB_V_DOUBLE_ARROW: shape_str = g_strdup(
"GDK_SB_V_DOUBLE_ARROW");
break;
198 case GDK_SHUTTLE: shape_str = g_strdup(
"GDK_SHUTTLE");
break;
199 case GDK_SIZING: shape_str = g_strdup(
"GDK_SIZING");
break;
200 case GDK_SPIDER: shape_str = g_strdup(
"GDK_SPIDER");
break;
201 case GDK_SPRAYCAN: shape_str = g_strdup(
"GDK_SPRAYCAN");
break;
202 case GDK_STAR: shape_str = g_strdup(
"GDK_STAR");
break;
203 case GDK_TARGET: shape_str = g_strdup(
"GDK_TARGET");
break;
204 case GDK_TCROSS: shape_str = g_strdup(
"GDK_TCROSS");
break;
205 case GDK_TOP_LEFT_ARROW: shape_str = g_strdup(
"GDK_TOP_LEFT_ARROW");
break;
206 case GDK_TOP_LEFT_CORNER: shape_str = g_strdup(
"GDK_TOP_LEFT_CORNER");
break;
207 case GDK_TOP_RIGHT_CORNER: shape_str = g_strdup(
"GDK_TOP_RIGHT_CORNER");
break;
208 case GDK_TOP_SIDE: shape_str = g_strdup(
"GDK_TOP_SIDE");
break;
209 case GDK_TOP_TEE: shape_str = g_strdup(
"GDK_TOP_TEE");
break;
210 case GDK_TREK: shape_str = g_strdup(
"GDK_TREK");
break;
211 case GDK_UL_ANGLE: shape_str = g_strdup(
"GDK_UL_ANGLE");
break;
212 case GDK_UMBRELLA: shape_str = g_strdup(
"GDK_UMBRELLA");
break;
213 case GDK_UR_ANGLE: shape_str = g_strdup(
"GDK_UR_ANGLE");
break;
214 case GDK_WATCH: shape_str = g_strdup(
"GDK_WATCH");
break;
215 case GDK_XTERM: shape_str = g_strdup(
"GDK_XTERM");
break;
216 case GDK_LAST_CURSOR: shape_str = g_strdup(
"GDK_LAST_CURSOR");
break;
217 case GDK_BLANK_CURSOR: shape_str = g_strdup(
"GDK_BLANK_CURSOR");
break;
218 case GDK_CURSOR_IS_PIXMAP: shape_str = g_strdup(
"GDK_CURSOR_IS_PIXMAP");
break;
238 GdkWindow *window = gtk_widget_get_window(widget);
239 if(!
IS_NULL_PTR(window)) gdk_window_set_cursor(window, cursor);
250 if(gtk_widget_get_window(center_base) != gtk_widget_get_window(main_window))
253 if(gtk_widget_get_window(center) != gtk_widget_get_window(center_base)
254 && gtk_widget_get_window(center) != gtk_widget_get_window(main_window))
260 gchar *current_shape_str = g_strdup(shape_str);
281 const gboolean current_is_named_cursor =
286 if(g_strcmp0(curs_str,
"progress") != 0)
295 else if(current_is_named_cursor)
300 const dt_cursor_t chosen_shape = hide ? GDK_BLANK_CURSOR : GDK_CURSOR_IS_PIXMAP;
301 GdkCursor *cursor_shape = hide
302 ? gdk_cursor_new_for_display(gdk_display_get_default(), GDK_BLANK_CURSOR)
303 : gdk_cursor_new_from_name(gdk_display_get_default(), curs_str);
312 g_object_unref(cursor_shape);
330 GdkDisplay *display = gdk_display_get_default();
331 if(!
IS_NULL_PTR(display)) gdk_display_flush(display);
351 const dt_cursor_t requested_shape = cursor == GDK_CURSOR_IS_PIXMAP ? GDK_LEFT_PTR : cursor;
352 const dt_cursor_t chosen_shape = hide ? GDK_BLANK_CURSOR : requested_shape;
363 GdkCursor *cursor_shape = gdk_cursor_new_for_display(gdk_display_get_default(), chosen_shape);
366 g_object_unref(cursor_shape);
371 "Changing cursor to `%s`, requested from %s:%d\n",
378 const dt_cursor_t requested_shape = cursor == GDK_CURSOR_IS_PIXMAP ? GDK_LEFT_PTR : cursor;
403 if(g_strcmp0(curs_str,
"progress") == 0)
408 GdkCursor *cursor = gdk_cursor_new_from_name(gdk_display_get_default(), curs_str);
410 g_object_unref(cursor);
443 if(gtk_main_level() > 0) gtk_main_quit();
453 pthread_cond_broadcast(&s->
cond);
461 pthread_join(s->
thread[
k], NULL);
499 GdkRGBA color, fallback = {1.0, 0.0, 0.0, 1.0};
500 if(!gtk_style_context_lookup_color (context,
name, &color))
511 pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE);
512 pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
513 layout = pango_cairo_create_layout(cr);
514 pango_layout_set_font_description(layout, desc);
516 pango_layout_get_pixel_extents(layout, &ink, NULL);
517 if(ink.width >
width * 0.98)
519 pango_layout_set_text(layout,
"...", -1);
520 pango_layout_get_pixel_extents(layout, &ink, NULL);
523 cairo_move_to(cr, xc - wd, yc + 1. / 3. * fontsize - fontsize);
524 pango_cairo_layout_path(cr, layout);
525 cairo_set_line_width(cr, 2.0);
527 cairo_stroke_preserve(cr);
530 pango_font_description_free(desc);
531 g_object_unref(layout);
536 int pointerx, pointery;
541 gdk_window_get_device_position(gtk_widget_get_window(widget),
542 gdk_seat_get_pointer(gdk_display_get_default_seat(gtk_widget_get_display(widget))),
543 &pointerx, &pointery, NULL);
547 cairo_t *cr = cairo_create(cst);
554 GtkStyleContext *context = gtk_widget_get_style_context(widget);
559 gdk_cairo_set_source_rgba(cr, &bg_color);
587 cairo_rectangle(cr, 0,
height - progress_h,
590 cairo_set_source_rgba(cr, 0., 0., 0., 0.33);
596 cairo_set_source_surface(cr_pixmap, cst, 0, 0);
597 cairo_paint(cr_pixmap);
598 cairo_destroy(cr_pixmap);
600 cairo_surface_destroy(cst);
638 gtk_widget_set_tooltip_text(widget,
"");
643 const char *mode = (
const char*)user_data;
660 if(current_view && !strcmp(mode, current_view->
module_name))
679 if(current_view && g_strcmp0(current_view->
module_name,
"lighttable"))
720 const float yc = ht * 0.85 + 10;
722 if(which == 1 && y > yc - 10 && y < yc + 10)
738 if(which == 1 && y > yc - 10 && y < yc + 10)
766 char *escaped_msg = g_markup_vprintf_escaped(msg, ap);
767 const int msglen = strlen(escaped_msg);
784static void _toast_log(
const gboolean markup,
const char *msg, va_list ap)
793 char *escaped_msg = g_markup_vprintf_escaped(msg, ap);
892 gtk_widget_queue_draw(widget);
893 g_object_unref(widget);
913 g_weak_ref_init(&redraw_widget->
widget_ref, G_OBJECT(widget));
void dt_ctl_switch_mode_to(const char *mode)
static int _widget_queue_draw(void *widget_data)
void dt_control_set_cursor_visible_EXT(gboolean visible, const char *file, int line)
Set whether the cursor should be visible or not.
void dt_control_key_pressed(GdkEventKey *event)
static void _dt_ctl_switch_mode_prepare()
void dt_control_init(dt_control_t *s)
static void _control_set_cursor_on_widget(GtkWidget *widget, GdkCursor *cursor)
int32_t dt_control_get_mouse_over_id()
void dt_control_draw_busy_msg(cairo_t *cr, int width, int height)
gchar * _get_cursor_name(dt_cursor_t cursor)
void dt_control_button_pressed(double x, double y, double pressure, int which, int type, uint32_t state)
void * dt_control_expose(void *voidptr)
void dt_toast_log(const char *msg,...)
void dt_ctl_switch_mode_to_by_view(const dt_view_t *view)
void dt_control_queue_cursor_EXT(dt_cursor_t cursor, const char *file, int line)
void dt_control_get_pointer_input(dt_control_pointer_input_t *input)
void dt_control_set_mouse_over_id(int32_t value)
static gboolean _redraw_center(gpointer user_data)
void dt_control_forbid_change_cursor()
void dt_toast_markup_log(const char *msg,...)
void dt_control_log(const char *msg,...)
static GdkRGBA lookup_color(GtkStyleContext *context, const char *name)
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
static gboolean _dt_ctl_switch_mode_to_by_view(gpointer user_data)
void dt_control_mouse_leave()
void dt_control_toast_busy_enter()
void dt_control_shutdown(dt_control_t *s)
void dt_control_log_busy_leave()
gboolean dt_control_configure(GtkWidget *da, GdkEventConfigure *event, gpointer user_data)
void dt_control_change_cursor_by_name_and_flush(const char *curs_str)
Apply a named cursor immediatelly and flush display updates for immediate feedback.
void dt_control_cleanup(dt_control_t *s)
void dt_control_button_released(double x, double y, int which, uint32_t state)
void dt_control_commit_cursor()
void dt_control_set_pointer_input(const dt_control_pointer_input_t *input)
static void _control_store_current_cursor(const dt_cursor_t shape, const char *shape_str)
void dt_control_change_cursor_by_name(const char *curs_str)
Apply a GTK named cursor without changing the queued cursor.
void dt_control_allow_change_cursor()
static void _control_apply_cursor(GdkCursor *cursor)
void dt_control_log_busy_enter()
static dt_control_pointer_input_t _pointer_input
void dt_control_mouse_moved(double x, double y, double pressure, int which)
void dt_ctl_reload_view(const char *mode)
void dt_control_queue_redraw_widget(GtkWidget *widget)
threadsafe request of redraw of specific widget. Use this function if you need to redraw a specific w...
void dt_control_hinter_message(const struct dt_control_t *s, const char *message)
int32_t dt_control_get_keyboard_over_id()
void dt_control_toast_redraw()
request redraw of the toast widget. This redraws the message label.
void dt_control_mouse_enter()
void dt_control_change_cursor_EXT(dt_cursor_t cursor, const char *file, int line)
void dt_control_log_redraw()
request redraw of the log widget. This redraws the message label.
static gboolean _dt_ctl_toast_message_timeout_callback(gpointer data)
void dt_control_navigation_redraw()
request redraw of the navigation widget. This redraws the wiget of the navigation module.
static void _widget_queue_draw_cleanup(void *widget_data)
void dt_control_toast_busy_leave()
void dt_control_queue_cursor_by_name(const char *curs_str)
Queue a GTK named cursor for the next cursor commit.
static void _toast_log(const gboolean markup, const char *msg, va_list ap)
static gboolean _dt_ctl_log_message_timeout_callback(gpointer data)
static gboolean _dt_ctl_switch_mode_to(gpointer user_data)
void dt_control_queue_redraw()
request redraw of the workspace. This redraws the whole workspace within a gdk critical section to pr...
void dt_control_set_keyboard_over_id(int32_t value)
#define DT_CTL_LOG_TIMEOUT
#define DT_CTL_TOAST_SIZE
#define DT_CTL_TOAST_MSG_SIZE
#define dt_control_change_cursor(cursor)
#define DT_CTL_LOG_MSG_SIZE
#define DT_CTL_TOAST_TIMEOUT
GdkCursorType dt_cursor_t
uint32_t view(const dt_view_t *self)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
static const dt_aligned_pixel_simd_t value
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
void dt_gui_gtk_set_source_rgb(cairo_t *cr, dt_gui_color_t color)
GtkWidget * dt_ui_center(dt_ui_t *ui)
get the center drawable widget
static cairo_surface_t * dt_cairo_image_surface_create(cairo_format_t format, int width, int height)
GtkWidget * dt_ui_main_window(dt_ui_t *ui)
get the main window widget
static int dt_cairo_image_surface_get_width(cairo_surface_t *surface)
#define DT_PIXEL_APPLY_DPI(value)
GtkWidget * dt_ui_center_base(dt_ui_t *ui)
static int dt_cairo_image_surface_get_height(cairo_surface_t *surface)
void dt_control_jobs_cleanup(dt_control_t *control)
void dt_control_jobs_init(dt_control_t *control)
#define DT_CTL_WORKER_RESERVED
float *const restrict const size_t k
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ DT_SIGNAL_CONTROL_REDRAW_ALL
This signal is raised when dt_control_queue_redraw() is called. no param, no returned value.
@ DT_SIGNAL_MOUSE_OVER_IMAGE_CHANGE
This signal is raised when mouse hovers over image thumbs both on lighttable and in the filmstrip....
@ DT_SIGNAL_CONTROL_TOAST_REDRAW
This signal is raised when dt_control_toast_redraw() is called. no param, no returned value.
@ DT_SIGNAL_CONTROL_REDRAW_CENTER
This signal is raised when dt_control_queue_redraw_center() is called. no param, no returned value.
@ DT_SIGNAL_CONTROL_LOG_REDRAW
This signal is raised when dt_control_log_redraw() is called. no param, no returned value.
@ DT_SIGNAL_CONTROL_NAVIGATION_REDRAW
This signal is raised when dt_control_navigation_redraw() is called. no param, no returned value.
struct _GtkWidget GtkWidget
const float uint32_t state[4]
struct dt_gui_gtk_t * gui
struct dt_control_signal_t * signals
struct dt_bauhaus_t * bauhaus
struct dt_develop_t * develop
struct dt_view_manager_t * view_manager
struct dt_control_t * control
PangoFontDescription * pango_font_desc
dt_pthread_mutex_t run_mutex
struct dt_control_t::@12 cursor
struct dt_control_t::@13 progress_system
char toast_message[10][300]
gchar * current_shape_str
pthread_t thread_res[DT_CTL_WORKER_RESERVED]
dt_pthread_mutex_t log_mutex
guint log_message_timeout_id
guint toast_message_timeout_id
dt_pthread_mutex_t res_mutex
dt_cursor_t current_shape
pthread_t kick_on_workers_thread
dt_pthread_mutex_t queue_mutex
dt_pthread_mutex_t toast_mutex
char log_message[10][1000]
dt_pthread_mutex_t cond_mutex
dt_pthread_mutex_t global_mutex
struct dt_develop_t::@26 progress
cairo_surface_t * surface
void dt_view_manager_mouse_moved(dt_view_manager_t *vm, double x, double y, double pressure, int which)
void dt_view_manager_mouse_enter(dt_view_manager_t *vm)
void dt_view_manager_configure(dt_view_manager_t *vm, int width, int height)
int dt_view_manager_button_released(dt_view_manager_t *vm, double x, double y, int which, uint32_t state)
void dt_view_manager_expose(dt_view_manager_t *vm, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
int dt_view_manager_key_pressed(dt_view_manager_t *vm, GdkEventKey *event)
int dt_view_manager_button_pressed(dt_view_manager_t *vm, double x, double y, double pressure, int which, int type, uint32_t state)
int dt_view_manager_switch(dt_view_manager_t *vm, const char *view_name)
int dt_view_manager_switch_by_view(dt_view_manager_t *vm, const dt_view_t *nv)
void dt_view_manager_mouse_leave(dt_view_manager_t *vm)
const dt_view_t * dt_view_manager_get_current_view(dt_view_manager_t *vm)
void dt_hinter_set_message(dt_ui_t *ui, const char *message)