Mercurial > dwindows
comparison gtk4/dw.c @ 2321:52ca7647f665
GTK4: Implement pointer grabbing using Xlib and center message boxes.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Wed, 17 Feb 2021 03:52:41 +0000 |
parents | 829228de003f |
children | ebcaedfa7ff4 |
comparison
equal
deleted
inserted
replaced
2320:829228de003f | 2321:52ca7647f665 |
---|---|
56 * ... | 56 * ... |
57 */ | 57 */ |
58 #ifndef _DW_SINGLE_THREADED | 58 #ifndef _DW_SINGLE_THREADED |
59 #define DW_FUNCTION_DEFINITION(func, rettype, ...) gboolean _##func(void **_args); \ | 59 #define DW_FUNCTION_DEFINITION(func, rettype, ...) gboolean _##func(void **_args); \ |
60 rettype API func(__VA_ARGS__) { | 60 rettype API func(__VA_ARGS__) { |
61 #define DW_FUNCTION_ADD_PARAM void **_args = alloca(sizeof(void *)*2); \ | |
62 _args[0] = (void *)pthread_getspecific(_dw_event_key); \ | |
63 _args[1] = (void *)NULL; | |
61 #define DW_FUNCTION_ADD_PARAM1(param1) void **_args = alloca(sizeof(void *)*3); \ | 64 #define DW_FUNCTION_ADD_PARAM1(param1) void **_args = alloca(sizeof(void *)*3); \ |
62 _args[0] = (void *)pthread_getspecific(_dw_event_key); \ | 65 _args[0] = (void *)pthread_getspecific(_dw_event_key); \ |
63 _args[1] = (void *)NULL; \ | 66 _args[1] = (void *)NULL; \ |
64 _args[2] = (void *)¶m1; | 67 _args[2] = (void *)¶m1; |
65 #define DW_FUNCTION_ADD_PARAM2(param1, param2) void **_args = alloca(sizeof(void *)*4); \ | 68 #define DW_FUNCTION_ADD_PARAM2(param1, param2) void **_args = alloca(sizeof(void *)*4); \ |
1613 GtkWidget *dialog; | 1616 GtkWidget *dialog; |
1614 int response; | 1617 int response; |
1615 va_list args; | 1618 va_list args; |
1616 char outbuf[1025] = {0}; | 1619 char outbuf[1025] = {0}; |
1617 DWDialog *tmp = dw_dialog_new(NULL); | 1620 DWDialog *tmp = dw_dialog_new(NULL); |
1621 ULONG width, height; | |
1618 | 1622 |
1619 va_start(args, format); | 1623 va_start(args, format); |
1620 vsnprintf(outbuf, 1024, format, args); | 1624 vsnprintf(outbuf, 1024, format, args); |
1621 va_end(args); | 1625 va_end(args); |
1622 | 1626 |
1640 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", outbuf); | 1644 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", outbuf); |
1641 if(flags & DW_MB_YESNOCANCEL) | 1645 if(flags & DW_MB_YESNOCANCEL) |
1642 gtk_dialog_add_button(GTK_DIALOG(dialog), "Cancel", GTK_RESPONSE_CANCEL); | 1646 gtk_dialog_add_button(GTK_DIALOG(dialog), "Cancel", GTK_RESPONSE_CANCEL); |
1643 gtk_widget_show(GTK_WIDGET(dialog)); | 1647 gtk_widget_show(GTK_WIDGET(dialog)); |
1644 g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(_dw_dialog_response), (gpointer)tmp); | 1648 g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(_dw_dialog_response), (gpointer)tmp); |
1649 /* Center the dialog on the screen since there is no parent */ | |
1650 dw_window_get_pos_size((HWND)dialog, NULL, NULL, &width, &height); | |
1651 dw_window_set_pos((HWND)dialog, (dw_screen_width() - width)/2, (dw_screen_height() - height)/2); | |
1645 response = DW_POINTER_TO_INT(dw_dialog_wait(tmp)); | 1652 response = DW_POINTER_TO_INT(dw_dialog_wait(tmp)); |
1646 if(GTK_IS_WINDOW(dialog)) | 1653 if(GTK_IS_WINDOW(dialog)) |
1647 gtk_window_destroy(GTK_WINDOW(dialog)); | 1654 gtk_window_destroy(GTK_WINDOW(dialog)); |
1648 switch(response) | 1655 switch(response) |
1649 { | 1656 { |
2289 /* TODO */ | 2296 /* TODO */ |
2290 return 0; | 2297 return 0; |
2291 } | 2298 } |
2292 | 2299 |
2293 /* | 2300 /* |
2294 * Captures the mouse input to this window. | |
2295 * Parameters: | |
2296 * handle: Handle to receive mouse input. | |
2297 */ | |
2298 void dw_window_capture(HWND handle) | |
2299 { | |
2300 /* TODO: See if this is possible in GTK4 */ | |
2301 } | |
2302 | |
2303 /* | |
2304 * Changes the appearance of the mouse pointer. | 2301 * Changes the appearance of the mouse pointer. |
2305 * Parameters: | 2302 * Parameters: |
2306 * handle: Handle to widget for which to change. | 2303 * handle: Handle to widget for which to change. |
2307 * cursortype: ID of the pointer you want. | 2304 * cursortype: ID of the pointer you want. |
2308 */ | 2305 */ |
2328 gtk_widget_set_cursor(GTK_WIDGET(handle), NULL); | 2325 gtk_widget_set_cursor(GTK_WIDGET(handle), NULL); |
2329 DW_FUNCTION_RETURN_NOTHING; | 2326 DW_FUNCTION_RETURN_NOTHING; |
2330 } | 2327 } |
2331 | 2328 |
2332 /* | 2329 /* |
2330 * Captures the mouse input to this window. | |
2331 * Parameters: | |
2332 * handle: Handle to receive mouse input. | |
2333 */ | |
2334 #ifndef GDK_WINDOWING_X11 | |
2335 void dw_window_capture(HWND handle) | |
2336 { | |
2337 } | |
2338 #else | |
2339 static Display *_DWXGrabbedDisplay = NULL; | |
2340 | |
2341 DW_FUNCTION_DEFINITION(dw_window_capture, void, HWND handle) | |
2342 DW_FUNCTION_ADD_PARAM1(handle) | |
2343 DW_FUNCTION_NO_RETURN(dw_window_capture) | |
2344 DW_FUNCTION_RESTORE_PARAM1(handle, HWND) | |
2345 { | |
2346 if(_DWXGrabbedDisplay == NULL && handle && GTK_IS_WINDOW(handle)) | |
2347 { | |
2348 GdkSurface *surface = gtk_native_get_surface(GTK_NATIVE(handle)); | |
2349 | |
2350 if(surface) | |
2351 { | |
2352 if(XGrabPointer(GDK_SURFACE_XDISPLAY(surface), GDK_SURFACE_XID(surface), FALSE, | |
2353 ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask, | |
2354 GrabModeAsync, GrabModeAsync, None, None, CurrentTime) == GrabSuccess) | |
2355 _DWXGrabbedDisplay = GDK_SURFACE_XDISPLAY(surface); | |
2356 | |
2357 } | |
2358 } | |
2359 DW_FUNCTION_RETURN_NOTHING; | |
2360 } | |
2361 #endif | |
2362 | |
2363 /* | |
2333 * Releases previous mouse capture. | 2364 * Releases previous mouse capture. |
2334 */ | 2365 */ |
2366 #ifndef GDK_WINDOWING_X11 | |
2335 void dw_window_release(void) | 2367 void dw_window_release(void) |
2336 { | 2368 { |
2337 /* TODO: See if this is possible in GTK4 */ | 2369 } |
2338 } | 2370 #else |
2371 DW_FUNCTION_DEFINITION(dw_window_release, void) | |
2372 DW_FUNCTION_ADD_PARAM | |
2373 DW_FUNCTION_NO_RETURN(dw_window_release) | |
2374 { | |
2375 if(_DWXGrabbedDisplay) | |
2376 { | |
2377 XUngrabPointer(_DWXGrabbedDisplay, CurrentTime); | |
2378 _DWXGrabbedDisplay = NULL; | |
2379 } | |
2380 DW_FUNCTION_RETURN_NOTHING; | |
2381 } | |
2382 #endif | |
2339 | 2383 |
2340 /* Window creation flags that will cause the window to have decorations */ | 2384 /* Window creation flags that will cause the window to have decorations */ |
2341 #define _DW_DECORATION_FLAGS (DW_FCF_CLOSEBUTTON|DW_FCF_SYSMENU|DW_FCF_TITLEBAR|DW_FCF_MINMAX|DW_FCF_SIZEBORDER|DW_FCF_BORDER|DW_FCF_DLGBORDER) | 2385 #define _DW_DECORATION_FLAGS (DW_FCF_CLOSEBUTTON|DW_FCF_SYSMENU|DW_FCF_TITLEBAR|DW_FCF_MINMAX|DW_FCF_SIZEBORDER|DW_FCF_BORDER|DW_FCF_DLGBORDER) |
2342 | 2386 |
2343 /* | 2387 /* |
6862 /* Try with various extentions */ | 6906 /* Try with various extentions */ |
6863 while(_dw_image_exts[i] && !pixmap->pixbuf) | 6907 while(_dw_image_exts[i] && !pixmap->pixbuf) |
6864 { | 6908 { |
6865 strcpy(file, filename); | 6909 strcpy(file, filename); |
6866 strcat(file, _dw_image_exts[i]); | 6910 strcat(file, _dw_image_exts[i]); |
6867 if(access(file, 04 ) == 0) | 6911 if(access(file, 04) == 0) |
6868 pixmap->pixbuf = gdk_pixbuf_new_from_file(file, NULL); | 6912 pixmap->pixbuf = gdk_pixbuf_new_from_file(file, NULL); |
6869 i++; | 6913 i++; |
6870 } | 6914 } |
6871 } | 6915 } |
6872 else | 6916 else |
8581 DW_FUNCTION_NO_RETURN(dw_window_get_pos_size) | 8625 DW_FUNCTION_NO_RETURN(dw_window_get_pos_size) |
8582 DW_FUNCTION_RESTORE_PARAM5(handle, HWND, x, long *, y, long *, width, ULONG *, height, ULONG *) | 8626 DW_FUNCTION_RESTORE_PARAM5(handle, HWND, x, long *, y, long *, width, ULONG *, height, ULONG *) |
8583 { | 8627 { |
8584 if(handle && GTK_IS_WIDGET(handle)) | 8628 if(handle && GTK_IS_WIDGET(handle)) |
8585 { | 8629 { |
8630 GtkRequisition size; | |
8631 | |
8632 /* If the widget hasn't been shown, it returns 0 so use this as backup */ | |
8633 gtk_widget_get_preferred_size(GTK_WIDGET(handle), NULL, &size); | |
8634 | |
8586 if(width) | 8635 if(width) |
8636 { | |
8587 *width = (ULONG)gtk_widget_get_width(GTK_WIDGET(handle)); | 8637 *width = (ULONG)gtk_widget_get_width(GTK_WIDGET(handle)); |
8638 if(!*width) | |
8639 *width = (ULONG)size.width; | |
8640 } | |
8588 if(height) | 8641 if(height) |
8642 { | |
8589 *height = (ULONG)gtk_widget_get_height(GTK_WIDGET(handle)); | 8643 *height = (ULONG)gtk_widget_get_height(GTK_WIDGET(handle)); |
8644 if(!*height) | |
8645 *height = (ULONG)size.height; | |
8646 } | |
8590 | 8647 |
8591 #ifdef GDK_WINDOWING_X11 | 8648 #ifdef GDK_WINDOWING_X11 |
8592 { | 8649 { |
8593 GdkSurface *surface = gtk_native_get_surface(GTK_NATIVE(handle)); | 8650 GdkSurface *surface = gtk_native_get_surface(GTK_NATIVE(handle)); |
8594 | 8651 |