< prev index next >
modules/graphics/src/main/native-glass/gtk/glass_general.cpp
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -109,30 +109,10 @@
jfieldID jApplicationVisualID;
jmethodID jApplicationReportException;
jmethodID jApplicationGetApplication;
jmethodID jApplicationGetName;
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-void init_threads() {
- gboolean is_g_thread_get_initialized = FALSE;
- if (glib_check_version(2, 32, 0)) { // < 2.32
- if (!glib_check_version(2, 20, 0)) {
- is_g_thread_get_initialized = g_thread_get_initialized();
- }
- if (!is_g_thread_get_initialized) {
- // Calling g_thread_init() multiple times leads to crash on GLib < 2.24
- // We can use g_thread_get_initialized () but it is available only for
- // GLib >= 2.20. We rely on GThreadHelper for GLib < 2.20.
- // g_thread_init is no longer necessary for GLib >=2.32
- g_thread_init(NULL);
- }
- }
- gdk_threads_init();
-}
-#pragma GCC diagnostic pop
-
static jboolean displayValid = JNI_FALSE;
jboolean
is_display_valid() {
return displayValid;
@@ -336,45 +316,10 @@
jApplicationCls, "GetApplication", "()Lcom/sun/glass/ui/Application;");
if (env->ExceptionCheck()) return JNI_ERR;
jApplicationGetName = env->GetMethodID(jApplicationCls, "getName", "()Ljava/lang/String;");
if (env->ExceptionCheck()) return JNI_ERR;
- // Before doing anything with GTK we validate that the DISPLAY can be opened
- display = XOpenDisplay(NULL);
- if (display != NULL) {
- XCloseDisplay(display);
- displayValid = JNI_TRUE;
- } else {
- // Invalid DISPLAY, skip initialization
- return JNI_VERSION_1_6;
- }
-
- clazz = env->FindClass("sun/misc/GThreadHelper");
- if (env->ExceptionCheck()) return JNI_ERR;
- if (clazz) {
- jmethodID mid_getAndSetInitializationNeededFlag = env->GetStaticMethodID(clazz, "getAndSetInitializationNeededFlag", "()Z");
- if (env->ExceptionCheck()) return JNI_ERR;
- jmethodID mid_lock = env->GetStaticMethodID(clazz, "lock", "()V");
- if (env->ExceptionCheck()) return JNI_ERR;
- jmethodID mid_unlock = env->GetStaticMethodID(clazz, "unlock", "()V");
- if (env->ExceptionCheck()) return JNI_ERR;
-
- env->CallStaticVoidMethod(clazz, mid_lock);
-
- if (!env->CallStaticBooleanMethod(clazz, mid_getAndSetInitializationNeededFlag)) {
- init_threads();
- }
-
- env->CallStaticVoidMethod(clazz, mid_unlock);
- } else {
- env->ExceptionClear();
- init_threads();
- }
-
- gdk_threads_enter();
- gtk_init(NULL, NULL);
-
return JNI_VERSION_1_6;
}
void
glass_throw_exception(JNIEnv * env,
@@ -539,5 +484,438 @@
g_string_free(str, TRUE);
}
g_strfreev(uris);
return result;
}
+
+//***************************************************************************
+
+typedef struct _DeviceGrabContext {
+ GdkWindow * window;
+ gboolean grabbed;
+} DeviceGrabContext;
+
+gboolean disableGrab = FALSE;
+static gboolean configure_transparent_window(GtkWidget *window);
+static void configure_opaque_window(GtkWidget *window);
+
+static void grab_mouse_device(GdkDevice *device, DeviceGrabContext *context);
+static void ungrab_mouse_device(GdkDevice *device);
+
+gint glass_gdk_visual_get_depth (GdkVisual * visual)
+{
+ // gdk_visual_get_depth is GTK 2.2 +
+ return gdk_visual_get_depth(visual);
+}
+
+GdkScreen * glass_gdk_window_get_screen(GdkWindow * gdkWindow)
+{
+#ifdef GLASS_GTK3
+ GdkVisual * gdkVisual = gdk_window_get_visual(gdkWindow);
+ return gdk_visual_get_screen(gdkVisual);
+#else
+ return gdk_window_get_screen(gdkWindow);
+#endif
+}
+
+gboolean
+glass_gdk_mouse_devices_grab(GdkWindow *gdkWindow) {
+#ifdef GLASS_GTK3_DISABLED
+//this GTK 3 approach has synchronization issues covered in JDK-8176844
+// As the approach is also deprecated in GTK 3.20+, revert back to using GTK 2 mechanism
+
+ if (disableGrab) {
+ return TRUE;
+ }
+ DeviceGrabContext context;
+ GList *devices = gdk_device_manager_list_devices (
+ gdk_display_get_device_manager(
+ gdk_display_get_default()),
+ GDK_DEVICE_TYPE_MASTER);
+
+ context.window = gdkWindow;
+ context.grabbed = FALSE;
+ g_list_foreach(devices, (GFunc) grab_mouse_device, &context);
+ g_list_free(devices);
+
+ return context.grabbed;
+#else
+ return glass_gdk_mouse_devices_grab_with_cursor(gdkWindow, NULL, TRUE);
+#endif
+}
+
+gboolean
+glass_gdk_mouse_devices_grab_with_cursor(GdkWindow *gdkWindow, GdkCursor *cursor, gboolean owner_events) {
+ if (disableGrab) {
+ return TRUE;
+ }
+ GdkGrabStatus status = gdk_pointer_grab(gdkWindow, owner_events, (GdkEventMask)
+ (GDK_POINTER_MOTION_MASK
+ | GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON_MOTION_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_BUTTON2_MOTION_MASK
+ | GDK_BUTTON3_MOTION_MASK
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK),
+ NULL, cursor, GDK_CURRENT_TIME);
+
+ return (status == GDK_GRAB_SUCCESS) ? TRUE : FALSE;
+}
+
+void
+glass_gdk_mouse_devices_ungrab() {
+#ifdef GLASS_GTK3_DISABLED
+//this GTK 3 approach has synchronization issues covered in JDK-8176844
+// As the approach is also deprecated in GTK 3.20+, revert back to using GTK 2 mechanism
+ GList *devices = gdk_device_manager_list_devices(
+ gdk_display_get_device_manager(
+ gdk_display_get_default()),
+ GDK_DEVICE_TYPE_MASTER);
+ g_list_foreach(devices, (GFunc) ungrab_mouse_device, NULL);
+ g_list_free(devices);
+#else
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
+#endif
+}
+
+void
+glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor) {
+ if (disableGrab) {
+ gdk_window_set_cursor(window, cursor);
+ return;
+ }
+#ifdef GLASS_GTK3
+ gdk_device_grab(gdk_device_manager_get_client_pointer(
+ gdk_display_get_device_manager(
+ gdk_display_get_default())),
+ window, GDK_OWNERSHIP_NONE, FALSE, GDK_ALL_EVENTS_MASK,
+ cursor, GDK_CURRENT_TIME);
+#else
+ gdk_pointer_grab(window, FALSE, (GdkEventMask)
+ (GDK_POINTER_MOTION_MASK
+ | GDK_BUTTON_MOTION_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_BUTTON2_MOTION_MASK
+ | GDK_BUTTON3_MOTION_MASK
+ | GDK_BUTTON_RELEASE_MASK),
+ NULL, cursor, GDK_CURRENT_TIME);
+#endif
+}
+
+void
+glass_gdk_master_pointer_ungrab() {
+#ifdef GLASS_GTK3
+ gdk_device_ungrab(gdk_device_manager_get_client_pointer(
+ gdk_display_get_device_manager(
+ gdk_display_get_default())),
+ GDK_CURRENT_TIME);
+#else
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
+#endif
+}
+
+void
+glass_gdk_master_pointer_get_position(gint *x, gint *y) {
+#ifdef GLASS_GTK3
+ gdk_device_get_position(gdk_device_manager_get_client_pointer(
+ gdk_display_get_device_manager(
+ gdk_display_get_default())),
+ NULL, x, y);
+#else
+ gdk_display_get_pointer(gdk_display_get_default(), NULL, x, y, NULL);
+#endif
+}
+
+gboolean
+glass_gdk_device_is_grabbed(GdkDevice *device) {
+#ifdef GLASS_GTK3
+ return gdk_display_device_is_grabbed(gdk_display_get_default(), device);
+#else
+ (void) device;
+ return gdk_display_pointer_is_grabbed(gdk_display_get_default());
+#endif
+}
+
+void
+glass_gdk_device_ungrab(GdkDevice *device) {
+#ifdef GLASS_GTK3
+ gdk_device_ungrab(device, GDK_CURRENT_TIME);
+#else
+ (void) device;
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
+#endif
+}
+
+GdkWindow *
+glass_gdk_device_get_window_at_position(GdkDevice *device, gint *x, gint *y) {
+#ifdef GLASS_GTK3
+ return gdk_device_get_window_at_position(device, x, y);
+#else
+ (void) device;
+ return gdk_display_get_window_at_pointer(gdk_display_get_default(), x, y);
+#endif
+}
+
+void
+glass_gtk_configure_transparency_and_realize(GtkWidget *window,
+ gboolean transparent) {
+ gboolean isTransparent = glass_configure_window_transparency(window, transparent);
+ gtk_widget_realize(window);
+}
+
+void
+glass_gtk_window_configure_from_visual(GtkWidget *widget, GdkVisual *visual) {
+ glass_widget_set_visual(widget, visual);
+}
+
+static gboolean
+configure_transparent_window(GtkWidget *window) {
+ GdkScreen *default_screen = gdk_screen_get_default();
+ GdkDisplay *default_display = gdk_display_get_default();
+
+#ifdef GLASS_GTK3
+ GdkVisual *visual = gdk_screen_get_rgba_visual(default_screen);
+ if (visual
+ && gdk_display_supports_composite(default_display)
+ && gdk_screen_is_composited(default_screen)) {
+ glass_widget_set_visual(window, visual);
+ return TRUE;
+ }
+#else
+ GdkColormap *colormap = gdk_screen_get_rgba_colormap(default_screen);
+ if (colormap
+ && gdk_display_supports_composite(default_display)
+ && gdk_screen_is_composited(default_screen)) {
+ gtk_widget_set_colormap(window, colormap);
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
+void
+glass_gdk_window_get_size(GdkWindow *window, gint *w, gint *h) {
+ *w = gdk_window_get_width(window);
+ *h = gdk_window_get_height(window);
+}
+
+void
+glass_gdk_display_get_pointer(GdkDisplay* display, gint* x, gint *y) {
+#ifdef GLASS_GTK3
+ gdk_device_get_position(
+ gdk_device_manager_get_client_pointer(
+ gdk_display_get_device_manager(display)), NULL , x, y);
+#else
+ gdk_display_get_pointer(display, NULL, x, y, NULL);
+#endif
+}
+
+
+const guchar*
+glass_gtk_selection_data_get_data_with_length(
+ GtkSelectionData * selectionData,
+ gint * length) {
+ if (selectionData == NULL) {
+ return NULL;
+ }
+
+ *length = gtk_selection_data_get_length(selectionData);
+ return gtk_selection_data_get_data(selectionData);
+}
+
+static void
+configure_opaque_window(GtkWidget *window) {
+ (void) window;
+/* We need to pick a visual that really is glx compatible
+ * instead of using the default visual
+ */
+ /* see: JDK-8087516 for why this is commented out
+ glass_widget_set_visual(window,
+ gdk_screen_get_system_visual(
+ gdk_screen_get_default()));
+ */
+}
+
+gboolean
+glass_configure_window_transparency(GtkWidget *window, gboolean transparent) {
+ if (transparent) {
+ if (configure_transparent_window(window)) {
+ return TRUE;
+ }
+
+ fprintf(stderr,"Can't create transparent stage, because your screen doesn't"
+ " support alpha channel."
+ " You need to enable XComposite extension.\n");
+ fflush(stderr);
+ }
+
+ configure_opaque_window(window);
+ return FALSE;
+}
+
+static void
+grab_mouse_device(GdkDevice *device, DeviceGrabContext *context) {
+ GdkInputSource source = gdk_device_get_source(device);
+ if (source == GDK_SOURCE_MOUSE) {
+#ifdef GLASS_GTK3
+ GdkGrabStatus status = gdk_device_grab(device,
+ context->window,
+ GDK_OWNERSHIP_NONE,
+ TRUE,
+ GDK_ALL_EVENTS_MASK,
+ NULL,
+ GDK_CURRENT_TIME);
+#else
+ GdkGrabStatus status = GDK_GRAB_SUCCESS;
+/* FIXME reachable by 2?
+ GdkGrabStatus status = gdk_device_grab(device,
+ context->window,
+ GDK_OWNERSHIP_NONE,
+ TRUE,
+ GDK_ALL_EVENTS_MASK,
+ NULL,
+ GDK_CURRENT_TIME);
+ */
+#endif
+ if (status == GDK_GRAB_SUCCESS) {
+ context->grabbed = TRUE;
+ }
+ }
+}
+
+static void
+ungrab_mouse_device(GdkDevice *device) {
+#ifdef GLASS_GTK3
+ GdkInputSource source = gdk_device_get_source(device);
+ if (source == GDK_SOURCE_MOUSE) {
+ gdk_device_ungrab(device, GDK_CURRENT_TIME);
+ }
+#else
+ (void) device;
+ // not used on the GTK2 path
+#endif
+}
+
+GdkPixbuf *
+glass_pixbuf_from_window(GdkWindow *window,
+ gint srcx, gint srcy,
+ gint width, gint height)
+{
+ GdkPixbuf * ret = NULL;
+
+#ifdef GLASS_GTK3
+ ret = gdk_pixbuf_get_from_window (window, srcx, srcy, width, height);
+#else
+ ret = gdk_pixbuf_get_from_drawable (NULL,
+ window,
+ NULL,
+ srcx, srcy,
+ 0, 0,
+ width, height);
+#endif
+ return ret;
+}
+
+void
+glass_window_apply_shape_mask(GdkWindow *window,
+ void* data, uint width, uint height)
+{
+#ifndef GLASS_GTK3
+ GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data((guchar *) data,
+ GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL);
+
+ if (GDK_IS_PIXBUF(pixbuf)) {
+ GdkBitmap* mask = NULL;
+ gdk_pixbuf_render_pixmap_and_mask(pixbuf, NULL, &mask, 128);
+
+ gdk_window_input_shape_combine_mask(window, mask, 0, 0);
+
+ g_object_unref(pixbuf);
+ if (mask) {
+ g_object_unref(mask);
+ }
+ }
+#endif
+}
+
+void
+glass_window_reset_input_shape_mask(GdkWindow *window)
+{
+#ifdef GLASS_GTK3
+ gdk_window_input_shape_combine_region(window, NULL, 0, 0);
+#else
+ gdk_window_input_shape_combine_mask(window, NULL, 0, 0);
+#endif
+}
+
+GdkWindow *
+glass_gdk_drag_context_get_dest_window (GdkDragContext * context)
+{
+ return ((context != NULL) ? gdk_drag_context_get_dest_window(context) : NULL);
+}
+
+
+void glass_gdk_x11_display_set_window_scale (GdkDisplay *display,
+ gint scale)
+{
+#ifdef GLASS_GTK3
+ // Optional call, if it does not exist then GTK3 is not yet
+ // doing automatic scaling of coordinates so we do not need
+ // to override it.
+ wrapped_gdk_x11_display_set_window_scale(display, scale);
+#else
+ (void) display;
+ (void) scale;
+#endif
+}
+
+//-------- Glass utility ----------------------------------------
+
+void
+glass_widget_set_visual(GtkWidget *widget, GdkVisual *visual)
+{
+#ifdef GLASS_GTK3
+ gtk_widget_set_visual (widget, visual);
+#else
+ GdkColormap *colormap = gdk_colormap_new(visual, TRUE);
+ gtk_widget_set_colormap (widget, colormap);
+#endif
+}
+
+guint glass_settings_get_guint_opt (const gchar *schema_name,
+ const gchar *key_name,
+ int defval)
+{
+ GSettingsSchemaSource *default_schema_source =
+ wrapped_g_settings_schema_source_get_default();
+ if (default_schema_source == NULL) {
+ if (gtk_verbose) {
+ fprintf(stderr, "No schema source dir found!\n");
+ }
+ return defval;
+ }
+ GSettingsSchema *the_schema =
+ wrapped_g_settings_schema_source_lookup(default_schema_source, schema_name, TRUE);
+ if (the_schema == NULL) {
+ if (gtk_verbose) {
+ fprintf(stderr, "schema '%s' not found!\n", schema_name);
+ }
+ return defval;
+ }
+ if (!wrapped_g_settings_schema_has_key(the_schema, key_name)) {
+ if (gtk_verbose) {
+ fprintf(stderr, "key '%s' not found in schema '%s'!\n", key_name, schema_name);
+ }
+ return defval;
+ }
+ if (gtk_verbose) {
+ fprintf(stderr, "found schema '%s' and key '%s'\n", schema_name, key_name);
+ }
+
+ GSettings *gset = g_settings_new(schema_name);
+
+ wrapped_g_settings_schema_unref(the_schema);
+
+ return g_settings_get_uint(gset, key_name);
+}
< prev index next >