< prev index next >

modules/graphics/src/main/native-glass/gtk/glass_general.cpp

Print this page


   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 }
 890 
 891 guint glass_settings_get_guint_opt (const gchar *schema_name,
 892                     const gchar *key_name,
 893                     int defval)
 894 {
 895     GSettingsSchemaSource *default_schema_source =
 896             wrapped_g_settings_schema_source_get_default();
 897     if (default_schema_source == NULL) {
 898         if (gtk_verbose) {
 899             fprintf(stderr, "No schema source dir found!\n");
 900         }
 901         return defval;
 902     }
 903     GSettingsSchema *the_schema =
 904             wrapped_g_settings_schema_source_lookup(default_schema_source, schema_name, TRUE);
 905     if (the_schema == NULL) {
 906         if (gtk_verbose) {
 907             fprintf(stderr, "schema '%s' not found!\n", schema_name);
 908         }
 909         return defval;
 910     }
 911     if (!wrapped_g_settings_schema_has_key(the_schema, key_name)) {
 912         if (gtk_verbose) {
 913             fprintf(stderr, "key '%s' not found in schema '%s'!\n", key_name, schema_name);
 914         }
 915         return defval;
 916     }
 917     if (gtk_verbose) {
 918         fprintf(stderr, "found schema '%s' and key '%s'\n", schema_name, key_name);
 919     }
 920 
 921     GSettings *gset = g_settings_new(schema_name);
 922 
 923     wrapped_g_settings_schema_unref(the_schema);
 924 
 925     return g_settings_get_uint(gset, key_name);
 926 }
< prev index next >