1 /*
2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
94
95 jclass jHashSetCls;
96 jmethodID jHashSetInit;
97
98 jmethodID jSetAdd;
99 jmethodID jSetSize;
100 jmethodID jSetToArray;
101
102 jmethodID jIterableIterator;
103 jmethodID jIteratorHasNext;
104 jmethodID jIteratorNext;
105
106 jclass jApplicationCls;
107 jfieldID jApplicationDisplay;
108 jfieldID jApplicationScreen;
109 jfieldID jApplicationVisualID;
110 jmethodID jApplicationReportException;
111 jmethodID jApplicationGetApplication;
112 jmethodID jApplicationGetName;
113
114 #pragma GCC diagnostic push
115 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
116 void init_threads() {
117 gboolean is_g_thread_get_initialized = FALSE;
118 if (glib_check_version(2, 32, 0)) { // < 2.32
119 if (!glib_check_version(2, 20, 0)) {
120 is_g_thread_get_initialized = g_thread_get_initialized();
121 }
122 if (!is_g_thread_get_initialized) {
123 // Calling g_thread_init() multiple times leads to crash on GLib < 2.24
124 // We can use g_thread_get_initialized () but it is available only for
125 // GLib >= 2.20. We rely on GThreadHelper for GLib < 2.20.
126 // g_thread_init is no longer necessary for GLib >=2.32
127 g_thread_init(NULL);
128 }
129 }
130 gdk_threads_init();
131 }
132 #pragma GCC diagnostic pop
133
134 static jboolean displayValid = JNI_FALSE;
135
136 jboolean
137 is_display_valid() {
138 return displayValid;
139 }
140
141 JNIEXPORT jint JNICALL
142 JNI_OnLoad(JavaVM *jvm, void *reserved)
143 {
144 (void)reserved;
145
146 JNIEnv *env;
147 jclass clazz;
148 Display* display;
149
150 if (jvm->GetEnv((void **)&env, JNI_VERSION_1_6)) {
151 return JNI_ERR; /* JNI version not supported */
152 }
153
321 if (env->ExceptionCheck()) return JNI_ERR;
322
323 clazz = env->FindClass("com/sun/glass/ui/gtk/GtkApplication");
324 if (env->ExceptionCheck()) return JNI_ERR;
325 jApplicationCls = (jclass) env->NewGlobalRef(clazz);
326 jApplicationDisplay = env->GetStaticFieldID(jApplicationCls, "display", "J");
327 if (env->ExceptionCheck()) return JNI_ERR;
328 jApplicationScreen = env->GetStaticFieldID(jApplicationCls, "screen", "I");
329 if (env->ExceptionCheck()) return JNI_ERR;
330 jApplicationVisualID = env->GetStaticFieldID(jApplicationCls, "visualID", "J");
331 if (env->ExceptionCheck()) return JNI_ERR;
332 jApplicationReportException = env->GetStaticMethodID(
333 jApplicationCls, "reportException", "(Ljava/lang/Throwable;)V");
334 if (env->ExceptionCheck()) return JNI_ERR;
335 jApplicationGetApplication = env->GetStaticMethodID(
336 jApplicationCls, "GetApplication", "()Lcom/sun/glass/ui/Application;");
337 if (env->ExceptionCheck()) return JNI_ERR;
338 jApplicationGetName = env->GetMethodID(jApplicationCls, "getName", "()Ljava/lang/String;");
339 if (env->ExceptionCheck()) return JNI_ERR;
340
341 // Before doing anything with GTK we validate that the DISPLAY can be opened
342 display = XOpenDisplay(NULL);
343 if (display != NULL) {
344 XCloseDisplay(display);
345 displayValid = JNI_TRUE;
346 } else {
347 // Invalid DISPLAY, skip initialization
348 return JNI_VERSION_1_6;
349 }
350
351 clazz = env->FindClass("sun/misc/GThreadHelper");
352 if (env->ExceptionCheck()) return JNI_ERR;
353 if (clazz) {
354 jmethodID mid_getAndSetInitializationNeededFlag = env->GetStaticMethodID(clazz, "getAndSetInitializationNeededFlag", "()Z");
355 if (env->ExceptionCheck()) return JNI_ERR;
356 jmethodID mid_lock = env->GetStaticMethodID(clazz, "lock", "()V");
357 if (env->ExceptionCheck()) return JNI_ERR;
358 jmethodID mid_unlock = env->GetStaticMethodID(clazz, "unlock", "()V");
359 if (env->ExceptionCheck()) return JNI_ERR;
360
361 env->CallStaticVoidMethod(clazz, mid_lock);
362
363 if (!env->CallStaticBooleanMethod(clazz, mid_getAndSetInitializationNeededFlag)) {
364 init_threads();
365 }
366
367 env->CallStaticVoidMethod(clazz, mid_unlock);
368 } else {
369 env->ExceptionClear();
370 init_threads();
371 }
372
373 gdk_threads_enter();
374 gtk_init(NULL, NULL);
375
376 return JNI_VERSION_1_6;
377 }
378
379 void
380 glass_throw_exception(JNIEnv * env,
381 const char * exceptionClass,
382 const char * exceptionMessage) {
383 jclass throwableClass = env->FindClass(exceptionClass);
384 if (check_and_clear_exception(env)) return;
385 env->ThrowNew(throwableClass, exceptionMessage);
386 check_and_clear_exception(env);
387 }
388
389 int
390 glass_throw_oom(JNIEnv * env, const char * message) {
391 glass_throw_exception(env, "java/lang/OutOfMemoryError", message);
392 // must return a non-zero value, see HANDLE_MEM_ALLOC_ERROR
393 return 1;
394 }
395
523
524 for (guint i = 0; i < size; ++i) {
525 if (!g_str_has_prefix(uris[i], FILE_PREFIX)
526 && !g_str_has_prefix(uris[i], URI_LIST_COMMENT_PREFIX)) {
527 g_string_append(str, uris[i]);
528 g_string_append(str, URI_LIST_LINE_BREAK);
529 }
530 }
531
532 if (str->len > 2) {
533 g_string_erase(str, str->len - 2, 2);
534 }
535
536 result = env->NewStringUTF(str->str);
537 check_and_clear_exception(env);
538
539 g_string_free(str, TRUE);
540 }
541 g_strfreev(uris);
542 return result;
543 }
|
1 /*
2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
94
95 jclass jHashSetCls;
96 jmethodID jHashSetInit;
97
98 jmethodID jSetAdd;
99 jmethodID jSetSize;
100 jmethodID jSetToArray;
101
102 jmethodID jIterableIterator;
103 jmethodID jIteratorHasNext;
104 jmethodID jIteratorNext;
105
106 jclass jApplicationCls;
107 jfieldID jApplicationDisplay;
108 jfieldID jApplicationScreen;
109 jfieldID jApplicationVisualID;
110 jmethodID jApplicationReportException;
111 jmethodID jApplicationGetApplication;
112 jmethodID jApplicationGetName;
113
114 static jboolean displayValid = JNI_FALSE;
115
116 jboolean
117 is_display_valid() {
118 return displayValid;
119 }
120
121 JNIEXPORT jint JNICALL
122 JNI_OnLoad(JavaVM *jvm, void *reserved)
123 {
124 (void)reserved;
125
126 JNIEnv *env;
127 jclass clazz;
128 Display* display;
129
130 if (jvm->GetEnv((void **)&env, JNI_VERSION_1_6)) {
131 return JNI_ERR; /* JNI version not supported */
132 }
133
301 if (env->ExceptionCheck()) return JNI_ERR;
302
303 clazz = env->FindClass("com/sun/glass/ui/gtk/GtkApplication");
304 if (env->ExceptionCheck()) return JNI_ERR;
305 jApplicationCls = (jclass) env->NewGlobalRef(clazz);
306 jApplicationDisplay = env->GetStaticFieldID(jApplicationCls, "display", "J");
307 if (env->ExceptionCheck()) return JNI_ERR;
308 jApplicationScreen = env->GetStaticFieldID(jApplicationCls, "screen", "I");
309 if (env->ExceptionCheck()) return JNI_ERR;
310 jApplicationVisualID = env->GetStaticFieldID(jApplicationCls, "visualID", "J");
311 if (env->ExceptionCheck()) return JNI_ERR;
312 jApplicationReportException = env->GetStaticMethodID(
313 jApplicationCls, "reportException", "(Ljava/lang/Throwable;)V");
314 if (env->ExceptionCheck()) return JNI_ERR;
315 jApplicationGetApplication = env->GetStaticMethodID(
316 jApplicationCls, "GetApplication", "()Lcom/sun/glass/ui/Application;");
317 if (env->ExceptionCheck()) return JNI_ERR;
318 jApplicationGetName = env->GetMethodID(jApplicationCls, "getName", "()Ljava/lang/String;");
319 if (env->ExceptionCheck()) return JNI_ERR;
320
321 return JNI_VERSION_1_6;
322 }
323
324 void
325 glass_throw_exception(JNIEnv * env,
326 const char * exceptionClass,
327 const char * exceptionMessage) {
328 jclass throwableClass = env->FindClass(exceptionClass);
329 if (check_and_clear_exception(env)) return;
330 env->ThrowNew(throwableClass, exceptionMessage);
331 check_and_clear_exception(env);
332 }
333
334 int
335 glass_throw_oom(JNIEnv * env, const char * message) {
336 glass_throw_exception(env, "java/lang/OutOfMemoryError", message);
337 // must return a non-zero value, see HANDLE_MEM_ALLOC_ERROR
338 return 1;
339 }
340
468
469 for (guint i = 0; i < size; ++i) {
470 if (!g_str_has_prefix(uris[i], FILE_PREFIX)
471 && !g_str_has_prefix(uris[i], URI_LIST_COMMENT_PREFIX)) {
472 g_string_append(str, uris[i]);
473 g_string_append(str, URI_LIST_LINE_BREAK);
474 }
475 }
476
477 if (str->len > 2) {
478 g_string_erase(str, str->len - 2, 2);
479 }
480
481 result = env->NewStringUTF(str->str);
482 check_and_clear_exception(env);
483
484 g_string_free(str, TRUE);
485 }
486 g_strfreev(uris);
487 return result;
488 }
489
490 //***************************************************************************
491
492 typedef struct _DeviceGrabContext {
493 GdkWindow * window;
494 gboolean grabbed;
495 } DeviceGrabContext;
496
497 gboolean disableGrab = FALSE;
498 static gboolean configure_transparent_window(GtkWidget *window);
499 static void configure_opaque_window(GtkWidget *window);
500
501 static void grab_mouse_device(GdkDevice *device, DeviceGrabContext *context);
502 static void ungrab_mouse_device(GdkDevice *device);
503
504 gint glass_gdk_visual_get_depth (GdkVisual * visual)
505 {
506 // gdk_visual_get_depth is GTK 2.2 +
507 return gdk_visual_get_depth(visual);
508 }
509
510 GdkScreen * glass_gdk_window_get_screen(GdkWindow * gdkWindow)
511 {
512 #ifdef GLASS_GTK3
513 GdkVisual * gdkVisual = gdk_window_get_visual(gdkWindow);
514 return gdk_visual_get_screen(gdkVisual);
515 #else
516 return gdk_window_get_screen(gdkWindow);
517 #endif
518 }
519
520 gboolean
521 glass_gdk_mouse_devices_grab(GdkWindow *gdkWindow) {
522 #ifdef GLASS_GTK3_DISABLED
523 //this GTK 3 approach has synchronization issues covered in JDK-8176844
524 // As the approach is also deprecated in GTK 3.20+, revert back to using GTK 2 mechanism
525
526 if (disableGrab) {
527 return TRUE;
528 }
529 DeviceGrabContext context;
530 GList *devices = gdk_device_manager_list_devices (
531 gdk_display_get_device_manager(
532 gdk_display_get_default()),
533 GDK_DEVICE_TYPE_MASTER);
534
535 context.window = gdkWindow;
536 context.grabbed = FALSE;
537 g_list_foreach(devices, (GFunc) grab_mouse_device, &context);
538 g_list_free(devices);
539
540 return context.grabbed;
541 #else
542 return glass_gdk_mouse_devices_grab_with_cursor(gdkWindow, NULL, TRUE);
543 #endif
544 }
545
546 gboolean
547 glass_gdk_mouse_devices_grab_with_cursor(GdkWindow *gdkWindow, GdkCursor *cursor, gboolean owner_events) {
548 if (disableGrab) {
549 return TRUE;
550 }
551 GdkGrabStatus status = gdk_pointer_grab(gdkWindow, owner_events, (GdkEventMask)
552 (GDK_POINTER_MOTION_MASK
553 | GDK_POINTER_MOTION_HINT_MASK
554 | GDK_BUTTON_MOTION_MASK
555 | GDK_BUTTON1_MOTION_MASK
556 | GDK_BUTTON2_MOTION_MASK
557 | GDK_BUTTON3_MOTION_MASK
558 | GDK_BUTTON_PRESS_MASK
559 | GDK_BUTTON_RELEASE_MASK),
560 NULL, cursor, GDK_CURRENT_TIME);
561
562 return (status == GDK_GRAB_SUCCESS) ? TRUE : FALSE;
563 }
564
565 void
566 glass_gdk_mouse_devices_ungrab() {
567 #ifdef GLASS_GTK3_DISABLED
568 //this GTK 3 approach has synchronization issues covered in JDK-8176844
569 // As the approach is also deprecated in GTK 3.20+, revert back to using GTK 2 mechanism
570 GList *devices = gdk_device_manager_list_devices(
571 gdk_display_get_device_manager(
572 gdk_display_get_default()),
573 GDK_DEVICE_TYPE_MASTER);
574 g_list_foreach(devices, (GFunc) ungrab_mouse_device, NULL);
575 g_list_free(devices);
576 #else
577 gdk_pointer_ungrab(GDK_CURRENT_TIME);
578 #endif
579 }
580
581 void
582 glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor) {
583 if (disableGrab) {
584 gdk_window_set_cursor(window, cursor);
585 return;
586 }
587 #ifdef GLASS_GTK3
588 gdk_device_grab(gdk_device_manager_get_client_pointer(
589 gdk_display_get_device_manager(
590 gdk_display_get_default())),
591 window, GDK_OWNERSHIP_NONE, FALSE, GDK_ALL_EVENTS_MASK,
592 cursor, GDK_CURRENT_TIME);
593 #else
594 gdk_pointer_grab(window, FALSE, (GdkEventMask)
595 (GDK_POINTER_MOTION_MASK
596 | GDK_BUTTON_MOTION_MASK
597 | GDK_BUTTON1_MOTION_MASK
598 | GDK_BUTTON2_MOTION_MASK
599 | GDK_BUTTON3_MOTION_MASK
600 | GDK_BUTTON_RELEASE_MASK),
601 NULL, cursor, GDK_CURRENT_TIME);
602 #endif
603 }
604
605 void
606 glass_gdk_master_pointer_ungrab() {
607 #ifdef GLASS_GTK3
608 gdk_device_ungrab(gdk_device_manager_get_client_pointer(
609 gdk_display_get_device_manager(
610 gdk_display_get_default())),
611 GDK_CURRENT_TIME);
612 #else
613 gdk_pointer_ungrab(GDK_CURRENT_TIME);
614 #endif
615 }
616
617 void
618 glass_gdk_master_pointer_get_position(gint *x, gint *y) {
619 #ifdef GLASS_GTK3
620 gdk_device_get_position(gdk_device_manager_get_client_pointer(
621 gdk_display_get_device_manager(
622 gdk_display_get_default())),
623 NULL, x, y);
624 #else
625 gdk_display_get_pointer(gdk_display_get_default(), NULL, x, y, NULL);
626 #endif
627 }
628
629 gboolean
630 glass_gdk_device_is_grabbed(GdkDevice *device) {
631 #ifdef GLASS_GTK3
632 return gdk_display_device_is_grabbed(gdk_display_get_default(), device);
633 #else
634 (void) device;
635 return gdk_display_pointer_is_grabbed(gdk_display_get_default());
636 #endif
637 }
638
639 void
640 glass_gdk_device_ungrab(GdkDevice *device) {
641 #ifdef GLASS_GTK3
642 gdk_device_ungrab(device, GDK_CURRENT_TIME);
643 #else
644 (void) device;
645 gdk_pointer_ungrab(GDK_CURRENT_TIME);
646 #endif
647 }
648
649 GdkWindow *
650 glass_gdk_device_get_window_at_position(GdkDevice *device, gint *x, gint *y) {
651 #ifdef GLASS_GTK3
652 return gdk_device_get_window_at_position(device, x, y);
653 #else
654 (void) device;
655 return gdk_display_get_window_at_pointer(gdk_display_get_default(), x, y);
656 #endif
657 }
658
659 void
660 glass_gtk_configure_transparency_and_realize(GtkWidget *window,
661 gboolean transparent) {
662 gboolean isTransparent = glass_configure_window_transparency(window, transparent);
663 gtk_widget_realize(window);
664 }
665
666 void
667 glass_gtk_window_configure_from_visual(GtkWidget *widget, GdkVisual *visual) {
668 glass_widget_set_visual(widget, visual);
669 }
670
671 static gboolean
672 configure_transparent_window(GtkWidget *window) {
673 GdkScreen *default_screen = gdk_screen_get_default();
674 GdkDisplay *default_display = gdk_display_get_default();
675
676 #ifdef GLASS_GTK3
677 GdkVisual *visual = gdk_screen_get_rgba_visual(default_screen);
678 if (visual
679 && gdk_display_supports_composite(default_display)
680 && gdk_screen_is_composited(default_screen)) {
681 glass_widget_set_visual(window, visual);
682 return TRUE;
683 }
684 #else
685 GdkColormap *colormap = gdk_screen_get_rgba_colormap(default_screen);
686 if (colormap
687 && gdk_display_supports_composite(default_display)
688 && gdk_screen_is_composited(default_screen)) {
689 gtk_widget_set_colormap(window, colormap);
690 return TRUE;
691 }
692 #endif
693
694 return FALSE;
695 }
696
697 void
698 glass_gdk_window_get_size(GdkWindow *window, gint *w, gint *h) {
699 *w = gdk_window_get_width(window);
700 *h = gdk_window_get_height(window);
701 }
702
703 void
704 glass_gdk_display_get_pointer(GdkDisplay* display, gint* x, gint *y) {
705 #ifdef GLASS_GTK3
706 gdk_device_get_position(
707 gdk_device_manager_get_client_pointer(
708 gdk_display_get_device_manager(display)), NULL , x, y);
709 #else
710 gdk_display_get_pointer(display, NULL, x, y, NULL);
711 #endif
712 }
713
714
715 const guchar*
716 glass_gtk_selection_data_get_data_with_length(
717 GtkSelectionData * selectionData,
718 gint * length) {
719 if (selectionData == NULL) {
720 return NULL;
721 }
722
723 *length = gtk_selection_data_get_length(selectionData);
724 return gtk_selection_data_get_data(selectionData);
725 }
726
727 static void
728 configure_opaque_window(GtkWidget *window) {
729 (void) window;
730 /* We need to pick a visual that really is glx compatible
731 * instead of using the default visual
732 */
733 /* see: JDK-8087516 for why this is commented out
734 glass_widget_set_visual(window,
735 gdk_screen_get_system_visual(
736 gdk_screen_get_default()));
737 */
738 }
739
740 gboolean
741 glass_configure_window_transparency(GtkWidget *window, gboolean transparent) {
742 if (transparent) {
743 if (configure_transparent_window(window)) {
744 return TRUE;
745 }
746
747 fprintf(stderr,"Can't create transparent stage, because your screen doesn't"
748 " support alpha channel."
749 " You need to enable XComposite extension.\n");
750 fflush(stderr);
751 }
752
753 configure_opaque_window(window);
754 return FALSE;
755 }
756
757 static void
758 grab_mouse_device(GdkDevice *device, DeviceGrabContext *context) {
759 GdkInputSource source = gdk_device_get_source(device);
760 if (source == GDK_SOURCE_MOUSE) {
761 #ifdef GLASS_GTK3
762 GdkGrabStatus status = gdk_device_grab(device,
763 context->window,
764 GDK_OWNERSHIP_NONE,
765 TRUE,
766 GDK_ALL_EVENTS_MASK,
767 NULL,
768 GDK_CURRENT_TIME);
769 #else
770 GdkGrabStatus status = GDK_GRAB_SUCCESS;
771 /* FIXME reachable by 2?
772 GdkGrabStatus status = gdk_device_grab(device,
773 context->window,
774 GDK_OWNERSHIP_NONE,
775 TRUE,
776 GDK_ALL_EVENTS_MASK,
777 NULL,
778 GDK_CURRENT_TIME);
779 */
780 #endif
781 if (status == GDK_GRAB_SUCCESS) {
782 context->grabbed = TRUE;
783 }
784 }
785 }
786
787 static void
788 ungrab_mouse_device(GdkDevice *device) {
789 #ifdef GLASS_GTK3
790 GdkInputSource source = gdk_device_get_source(device);
791 if (source == GDK_SOURCE_MOUSE) {
792 gdk_device_ungrab(device, GDK_CURRENT_TIME);
793 }
794 #else
795 (void) device;
796 // not used on the GTK2 path
797 #endif
798 }
799
800 GdkPixbuf *
801 glass_pixbuf_from_window(GdkWindow *window,
802 gint srcx, gint srcy,
803 gint width, gint height)
804 {
805 GdkPixbuf * ret = NULL;
806
807 #ifdef GLASS_GTK3
808 ret = gdk_pixbuf_get_from_window (window, srcx, srcy, width, height);
809 #else
810 ret = gdk_pixbuf_get_from_drawable (NULL,
811 window,
812 NULL,
813 srcx, srcy,
814 0, 0,
815 width, height);
816 #endif
817 return ret;
818 }
819
820 void
821 glass_window_apply_shape_mask(GdkWindow *window,
822 void* data, uint width, uint height)
823 {
824 #ifdef GLASS_GTK3
825 (void) window;
826 (void) data;
827 (void) width;
828 (void) height;
829 #else
830 GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data((guchar *) data,
831 GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL);
832
833 if (GDK_IS_PIXBUF(pixbuf)) {
834 GdkBitmap* mask = NULL;
835 gdk_pixbuf_render_pixmap_and_mask(pixbuf, NULL, &mask, 128);
836
837 gdk_window_input_shape_combine_mask(window, mask, 0, 0);
838
839 g_object_unref(pixbuf);
840 if (mask) {
841 g_object_unref(mask);
842 }
843 }
844 #endif
845 }
846
847 void
848 glass_window_reset_input_shape_mask(GdkWindow *window)
849 {
850 #ifdef GLASS_GTK3
851 gdk_window_input_shape_combine_region(window, NULL, 0, 0);
852 #else
853 gdk_window_input_shape_combine_mask(window, NULL, 0, 0);
854 #endif
855 }
856
857 GdkWindow *
858 glass_gdk_drag_context_get_dest_window (GdkDragContext * context)
859 {
860 return ((context != NULL) ? gdk_drag_context_get_dest_window(context) : NULL);
861 }
862
863
864 void glass_gdk_x11_display_set_window_scale (GdkDisplay *display,
865 gint scale)
866 {
867 #ifdef GLASS_GTK3
868 // Optional call, if it does not exist then GTK3 is not yet
869 // doing automatic scaling of coordinates so we do not need
870 // to override it.
871 wrapped_gdk_x11_display_set_window_scale(display, scale);
872 #else
873 (void) display;
874 (void) scale;
875 #endif
876 }
877
878 //-------- Glass utility ----------------------------------------
879
880 void
881 glass_widget_set_visual(GtkWidget *widget, GdkVisual *visual)
882 {
883 #ifdef GLASS_GTK3
884 gtk_widget_set_visual (widget, visual);
885 #else
886 GdkColormap *colormap = gdk_colormap_new(visual, TRUE);
887 gtk_widget_set_colormap (widget, colormap);
888 #endif
889 }
|