comparison gtk4/dw.c @ 2269:a26cfd4bbffe

GTK4: More work on signal handlers, and disable the font CSS override. The override was causing a crash in pango for some reason.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 31 Jan 2021 12:42:25 +0000
parents fefeb5b4e512
children 819f2492c85f
comparison
equal deleted inserted replaced
2268:fefeb5b4e512 2269:a26cfd4bbffe
116 116
117 /* Signal forwarder prototypes */ 117 /* Signal forwarder prototypes */
118 static gint _button_press_event(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data); 118 static gint _button_press_event(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data);
119 static gint _button_release_event(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data); 119 static gint _button_release_event(GtkGestureClick *gesture, int n_press, double x, double y, gpointer data);
120 static gint _motion_notify_event(GtkEventControllerMotion *controller, double x, double y, gpointer data); 120 static gint _motion_notify_event(GtkEventControllerMotion *controller, double x, double y, gpointer data);
121 static gint _delete_event(GtkWidget *widget, gpointer data); 121 static gboolean _delete_event(GtkWidget *window, gpointer data);
122 static gint _key_press_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data); 122 static gint _key_press_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data);
123 static gint _generic_event(GtkWidget *widget, gpointer data); 123 static gint _generic_event(GtkWidget *widget, gpointer data);
124 static gint _configure_event(GtkWidget *widget, GdkEvent *event, gpointer data); 124 static gint _configure_event(GtkWidget *widget, int width, int height, gpointer data);
125 static gint _container_enter_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data); 125 static gint _container_enter_event(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data);
126 static gint _combobox_select_event(GtkWidget *widget, gpointer data); 126 static gint _combobox_select_event(GtkWidget *widget, gpointer data);
127 static gint _expose_event(GtkWidget *widget, cairo_t *cr, gpointer data); 127 static gint _expose_event(GtkWidget *widget, cairo_t *cr, int width, int height, gpointer data);
128 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data); 128 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data);
129 static gint _tree_context_event(GtkWidget *widget, GdkEvent *event, gpointer data); 129 static gint _tree_context_event(GtkWidget *widget, GdkEvent *event, gpointer data);
130 static gint _value_changed_event(GtkWidget *widget, gpointer user_data); 130 static gint _value_changed_event(GtkWidget *widget, gpointer user_data);
131 static gint _tree_select_event(GtkTreeSelection *sel, gpointer data); 131 static gint _tree_select_event(GtkTreeSelection *sel, gpointer data);
132 static gint _tree_expand_event(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer data); 132 static gint _tree_expand_event(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer data);
155 } SignalList; 155 } SignalList;
156 156
157 /* Signal setup function prototypes */ 157 /* Signal setup function prototypes */
158 GObject *_dw_key_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data); 158 GObject *_dw_key_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
159 GObject *_dw_button_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data); 159 GObject *_dw_button_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
160 GObject *_dw_mouse_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
160 GObject *_dw_motion_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data); 161 GObject *_dw_motion_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
161 GObject *_dw_draw_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data); 162 GObject *_dw_draw_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
162 GObject *_dw_value_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data); 163 GObject *_dw_value_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
163 GObject *_dw_list_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
164 GObject *_dw_tree_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data); 164 GObject *_dw_tree_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
165 GObject *_dw_focus_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data); 165 GObject *_dw_focus_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
166 GObject *_dw_html_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data); 166 GObject *_dw_html_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data);
167 167
168 typedef struct 168 typedef struct
177 177
178 /* A list of signal forwarders, to account for paramater differences. */ 178 /* A list of signal forwarders, to account for paramater differences. */
179 static SignalList SignalTranslate[] = { 179 static SignalList SignalTranslate[] = {
180 { _configure_event, DW_SIGNAL_CONFIGURE, "resize", NULL }, 180 { _configure_event, DW_SIGNAL_CONFIGURE, "resize", NULL },
181 { _key_press_event, DW_SIGNAL_KEY_PRESS, "key-pressed", _dw_key_setup }, 181 { _key_press_event, DW_SIGNAL_KEY_PRESS, "key-pressed", _dw_key_setup },
182 { _button_press_event, DW_SIGNAL_BUTTON_PRESS, "pressed", _dw_button_setup }, 182 { _button_press_event, DW_SIGNAL_BUTTON_PRESS, "pressed", _dw_mouse_setup },
183 { _button_release_event, DW_SIGNAL_BUTTON_RELEASE, "released", _dw_button_setup }, 183 { _button_release_event, DW_SIGNAL_BUTTON_RELEASE, "released", _dw_mouse_setup },
184 { _motion_notify_event, DW_SIGNAL_MOTION_NOTIFY, "motion", _dw_motion_setup }, 184 { _motion_notify_event, DW_SIGNAL_MOTION_NOTIFY, "motion", _dw_motion_setup },
185 { _delete_event, DW_SIGNAL_DELETE, "close-request", NULL }, 185 { _delete_event, DW_SIGNAL_DELETE, "close-request", NULL },
186 { _expose_event, DW_SIGNAL_EXPOSE, "draw", _dw_draw_setup }, 186 { _expose_event, DW_SIGNAL_EXPOSE, "draw", _dw_draw_setup },
187 { _generic_event, DW_SIGNAL_CLICKED, "pressed", _dw_button_setup }, 187 { _generic_event, DW_SIGNAL_CLICKED, "clicked", _dw_button_setup },
188 { _container_enter_event, DW_SIGNAL_ITEM_ENTER, "key-pressed", _dw_key_setup }, 188 { _container_enter_event, DW_SIGNAL_ITEM_ENTER, "key-pressed", _dw_key_setup },
189 { _tree_context_event, DW_SIGNAL_ITEM_CONTEXT, "pressed", _dw_tree_setup }, 189 { _tree_context_event, DW_SIGNAL_ITEM_CONTEXT, "pressed", _dw_tree_setup },
190 { _combobox_select_event, DW_SIGNAL_LIST_SELECT, "changed", _dw_list_setup }, 190 { _combobox_select_event, DW_SIGNAL_LIST_SELECT, "changed", NULL },
191 { _tree_select_event, DW_SIGNAL_ITEM_SELECT, "row-activated", _dw_list_setup }, 191 { _tree_select_event, DW_SIGNAL_ITEM_SELECT, "row-activated", NULL },
192 { _set_focus_event, DW_SIGNAL_SET_FOCUS, "activate-focus", _dw_focus_setup }, 192 { _set_focus_event, DW_SIGNAL_SET_FOCUS, "activate-focus", _dw_focus_setup },
193 { _value_changed_event, DW_SIGNAL_VALUE_CHANGED, "value-changed", _dw_value_setup }, 193 { _value_changed_event, DW_SIGNAL_VALUE_CHANGED, "value-changed", _dw_value_setup },
194 { _switch_page_event, DW_SIGNAL_SWITCH_PAGE, "switch-page", NULL }, 194 { _switch_page_event, DW_SIGNAL_SWITCH_PAGE, "switch-page", NULL },
195 { _column_click_event, DW_SIGNAL_COLUMN_CLICK, "activate", _dw_tree_setup }, 195 { _column_click_event, DW_SIGNAL_COLUMN_CLICK, "activate", _dw_tree_setup },
196 { _tree_expand_event, DW_SIGNAL_TREE_EXPAND, "row-expanded", NULL }, 196 { _tree_expand_event, DW_SIGNAL_TREE_EXPAND, "row-expanded", NULL },
227 usleep(period * 1000); 227 usleep(period * 1000);
228 #endif 228 #endif
229 } 229 }
230 230
231 /* Finds the translation function for a given signal name */ 231 /* Finds the translation function for a given signal name */
232 static SignalList *_dw_findsignal(const char *signame) 232 static SignalList _dw_findsignal(const char *signame)
233 { 233 {
234 int z=0; 234 int z=0;
235 static SignalList empty = {0};
235 236
236 while(SignalTranslate[z].func) 237 while(SignalTranslate[z].func)
237 { 238 {
238 if(strcasecmp(signame, SignalTranslate[z].name) == 0) 239 if(strcasecmp(signame, SignalTranslate[z].name) == 0)
239 return &SignalTranslate[z]; 240 return SignalTranslate[z];
240 z++; 241 z++;
241 } 242 }
242 return NULL; 243 return empty;
243 } 244 }
244 245
245 static SignalHandler _get_signal_handler(gpointer data) 246 static SignalHandler _get_signal_handler(gpointer data)
246 { 247 {
247 SignalHandler sh = {0}; 248 SignalHandler sh = {0};
485 retval = motionfunc(work.window, (int)x, (int)y, keys, work.data); 486 retval = motionfunc(work.window, (int)x, (int)y, keys, work.data);
486 } 487 }
487 return retval; 488 return retval;
488 } 489 }
489 490
490 static gint _delete_event(GtkWidget *widget, gpointer data) 491 static gboolean _delete_event(GtkWidget *window, gpointer data)
491 { 492 {
492 SignalHandler work = _get_signal_handler(data); 493 SignalHandler work = _get_signal_handler(data);
493 int retval = FALSE; 494 int retval = FALSE;
494 495
495 if(work.window) 496 if(work.window)
532 retval = genericfunc(work.window, work.data); 533 retval = genericfunc(work.window, work.data);
533 } 534 }
534 return retval; 535 return retval;
535 } 536 }
536 537
537 static gint _configure_event(GtkWidget *widget, GdkEvent *event, gpointer data) 538 static gint _configure_event(GtkWidget *widget, int width, int height, gpointer data)
538 { 539 {
539 SignalHandler work = _get_signal_handler(data); 540 SignalHandler work = _get_signal_handler(data);
540 int retval = FALSE; 541 int retval = FALSE;
541 542
542 if(work.window) 543 if(work.window)
543 { 544 {
544 int (*sizefunc)(HWND, int, int, void *) = work.func; 545 int (*sizefunc)(HWND, int, int, void *) = work.func;
545 546
546 retval = sizefunc(work.window, 100, 100, work.data); 547 retval = sizefunc(work.window, width, height, work.data);
547 } 548 }
548 return retval; 549 return retval;
549 } 550 }
550 551
551 static gint _expose_event(GtkWidget *widget, cairo_t *cr, gpointer data) 552 static gint _expose_event(GtkWidget *widget, cairo_t *cr, int width, int height, gpointer data)
552 { 553 {
553 SignalHandler work = _get_signal_handler(data); 554 SignalHandler work = _get_signal_handler(data);
554 int retval = FALSE; 555 int retval = FALSE;
555 556
556 if(work.window) 557 if(work.window)
557 { 558 {
558 DWExpose exp; 559 DWExpose exp;
559 int (*exposefunc)(HWND, DWExpose *, void *) = work.func; 560 int (*exposefunc)(HWND, DWExpose *, void *) = work.func;
560 561
561 exp.x = exp.y = 0; 562 exp.x = exp.y = 0;
562 exp.width = gtk_widget_get_allocated_width(widget); 563 exp.width = width;
563 exp.height = gtk_widget_get_allocated_height(widget); 564 exp.height = height;
564 retval = exposefunc(work.window, &exp, work.data); 565 retval = exposefunc(work.window, &exp, work.data);
565 } 566 }
566 return retval; 567 return retval;
567 } 568 }
568 569
1584 g_free(dataname); 1585 g_free(dataname);
1585 } 1586 }
1586 1587
1587 static void _dw_override_font(GtkWidget *widget, const char *font) 1588 static void _dw_override_font(GtkWidget *widget, const char *font)
1588 { 1589 {
1590 #if 0
1589 GtkCssProvider *provider = g_object_get_data(G_OBJECT(widget), "_dw_font"); 1591 GtkCssProvider *provider = g_object_get_data(G_OBJECT(widget), "_dw_font");
1590 GtkStyleContext *scontext = gtk_widget_get_style_context(widget); 1592 GtkStyleContext *scontext = gtk_widget_get_style_context(widget);
1591 1593
1592 /* If we have an old context from a previous override remove it */ 1594 /* If we have an old context from a previous override remove it */
1593 if(provider) 1595 if(provider)
1606 gtk_css_provider_load_from_data(provider, css, -1); 1608 gtk_css_provider_load_from_data(provider, css, -1);
1607 g_free(css); 1609 g_free(css);
1608 gtk_style_context_add_provider(scontext, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); 1610 gtk_style_context_add_provider(scontext, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1609 } 1611 }
1610 g_object_set_data(G_OBJECT(widget), "_dw_font", (gpointer)provider); 1612 g_object_set_data(G_OBJECT(widget), "_dw_font", (gpointer)provider);
1613 #endif
1611 } 1614 }
1612 1615
1613 /* 1616 /*
1614 * Sets the font used by a specified window (widget) handle. 1617 * Sets the font used by a specified window (widget) handle.
1615 * Parameters: 1618 * Parameters:
9522 g_object_set_data(G_OBJECT(_DWApp), textbuf, DW_POINTER(sigfunc)); 9525 g_object_set_data(G_OBJECT(_DWApp), textbuf, DW_POINTER(sigfunc));
9523 snprintf(textbuf, 100, "dw-notification-%llu-data", DW_POINTER_TO_ULONGLONG(object)); 9526 snprintf(textbuf, 100, "dw-notification-%llu-data", DW_POINTER_TO_ULONGLONG(object));
9524 g_object_set_data(G_OBJECT(_DWApp), textbuf, DW_POINTER(data)); 9527 g_object_set_data(G_OBJECT(_DWApp), textbuf, DW_POINTER(data));
9525 return NULL; 9528 return NULL;
9526 } 9529 }
9527 else if(GTK_IS_WIDGET(object)) 9530 /* GTK signal name for check buttons is "toggled" not "clicked" */
9531 else if(GTK_IS_CHECK_BUTTON(object) && strcmp(signal->name, DW_SIGNAL_CLICKED) == 0)
9532 strcpy(signal->gname, "toggled");
9533 return object;
9534 }
9535
9536 GObject *_dw_mouse_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data)
9537 {
9538 if(GTK_IS_WIDGET(object))
9528 { 9539 {
9529 GtkGesture *gesture = gtk_gesture_click_new(); 9540 GtkGesture *gesture = gtk_gesture_click_new();
9530 gtk_widget_add_controller(GTK_WIDGET(object), GTK_EVENT_CONTROLLER(gesture)); 9541 gtk_widget_add_controller(GTK_WIDGET(object), GTK_EVENT_CONTROLLER(gesture));
9531 return G_OBJECT(gesture); 9542 return G_OBJECT(gesture);
9532 } 9543 }
9577 } 9588 }
9578 } 9589 }
9579 return object; 9590 return object;
9580 } 9591 }
9581 9592
9582 GObject *_dw_list_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data)
9583 {
9584 if((GTK_IS_TREE_VIEW(object) && strcmp(signal->name, DW_SIGNAL_ITEM_SELECT) == 0) ||
9585 (GTK_IS_COMBO_BOX(object) && strcmp(signal->name, DW_SIGNAL_LIST_SELECT) == 0))
9586 {
9587 /* TODO: Might need to allocate a new "params" here */
9588 int cid, sigid = _set_signal_handler(object, (HWND)object, sigfunc, data, signal->func, discfunc);
9589 params[0] = DW_INT_TO_POINTER(sigid);
9590 params[2] = DW_POINTER(object);
9591 if(GTK_IS_TREE_VIEW(object))
9592 cid = g_signal_connect_data(object, signal->gname, G_CALLBACK(signal->func), params, _dw_signal_disconnect, 0);
9593 else
9594 cid = g_signal_connect_data(object, signal->gname, G_CALLBACK(_combobox_select_event), params, _dw_signal_disconnect, 0);
9595 _set_signal_handler_id(object, sigid, cid);
9596 return NULL;
9597 }
9598 return object;
9599 }
9600
9601 GObject *_dw_value_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data) 9593 GObject *_dw_value_setup(struct _dw_signal_list *signal, GObject *object, void *params[], void *sigfunc, void *discfunc, void *data)
9602 { 9594 {
9603 if(GTK_IS_SCALE(object) || GTK_IS_SCROLLBAR(object) || GTK_IS_SPIN_BUTTON(object)) 9595 if(GTK_IS_SCALE(object) || GTK_IS_SCROLLBAR(object) || GTK_IS_SPIN_BUTTON(object))
9604 return G_OBJECT(g_object_get_data(object, "_dw_adjustment")); 9596 return G_OBJECT(g_object_get_data(object, "_dw_adjustment"));
9605 return object; 9597 return object;
9637 * discfunc: The pointer to the function called when this handler is removed. 9629 * discfunc: The pointer to the function called when this handler is removed.
9638 * data: User data to be passed to the handler function. 9630 * data: User data to be passed to the handler function.
9639 */ 9631 */
9640 void dw_signal_connect_data(HWND window, const char *signame, void *sigfunc, void *discfunc, void *data) 9632 void dw_signal_connect_data(HWND window, const char *signame, void *sigfunc, void *discfunc, void *data)
9641 { 9633 {
9642 SignalList *signal = _dw_findsignal(signame); 9634 SignalList signal = _dw_findsignal(signame);
9643 9635
9644 if(signal && signal->func) 9636 if(signal.func)
9645 { 9637 {
9646 GObject *object = (GObject *)window; 9638 GObject *object = (GObject *)window;
9647 void **params = calloc(_DW_INTERNAL_CALLBACK_PARAMS, sizeof(void *)); 9639 void **params = calloc(_DW_INTERNAL_CALLBACK_PARAMS, sizeof(void *));
9648 int sigid; 9640 int sigid;
9649 gint cid; 9641 gint cid;
9661 #endif 9653 #endif
9662 ) 9654 )
9663 object = (GObject *)g_object_get_data(G_OBJECT(window), "_dw_user"); 9655 object = (GObject *)g_object_get_data(G_OBJECT(window), "_dw_user");
9664 9656
9665 /* Do object class specific setup */ 9657 /* Do object class specific setup */
9666 if(signal->setup) 9658 if(signal.setup)
9667 object = signal->setup(signal, object, params, sigfunc, discfunc, data); 9659 object = signal.setup(&signal, object, params, sigfunc, discfunc, data);
9668 9660
9669 if(!object) 9661 if(!object)
9670 { 9662 {
9671 free(params); 9663 free(params);
9672 return; 9664 return;
9673 } 9665 }
9674 9666
9675 sigid = _set_signal_handler(object, window, sigfunc, data, signal->func, discfunc); 9667 sigid = _set_signal_handler(object, window, sigfunc, data, signal.func, discfunc);
9676 params[0] = DW_INT_TO_POINTER(sigid); 9668 params[0] = DW_INT_TO_POINTER(sigid);
9677 params[2] = DW_POINTER(object); 9669 params[2] = DW_POINTER(object);
9678 cid = g_signal_connect_data(object, signal->gname, G_CALLBACK(signal->func), params, _dw_signal_disconnect, 0); 9670 cid = g_signal_connect_data(object, signal.gname, G_CALLBACK(signal.func), params, _dw_signal_disconnect, 0);
9679 _set_signal_handler_id(object, sigid, cid); 9671 _set_signal_handler_id(object, sigid, cid);
9680 } 9672 }
9681 } 9673 }
9682 9674
9683 /* 9675 /*
9686 * window: Window handle of callback to be removed. 9678 * window: Window handle of callback to be removed.
9687 */ 9679 */
9688 void dw_signal_disconnect_by_name(HWND window, const char *signame) 9680 void dw_signal_disconnect_by_name(HWND window, const char *signame)
9689 { 9681 {
9690 int z, count; 9682 int z, count;
9691 SignalList *signal; 9683 SignalList signal;
9692 void **params = alloca(sizeof(void *) * 3); 9684 void **params = alloca(sizeof(void *) * 3);
9693 9685
9694 params[2] = _find_signal_window(window, signame); 9686 params[2] = _find_signal_window(window, signame);
9695 count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(params[2]), "_dw_sigcounter")); 9687 count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(params[2]), "_dw_sigcounter"));
9696 9688 signal = _dw_findsignal(signame);
9697 if((signal = _dw_findsignal(signame))) 9689
9690 if(signal.func)
9698 { 9691 {
9699 for(z=0;z<count;z++) 9692 for(z=0;z<count;z++)
9700 { 9693 {
9701 SignalHandler sh; 9694 SignalHandler sh;
9702 9695
9703 params[0] = GINT_TO_POINTER(z); 9696 params[0] = GINT_TO_POINTER(z);
9704 sh = _get_signal_handler(params); 9697 sh = _get_signal_handler(params);
9705 9698
9706 if(sh.intfunc == signal->func) 9699 if(sh.intfunc == signal.func)
9707 _remove_signal_handler((HWND)params[2], z); 9700 _remove_signal_handler((HWND)params[2], z);
9708 } 9701 }
9709 } 9702 }
9710 } 9703 }
9711 9704