diff options
Diffstat (limited to 'gdk')
74 files changed, 6384 insertions, 4253 deletions
diff --git a/gdk/Makefile.am b/gdk/Makefile.am index 46e79e74e..9b33cb066 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -110,6 +110,8 @@ gdk_public_h_sources = @STRIP_BEGIN@ \ gdktypes.h \ gdkvisual.h \ gdkwindow.h \ + gdkdisplay.h \ + gdkscreen.h \ @STRIP_END@ gdk_headers = @STRIP_BEGIN@ \ @@ -142,6 +144,8 @@ gdk_c_sources = @STRIP_BEGIN@ \ gdkregion-generic.c \ gdkregion-generic.h \ gdkwindow.c \ + gdkdisplay.c \ + gdkscreen.c \ @STRIP_END@ # @@ -51,6 +51,8 @@ static int gdk_initialized = 0; /* 1 if the library is initialized, */ static gchar *gdk_progclass = NULL; +static gint gdk_argc = 0; +static gchar **gdk_argv = NULL; #ifdef G_ENABLE_DEBUG static const GDebugKey gdk_debug_keys[] = { @@ -66,6 +68,7 @@ static const GDebugKey gdk_debug_keys[] = { {"image", GDK_DEBUG_IMAGE}, {"input", GDK_DEBUG_INPUT}, {"cursor", GDK_DEBUG_CURSOR}, + {"multihead", GDK_DEBUG_MULTIHEAD}, }; static const int gdk_ndebug_keys = G_N_ELEMENTS (gdk_debug_keys); @@ -233,8 +236,10 @@ gdk_arg_name_cb (const char *key, const char *value, gpointer user_data) } static GdkArgDesc gdk_args[] = { - { "class" , GDK_ARG_CALLBACK, NULL, gdk_arg_class_cb }, - { "name", GDK_ARG_CALLBACK, NULL, gdk_arg_name_cb }, + { "class" , GDK_ARG_CALLBACK, NULL, gdk_arg_class_cb }, + { "name", GDK_ARG_CALLBACK, NULL, gdk_arg_name_cb }, + { "display", GDK_ARG_STRING, &_gdk_display_name, (GdkArgFunc)NULL }, + #ifdef G_ENABLE_DEBUG { "gdk-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_debug_cb }, { "gdk-no-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_no_debug_cb }, @@ -242,49 +247,53 @@ static GdkArgDesc gdk_args[] = { { NULL } }; -/* - *-------------------------------------------------------------- - * gdk_init_check - * - * Initialize the library for use. - * - * Arguments: - * "argc" is the number of arguments. - * "argv" is an array of strings. - * - * Results: - * "argc" and "argv" are modified to reflect any arguments - * which were not handled. (Such arguments should either - * be handled by the application or dismissed). If initialization - * fails, returns FALSE, otherwise TRUE. + +/** + * _gdk_get_command_line_args: + * @argv: location to store argv pointer + * @argc: location + * + * Retrieve the command line arguments passed to gdk_init(). + * The returned argv pointer points to static storage ; no + * copy is made. + **/ +void +_gdk_get_command_line_args (int *argc, + char ***argv) +{ + *argc = gdk_argc; + *argv = gdk_argv; +} + +/** + * gdk_parse_args: + * @argc: the number of command line arguments. + * @argv: the array of command line arguments. + * + * Parse command line arguments, and store for future + * use by calls to gdk_open_display(). * - * Side effects: - * The library is initialized. + * Any arguments used by GDK are removed from the array and @argc and @argv are + * updated accordingly. * - *-------------------------------------------------------------- - */ - -gboolean -gdk_init_check (int *argc, + * You shouldn't call this function explicitely if you are using + * gtk_init(), gtk_init_check(), gdk_init(), or gdk_init_check(). + **/ +void +gdk_parse_args (int *argc, char ***argv) { - gchar **argv_orig = NULL; - gint argc_orig = 0; GdkArgContext *arg_context; - gboolean result; - int i; - - if (gdk_initialized) - return TRUE; + gint i; if (argc && argv) { - argc_orig = *argc; + gdk_argc = *argc; - argv_orig = g_malloc ((argc_orig + 1) * sizeof (char*)); - for (i = 0; i < argc_orig; i++) - argv_orig[i] = g_strdup ((*argv)[i]); - argv_orig[argc_orig] = NULL; + gdk_argv = g_malloc ((gdk_argc + 1) * sizeof (char*)); + for (i = 0; i < gdk_argc; i++) + gdk_argv[i] = g_strdup ((*argv)[i]); + gdk_argv[gdk_argc] = NULL; if (*argc > 0) { @@ -301,13 +310,13 @@ gdk_init_check (int *argc, { g_set_prgname ("<unknown>"); } - + /* We set the fallback program class here, rather than lazily in * gdk_get_program_class, since we don't want -name to override it. */ gdk_progclass = g_strdup (g_get_prgname ()); if (gdk_progclass[0]) - gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]); + gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]); #ifdef G_ENABLE_DEBUG { @@ -328,26 +337,70 @@ gdk_init_check (int *argc, GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ())); g_type_init (); - - result = _gdk_windowing_init_check (argc_orig, argv_orig); - for (i = 0; i < argc_orig; i++) - g_free(argv_orig[i]); - g_free(argv_orig); + /* Do any setup particular to the windowing system + */ + _gdk_windowing_init (); +} + +/** + * gdk_get_display_arg_name: + * + * Gets the display name specified in the command line arguments passed + * to gdk_init() or gdk_parse_args(), if any. + * + * Returns: the display name, if specified explicitely, otherwise %NULL + */ +gchar * +gdk_get_display_arg_name (void) +{ + return _gdk_display_name; +} - if (!result) - return FALSE; +/* + *-------------------------------------------------------------- + * gdk_init_check + * + * Initialize the library for use. + * + * Arguments: + * "argc" is the number of arguments. + * "argv" is an array of strings. + * + * Results: + * "argc" and "argv" are modified to reflect any arguments + * which were not handled. (Such arguments should either + * be handled by the application or dismissed). If initialization + * fails, returns FALSE, otherwise TRUE. + * + * Side effects: + * The library is initialized. + * + *-------------------------------------------------------------- + */ + +gboolean +gdk_init_check (int *argc, + char ***argv) +{ + GdkDisplay *display; - _gdk_visual_init (); - _gdk_windowing_window_init (); - _gdk_windowing_image_init (); - _gdk_events_init (); - _gdk_input_init (); - _gdk_dnd_init (); + if (gdk_initialized) + return TRUE; + + gdk_parse_args (argc, argv); gdk_initialized = 1; - return TRUE; + display = gdk_open_display (_gdk_display_name); + + if (display) + { + gdk_set_default_display (display); + return TRUE; + } + else + return FALSE; } void @@ -355,7 +408,7 @@ gdk_init (int *argc, char ***argv) { if (!gdk_init_check (argc, argv)) { - g_warning ("cannot open display: %s", gdk_get_display ()); + g_warning ("cannot open display: %s", gdk_get_display_arg_name ()); exit(1); } } @@ -29,6 +29,7 @@ #include <gdk/gdkcolor.h> #include <gdk/gdkcursor.h> +#include <gdk/gdkdisplay.h> #include <gdk/gdkdnd.h> #include <gdk/gdkdrawable.h> #include <gdk/gdkenumtypes.h> @@ -44,6 +45,7 @@ #include <gdk/gdkproperty.h> #include <gdk/gdkregion.h> #include <gdk/gdkrgb.h> +#include <gdk/gdkscreen.h> #include <gdk/gdkselection.h> #include <gdk/gdktypes.h> #include <gdk/gdkvisual.h> @@ -57,6 +59,8 @@ extern "C" { /* Initialization, exit and events */ #define GDK_PRIORITY_EVENTS (G_PRIORITY_DEFAULT) +void gdk_parse_args (gint *argc, + gchar ***argv); void gdk_init (gint *argc, gchar ***argv); gboolean gdk_init_check (gint *argc, @@ -81,6 +85,7 @@ gboolean gdk_get_use_xshm (void); #endif /* GDK_DISABLE_DEPRECATED */ gchar* gdk_get_display (void); +gchar* gdk_get_display_arg_name (void); #ifndef GDK_DISABLE_DEPRECATED gint gdk_input_add_full (gint source, @@ -101,10 +106,12 @@ GdkGrabStatus gdk_pointer_grab (GdkWindow *window, GdkWindow *confine_to, GdkCursor *cursor, guint32 time); -void gdk_pointer_ungrab (guint32 time); GdkGrabStatus gdk_keyboard_grab (GdkWindow *window, gboolean owner_events, guint32 time); + +#ifndef GDK_MULTIHEAD_SAFE +void gdk_pointer_ungrab (guint32 time); void gdk_keyboard_ungrab (guint32 time); gboolean gdk_pointer_is_grabbed (void); @@ -114,10 +121,14 @@ gint gdk_screen_height (void) G_GNUC_CONST; gint gdk_screen_width_mm (void) G_GNUC_CONST; gint gdk_screen_height_mm (void) G_GNUC_CONST; -void gdk_flush (void); void gdk_beep (void); +#endif /* GDK_MULTIHEAD_SAFE */ + +void gdk_flush (void); -void gdk_set_double_click_time (guint msec); +#ifndef GDK_MULTIHEAD_SAFE +void gdk_set_double_click_time (guint msec); +#endif /* Rectangle utilities */ @@ -140,10 +151,14 @@ gint gdk_mbstowcs (GdkWChar *dest, gint dest_max); /* Miscellaneous */ -void gdk_event_send_clientmessage_toall (GdkEvent *event); -gboolean gdk_event_send_client_message (GdkEvent *event, - guint32 xid); - +#ifndef GDK_MULTIHEAD_SAFE +gboolean gdk_event_send_client_message (GdkEvent *event, + guint32 xid); +void gdk_event_send_clientmessage_toall (GdkEvent *event); +#endif +gboolean gdk_event_send_client_message_for_display (GdkDisplay *display, + GdkEvent *event, + guint32 xid); /* Threading */ diff --git a/gdk/gdkcolor.h b/gdk/gdkcolor.h index 490f1f491..6e7308048 100644 --- a/gdk/gdkcolor.h +++ b/gdk/gdkcolor.h @@ -48,6 +48,7 @@ struct _GdkColormap GdkVisual *visual; gpointer windowing_data; + GdkScreen *screen; }; struct _GdkColormapClass @@ -66,9 +67,13 @@ GdkColormap* gdk_colormap_ref (GdkColormap *cmap); void gdk_colormap_unref (GdkColormap *cmap); #endif -GdkColormap* gdk_colormap_get_system (void); +#ifndef GDK_MULTIHEAD_SAFE +GdkColormap* gdk_colormap_get_system (void); +#endif + #ifndef GDK_DISABLE_DEPRECATED -gint gdk_colormap_get_system_size (void); +gint gdk_colormap_get_system_size (void); + void gdk_colormap_change (GdkColormap *colormap, gint ncolors); #endif diff --git a/gdk/gdkcursor.h b/gdk/gdkcursor.h index 24e9c7f7d..187299a0e 100644 --- a/gdk/gdkcursor.h +++ b/gdk/gdkcursor.h @@ -105,13 +105,18 @@ struct _GdkCursor GType gdk_cursor_get_type (void); +GdkCursor* gdk_cursor_new_for_screen (GdkScreen *screen, + GdkCursorType cursor_type); +#ifndef GDK_MULTIHEAD_SAFE GdkCursor* gdk_cursor_new (GdkCursorType cursor_type); +#endif GdkCursor* gdk_cursor_new_from_pixmap (GdkPixmap *source, GdkPixmap *mask, GdkColor *fg, GdkColor *bg, gint x, gint y); +GdkScreen* gdk_cursor_get_screen (GdkCursor *cursor); GdkCursor* gdk_cursor_ref (GdkCursor *cursor); void gdk_cursor_unref (GdkCursor *cursor); diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c new file mode 100644 index 000000000..6e62364ab --- /dev/null +++ b/gdk/gdkdisplay.c @@ -0,0 +1,292 @@ +/* GDK - The GIMP Drawing Kit + * gdkdisplay.c + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede <erwann.chenede@sun.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <glib.h> +#include "gdkdisplay.h" +#include "gdkinternals.h" + +static void gdk_display_class_init (GdkDisplayClass *class); +static void gdk_display_init (GdkDisplay *display); +static void gdk_display_finalize (GObject *object); + +static GdkDisplay *default_display = NULL; + +static GObjectClass *parent_class; + +GType +gdk_display_get_type (void) +{ + + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = { + sizeof (GdkDisplayClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gdk_display_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkDisplay), + 0, /* n_preallocs */ + (GInstanceInitFunc) gdk_display_init + }; + object_type = g_type_register_static (G_TYPE_OBJECT, + "GdkDisplay", &object_info, 0); + } + + return object_type; +} + +static void +gdk_display_class_init (GdkDisplayClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + parent_class = g_type_class_peek_parent (class); + + object_class->finalize = gdk_display_finalize; +} + +static void +gdk_display_init (GdkDisplay *display) +{ + _gdk_displays = g_slist_prepend (_gdk_displays, display); + + display->button_click_time[0] = display->button_click_time[1] = 0; + display->button_window[0] = display->button_window[1] = NULL; + display->button_number[0] = display->button_number[1] = -1; + + display->double_click_time = 250; +} + +static void +gdk_display_finalize (GObject *object) +{ + GdkDisplay *display = GDK_DISPLAY_OBJECT (object); + + _gdk_displays = g_slist_remove (_gdk_displays, display); + + if (default_display == display) + default_display = NULL; + + parent_class->finalize (object); +} + +/** + * gdk_display_get_name: + * @display: a #GdkDisplay + * + * Gets the name of the display. + * + * Returns: a string representing the display name. + */ +G_CONST_RETURN gchar * +gdk_display_get_name (GdkDisplay * display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + return GDK_DISPLAY_GET_CLASS (display)->get_display_name (display); +} + +/** + * gdk_display_get_n_screens: + * @display: a #GdkDisplay + * + * Gets the number of screen managed by the @display. + * + * Returns: number of screens. + */ + +gint +gdk_display_get_n_screens (GdkDisplay * display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), 0); + return GDK_DISPLAY_GET_CLASS (display)->get_n_screens (display); +} + +/** + * gdk_display_get_screen: + * @display: a #GdkDisplay + * @screen_num: the screen number + * + * Returns a screen object for one of the screens of the display. + * + * Returns: the #GdkScreen object + */ + +GdkScreen * +gdk_display_get_screen (GdkDisplay * display, gint screen_num) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + return GDK_DISPLAY_GET_CLASS (display)->get_screen (display, screen_num); +} + +/** + * gdk_display_get_default_screen: + * @display: a #GdkDisplay + * + * Get the default #GdkScreen for @display. + * + * Returns: the default #GdkScreen object for @display + */ + +GdkScreen * +gdk_display_get_default_screen (GdkDisplay * display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + return GDK_DISPLAY_GET_CLASS (display)->get_default_screen (display); +} + +/** + * gdk_display_close: + * @display: a #GdkDisplay + * + * Closes and cleanup the resources used by the @display + */ +void +gdk_display_close (GdkDisplay *display) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + g_object_unref (G_OBJECT (display)); +} + +/** + * gdk_set_default_display: + * @display: a #GdkDisplay + * + * Sets @display as the default display. + **/ +void +gdk_set_default_display (GdkDisplay *display) +{ + default_display = display; +} + +/** + * gdk_get_default_display: + * + * Gets the default #GdkDisplay. + * + * Returns: a #GdkDisplay, or %NULL if there is no default + * display. + */ +GdkDisplay * +gdk_get_default_display (void) +{ + return default_display; +} + +/** + * gdk_get_default_screen: + * + * Gets the default screen for the default display. (See + * gdk_get_default_display ()). + * + * Returns: a #GdkScreen. + */ +GdkScreen * +gdk_get_default_screen (void) +{ + return gdk_display_get_default_screen (gdk_get_default_display ()); +} + +/** + * gdk_list_displays: + * + * List all currently open displays. + * + * Return value: a newly allocated #GSList of #GdkDisplay objects. + * Free this list with g_slist_free() when you are done with it. + **/ +GSList * +gdk_list_displays (void) +{ + return g_slist_copy (_gdk_displays); +} + +/** + * gdk_display_get_event: + * @display: a #GdkDisplay + * @event: a #GdkEvent + * + * Gets the next #GdkEvent to be processed for @display, fetching events from the + * windowing system if necessary. + * + * Return value: the next #GdkEvent to be processed, or %NULL if no events + * are pending. The returned #GdkEvent should be freed with gdk_event_free(). + **/ +GdkEvent* +gdk_display_get_event (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + _gdk_events_queue (display); + return _gdk_event_unqueue (display); +} + +/** + * gdk_display_peek_event: + * @void: + * + * Gets a copy of the first #GdkEvent in the @display's event queue, without + * removing the event from the queue. (Note that this function will + * not get more events from the windowing system. It only checks the events + * that have already been moved to the GDK event queue.) + * + * Return value: a copy of the first #GdkEvent on the event queue, or %NULL if no + * events are in the queue. The returned #GdkEvent should be freed with + * gdk_event_free(). + **/ +GdkEvent* +gdk_display_peek_event (GdkDisplay *display) +{ + GList *tmp_list; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + tmp_list = _gdk_event_queue_find_first (display); + + if (tmp_list) + return gdk_event_copy (tmp_list->data); + else + return NULL; +} + +/** + * gdk_display_put_event: + * @display: a #GdkDisplay + * @event: a #GdkEvent. + * + * Appends a copy of the given event onto the front of the event + * queue for @display. + **/ +void +gdk_display_put_event (GdkDisplay *display, + GdkEvent *event) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + g_return_if_fail (event != NULL); + + _gdk_event_queue_append (display, gdk_event_copy (event)); +} diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h new file mode 100644 index 000000000..504b497c0 --- /dev/null +++ b/gdk/gdkdisplay.h @@ -0,0 +1,112 @@ +/* + * gdkdisplay.h + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede <erwann.chenede@sun.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GDK_DISPLAY_H__ +#define __GDK_DISPLAY_H__ + +#include <gdk/gdktypes.h> +#include <gdk/gdkevents.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +typedef struct _GdkDisplayClass GdkDisplayClass; + +#define GDK_TYPE_DISPLAY (gdk_display_get_type ()) +#define GDK_DISPLAY_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DISPLAY, GdkDisplay)) +#define GDK_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DISPLAY, GdkDisplayClass)) +#define GDK_IS_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DISPLAY)) +#define GDK_IS_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DISPLAY)) +#define GDK_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DISPLAY, GdkDisplayClass)) + + +struct _GdkDisplay +{ + GObject parent_instance; + + /*< private >*/ + GList *queued_events; + GList *queued_tail; + + /* Information for determining if the latest button click + * is part of a double-click or triple-click + */ + guint32 button_click_time[2]; /* The last 2 button click times. */ + GdkWindow *button_window[2]; /* The last 2 windows to receive button presses. */ + guint button_number[2]; /* The last 2 buttons to be pressed. */ + + guint double_click_time; /* Maximum time between clicks in msecs */ +}; + +struct _GdkDisplayClass +{ + GObjectClass parent_class; + + G_CONST_RETURN gchar * (*get_display_name) (GdkDisplay *display); + gint (*get_n_screens) (GdkDisplay *display); + GdkScreen * (*get_screen) (GdkDisplay *display, + gint screen_num); + GdkScreen * (*get_default_screen) (GdkDisplay *display); +}; + +GType gdk_display_get_type (void); +GdkDisplay *gdk_open_display (const gchar *display_name); + +G_CONST_RETURN gchar * gdk_display_get_name (GdkDisplay *display); + +gint gdk_display_get_n_screens (GdkDisplay *display); +GdkScreen * gdk_display_get_screen (GdkDisplay *display, + gint screen_num); +GdkScreen * gdk_display_get_default_screen (GdkDisplay *display); +void gdk_display_pointer_ungrab (GdkDisplay *display, + guint32 time); +void gdk_display_keyboard_ungrab (GdkDisplay *display, + guint32 time); +gboolean gdk_display_pointer_is_grabbed (GdkDisplay *display); +void gdk_display_beep (GdkDisplay *display); +void gdk_display_sync (GdkDisplay *display); +void gdk_display_close (GdkDisplay *display); + +GList * gdk_display_list_devices (GdkDisplay *display); + +GdkEvent* gdk_display_get_event (GdkDisplay *display); +GdkEvent* gdk_display_peek_event (GdkDisplay *display); +void gdk_display_put_event (GdkDisplay *display, + GdkEvent *event); + +void gdk_display_add_client_message_filter (GdkDisplay *display, + GdkAtom message_type, + GdkFilterFunc func, + gpointer data); + +void gdk_display_set_double_click_time (GdkDisplay *display, + guint msec); +void gdk_display_set_sm_client_id (GdkDisplay *display, + const gchar *sm_client_id); + +void gdk_set_default_display (GdkDisplay *display); +GdkDisplay *gdk_get_default_display (void); + +G_END_DECLS + +#endif /* __GDK_DISPLAY_H__ */ diff --git a/gdk/gdkdnd.h b/gdk/gdkdnd.h index c3dd4d1c3..5ff7448b6 100644 --- a/gdk/gdkdnd.h +++ b/gdk/gdkdnd.h @@ -101,8 +101,15 @@ GdkAtom gdk_drag_get_selection (GdkDragContext *context); GdkDragContext * gdk_drag_begin (GdkWindow *window, GList *targets); -guint32 gdk_drag_get_protocol (guint32 xid, - GdkDragProtocol *protocol); + +guint32 gdk_drag_get_protocol_for_display (GdkDisplay *display, + guint32 xid, + GdkDragProtocol *protocol); +#ifndef GDK_MULTIHEAD_SAFE +guint32 gdk_drag_get_protocol (guint32 xid, + GdkDragProtocol *protocol); +#endif /* GDK_MULTIHEAD_SAFE */ + void gdk_drag_find_window (GdkDragContext *context, GdkWindow *drag_window, gint x_root, diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c index 9778c879d..eee273038 100644 --- a/gdk/gdkdraw.c +++ b/gdk/gdkdraw.c @@ -27,6 +27,7 @@ #include "gdkdrawable.h" #include "gdkinternals.h" #include "gdkwindow.h" +#include "gdkscreen.h" #include "gdk-pixbuf-private.h" #include "gdkpixbuf.h" @@ -202,8 +203,39 @@ gdk_drawable_get_depth (GdkDrawable *drawable) return GDK_DRAWABLE_GET_CLASS (drawable)->get_depth (drawable); } +/** + * gdk_drawable_get_screen: + * @drawable: a #GdkDrawable + * + * Gets the #GdkScreen associated with a #GdkDrawable. + * + * Return value: the #GdkScreen associated with @drawable + **/ +GdkScreen* +gdk_drawable_get_screen(GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return GDK_DRAWABLE_GET_CLASS (drawable)->get_screen (drawable); +} /** + * gdk_drawable_get_display: + * @drawable: a #GdkDrawable + * + * Gets the #GdkDisplay associated with a #GdkDrawable. + * + * Return value: the #GdkDisplay associated with @drawable + **/ +GdkDisplay* +gdk_drawable_get_display (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return gdk_screen_get_display (gdk_drawable_get_screen (drawable)); +} + +/** * gdk_drawable_set_colormap: * @drawable: a #GdkDrawable * @colormap: a #GdkColormap @@ -1216,7 +1248,8 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, */ if (visual) { - gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (visual->depth); + gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (gdk_drawable_get_display (drawable), + visual->depth); if (visual->byte_order == (G_BYTE_ORDER == G_BIG_ENDIAN ? GDK_MSB_FIRST : GDK_LSB_FIRST) && visual->depth == 16 && @@ -1245,7 +1278,9 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH); - GdkImage *image = _gdk_image_get_scratch (width1, height1, gdk_drawable_get_depth (drawable), &xs0, &ys0); + GdkImage *image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable), + width1, height1, + gdk_drawable_get_depth (drawable), &xs0, &ys0); _gdk_drawable_copy_to_image (drawable, image, dest_x + x0, dest_y + y0, diff --git a/gdk/gdkdrawable.h b/gdk/gdkdrawable.h index 9d4fd1411..32982ddfc 100644 --- a/gdk/gdkdrawable.h +++ b/gdk/gdkdrawable.h @@ -113,8 +113,9 @@ struct _GdkDrawableClass void (*set_colormap) (GdkDrawable *drawable, GdkColormap *cmap); - GdkColormap* (*get_colormap) (GdkDrawable *drawable); - GdkVisual* (*get_visual) (GdkDrawable *drawable); + GdkColormap* (*get_colormap) (GdkDrawable *drawable); + GdkVisual* (*get_visual) (GdkDrawable *drawable); + GdkScreen* (*get_screen) (GdkDrawable *drawable); GdkImage* (*get_image) (GdkDrawable *drawable, gint x, @@ -194,6 +195,8 @@ void gdk_drawable_set_colormap (GdkDrawable *drawable, GdkColormap* gdk_drawable_get_colormap (GdkDrawable *drawable); GdkVisual* gdk_drawable_get_visual (GdkDrawable *drawable); gint gdk_drawable_get_depth (GdkDrawable *drawable); +GdkScreen* gdk_drawable_get_screen (GdkDrawable *drawable); +GdkDisplay* gdk_drawable_get_display (GdkDrawable *drawable); #ifndef GDK_DISABLE_DEPRECATED GdkDrawable* gdk_drawable_ref (GdkDrawable *drawable); diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index 7e211789f..e566af0fc 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -55,22 +55,11 @@ struct _GdkEventPrivate /* Private variable declarations */ -static guint32 button_click_time[2] = { 0, 0}; /* The last 2 button click times. Used - * to determine if the latest button click - * is part of a double or triple click. - */ -static GdkWindow *button_window[2] = { NULL, NULL}; /* The last 2 windows to receive button presses. - * Also used to determine if the latest button - * click is part of a double or triple click. - */ -static guint button_number[2] = { -1, -1 }; /* The last 2 buttons to be pressed. - */ GdkEventFunc _gdk_event_func = NULL; /* Callback for events */ gpointer _gdk_event_data = NULL; GDestroyNotify _gdk_event_notify = NULL; -static guint double_click_time = 250; -#define TRIPLE_CLICK_TIME (2*double_click_time) +#define TRIPLE_CLICK_TIME(display) (2*display->double_click_time) #define DOUBLE_CLICK_DIST 5 #define TRIPLE_CLICK_DIST 5 @@ -78,20 +67,19 @@ static guint double_click_time = 250; * Functions for maintaining the event queue * *********************************************/ -/************************************************************* +/** * _gdk_event_queue_find_first: - * Find the first event on the queue that is not still - * being filled in. - * arguments: - * - * results: - * Pointer to the list node for that event, or NULL - *************************************************************/ - + * @display: a #GdkDisplay + * + * Find the first event on the queue that is not still + * being filled in. + * + * Return value: Pointer to the list node for that event, or NULL. + **/ GList* -_gdk_event_queue_find_first (void) +_gdk_event_queue_find_first (GdkDisplay *display) { - GList *tmp_list = _gdk_queued_events; + GList *tmp_list = display->queued_events; while (tmp_list) { @@ -105,58 +93,93 @@ _gdk_event_queue_find_first (void) return NULL; } -/************************************************************* - * _gdk_event_queue_remove_link: - * Remove a specified list node from the event queue. - * arguments: - * node: Node to remove. - * results: - *************************************************************/ +/** + * _gdk_event_queue_append: + * @display: a #GdkDisplay + * @event: Event to append. + * + * Appends an event onto the tail of the event queue. + * + * Returns: the newly appended list node. + **/ +GList * +_gdk_event_queue_append (GdkDisplay *display, + GdkEvent *event) +{ + display->queued_tail = g_list_append (display->queued_tail, event); + + if (!display->queued_events) + display->queued_events = display->queued_tail; + else + display->queued_tail = display->queued_tail->next; + + return display->queued_tail; +} +/** + * _gdk_event_queue_remove_link: + * @display: a #GdkDisplay + * @node: node to remove + * + * Removes a specified list node from the event queue. + **/ void -_gdk_event_queue_remove_link (GList *node) +_gdk_event_queue_remove_link (GdkDisplay *display, + GList *node) { if (node->prev) node->prev->next = node->next; else - _gdk_queued_events = node->next; + display->queued_events = node->next; if (node->next) node->next->prev = node->prev; else - _gdk_queued_tail = node->prev; + display->queued_tail = node->prev; } -/************************************************************* - * _gdk_event_queue_append: - * Append an event onto the tail of the event queue. - * arguments: - * event: Event to append. - * results: - *************************************************************/ - -void -_gdk_event_queue_append (GdkEvent *event) +/** + * _gdk_event_unqueue: + * @display: a #GdkDisplay + * + * Removes and returns the first event from the event + * queue that is not still being filled in. + * + * Return value: the event, or %NULL. Ownership is transferred + * to the caller. + **/ +GdkEvent* +_gdk_event_unqueue (GdkDisplay *display) { - _gdk_queued_tail = g_list_append (_gdk_queued_tail, event); - - if (!_gdk_queued_events) - _gdk_queued_events = _gdk_queued_tail; - else - _gdk_queued_tail = _gdk_queued_tail->next; + GdkEvent *event = NULL; + GList *tmp_list; + + tmp_list = _gdk_event_queue_find_first (display); + + if (tmp_list) + { + event = tmp_list->data; + _gdk_event_queue_remove_link (display, tmp_list); + g_list_free_1 (tmp_list); + } + + return event; } -/************************************************************* +/** * gdk_event_handler_set: - * - * arguments: - * func: Callback function to be called for each event. - * data: Data supplied to the function - * notify: function called when function is no longer needed + * @func: the function to call to handle events from GDK. + * @data: user data to pass to the function. + * @notify: the function to call when the handler function is removed, i.e. when + * gdk_event_handler_set() is called with another event handler. * - * results: - *************************************************************/ - + * Sets the function to call to handle all events from GDK. + * + * Note that GTK+ uses this to install its own event handler, so it is + * usually not useful for GTK+ applications. (Although an application + * can call this function then call gtk_main_do_event() to pass + * events to GTK+.) + **/ void gdk_event_handler_set (GdkEventFunc func, gpointer data, @@ -170,93 +193,82 @@ gdk_event_handler_set (GdkEventFunc func, _gdk_event_notify = notify; } -/* - *-------------------------------------------------------------- - * gdk_event_get - * - * Gets the next event. - * - * Arguments: - * - * Results: - * If an event is waiting that we care about, returns - * a pointer to that event, to be freed with gdk_event_free. - * Otherwise, returns NULL. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - +/** + * gdk_event_get: + * + * Checks all open displays for a #GdkEvent to process,to be processed + * on, fetching events from the windowing system if necessary. + * See gdk_display_get_event(). + * + * Return value: the next #GdkEvent to be processed, or %NULL if no events + * are pending. The returned #GdkEvent should be freed with gdk_event_free(). + **/ GdkEvent* gdk_event_get (void) { - _gdk_events_queue (); + GSList *tmp_list; - return _gdk_event_unqueue (); + for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next) + { + GdkEvent *event = gdk_display_get_event (tmp_list->data); + if (event) + return event; + } + + return NULL; } -/* - *-------------------------------------------------------------- - * gdk_event_peek - * - * Gets the next event. - * - * Arguments: - * - * Results: - * If an event is waiting that we care about, returns - * a copy of that event, but does not remove it from - * the queue. The pointer is to be freed with gdk_event_free. - * Otherwise, returns NULL. - * - * Side effects: +/** + * gdk_event_peek: * - *-------------------------------------------------------------- - */ - + * If there is an event waiting in the event queue of some open + * display, returns a copy of it. See gdk_display_peek_event(). + * + * Return value: a copy of the first #GdkEvent on some event queue, or %NULL if no + * events are in any queues. The returned #GdkEvent should be freed with + * gdk_event_free(). + **/ GdkEvent* gdk_event_peek (void) { - GList *tmp_list; + GSList *tmp_list; - tmp_list = _gdk_event_queue_find_first (); - - if (tmp_list) - return gdk_event_copy (tmp_list->data); - else - return NULL; + for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next) + { + GdkEvent *event = gdk_display_peek_event (tmp_list->data); + if (event) + return event; + } + + return NULL; } +/** + * gdk_event_put: + * @event: a #GdkEvent. + * + * Appends a copy of the given event onto the front of the event + * queue for event->any.window's display, or the default event + * queue if event->any.window is %NULL. See gdk_display_put_event(). + **/ void gdk_event_put (GdkEvent *event) { - GdkEvent *new_event; + GdkDisplay *display; g_return_if_fail (event != NULL); - - new_event = gdk_event_copy (event); - _gdk_event_queue_append (new_event); -} + if (event->any.window) + display = gdk_drawable_get_display (event->any.window); + else + { + GDK_NOTE (MULTIHEAD, + g_message ("Falling back to default display for gdk_event_put()")); + display = gdk_get_default_display (); + } -/* - *-------------------------------------------------------------- - * gdk_event_copy - * - * Copy a event structure into new storage. - * - * Arguments: - * "event" is the event struct to copy. - * - * Results: - * A new event structure. Free it with gdk_event_free. - * - * Side effects: - * The reference count of the window in the event is increased. - * - *-------------------------------------------------------------- - */ + gdk_display_put_event (display, event); +} static GMemChunk *event_chunk = NULL; @@ -277,6 +289,16 @@ _gdk_event_new (void) return (GdkEvent*) new_event; } +/** + * gdk_event_copy: + * @event: a #GdkEvent + * + * Copies a #GdkEvent, copying or incrementing the reference count of the + * resources associated with it (e.g. #GdkWindow's and strings). + * + * Return value: a copy of @event. The returned #GdkEvent should be freed with + * gdk_event_free(). + **/ GdkEvent* gdk_event_copy (GdkEvent *event) { @@ -328,24 +350,15 @@ gdk_event_copy (GdkEvent *event) return new_event; } -/* - *-------------------------------------------------------------- - * gdk_event_free - * - * Free a event structure obtained from gdk_event_copy. Do not use - * with other event structures. - * - * Arguments: - * "event" is the event struct to free. - * - * Results: - * - * Side effects: - * The reference count of the window in the event is decreased and - * might be freed, too. - * - *-------------------------------------------------------------- */ - +/** + * gdk_event_free: + * @event: a #GdkEvent. + * + * Frees a #GdkEvent, freeing or decrementing any resources associated with it. + * Note that this function should only be called with events returned from + * gdk_event_peek(), gdk_event_get(), gdk_event_get_graphics_expose() and + * gdk_event_copy(). + **/ void gdk_event_free (GdkEvent *event) { @@ -740,26 +753,15 @@ gdk_event_get_axis (GdkEvent *event, return gdk_device_get_axis (device, axes, axis_use, value); } -/* - *-------------------------------------------------------------- - * gdk_set_show_events - * - * Turns on/off the showing of events. - * - * Arguments: - * "show_events" is a boolean describing whether or - * not to show the events gdk receives. - * - * Results: - * - * Side effects: - * When "show_events" is TRUE, calls to "gdk_event_get" - * will output debugging informatin regarding the event - * received to stdout. - * - *-------------------------------------------------------------- - */ - +/** + * gdk_set_show_events: + * @show_events: %TRUE to output event debugging information. + * + * Sets whether a trace of received events is output. + * Note that GTK+ must be compiled with debugging (that is, + * configured using the <option>--enable-debug</option> option) + * to use this option. + **/ void gdk_set_show_events (gboolean show_events) { @@ -769,6 +771,13 @@ gdk_set_show_events (gboolean show_events) _gdk_debug_flags &= ~GDK_DEBUG_EVENTS; } +/** + * gdk_get_show_events: + * + * Returns non-zero if event debugging output is enabled. + * + * Return value: non-zero if event debugging output is enabled. + **/ gboolean gdk_get_show_events (void) { @@ -861,27 +870,10 @@ gdk_input_remove (gint tag) g_source_remove (tag); } -GdkEvent* -_gdk_event_unqueue (void) -{ - GdkEvent *event = NULL; - GList *tmp_list; - - tmp_list = _gdk_event_queue_find_first (); - - if (tmp_list) - { - event = tmp_list->data; - _gdk_event_queue_remove_link (tmp_list); - g_list_free_1 (tmp_list); - } - - return event; -} - static void -gdk_synthesize_click (GdkEvent *event, - gint nclicks) +gdk_synthesize_click (GdkDisplay *display, + GdkEvent *event, + gint nclicks) { GdkEvent temp_event; @@ -890,50 +882,50 @@ gdk_synthesize_click (GdkEvent *event, temp_event = *event; temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS; - gdk_event_put (&temp_event); + gdk_display_put_event (display, &temp_event); } void -_gdk_event_button_generate (GdkEvent *event) +_gdk_event_button_generate (GdkDisplay *display, + GdkEvent *event) { - if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) && - (event->button.window == button_window[1]) && - (event->button.button == button_number[1])) + if ((event->button.time < (display->button_click_time[1] + TRIPLE_CLICK_TIME (display))) && + (event->button.window == display->button_window[1]) && + (event->button.button == display->button_number[1])) { - gdk_synthesize_click (event, 3); + gdk_synthesize_click (display, event, 3); - button_click_time[1] = 0; - button_click_time[0] = 0; - button_window[1] = NULL; - button_window[0] = 0; - button_number[1] = -1; - button_number[0] = -1; + display->button_click_time[1] = 0; + display->button_click_time[0] = 0; + display->button_window[1] = NULL; + display->button_window[0] = 0; + display->button_number[1] = -1; + display->button_number[0] = -1; } - else if ((event->button.time < (button_click_time[0] + double_click_time)) && - (event->button.window == button_window[0]) && - (event->button.button == button_number[0])) + else if ((event->button.time < (display->button_click_time[0] + display->double_click_time)) && + (event->button.window == display->button_window[0]) && + (event->button.button == display->button_number[0])) { - gdk_synthesize_click (event, 2); + gdk_synthesize_click (display, event, 2); - button_click_time[1] = button_click_time[0]; - button_click_time[0] = event->button.time; - button_window[1] = button_window[0]; - button_window[0] = event->button.window; - button_number[1] = button_number[0]; - button_number[0] = event->button.button; + display->button_click_time[1] = display->button_click_time[0]; + display->button_click_time[0] = event->button.time; + display->button_window[1] = display->button_window[0]; + display->button_window[0] = event->button.window; + display->button_number[1] = display->button_number[0]; + display->button_number[0] = event->button.button; } else { - button_click_time[1] = 0; - button_click_time[0] = event->button.time; - button_window[1] = NULL; - button_window[0] = event->button.window; - button_number[1] = -1; - button_number[0] = event->button.button; + display->button_click_time[1] = 0; + display->button_click_time[0] = event->button.time; + display->button_window[1] = NULL; + display->button_window[0] = event->button.window; + display->button_number[1] = -1; + display->button_number[0] = event->button.button; } } - void gdk_synthesize_window_state (GdkWindow *window, GdkWindowState unset_flags, @@ -975,7 +967,7 @@ gdk_synthesize_window_state (GdkWindow *window, case GDK_WINDOW_TOPLEVEL: case GDK_WINDOW_DIALOG: case GDK_WINDOW_TEMP: /* ? */ - gdk_event_put (&temp_event); + gdk_display_put_event (gdk_drawable_get_display (window), &temp_event); break; case GDK_WINDOW_FOREIGN: @@ -986,18 +978,33 @@ gdk_synthesize_window_state (GdkWindow *window, } /** - * gdk_set_double_click_time: - * @msec: double click time in milliseconds (thousandths of a second) - * + * gdk_display_set_double_click_time: + * @display: a #GdkDisplay + * @msec: double click time in milliseconds (thousandths of a second) + * * Sets the double click time (two clicks within this time interval * count as a double click and result in a #GDK_2BUTTON_PRESS event). * Applications should NOT set this, it is a global user-configured setting. + **/ +void +gdk_set_double_click_time_for_display (GdkDisplay *display, + guint msec) +{ + display->double_click_time = msec; +} + +/** + * gdk_set_double_click_time: + * @msec: double click time in milliseconds (thousandths of a second) * + * Set the double click time for the default display. See + * gdk_display_set_double_click_time(). Applications should NOT + * set this, it is a global user-configured setting. **/ void gdk_set_double_click_time (guint msec) { - double_click_time = msec; + gdk_set_double_click_time_for_display (gdk_get_default_display (), msec); } GType diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h index 763c1a377..19990ce4d 100644 --- a/gdk/gdkevents.h +++ b/gdk/gdkevents.h @@ -472,16 +472,14 @@ void gdk_event_handler_set (GdkEventFunc func, void gdk_set_show_events (gboolean show_events); gboolean gdk_get_show_events (void); -/* - * The following function adds a global filter for all client - * messages of type message_type - */ +#ifndef GDK_MULTIHEAD_SAFE void gdk_add_client_message_filter (GdkAtom message_type, GdkFilterFunc func, gpointer data); gboolean gdk_setting_get (const gchar *name, GValue *value); +#endif /* GDK_MULTIHEAD_SAFE */ #ifdef __cplusplus } diff --git a/gdk/gdkfont.h b/gdk/gdkfont.h index 6f17de7c5..65356f5d7 100644 --- a/gdk/gdkfont.h +++ b/gdk/gdkfont.h @@ -31,9 +31,18 @@ struct _GdkFont GType gdk_font_get_type (void); +#ifndef GDK_MULTIHEAD_SAFE GdkFont* gdk_font_load (const gchar *font_name); GdkFont* gdk_fontset_load (const gchar *fontset_name); GdkFont* gdk_font_from_description (PangoFontDescription *font_desc); +#endif + +GdkFont *gdk_font_load_for_display (GdkDisplay *display, + const gchar *font_name); +GdkFont *gdk_fontset_load_for_display (GdkDisplay *display, + const gchar *fontset_name); +GdkFont *gdk_font_from_description_for_display (GdkDisplay *display, + PangoFontDescription *font_desc); GdkFont* gdk_font_ref (GdkFont *font); void gdk_font_unref (GdkFont *font); @@ -92,6 +101,8 @@ void gdk_string_extents (GdkFont *font, gint *ascent, gint *descent); +GdkDisplay * gdk_font_get_display (GdkFont *font); + #ifdef GDK_WINDOWING_WIN32 /* Ditto temporary */ gchar* gdk_font_full_name_get (GdkFont *font); diff --git a/gdk/gdkgc.h b/gdk/gdkgc.h index a7c34bfc6..eb2fc91b0 100644 --- a/gdk/gdkgc.h +++ b/gdk/gdkgc.h @@ -263,6 +263,7 @@ void gdk_gc_set_rgb_fg_color (GdkGC *gc, GdkColor *color); void gdk_gc_set_rgb_bg_color (GdkGC *gc, GdkColor *color); +GdkScreen * gdk_gc_get_screen (GdkGC *gc); #ifndef GDK_DISABLE_DEPRECATED #define gdk_gc_destroy gdk_gc_unref diff --git a/gdk/gdkglobals.c b/gdk/gdkglobals.c index e30d17197..052938952 100644 --- a/gdk/gdkglobals.c +++ b/gdk/gdkglobals.c @@ -30,13 +30,13 @@ #include "gdkprivate.h" #include "config.h" -guint _gdk_debug_flags = 0; -GdkWindow *_gdk_parent_root = NULL; -gint _gdk_error_code = 0; -gint _gdk_error_warnings = TRUE; -GList *_gdk_default_filters = NULL; -GList *_gdk_queued_events = NULL; -GList *_gdk_queued_tail = NULL; +guint _gdk_debug_flags = 0; +gint _gdk_error_code = 0; +gint _gdk_error_warnings = TRUE; +GList *_gdk_default_filters = NULL; +gchar *_gdk_display_name = NULL; + +GSList *_gdk_displays = NULL; GMutex *gdk_threads_mutex = NULL; /* Global GDK lock */ diff --git a/gdk/gdkimage.c b/gdk/gdkimage.c index e4389eb9b..d5b145cfb 100644 --- a/gdk/gdkimage.c +++ b/gdk/gdkimage.c @@ -188,6 +188,8 @@ struct _GdkScratchImageInfo { gint tile_x; gint tile_y1; gint tile_y2; + + GdkScreen *screen; }; static GSList *scratch_image_infos = NULL; @@ -201,9 +203,11 @@ allocate_scratch_images (GdkScratchImageInfo *info, for (i = 0; i < n_images; i++) { - info->static_image[i] = _gdk_image_new_for_depth (shared ? GDK_IMAGE_SHARED : GDK_IMAGE_NORMAL, + info->static_image[i] = _gdk_image_new_for_depth (info->screen, + shared ? GDK_IMAGE_SHARED : GDK_IMAGE_NORMAL, NULL, - GDK_SCRATCH_IMAGE_WIDTH * (N_REGIONS / n_images), GDK_SCRATCH_IMAGE_HEIGHT, + GDK_SCRATCH_IMAGE_WIDTH * (N_REGIONS / n_images), + GDK_SCRATCH_IMAGE_HEIGHT, info->depth); if (!info->static_image[i]) @@ -221,7 +225,8 @@ allocate_scratch_images (GdkScratchImageInfo *info, } static GdkScratchImageInfo * -scratch_image_info_for_depth (gint depth) +scratch_image_info_for_depth (GdkScreen *screen, + gint depth) { GSList *tmp_list; GdkScratchImageInfo *image_info; @@ -231,7 +236,7 @@ scratch_image_info_for_depth (gint depth) while (tmp_list) { image_info = tmp_list->data; - if (image_info->depth == depth) + if (image_info->depth == depth && image_info->screen == screen) return image_info; tmp_list = tmp_list->next; @@ -240,6 +245,7 @@ scratch_image_info_for_depth (gint depth) image_info = g_new (GdkScratchImageInfo, 1); image_info->depth = depth; + image_info->screen = screen; /* Try to allocate as few possible shared images */ for (i=0; i < G_N_ELEMENTS (possible_n_images); i++) @@ -307,6 +313,7 @@ alloc_scratch_image (GdkScratchImageInfo *image_info) /** * _gdk_image_get_scratch: + * @screen: a #GdkScreen * @width: desired width * @height: desired height * @depth: depth of image @@ -314,24 +321,28 @@ alloc_scratch_image (GdkScratchImageInfo *image_info) * @y: Y location within returned image of scratch image * * Allocates an image of size width/height, up to a maximum - * of GDK_SCRATCH_IMAGE_WIDTHxGDK_SCRATCH_IMAGE_HEIGHT + * of GDK_SCRATCH_IMAGE_WIDTHxGDK_SCRATCH_IMAGE_HEIGHT that is + * suitable to use on @screen. * * Return value: a scratch image. This must be used by a * call to gdk_image_put() before any other calls to * _gdk_image_get_scratch() **/ GdkImage * -_gdk_image_get_scratch (gint width, - gint height, - gint depth, - gint *x, - gint *y) +_gdk_image_get_scratch (GdkScreen *screen, + gint width, + gint height, + gint depth, + gint *x, + gint *y) { GdkScratchImageInfo *image_info; GdkImage *image; gint idx; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); - image_info = scratch_image_info_for_depth (depth); + image_info = scratch_image_info_for_depth (screen, depth); if (width >= (GDK_SCRATCH_IMAGE_WIDTH >> 1)) { diff --git a/gdk/gdkinput.h b/gdk/gdkinput.h index b5b004d9c..a923a9c7c 100644 --- a/gdk/gdkinput.h +++ b/gdk/gdkinput.h @@ -97,8 +97,10 @@ struct _GdkTimeCoord GType gdk_device_get_type (void); +#ifndef GDK_MULTIHEAD_SAFE /* Returns a list of GdkDevice * */ -GList * gdk_devices_list (void); +GList * gdk_devices_list (void); +#endif /* GDK_MULTIHEAD_SAFE */ /* Functions to configure a device */ void gdk_device_set_source (GdkDevice *device, diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h index ae7a9451a..a97b291b1 100644 --- a/gdk/gdkinternals.h +++ b/gdk/gdkinternals.h @@ -75,7 +75,8 @@ typedef enum { GDK_DEBUG_PIXMAP = 1 << 8, GDK_DEBUG_IMAGE = 1 << 9, GDK_DEBUG_INPUT = 1 <<10, - GDK_DEBUG_CURSOR = 1 <<11 + GDK_DEBUG_CURSOR = 1 <<11, + GDK_DEBUG_MULTIHEAD = 1 <<12 } GdkDebugFlag; #ifndef GDK_DISABLE_DEPRECATED @@ -145,39 +146,44 @@ extern GdkEventFunc _gdk_event_func; /* Callback for events */ extern gpointer _gdk_event_data; extern GDestroyNotify _gdk_event_notify; -/* FIFO's for event queue, and for events put back using - * gdk_event_put(). - */ -extern GList *_gdk_queued_events; -extern GList *_gdk_queued_tail; - extern GdkDevice *_gdk_core_pointer; +extern GSList *_gdk_displays; +extern gchar *_gdk_display_name; + GdkEvent* _gdk_event_new (void); -void _gdk_events_init (void); -void _gdk_events_queue (void); -GdkEvent* _gdk_event_unqueue (void); -GList* _gdk_event_queue_find_first (void); -void _gdk_event_queue_remove_link (GList *node); -void _gdk_event_queue_append (GdkEvent *event); +void _gdk_events_queue (GdkDisplay *display); +GdkEvent* _gdk_event_unqueue (GdkDisplay *display); -void _gdk_event_button_generate (GdkEvent *event); +GList* _gdk_event_queue_find_first (GdkDisplay *display); +void _gdk_event_queue_remove_link (GdkDisplay *display, + GList *node); +GList* _gdk_event_queue_append (GdkDisplay *display, + GdkEvent *event); +void _gdk_event_button_generate (GdkDisplay *display, + GdkEvent *event); + +void gdk_synthesize_window_state (GdkWindow *window, + GdkWindowState unset_flags, + GdkWindowState set_flags); #define GDK_SCRATCH_IMAGE_WIDTH 256 #define GDK_SCRATCH_IMAGE_HEIGHT 64 -GdkImage* _gdk_image_new_for_depth (GdkImageType type, +GdkImage* _gdk_image_new_for_depth (GdkScreen *screen, + GdkImageType type, GdkVisual *visual, gint width, gint height, gint depth); -GdkImage *_gdk_image_get_scratch (gint width, - gint height, - gint depth, - gint *x, - gint *y); +GdkImage *_gdk_image_get_scratch (GdkScreen *screen, + gint width, + gint height, + gint depth, + gint *x, + gint *y); /* Will most likely be exported in the future */ @@ -224,8 +230,8 @@ void _gdk_colormap_real_destroy (GdkColormap *colormap); void _gdk_cursor_destroy (GdkCursor *cursor); extern GdkArgDesc _gdk_windowing_args[]; -gboolean _gdk_windowing_init_check (int argc, - char **argv); +void _gdk_windowing_init (void); + void _gdk_windowing_window_get_offsets (GdkWindow *window, gint *x_offset, gint *y_offset); @@ -248,10 +254,9 @@ GdkWindow* _gdk_windowing_window_get_pointer (GdkWindow *window, gint *y, GdkModifierType *mask); -/* Return the number of bits-per-pixel for images of the specified depth. - * (Future: needs to be GdkDiplay specific.) - */ -gint _gdk_windowing_get_bits_for_depth (gint depth); +/* Return the number of bits-per-pixel for images of the specified depth. */ +gint _gdk_windowing_get_bits_for_depth (GdkDisplay *display, + gint depth); #define GDK_WINDOW_IS_MAPPED(window) ((((GdkWindowObject*)window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0) @@ -289,18 +294,12 @@ GType _gdk_pixmap_impl_get_type (void) G_GNUC_CONST; * Initialization and exit routines * ************************************/ -void _gdk_windowing_window_init (void); -void _gdk_visual_init (void); -void _gdk_dnd_init (void); - -void _gdk_windowing_image_init (void); void _gdk_image_exit (void); - -void _gdk_input_init (void); -void _gdk_input_exit (void); - void _gdk_windowing_exit (void); +void _gdk_get_command_line_args (int *argc, + char ***argv); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gdk/gdkkeys.c b/gdk/gdkkeys.c index f2607b7ed..192fa9a2e 100644 --- a/gdk/gdkkeys.c +++ b/gdk/gdkkeys.c @@ -24,19 +24,17 @@ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ -#include "gdkkeys.h" #include <config.h> +#include "gdkkeys.h" + enum { DIRECTION_CHANGED, LAST_SIGNAL }; -static void gdk_keymap_init (GdkKeymap *keymap); static void gdk_keymap_class_init (GdkKeymapClass *klass); -static gpointer parent_class = NULL; - static guint signals[LAST_SIGNAL] = { 0 }; GType @@ -56,7 +54,7 @@ gdk_keymap_get_type (void) NULL, /* class_data */ sizeof (GdkKeymap), 0, /* n_preallocs */ - (GInstanceInitFunc) gdk_keymap_init, + (GInstanceInitFunc) NULL, }; object_type = g_type_register_static (G_TYPE_OBJECT, @@ -68,18 +66,10 @@ gdk_keymap_get_type (void) } static void -gdk_keymap_init (GdkKeymap *keymap) -{ - -} - -static void gdk_keymap_class_init (GdkKeymapClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); - signals[DIRECTION_CHANGED] = g_signal_new ("direction_changed", G_OBJECT_CLASS_TYPE (object_class), diff --git a/gdk/gdkkeys.h b/gdk/gdkkeys.h index c884b964f..9f51e69ef 100644 --- a/gdk/gdkkeys.h +++ b/gdk/gdkkeys.h @@ -61,10 +61,10 @@ typedef struct _GdkKeymapClass GdkKeymapClass; #define GDK_IS_KEYMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_KEYMAP)) #define GDK_KEYMAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_KEYMAP, GdkKeymapClass)) - struct _GdkKeymap { - GObject parent_instance; + GObject parent_instance; + GdkDisplay *display; }; struct _GdkKeymapClass @@ -76,7 +76,10 @@ struct _GdkKeymapClass GType gdk_keymap_get_type (void) G_GNUC_CONST; -GdkKeymap* gdk_keymap_get_default (void); +#ifndef GDK_MULTIHEAD_SAFE +GdkKeymap* gdk_keymap_get_default (void); +#endif +GdkKeymap* gdk_keymap_get_for_display (GdkDisplay *display); guint gdk_keymap_lookup_key (GdkKeymap *keymap, diff --git a/gdk/gdkpango.h b/gdk/gdkpango.h index f6019d426..5a35c45fb 100644 --- a/gdk/gdkpango.h +++ b/gdk/gdkpango.h @@ -28,13 +28,10 @@ extern "C" { /* Pango interaction */ -/* FIXME: The following function needs more parameters so that we can - * properly deal with different visuals, the potential for multiple - * screens in the future, etc. The PangoContext needs enough information - * in it to create new GC's and to set the colors on those GC's. - * A colormap is not sufficient. - */ +PangoContext *gdk_pango_context_get_for_screen (GdkScreen *screen); +#ifndef GDK_MULTIHEAD_SAFE PangoContext *gdk_pango_context_get (void); +#endif void gdk_pango_context_set_colormap (PangoContext *context, GdkColormap *colormap); diff --git a/gdk/gdkpixbuf-drawable.c b/gdk/gdkpixbuf-drawable.c index d74ee95d2..0a4474969 100644 --- a/gdk/gdkpixbuf-drawable.c +++ b/gdk/gdkpixbuf-drawable.c @@ -25,12 +25,12 @@ #include <config.h> #include <stdio.h> #include <string.h> -#include "gdk.h" /* For gdk_screen_width/gdk_screen_height */ #include "gdkcolor.h" #include "gdkimage.h" #include "gdkvisual.h" #include "gdkwindow.h" #include "gdkpixbuf.h" +#include "gdkpixmap.h" #include "gdk-pixbuf-private.h" #include "gdkinternals.h" @@ -1552,7 +1552,8 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf *dest, gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH); - image = _gdk_image_get_scratch (width1, height1, depth, &xs0, &ys0); + image = _gdk_image_get_scratch (gdk_drawable_get_screen (src), + width1, height1, depth, &xs0, &ys0); _gdk_drawable_copy_to_image (src, image, src_x + x0, src_y + y0, diff --git a/gdk/gdkpixbuf-render.c b/gdk/gdkpixbuf-render.c index 4361c75be..d4a417bcb 100644 --- a/gdk/gdkpixbuf-render.c +++ b/gdk/gdkpixbuf-render.c @@ -25,6 +25,7 @@ #include "gdkinternals.h" /* _gdk_draw_pixbuf() */ #include "gdk-pixbuf-private.h" #include "gdkpixbuf.h" +#include "gdkscreen.h" @@ -309,10 +310,11 @@ gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf, { GdkGC *gc; - *pixmap_return = gdk_pixmap_new (NULL, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), - gdk_colormap_get_visual (colormap)->depth); - gdk_drawable_set_colormap (GDK_DRAWABLE (*pixmap_return), - colormap); + *pixmap_return = gdk_pixmap_new (gdk_screen_get_root_window (colormap->screen), + gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), + gdk_screen_get_rgb_visual (colormap->screen)->depth); + + gdk_drawable_set_colormap (GDK_DRAWABLE (*pixmap_return), colormap); gc = gdk_gc_new (*pixmap_return); gdk_pixbuf_render_to_drawable (pixbuf, *pixmap_return, gc, 0, 0, 0, 0, @@ -326,8 +328,9 @@ gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf, { if (gdk_pixbuf_get_has_alpha (pixbuf)) { - *mask_return = gdk_pixmap_new (NULL, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), 1); - + *mask_return = gdk_pixmap_new (gdk_screen_get_root_window (colormap->screen), + gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), 1); + gdk_pixbuf_render_threshold_alpha (pixbuf, *mask_return, 0, 0, 0, 0, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), diff --git a/gdk/gdkpixbuf.h b/gdk/gdkpixbuf.h index 3298ad8b9..74bc5f346 100644 --- a/gdk/gdkpixbuf.h +++ b/gdk/gdkpixbuf.h @@ -51,10 +51,12 @@ void gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf, GdkPixmap **pixmap_return, GdkBitmap **mask_return, int alpha_threshold); +#ifndef GDK_MULTIHEAD_SAFE void gdk_pixbuf_render_pixmap_and_mask (GdkPixbuf *pixbuf, GdkPixmap **pixmap_return, GdkBitmap **mask_return, int alpha_threshold); +#endif /* Fetching a region from a drawable */ diff --git a/gdk/gdkpixmap.c b/gdk/gdkpixmap.c index 5e757246f..46a19f560 100644 --- a/gdk/gdkpixmap.c +++ b/gdk/gdkpixmap.c @@ -27,6 +27,7 @@ #include "gdkpixmap.h" #include "gdkinternals.h" #include "gdkpixbuf.h" +#include "gdkscreen.h" static GdkGC *gdk_pixmap_create_gc (GdkDrawable *drawable, GdkGCValues *values, @@ -200,6 +201,7 @@ gdk_pixmap_class_init (GdkPixmapObjectClass *klass) drawable_class->draw_image = gdk_pixmap_draw_image; drawable_class->_draw_pixbuf = gdk_pixmap_draw_pixbuf; drawable_class->get_depth = gdk_pixmap_real_get_depth; + drawable_class->get_screen = gdk_pixmap_get_screen; drawable_class->get_size = gdk_pixmap_real_get_size; drawable_class->set_colormap = gdk_pixmap_real_set_colormap; drawable_class->get_colormap = gdk_pixmap_real_get_colormap; @@ -474,13 +476,14 @@ gdk_pixmap_copy_to_image (GdkDrawable *drawable, } static GdkBitmap * -make_solid_mask (gint width, gint height) +make_solid_mask (GdkScreen *screen, gint width, gint height) { GdkBitmap *bitmap; GdkGC *gc; GdkGCValues gc_values; - bitmap = gdk_pixmap_new (NULL, width, height, 1); + bitmap = gdk_pixmap_new (gdk_screen_get_root_window (screen), + width, height, 1); gc_values.foreground.pixel = 1; gc = gdk_gc_new_with_values (bitmap, &gc_values, GDK_GC_FOREGROUND); @@ -504,7 +507,7 @@ gdk_pixmap_colormap_new_from_pixbuf (GdkColormap *colormap, GdkPixbuf *render_pixbuf; GdkGC *tmp_gc; - pixmap = gdk_pixmap_new (NULL, + pixmap = gdk_pixmap_new (gdk_screen_get_root_window (colormap->screen), gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), gdk_colormap_get_visual (colormap)->depth); @@ -533,10 +536,11 @@ gdk_pixmap_colormap_new_from_pixbuf (GdkColormap *colormap, gdk_pixbuf_unref (render_pixbuf); if (mask) - gdk_pixbuf_render_pixmap_and_mask (pixbuf, NULL, mask, 128); + gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, colormap, NULL, mask, 128); if (mask && !*mask) - *mask = make_solid_mask (gdk_pixbuf_get_width (pixbuf), + *mask = make_solid_mask (colormap->screen, + gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf)); return pixmap; diff --git a/gdk/gdkpixmap.h b/gdk/gdkpixmap.h index b7e0a930b..aa5c56bb8 100644 --- a/gdk/gdkpixmap.h +++ b/gdk/gdkpixmap.h @@ -73,9 +73,19 @@ GdkPixmap* gdk_pixmap_colormap_create_from_xpm_d (GdkWindow *window, GdkColor *transparent_color, gchar **data); -/* Functions to create/lookup pixmaps from their native equivalents */ +GdkScreen *gdk_pixmap_get_screen (GdkDrawable *drawable); + +/* Functions to create/lookup pixmaps from their native equivalents + */ +#ifndef GDK_MULTIHEAD_SAFE GdkPixmap* gdk_pixmap_foreign_new (GdkNativeWindow anid); GdkPixmap* gdk_pixmap_lookup (GdkNativeWindow anid); +#endif /* GDK_MULTIHEAD_SAFE */ + +GdkPixmap* gdk_pixmap_foreign_new_for_screen (GdkScreen *screen, + GdkNativeWindow anid); +GdkPixmap* gdk_pixmap_lookup_for_display (GdkDisplay *display, + GdkNativeWindow anid); #ifndef GDK_DISABLE_DEPRECATED #define gdk_bitmap_ref gdk_drawable_ref diff --git a/gdk/gdkproperty.h b/gdk/gdkproperty.h index 0a6d45f32..7d1151488 100644 --- a/gdk/gdkproperty.h +++ b/gdk/gdkproperty.h @@ -37,7 +37,7 @@ void gdk_property_change (GdkWindow *window, gint nelements); void gdk_property_delete (GdkWindow *window, GdkAtom property); - +#ifndef GDK_MULTIHEAD_SAFE gint gdk_text_property_to_text_list (GdkAtom encoding, gint format, const guchar *text, @@ -48,20 +48,46 @@ gint gdk_text_property_to_utf8_list (GdkAtom encoding, const guchar *text, gint length, gchar ***list); - -gchar *gdk_utf8_to_string_target (const gchar *str); gboolean gdk_utf8_to_compound_text (const gchar *str, GdkAtom *encoding, gint *format, guchar **ctext, gint *length); - -void gdk_free_text_list (gchar **list); gint gdk_string_to_compound_text (const gchar *str, GdkAtom *encoding, gint *format, guchar **ctext, gint *length); +#endif + +gint gdk_text_property_to_text_list_for_display (GdkDisplay *display, + GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list); +gint gdk_text_property_to_utf8_list_for_display (GdkDisplay *display, + GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list); + +gchar *gdk_utf8_to_string_target (const gchar *str); +gint gdk_string_to_compound_text_for_display (GdkDisplay *display, + const gchar *str, + GdkAtom *encoding, + gint *format, + guchar **ctext, + gint *length); +gboolean gdk_utf8_to_compound_text_for_display (GdkDisplay *display, + const gchar *str, + GdkAtom *encoding, + gint *format, + guchar **ctext, + gint *length); + +void gdk_free_text_list (gchar **list); void gdk_free_compound_text (guchar *ctext); #ifdef __cplusplus diff --git a/gdk/gdkregion-generic.c b/gdk/gdkregion-generic.c index e29a1b9db..cba6daf37 100644 --- a/gdk/gdkregion-generic.c +++ b/gdk/gdkregion-generic.c @@ -516,7 +516,6 @@ miIntersectO (GdkRegion *pReg, * Converts @source1 into the intersection between @source1 and @source2. * That is, after calling this function @source2 will be unchanged and * @source1 will be the areas the two regions have in common. - * **/ void gdk_region_intersect (GdkRegion *region, @@ -1409,8 +1408,8 @@ gdk_region_subtract (GdkRegion *region, * @source2: another #GdkRegion * * XORs the two regions, placing the result in @source1. The XOR of two - * regions contains all areas which were not overlapping. That is, - * it's the union of the regions minus the intersection of the + * regions contains all areas in one or the other ofthe regions, but not both. + * That is, it's the union of the regions minus the intersection of the * regions. * **/ diff --git a/gdk/gdkrgb.c b/gdk/gdkrgb.c index 29fecdd1a..93f260578 100644 --- a/gdk/gdkrgb.c +++ b/gdk/gdkrgb.c @@ -51,6 +51,7 @@ #include "gdkinternals.h" /* _gdk_windowing_get_bits_for_depth() */ #include "gdkrgb.h" +#include "gdkscreen.h" typedef struct _GdkRgbInfo GdkRgbInfo; typedef struct _GdkRgbCmapInfo GdkRgbCmapInfo; @@ -228,7 +229,7 @@ gdk_rgb_try_colormap (GdkRgbInfo *image_info, gboolean force, if (image_info->cmap) cmap = image_info->cmap; else - cmap = gdk_colormap_get_system (); + cmap = gdk_screen_get_system_colormap (image_info->visual->screen); colors_needed = nr * ng * nb; for (i = 0; i < 256; i++) @@ -238,7 +239,7 @@ gdk_rgb_try_colormap (GdkRgbInfo *image_info, gboolean force, } #ifndef GAMMA - if (cmap == gdk_colormap_get_system()) + if (cmap == gdk_screen_get_system_colormap (image_info->visual->screen)) /* find color cube colors that are already present */ for (i = 0; i < MIN (256, cmap->size); i++) { @@ -457,7 +458,7 @@ gdk_rgb_score_visual (GdkVisual *visual) if (quality == 0) return 0; - sys = (visual == gdk_visual_get_system ()); + sys = (visual == gdk_screen_get_system_visual (visual->screen)); pseudo = (visual->type == GDK_VISUAL_PSEUDO_COLOR || visual->type == GDK_VISUAL_TRUE_COLOR); @@ -475,13 +476,13 @@ gdk_rgb_score_visual (GdkVisual *visual) } static GdkVisual * -gdk_rgb_choose_visual (void) +gdk_rgb_choose_visual (GdkScreen *screen) { GList *visuals, *tmp_list; guint32 score, best_score; GdkVisual *visual, *best_visual; - visuals = gdk_list_visuals (); + visuals = gdk_screen_list_visuals (screen); tmp_list = visuals; best_visual = tmp_list->data; @@ -633,14 +634,14 @@ gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap) image_info->visual->depth >= 3)) { if (!image_info->cmap) - image_info->cmap = gdk_colormap_ref (gdk_colormap_get_system ()); + image_info->cmap = gdk_colormap_ref (gdk_screen_get_system_colormap (visual->screen)); gdk_rgb_colorcube_222 (image_info); } else if (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR) { if (!image_info->cmap && - (gdk_rgb_install_cmap || image_info->visual != gdk_visual_get_system ())) + (gdk_rgb_install_cmap || image_info->visual != gdk_screen_get_system_visual (visual->screen))) { image_info->cmap = gdk_colormap_new (image_info->visual, FALSE); image_info->cmap_alloced = TRUE; @@ -658,7 +659,7 @@ gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap) image_info->nblue_shades); if (!image_info->cmap) - image_info->cmap = gdk_colormap_ref (gdk_colormap_get_system ()); + image_info->cmap = gdk_colormap_ref (gdk_screen_get_system_colormap (visual->screen)); } #ifdef ENABLE_GRAYSCALE else if (image_info->visual->type == GDK_VISUAL_GRAYSCALE) @@ -678,8 +679,8 @@ gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap) { /* Always install colormap in direct color. */ if (image_info->visual->type != GDK_VISUAL_DIRECT_COLOR && - image_info->visual == gdk_visual_get_system ()) - image_info->cmap = gdk_colormap_ref (gdk_colormap_get_system ()); + image_info->visual == gdk_screen_get_system_visual (visual->screen)) + image_info->cmap = gdk_colormap_ref (gdk_screen_get_system_colormap (visual->screen)); else { image_info->cmap = gdk_colormap_new (image_info->visual, FALSE); @@ -690,8 +691,7 @@ gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap) image_info->bitmap = (image_info->visual->depth == 1); - image_info->bpp = (_gdk_windowing_get_bits_for_depth (image_info->visual->depth) + 7) / 8; - + image_info->bpp = (_gdk_windowing_get_bits_for_depth (gdk_screen_get_display (visual->screen), image_info->visual->depth) + 7) / 8; gdk_rgb_select_conv (image_info); if (!gdk_rgb_quark) @@ -793,7 +793,7 @@ gdk_rgb_xpixel_from_rgb (guint32 rgb) guint32 g = rgb & 0xff00; guint32 b = rgb & 0xff; - return gdk_rgb_xpixel_from_rgb_internal (gdk_rgb_get_colormap(), + return gdk_rgb_xpixel_from_rgb_internal (gdk_screen_get_rgb_colormap (gdk_get_default_screen ()), (r >> 8) + (r >> 16), g + (g >> 8), b + (b << 8)); } @@ -2884,7 +2884,8 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info) depth = image_info->visual->depth; - bpp = _gdk_windowing_get_bits_for_depth (image_info->visual->depth); + bpp = _gdk_windowing_get_bits_for_depth (gdk_screen_get_display (image_info->visual->screen), + image_info->visual->depth); byte_order = image_info->visual->byte_order; if (gdk_rgb_verbose) @@ -3117,7 +3118,9 @@ gdk_draw_rgb_image_core (GdkRgbInfo *image_info, width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH); buf_ptr = buf + y0 * rowstride + x0 * pixstride; - image = _gdk_image_get_scratch (width1, height1, image_info->visual->depth, &xs0, &ys0); + image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable), + width1, height1, + image_info->visual->depth, &xs0, &ys0); conv (image_info, image, xs0, ys0, width1, height1, buf_ptr, rowstride, x + x0 + xdith, y + y0 + ydith, cmap); @@ -3134,6 +3137,7 @@ static GdkRgbInfo * gdk_rgb_get_info_from_drawable (GdkDrawable *drawable) { GdkColormap *cmap = gdk_drawable_get_colormap (drawable); + GdkScreen *screen = gdk_drawable_get_screen (drawable); if (!cmap) { @@ -3142,7 +3146,7 @@ gdk_rgb_get_info_from_drawable (GdkDrawable *drawable) */ gint depth = gdk_drawable_get_depth (drawable); - GdkColormap *rgb_cmap = gdk_rgb_get_colormap(); + GdkColormap *rgb_cmap = gdk_screen_get_rgb_colormap (screen); if (depth == gdk_colormap_get_visual (rgb_cmap)->depth) cmap = rgb_cmap; else @@ -3453,7 +3457,7 @@ gdk_rgb_ditherable (void) /** * gdk_rgb_get_colormap: * - * Returns the preferred colormap for rendering image data. Not a + * Get the preferred colormap for rendering image data. Not a * very useful function; historically, GDK could only render RGB image * data to one colormap and visual, but in the current version it can * render to any colormap and visual. So there's no need to call this @@ -3465,18 +3469,77 @@ GdkColormap * gdk_rgb_get_colormap (void) { static GdkColormap *cmap = NULL; - if (!cmap) { - GdkRgbInfo *image_info = gdk_rgb_create_info (gdk_rgb_choose_visual (), NULL); + GdkRgbInfo *image_info = gdk_rgb_create_info (gdk_rgb_choose_visual (gdk_get_default_screen ()), NULL); + cmap = image_info->cmap; + } + + return cmap; +} + +/** + * gdk_screen_get_rgb_colormap: + * @screen : a #GdkScreen. + * + * Gets the preferred colormap for rendering image data on @screen. + * Not a very useful function; historically, GDK could only render RGB + * image data to one colormap and visual, but in the current version + * it can render to any colormap and visual. So there's no need to + * call this function. + * + * Return value: the preferred colormap + **/ +GdkColormap * +gdk_screen_get_rgb_colormap (GdkScreen *screen) +{ + GdkColormap *cmap; + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + cmap = g_object_get_data (G_OBJECT (screen), "rgb-colormap"); + if (!cmap) + { + GdkRgbInfo *image_info = gdk_rgb_create_info (gdk_rgb_choose_visual (screen), NULL); cmap = image_info->cmap; + g_object_set_data (G_OBJECT (screen), "rgb-colormap", cmap); } return cmap; } +/** + * gdk_screen_get_rgb_visual: + * @screen : a #GdkScreen + * + * Gets a "preferred visual" chosen by GdkRGB for rendering image data + * on @screen. In previous versions of + * GDK, this was the only visual GdkRGB could use for rendering. In + * current versions, it's simply the visual GdkRGB would have chosen as + * the optimal one in those previous versions. GdkRGB can now render to + * drawables with any visual. + * + * Return value: The #GdkVisual chosen by GdkRGB. + **/ +GdkVisual * +gdk_screen_get_rgb_visual (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + return gdk_colormap_get_visual (gdk_screen_get_rgb_colormap (screen)); +} + +/** + * gdk_rgb_get_visual: + * + * Gets a "preferred visual" chosen by GdkRGB for rendering image data + * on the default screen. In previous versions of GDK, this was the + * only visual GdkRGB could use for rendering. In current versions, + * it's simply the visual GdkRGB would have chosen as the optimal one + * in those previous versions. GdkRGB can now render to drawables with + * any visual. + * + * Return value: The #GdkVisual chosen by GdkRGB. + **/ GdkVisual * gdk_rgb_get_visual (void) { - return gdk_colormap_get_visual (gdk_rgb_get_colormap ()); + return gdk_screen_get_rgb_visual (gdk_get_default_screen ()); } diff --git a/gdk/gdkrgb.h b/gdk/gdkrgb.h index 7b1a1c60a..7c59e288d 100644 --- a/gdk/gdkrgb.h +++ b/gdk/gdkrgb.h @@ -127,17 +127,17 @@ GdkRgbCmap *gdk_rgb_cmap_new (guint32 *colors, gint n_colors); void gdk_rgb_cmap_free (GdkRgbCmap *cmap); -/* Below are some functions which are primarily useful for debugging - and experimentation. */ -gboolean gdk_rgb_ditherable (void); void gdk_rgb_set_verbose (gboolean verbose); /* experimental colormap stuff */ void gdk_rgb_set_install (gboolean install); void gdk_rgb_set_min_colors (gint min_colors); +#ifndef GDK_MULTIHEAD_SAFE GdkColormap *gdk_rgb_get_colormap (void); GdkVisual * gdk_rgb_get_visual (void); +gboolean gdk_rgb_ditherable (void); +#endif #ifdef __cplusplus } diff --git a/gdk/gdkscreen.c b/gdk/gdkscreen.c new file mode 100644 index 000000000..f1097fd16 --- /dev/null +++ b/gdk/gdkscreen.c @@ -0,0 +1,336 @@ +/* + * gdkscreen.c + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede <erwann.chenede@sun.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gdkscreen.h" +#include "gdkcolor.h" + +GType +gdk_screen_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (GdkScreenClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + NULL, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkScreen), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (G_TYPE_OBJECT, + "GdkScreen", &object_info, 0); + } + + return object_type; +} + +/** + * gdk_screen_get_default_colormap: + * @screen: a #GdkScreen + * + * Gets the default colormap for @screen. + * + * Returns: the default #GdkColormap. + **/ +GdkColormap * +gdk_screen_get_default_colormap (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return GDK_SCREEN_GET_CLASS (screen)->get_default_colormap (screen); +} + +/** + * gdk_screen_set_default_colormap: + * @screen: a #GdkScreen + * @colormap: a #GdkColormap + * + * Sets the default @colormap for @screen. + **/ +void +gdk_screen_set_default_colormap (GdkScreen *screen, + GdkColormap *colormap) +{ + g_return_if_fail (GDK_IS_SCREEN (screen)); + g_return_if_fail (GDK_IS_COLORMAP (colormap)); + + GDK_SCREEN_GET_CLASS (screen)->set_default_colormap (screen, colormap); +} + +/** + * gdk_screen_get_root_window: + * @screen: a #GdkScreen + * + * Gets the root window of @screen. + * + * Returns: the root window + **/ +GdkWindow * +gdk_screen_get_root_window (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return GDK_SCREEN_GET_CLASS (screen)->get_root_window (screen); +} + +/** + * gdk_screen_get_display: + * @screen: a #GdkScreen + * + * Gets the display to which the @screen belongs. + * + * Returns: the display to which @screen belongs + **/ +GdkDisplay * +gdk_screen_get_display (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return GDK_SCREEN_GET_CLASS (screen)->get_display (screen); +} + +/** + * gdk_screen_get_number: + * @screen: a #GdkScreen + * + * Gets the index of @screen among the screens in the display + * to which it belongs. (See gdk_screen_get_display()) + * + * Returns: the index + **/ +gint +gdk_screen_get_number (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_GET_CLASS (screen)->get_screen_num (screen); +} + +/** + * gdk_screen_get_window_at_pointer: + * @screen: a #GdkScreen + * @win_x: return location for origin of the window under the pointer + * @win_y: return location for origin of the window under the pointer + * + * Obtains the window underneath the mouse pointer, returning the location + * of that window in @win_x, @win_y for @screen. Returns %NULL if the window + * under the mouse pointer is not known to GDK (for example, belongs to + * another application). + * + * Returns: the window under the mouse pointer, or %NULL + **/ +GdkWindow * +gdk_screen_get_window_at_pointer (GdkScreen *screen, + gint *win_x, + gint *win_y) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return GDK_SCREEN_GET_CLASS (screen)->get_window_at_pointer (screen, win_x, win_y); +} + +/** + * gdk_screen_get_width: + * @screen: a #GdkScreen + * + * Gets the width of @screen in pixels + * + * Returns: the width of @screen in pixels. + **/ +gint +gdk_screen_get_width (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_GET_CLASS (screen)->get_width (screen); +} + +/** + * gdk_screen_get_height: + * @screen: a #GdkScreen + * + * Gets the height of @screen in pixels + * + * Returns: the height of @screen in pixels. + **/ +gint +gdk_screen_get_height (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_GET_CLASS (screen)->get_height (screen); +} + +/** + * gdk_screen_get_width_mm: + * @screen: a #GdkScreen + * + * Gets the width of @screen in millimeters. + * Note that on some X servers this value will not be correct. + * + * Returns: the width of @screen in pixels. + **/ +gint +gdk_screen_get_width_mm (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_GET_CLASS (screen)->get_width_mm (screen); +} + +/** + * gdk_screen_get_height_mm: + * @screen: a #GdkScreen + * + * Returns the height of @screen in millimeters. + * Note that on some X servers this value will not be correct. + * + * Returns: the heigth of @screen in pixels. + **/ +gint +gdk_screen_get_height_mm (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_GET_CLASS (screen)->get_height_mm (screen); +} + +/** + * gdk_screen_close: + * @screen: a #GdkScreen + * + * Closes the @screen connection and cleanup its resources. + * Note that this function is called automatically by gdk_display_close(). + **/ +void +gdk_screen_close (GdkScreen *screen) +{ + g_return_if_fail (GDK_IS_SCREEN (screen)); + + g_object_run_dispose (G_OBJECT (screen)); +} + +/** + * gdk_screen_use_virtual_screen: + * @screen : a #GdkScreen. + * + * Determines whether @screen is uses multiple monitors as + * a single virtual screen (e.g. Xinerama mode under X). + * + * Returns: %TRUE if multiple monitors are used as a single screen + ***/ +gboolean +gdk_screen_use_virtual_screen (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE); + + return GDK_SCREEN_GET_CLASS (screen)->use_virtual_screen (screen); +} + +/** + * gdk_screen_get_n_monitors: + * @screen : a #GdkScreen. + * + * Returns the number of monitors being part of the virtual screen + * + * Returns: number of monitors part of the virtual screen or + * 0 if @screen is not in virtual screen mode. + **/ +gint +gdk_screen_get_n_monitors (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + return GDK_SCREEN_GET_CLASS (screen)->get_n_monitors (screen); +} + +/** + * gdk_screen_get_monitor_geometry: + * @screen : a #GdkScreen. + * @monitor_num: the monitor number. + * + * Returns a #GdkRectangle representing the size and start + * coordinates of the individual monitor within the the entire virtual + * screen. + * + * Note that the virtual screen coordinates can be retrieved via + * gdk_screen_get_width() and gdk_screen_get_height(). + * + * Returns: the size and start position of the monitor wrt to + * the virtual screen. + **/ +GdkRectangle * +gdk_screen_get_monitor_geometry (GdkScreen *screen, + gint monitor_num) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return GDK_SCREEN_GET_CLASS (screen)->get_monitor_geometry (screen, monitor_num); +} + +/** + * gdk_screen_get_monitor_at_point: + * @screen : a #GdkScreen. + * @x : the x coordinate in the virtual screen. + * @y : the y coordinate in the virtual screen. + * + * Returns the monitor number in which the point (@x,@y) is located. + * + * Returns: the monitor number in which the point (@x,@y) belong, or + * -1 if the point is not in any monitor. + **/ +gint +gdk_screen_get_monitor_at_point (GdkScreen *screen, + gint x, + gint y) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), -1); + + return GDK_SCREEN_GET_CLASS (screen)->get_monitor_at_point (screen, x,y); +} + +/** + * gdk_screen_get_monitor_num_at_window: + * @screen : a #GdkScreen. + * @anid : a #GdkDrawable ID. + * + * Returns the monitor number in which the largest area of the bounding rectangle + * of @anid resides. + * + * Returns: the monitor number in which most of @anid is located. + **/ +gint +gdk_screen_get_monitor_at_window (GdkScreen *screen, + GdkNativeWindow anid) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), -1); + + return GDK_SCREEN_GET_CLASS (screen)->get_monitor_at_window (screen, anid); +} diff --git a/gdk/gdkscreen.h b/gdk/gdkscreen.h new file mode 100644 index 000000000..2f3a23387 --- /dev/null +++ b/gdk/gdkscreen.h @@ -0,0 +1,122 @@ +/* + * gdkscreen.h + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede <erwann.chenede@sun.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GDK_SCREEN_H__ +#define __GDK_SCREEN_H__ + +#include "gdk/gdktypes.h" +#include "gdk/gdkdisplay.h" + +G_BEGIN_DECLS + +typedef struct _GdkScreenClass GdkScreenClass; + +#define GDK_TYPE_SCREEN (gdk_screen_get_type ()) +#define GDK_SCREEN(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SCREEN, GdkScreen)) +#define GDK_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SCREEN, GdkScreenClass)) +#define GDK_IS_SCREEN(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SCREEN)) +#define GDK_IS_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SCREEN)) +#define GDK_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SCREEN, GdkScreenClass)) + +struct _GdkScreen +{ + GObject parent_instance; +}; + +struct _GdkScreenClass +{ + GObjectClass parent_class; + + GdkDisplay * (*get_display) (GdkScreen *screen); + gint (*get_width) (GdkScreen *screen); + gint (*get_height) (GdkScreen *screen); + gint (*get_width_mm) (GdkScreen *screen); + gint (*get_height_mm) (GdkScreen *screen); + gint (*get_root_depth) (GdkScreen *screen); + gint (*get_screen_num) (GdkScreen *screen); + GdkWindow * (*get_root_window) (GdkScreen *screen); + GdkColormap * (*get_default_colormap) (GdkScreen *screen); + void (*set_default_colormap) (GdkScreen *screen, + GdkColormap *colormap); + GdkWindow * (*get_window_at_pointer) (GdkScreen *screen, + gint *win_x, + gint *win_y); + gboolean (*use_virtual_screen) (GdkScreen *screen); + gint (*get_n_monitors) (GdkScreen *screen); + GdkRectangle *(*get_monitor_geometry) (GdkScreen *screen, + gint monitor_num); + + gint (*get_monitor_at_point) (GdkScreen *screen, + gint x, + gint y); + gint (*get_monitor_at_window) (GdkScreen *screen, + GdkNativeWindow anid); +}; + +GType gdk_screen_get_type (void); +GdkColormap *gdk_screen_get_default_colormap (GdkScreen *screen); +void gdk_screen_set_default_colormap (GdkScreen *screen, + GdkColormap *colormap); +GdkColormap* gdk_screen_get_system_colormap (GdkScreen *screen); +GdkVisual* gdk_screen_get_system_visual (GdkScreen *screen); +GdkColormap *gdk_screen_get_rgb_colormap (GdkScreen *screen); +GdkVisual * gdk_screen_get_rgb_visual (GdkScreen *screen); + +GdkWindow * gdk_screen_get_root_window (GdkScreen *screen); +GdkDisplay * gdk_screen_get_display (GdkScreen *screen); +gint gdk_screen_get_number (GdkScreen *screen); +GdkWindow * gdk_screen_get_window_at_pointer (GdkScreen *screen, + gint *win_x, + gint *win_y); +gint gdk_screen_get_width (GdkScreen *screen); +gint gdk_screen_get_height (GdkScreen *screen); +gint gdk_screen_get_width_mm (GdkScreen *screen); +gint gdk_screen_get_height_mm (GdkScreen *screen); +void gdk_screen_close (GdkScreen *screen); + +GList * gdk_screen_list_visuals (GdkScreen *screen); +GList * gdk_screen_get_toplevel_windows (GdkScreen *screen); + + +gboolean gdk_screen_use_virtual_screen (GdkScreen *screen); +gint gdk_screen_get_n_monitors (GdkScreen *screen); +GdkRectangle *gdk_screen_get_monitor_geometry (GdkScreen *screen, + gint monitor_num); +gint gdk_screen_get_monitor_at_point (GdkScreen *screen, + gint x, + gint y); +gint gdk_screen_get_monitor_at_window (GdkScreen *screen, + GdkNativeWindow anid); + +void gdk_screen_broadcast_client_message (GdkScreen *screen, + GdkEvent *event); + +GdkScreen *gdk_get_default_screen (void); + +gboolean gdk_screen_get_setting (GdkScreen *screen, + const gchar *name, + GValue *value); + +G_END_DECLS + +#endif /* __GDK_SCREEN_H__ */ diff --git a/gdk/gdkselection.h b/gdk/gdkselection.h index 03832944b..109e3cd68 100644 --- a/gdk/gdkselection.h +++ b/gdk/gdkselection.h @@ -37,11 +37,23 @@ typedef GdkAtom GdkSelectionType; /* Selections */ + +#ifndef GDK_MULTIHEAD_SAFE gboolean gdk_selection_owner_set (GdkWindow *owner, GdkAtom selection, guint32 time, gboolean send_event); GdkWindow* gdk_selection_owner_get (GdkAtom selection); +#endif/* GDK_MULTIHEAD_SAFE */ + +gboolean gdk_selection_owner_set_for_display (GdkDisplay *display, + GdkWindow *owner, + GdkAtom selection, + guint32 time, + gboolean send_event); +GdkWindow *gdk_selection_owner_get_for_display (GdkDisplay *display, + GdkAtom selection); + void gdk_selection_convert (GdkWindow *requestor, GdkAtom selection, GdkAtom target, @@ -50,11 +62,21 @@ gboolean gdk_selection_property_get (GdkWindow *requestor, guchar **data, GdkAtom *prop_type, gint *prop_format); + +#ifndef GDK_MULTIHEAD_SAFE void gdk_selection_send_notify (guint32 requestor, GdkAtom selection, GdkAtom target, GdkAtom property, guint32 time); +#endif /* GDK_MULTIHEAD_SAFE */ + +void gdk_selection_send_notify_for_display (GdkDisplay *display, + guint32 requestor, + GdkAtom selection, + GdkAtom target, + GdkAtom property, + guint32 time); #ifdef __cplusplus } diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h index 5023ef0f3..c454cae80 100644 --- a/gdk/gdktypes.h +++ b/gdk/gdktypes.h @@ -104,6 +104,8 @@ typedef struct _GdkDrawable GdkDrawable; typedef struct _GdkDrawable GdkBitmap; typedef struct _GdkDrawable GdkPixmap; typedef struct _GdkDrawable GdkWindow; +typedef struct _GdkDisplay GdkDisplay; +typedef struct _GdkScreen GdkScreen; typedef enum { diff --git a/gdk/gdkvisual.h b/gdk/gdkvisual.h index 68334855f..a97adbb46 100644 --- a/gdk/gdkvisual.h +++ b/gdk/gdkvisual.h @@ -3,9 +3,7 @@ #include <gdk/gdktypes.h> -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #define GDK_TYPE_VISUAL (gdk_visual_get_type ()) #define GDK_VISUAL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_VISUAL, GdkVisual)) @@ -67,10 +65,13 @@ struct _GdkVisual guint32 blue_mask; gint blue_shift; gint blue_prec; + + GdkScreen *screen; }; GType gdk_visual_get_type (void); +#ifndef GDK_MULTIHEAD_SAFE gint gdk_visual_get_best_depth (void); GdkVisualType gdk_visual_get_best_type (void); GdkVisual* gdk_visual_get_system (void); @@ -80,20 +81,19 @@ GdkVisual* gdk_visual_get_best_with_type (GdkVisualType visual_type); GdkVisual* gdk_visual_get_best_with_both (gint depth, GdkVisualType visual_type); -#ifndef GDK_DISABLE_DEPRECATED -#define gdk_visual_ref(v) g_object_ref(v) -#define gdk_visual_unref(v) g_object_unref(v) -#endif - void gdk_query_depths (gint **depths, gint *count); void gdk_query_visual_types (GdkVisualType **visual_types, gint *count); GList* gdk_list_visuals (void); +#endif + +#ifndef GDK_DISABLE_DEPRECATED +#define gdk_visual_ref(v) g_object_ref(v) +#define gdk_visual_unref(v) g_object_unref(v) +#endif -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __GDK_VISUAL_H__ */ diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index ac66759ec..0c0fb2e7e 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -30,6 +30,7 @@ #include "gdkpixmap.h" #include "gdkdrawable.h" #include "gdkpixmap.h" +#include "gdkscreen.h" #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */ @@ -154,8 +155,9 @@ static void gdk_window_real_get_size (GdkDrawable *drawable, static GdkVisual* gdk_window_real_get_visual (GdkDrawable *drawable); static gint gdk_window_real_get_depth (GdkDrawable *drawable); +static GdkScreen* gdk_window_real_get_screen (GdkDrawable *drawable); static void gdk_window_real_set_colormap (GdkDrawable *drawable, - GdkColormap *cmap); + GdkColormap *cmap); static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable); static GdkDrawable* gdk_window_get_composite_drawable (GdkDrawable *drawable, @@ -240,6 +242,7 @@ gdk_window_class_init (GdkWindowObjectClass *klass) drawable_class->draw_image = gdk_window_draw_image; drawable_class->_draw_pixbuf = gdk_window_draw_pixbuf; drawable_class->get_depth = gdk_window_real_get_depth; + drawable_class->get_screen = gdk_window_real_get_screen; drawable_class->get_size = gdk_window_real_get_size; drawable_class->set_colormap = gdk_window_real_set_colormap; drawable_class->get_colormap = gdk_window_real_get_colormap; @@ -698,9 +701,10 @@ gdk_window_remove_filter (GdkWindow *window, } /** - * gdk_window_get_toplevels: + * gdk_screen_get_toplevel_windows: + * @screen : The #GdkScreen where the toplevels are located. * - * Obtains a list of all toplevel windows known to GDK. + * Obtains a list of all toplevel windows known to GDK on the screen @screen. * A toplevel window is a child of the root window (see * gdk_get_default_root_window()). * @@ -710,12 +714,17 @@ gdk_window_remove_filter (GdkWindow *window, * Return value: list of toplevel windows, free with g_list_free() **/ GList * -gdk_window_get_toplevels (void) +gdk_screen_get_toplevel_windows (GdkScreen *screen) { + GdkWindow * root_window; GList *new_list = NULL; GList *tmp_list; - tmp_list = ((GdkWindowObject *)_gdk_parent_root)->children; + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + root_window = gdk_screen_get_root_window (screen); + + tmp_list = ((GdkWindowObject *)root_window)->children; while (tmp_list) { if (GDK_WINDOW_TYPE (tmp_list->data) != GDK_WINDOW_FOREIGN) @@ -727,6 +736,25 @@ gdk_window_get_toplevels (void) } /** + * gdk_window_get_toplevels: + * + * Obtains a list of all toplevel windows known to GDK on the default + * screen (see gdk_window_get_toplevels_for_screen()). + * A toplevel window is a child of the root window (see + * gdk_get_default_root_window()). + * + * The returned list should be freed with g_list_free(), but + * its elements need not be freed. + * + * Return value: list of toplevel windows, free with g_list_free() + **/ +GList * +gdk_window_get_toplevels (void) +{ + return gdk_screen_get_toplevel_windows (gdk_get_default_screen ()); +} + +/** * gdk_window_is_visible: * @window: a #GdkWindow * @@ -758,12 +786,14 @@ gboolean gdk_window_is_viewable (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; + GdkScreen *screen = gdk_drawable_get_screen (window); + GdkWindow *root_window = gdk_screen_get_root_window (screen); g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); while (private && - (private != (GdkWindowObject *)_gdk_parent_root) && + (private != (GdkWindowObject *)root_window) && (GDK_WINDOW_TYPE (private) != GDK_WINDOW_FOREIGN)) { if (!GDK_WINDOW_IS_MAPPED (window)) @@ -1974,13 +2004,17 @@ gdk_window_real_get_visual (GdkDrawable *drawable) static gint gdk_window_real_get_depth (GdkDrawable *drawable) { - gint depth; - g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0); return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth; } +static GdkScreen* +gdk_window_real_get_screen (GdkDrawable *drawable) +{ + return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl); +} + static void gdk_window_real_set_colormap (GdkDrawable *drawable, GdkColormap *cmap) @@ -2069,7 +2103,7 @@ gdk_window_process_updates_internal (GdkWindow *window) if (debug_updates) { /* Make sure we see the red invalid area before redrawing. */ - gdk_flush (); + gdk_display_sync (gdk_drawable_get_display (window)); g_usleep (70000); } @@ -2723,6 +2757,9 @@ gdk_window_get_pointer (GdkWindow *window, * location of that window in @win_x, @win_y. Returns %NULL if the * window under the mouse pointer is not known to GDK (for example, * belongs to another application). + * + * NOTE: For multihead-aware widgets or applications use + * gdk_screen_get_window_at_pointer() instead. * * Return value: window under the mouse pointer **/ @@ -2730,7 +2767,7 @@ GdkWindow* gdk_window_at_pointer (gint *win_x, gint *win_y) { - return current_pointer_hooks->window_at_pointer (NULL, win_x, win_y); + return current_pointer_hooks->window_at_pointer (gdk_get_default_screen (), win_x, win_y); } /** @@ -2744,6 +2781,6 @@ gdk_window_at_pointer (gint *win_x, GdkWindow * gdk_get_default_root_window (void) { - return _gdk_parent_root; + return gdk_screen_get_root_window (gdk_get_default_screen ()); } diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index 7235ce2e3..2495dc410 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -197,10 +197,6 @@ struct _GdkGeometry GdkGravity win_gravity; }; -/* Dummy typedef for placeholder in GdkPointerHooks.window_at_pointer - */ -typedef struct _GdkScreen GdkScreen; - struct _GdkPointerHooks { GdkWindow* (*get_pointer) (GdkWindow *window, @@ -378,8 +374,14 @@ gboolean gdk_window_set_static_gravities (GdkWindow *window, gboolean use_static); /* Functions to create/lookup windows from their native equivalents */ +#ifndef GDK_MULTIHEAD_SAFE GdkWindow* gdk_window_foreign_new (GdkNativeWindow anid); GdkWindow* gdk_window_lookup (GdkNativeWindow anid); +#endif +GdkWindow *gdk_window_foreign_new_for_display (GdkDisplay *display, + GdkNativeWindow anid); +GdkWindow* gdk_window_lookup_for_display (GdkDisplay *display, + GdkNativeWindow anid); /* GdkWindow */ @@ -477,7 +479,10 @@ gboolean gdk_window_get_decorations (GdkWindow *window, GdkWMDecoration *decorations); void gdk_window_set_functions (GdkWindow *window, GdkWMFunction functions); +#ifndef GDK_MULTIHEAD_SAFE GList * gdk_window_get_toplevels (void); +void gdk_set_sm_client_id (const gchar *sm_client_id); +#endif void gdk_window_iconify (GdkWindow *window); void gdk_window_deiconify (GdkWindow *window); diff --git a/gdk/x11/Makefile.am b/gdk/x11/Makefile.am index 5392c5017..a9d3c5956 100644 --- a/gdk/x11/Makefile.am +++ b/gdk/x11/Makefile.am @@ -18,15 +18,6 @@ LDADDS = @STRIP_BEGIN@ \ noinst_LTLIBRARIES = libgdk-x11.la -if XINPUT_GXI -xinput_sources = \ - gdkinput-x11.c \ - gdkinput-gxi.c -gxid_sources = \ - gxid_lib.c \ - gxid_lib.h \ - gxid_proto.h -else if XINPUT_XFREE xinput_sources = \ gdkinput-x11.c \ @@ -35,12 +26,12 @@ else xinput_sources = \ gdkinput-none.c endif -endif libgdk_x11_la_SOURCES = \ MwmUtil.h \ gdkcolor-x11.c \ gdkcursor-x11.c \ + gdkdisplay-x11.c \ gdkdnd-x11.c \ gdkdrawable-x11.c \ gdkdrawable-x11.h \ @@ -58,6 +49,7 @@ libgdk_x11_la_SOURCES = \ gdkpixmap-x11.c \ gdkpixmap-x11.h \ gdkproperty-x11.c \ + gdkscreen-x11.c \ gdkselection-x11.c \ gdkvisual-x11.c \ gdkwindow-x11.c \ @@ -66,7 +58,6 @@ libgdk_x11_la_SOURCES = \ gdkx.h \ gdkprivate-x11.h \ gdkinputprivate.h \ - $(gxid_sources) \ xsettings-client.h \ xsettings-client.c \ xsettings-common.h \ @@ -76,16 +67,9 @@ libgdk_x11_la_SOURCES = \ libgdkinclude_HEADERS = \ gdkx.h -EXTRA_PROGRAMS = gxid -bin_PROGRAMS = @xinput_progs@ - -gxid_SOURCES = gxid.c -gxid_LDADD = $(LDADDS) - # We need to include all these C files here since the conditionals # don't seem to be correctly expanded for the dist files. EXTRA_DIST = \ gdkinput-x11.c \ gdkinput-xfree.c \ - gdkinput-gxi.c \ gdkinput-none.c diff --git a/gdk/x11/gdkcolor-x11.c b/gdk/x11/gdkcolor-x11.c index 7dcf27ecf..3e2d202fe 100644 --- a/gdk/x11/gdkcolor-x11.c +++ b/gdk/x11/gdkcolor-x11.c @@ -28,7 +28,9 @@ #include "gdkcolor.h" #include "gdkinternals.h" +#include "gdkx.h" #include "gdkprivate-x11.h" +#include "gdkscreen-x11.h" typedef struct _GdkColormapPrivateX11 GdkColormapPrivateX11; @@ -99,9 +101,9 @@ gdk_colormap_init (GdkColormap *colormap) private = g_new (GdkColormapPrivateX11, 1); + colormap->screen = NULL; colormap->windowing_data = private; - private->xdisplay = gdk_display; private->hash = NULL; private->last_sync_time = 0; private->info = NULL; @@ -128,7 +130,7 @@ gdk_colormap_finalize (GObject *object) gdk_colormap_remove (colormap); - XFreeColormap (private->xdisplay, private->xcolormap); + XFreeColormap (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap); if (private->hash) g_hash_table_destroy (private->hash); @@ -146,6 +148,8 @@ gdk_colormap_new (GdkVisual *visual, GdkColormap *colormap; GdkColormapPrivateX11 *private; Visual *xvisual; + Display *xdisplay; + Window xrootwin; int size; int i; @@ -159,8 +163,11 @@ gdk_colormap_new (GdkVisual *visual, private = GDK_COLORMAP_PRIVATE_DATA (colormap); colormap->visual = visual; + colormap->screen = visual->screen; xvisual = ((GdkVisualPrivate*) visual)->xvisual; + xdisplay = GDK_SCREEN_XDISPLAY (visual->screen); + xrootwin = GDK_SCREEN_XROOTWIN (visual->screen); colormap->size = visual->colormap_size; @@ -175,20 +182,20 @@ gdk_colormap_new (GdkVisual *visual, (GEqualFunc) gdk_color_equal); private->private_val = private_cmap; - private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window, + private->xcolormap = XCreateColormap (xdisplay, xrootwin, xvisual, (private_cmap) ? (AllocAll) : (AllocNone)); if (private_cmap) { XColor *default_colors; - default_colors = g_new (XColor, colormap->size); + default_colors = g_new (XColor, colormap->size); for (i = 0; i < colormap->size; i++) default_colors[i].pixel = i; - - XQueryColors (private->xdisplay, - DefaultColormap (private->xdisplay, _gdk_screen), + + XQueryColors (xdisplay, + DefaultColormapOfScreen (GDK_SCREEN_X11 (visual->screen)->xscreen), default_colors, colormap->size); for (i = 0; i < colormap->size; i++) @@ -207,7 +214,7 @@ gdk_colormap_new (GdkVisual *visual, case GDK_VISUAL_DIRECT_COLOR: private->private_val = TRUE; - private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window, + private->xcolormap = XCreateColormap (xdisplay, xrootwin, xvisual, AllocAll); colormap->colors = g_new (GdkColor, colormap->size); @@ -229,7 +236,7 @@ gdk_colormap_new (GdkVisual *visual, case GDK_VISUAL_STATIC_GRAY: case GDK_VISUAL_STATIC_COLOR: private->private_val = FALSE; - private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window, + private->xcolormap = XCreateColormap (xdisplay, xrootwin, xvisual, AllocNone); colormap->colors = g_new (GdkColor, colormap->size); @@ -238,7 +245,7 @@ gdk_colormap_new (GdkVisual *visual, case GDK_VISUAL_TRUE_COLOR: private->private_val = FALSE; - private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window, + private->xcolormap = XCreateColormap (xdisplay, xrootwin, xvisual, AllocNone); break; } @@ -283,7 +290,8 @@ gdk_colormap_sync (GdkColormap *colormap, } } - XQueryColors (gdk_display, private->xcolormap, xpalette, nlookup); + XQueryColors (GDK_SCREEN_XDISPLAY (colormap->screen), + private->xcolormap, xpalette, nlookup); for (i = 0; i < nlookup; i++) { @@ -297,58 +305,86 @@ gdk_colormap_sync (GdkColormap *colormap, g_free (xpalette); } - -GdkColormap* -gdk_colormap_get_system (void) +/** + * gdk_screen_get_system_colormap: + * @screen: a #GdkScreen + * + * Gets the system's default colormap for @screen + * + * Returns: the default colormap for @screen. + */ +GdkColormap * +gdk_screen_get_system_colormap (GdkScreen *screen) { - static GdkColormap *colormap = NULL; + GdkColormap *colormap = NULL; GdkColormapPrivateX11 *private; + GdkScreenX11 *screen_x11; - if (!colormap) - { - colormap = g_object_new (gdk_colormap_get_type (), NULL); - private = GDK_COLORMAP_PRIVATE_DATA (colormap); + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + screen_x11 = GDK_SCREEN_X11 (screen); - private->xdisplay = gdk_display; - private->xcolormap = DefaultColormap (gdk_display, _gdk_screen); - colormap->visual = gdk_visual_get_system (); - private->private_val = FALSE; + if (screen_x11->system_colormap) + return screen_x11->system_colormap; - private->hash = NULL; - private->last_sync_time = 0; - private->info = NULL; + colormap = g_object_new (gdk_colormap_get_type (), NULL); + private = GDK_COLORMAP_PRIVATE_DATA (colormap); - colormap->colors = NULL; - colormap->size = colormap->visual->colormap_size; + colormap->screen = screen; + colormap->visual = gdk_screen_get_system_visual (screen); + + private->xcolormap = DefaultColormapOfScreen (screen_x11->xscreen); + private->private_val = FALSE; - switch (colormap->visual->type) - { - case GDK_VISUAL_GRAYSCALE: - case GDK_VISUAL_PSEUDO_COLOR: - private->info = g_new0 (GdkColorInfo, colormap->size); - private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash, - (GEqualFunc) gdk_color_equal); - /* Fall through */ - case GDK_VISUAL_STATIC_GRAY: - case GDK_VISUAL_STATIC_COLOR: - colormap->colors = g_new (GdkColor, colormap->size); - gdk_colormap_sync (colormap, TRUE); - - case GDK_VISUAL_DIRECT_COLOR: - case GDK_VISUAL_TRUE_COLOR: - break; - } + private->hash = NULL; + private->last_sync_time = 0; + private->info = NULL; - gdk_colormap_add (colormap); - } + colormap->colors = NULL; + colormap->size = colormap->visual->colormap_size; + switch (colormap->visual->type) + { + case GDK_VISUAL_GRAYSCALE: + case GDK_VISUAL_PSEUDO_COLOR: + private->info = g_new0 (GdkColorInfo, colormap->size); + private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash, + (GEqualFunc) gdk_color_equal); + /* Fall through */ + case GDK_VISUAL_STATIC_GRAY: + case GDK_VISUAL_STATIC_COLOR: + colormap->colors = g_new (GdkColor, colormap->size); + gdk_colormap_sync (colormap, TRUE); + + case GDK_VISUAL_DIRECT_COLOR: + case GDK_VISUAL_TRUE_COLOR: + break; + } + + gdk_colormap_add (colormap); + screen_x11->system_colormap = colormap; + return colormap; } +/** + * gdk_colormap_get_system: + * + * Gets the system's default colormap for the default screen. (See + * gdk_colormap_get_system_for_screen ()) + * + * Return value: the default colormap. + **/ +GdkColormap* +gdk_colormap_get_system (void) +{ + return gdk_screen_get_system_colormap (gdk_get_default_screen ()); +} + gint gdk_colormap_get_system_size (void) { - return DisplayCells (gdk_display, _gdk_screen); + return DisplayCells (GDK_SCREEN_XDISPLAY (gdk_get_default_screen()), + GDK_SCREEN_X11 (gdk_get_default_screen())->screen_num); } void @@ -358,6 +394,7 @@ gdk_colormap_change (GdkColormap *colormap, GdkColormapPrivateX11 *private; GdkVisual *visual; XColor *palette; + Display *xdisplay; gint shift; int max_colors; int size; @@ -365,6 +402,7 @@ gdk_colormap_change (GdkColormap *colormap, g_return_if_fail (GDK_IS_COLORMAP (colormap)); + xdisplay = GDK_SCREEN_XDISPLAY (colormap->screen); palette = g_new (XColor, ncolors); private = GDK_COLORMAP_PRIVATE_DATA (colormap); @@ -381,7 +419,7 @@ gdk_colormap_change (GdkColormap *colormap, palette[i].flags = DoRed | DoGreen | DoBlue; } - XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors); + XStoreColors (xdisplay, private->xcolormap, palette, ncolors); break; case GDK_VISUAL_DIRECT_COLOR: @@ -398,7 +436,7 @@ gdk_colormap_change (GdkColormap *colormap, palette[i].flags = DoRed; } - XStoreColors (private->xdisplay, private->xcolormap, palette, size); + XStoreColors (xdisplay, private->xcolormap, palette, size); shift = visual->green_shift; max_colors = 1 << visual->green_prec; @@ -411,7 +449,7 @@ gdk_colormap_change (GdkColormap *colormap, palette[i].flags = DoGreen; } - XStoreColors (private->xdisplay, private->xcolormap, palette, size); + XStoreColors (xdisplay, private->xcolormap, palette, size); shift = visual->blue_shift; max_colors = 1 << visual->blue_prec; @@ -424,7 +462,7 @@ gdk_colormap_change (GdkColormap *colormap, palette[i].flags = DoBlue; } - XStoreColors (private->xdisplay, private->xcolormap, palette, size); + XStoreColors (xdisplay, private->xcolormap, palette, size); break; default: @@ -450,9 +488,9 @@ gdk_colors_alloc (GdkColormap *colormap, private = GDK_COLORMAP_PRIVATE_DATA (colormap); - return_val = XAllocColorCells (private->xdisplay, private->xcolormap, - contiguous, planes, nplanes, pixels, npixels); - + return_val = XAllocColorCells (GDK_SCREEN_XDISPLAY (colormap->screen), + private->xcolormap,contiguous, planes, + nplanes, pixels, npixels); if (return_val) { for (i=0; i<npixels; i++) @@ -509,7 +547,7 @@ gdk_colors_free (GdkColormap *colormap, } if (npixels) - XFreeColors (private->xdisplay, private->xcolormap, + XFreeColors (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, pixels, npixels, planes); g_free (pixels); } @@ -557,7 +595,7 @@ gdk_colormap_free_colors (GdkColormap *colormap, } if (npixels) - XFreeColors (private->xdisplay, private->xcolormap, + XFreeColors (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, pixels, npixels, 0); g_free (pixels); @@ -586,7 +624,7 @@ gdk_colormap_alloc1 (GdkColormap *colormap, xcolor.pixel = color->pixel; xcolor.flags = DoRed | DoGreen | DoBlue; - if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor)) + if (XAllocColor (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, &xcolor)) { ret->pixel = xcolor.pixel; ret->red = xcolor.red; @@ -597,7 +635,7 @@ gdk_colormap_alloc1 (GdkColormap *colormap, { if (private->info[ret->pixel].ref_count) /* got a duplicate */ { - XFreeColors (private->xdisplay, private->xcolormap, + XFreeColors (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, &xcolor.pixel, 1, 0); } else @@ -659,7 +697,7 @@ gdk_colormap_alloc_colors_writeable (GdkColormap *colormap, pixels = g_new (gulong, ncolors); /* Allocation of a writeable color cells */ - status = XAllocColorCells (private->xdisplay, private->xcolormap, + status = XAllocColorCells (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, FALSE, NULL, 0, pixels, ncolors); if (status) { @@ -722,7 +760,8 @@ gdk_colormap_alloc_colors_private (GdkColormap *colormap, } } - XStoreColors (private->xdisplay, private->xcolormap, store, nstore); + XStoreColors (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, + store, nstore); g_free (store); if (nremaining > 0 && best_match) @@ -954,7 +993,7 @@ gdk_colormap_alloc_colors (GdkColormap *colormap, xcolor.pixel = colors[i].pixel; xcolor.flags = DoRed | DoGreen | DoBlue; - if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor)) + if (XAllocColor (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, &xcolor)) { colors[i].pixel = xcolor.pixel; success[i] = TRUE; @@ -1013,7 +1052,7 @@ gdk_colormap_query_color (GdkColormap *colormap, break; case GDK_VISUAL_STATIC_COLOR: xcolor.pixel = pixel; - XQueryColor (private->xdisplay, private->xcolormap, &xcolor); + XQueryColor (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, &xcolor); result->red = xcolor.red; result->green = xcolor.green; result->blue = xcolor.blue; @@ -1047,7 +1086,7 @@ gdk_color_change (GdkColormap *colormap, xcolor.flags = DoRed | DoGreen | DoBlue; private = GDK_COLORMAP_PRIVATE_DATA (colormap); - XStoreColor (private->xdisplay, private->xcolormap, &xcolor); + XStoreColor (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, &xcolor); return TRUE; } @@ -1059,6 +1098,7 @@ GdkColormap* gdkx_colormap_get (Colormap xcolormap) { GdkColormap *colormap; +#if 0 GdkColormapPrivateX11 *private; colormap = gdk_colormap_lookup (xcolormap); @@ -1075,6 +1115,7 @@ gdkx_colormap_get (Colormap xcolormap) private->xcolormap = xcolormap; colormap->visual = NULL; private->private_val = TRUE; +#endif /* To do the following safely, we would have to have some way of finding * out what the size or visual of the given colormap is. It seems diff --git a/gdk/x11/gdkcursor-x11.c b/gdk/x11/gdkcursor-x11.c index de70775d5..6b8a94f10 100644 --- a/gdk/x11/gdkcursor-x11.c +++ b/gdk/x11/gdkcursor-x11.c @@ -30,10 +30,13 @@ #include "gdkprivate-x11.h" #include "gdkcursor.h" #include "gdkpixmap-x11.h" +#include "gdkx.h" #include <gdk/gdkpixmap.h> +#include "gdkscreen-x11.h" /** - * gdk_cursor_new: + * gdk_cursor_new_for_screen: + * @screen: the #GdkScreen where the cursor will be defined * @cursor_type: cursor to create * * Creates a new cursor from the set of builtin cursors. @@ -98,23 +101,44 @@ * Return value: a new #GdkCursor **/ GdkCursor* -gdk_cursor_new (GdkCursorType cursor_type) +gdk_cursor_new_for_screen (GdkScreen *screen, + GdkCursorType cursor_type) { GdkCursorPrivate *private; GdkCursor *cursor; Cursor xcursor; - xcursor = XCreateFontCursor (gdk_display, cursor_type); + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + xcursor = XCreateFontCursor (GDK_SCREEN_XDISPLAY (screen), cursor_type); private = g_new (GdkCursorPrivate, 1); - private->xdisplay = gdk_display; + private->screen = screen; private->xcursor = xcursor; - cursor = (GdkCursor*) private; + cursor = (GdkCursor *) private; cursor->type = cursor_type; cursor->ref_count = 1; return cursor; } +/** + * gdk_cursor_new: + * @cursor_type: cursor to create + * + * Creates a new cursor from the set of builtin cursors for the default screen. + * See gdk_cursor_new_for_screen(). + * + * To make the cursor invisible, use gdk_cursor_new_from_pixmap() to create + * a cursor with no pixels in it. + * + * Return value: a new #GdkCursor + **/ +GdkCursor* +gdk_cursor_new (GdkCursorType cursor_type) +{ + return gdk_cursor_new_for_screen (gdk_get_default_screen(), cursor_type); +} + GdkCursor* gdk_cursor_new_from_pixmap (GdkPixmap *source, GdkPixmap *mask, @@ -128,6 +152,7 @@ gdk_cursor_new_from_pixmap (GdkPixmap *source, Pixmap source_pixmap, mask_pixmap; Cursor xcursor; XColor xfg, xbg; + GdkScreen *screen; g_return_val_if_fail (GDK_IS_PIXMAP (source), NULL); g_return_val_if_fail (GDK_IS_PIXMAP (mask), NULL); @@ -136,6 +161,7 @@ gdk_cursor_new_from_pixmap (GdkPixmap *source, source_pixmap = GDK_PIXMAP_XID (source); mask_pixmap = GDK_PIXMAP_XID (mask); + screen = GDK_PIXMAP_SCREEN (source); xfg.pixel = fg->pixel; xfg.red = fg->red; @@ -146,9 +172,10 @@ gdk_cursor_new_from_pixmap (GdkPixmap *source, xbg.blue = bg->blue; xbg.green = bg->green; - xcursor = XCreatePixmapCursor (gdk_display, source_pixmap, mask_pixmap, &xfg, &xbg, x, y); + xcursor = XCreatePixmapCursor (GDK_SCREEN_XDISPLAY (screen), + source_pixmap, mask_pixmap, &xfg, &xbg, x, y); private = g_new (GdkCursorPrivate, 1); - private->xdisplay = gdk_display; + private->screen = screen; private->xcursor = xcursor; cursor = (GdkCursor *) private; cursor->type = GDK_CURSOR_IS_PIXMAP; @@ -166,7 +193,7 @@ _gdk_cursor_destroy (GdkCursor *cursor) g_return_if_fail (cursor->ref_count == 0); private = (GdkCursorPrivate *) cursor; - XFreeCursor (private->xdisplay, private->xcursor); + XFreeCursor (GDK_SCREEN_XDISPLAY (private->screen), private->xcursor); g_free (private); } @@ -176,7 +203,7 @@ gdk_x11_cursor_get_xdisplay (GdkCursor *cursor) { g_return_val_if_fail (cursor != NULL, NULL); - return ((GdkCursorPrivate *)cursor)->xdisplay; + return GDK_SCREEN_XDISPLAY(((GdkCursorPrivate *)cursor)->screen); } Cursor @@ -186,3 +213,20 @@ gdk_x11_cursor_get_xcursor (GdkCursor *cursor) return ((GdkCursorPrivate *)cursor)->xcursor; } + +/** + * gdk_cursor_get_screen: + * @cursor : a #GdkCursor. + * + * Returns the screen on which the GdkCursor is defined + * + * Returns : the #GdkScreen associated to @cursor + */ + +GdkScreen * +gdk_cursor_get_screen (GdkCursor *cursor) +{ + g_return_val_if_fail (cursor != NULL, NULL); + + return ((GdkCursorPrivate *)cursor)->screen; +} diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c new file mode 100644 index 000000000..41b0078ca --- /dev/null +++ b/gdk/x11/gdkdisplay-x11.c @@ -0,0 +1,640 @@ +/* GDK - The GIMP Drawing Kit + * gdkdisplay-x11.c + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede <erwann.chenede@sun.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <config.h> + +#include <unistd.h> + +#include <glib.h> +#include "gdkx.h" +#include "gdkdisplay.h" +#include "gdkdisplay-x11.h" +#include "gdkscreen.h" +#include "gdkscreen-x11.h" +#include "gdkinternals.h" +#include "gdkinputprivate.h" +#include "xsettings-client.h" + +#include <X11/Xatom.h> + +#ifdef HAVE_XKB +#include <X11/XKBlib.h> +#endif + +#ifdef HAS_SOLARIS_XINERAMA +#include <X11/extensions/xinerama.h> +#endif +#ifdef HAS_XFREE_XINERAMA +#include <X11/extensions/Xinerama.h> +#endif + +static void gdk_display_x11_class_init (GdkDisplayX11Class *class); +static gint gdk_display_x11_get_n_screens (GdkDisplay *display); +static GdkScreen * gdk_display_x11_get_screen (GdkDisplay *display, + gint screen_num); +G_CONST_RETURN static char *gdk_display_x11_get_display_name (GdkDisplay *display); +static GdkScreen * gdk_display_x11_get_default_screen (GdkDisplay *display); +static void gdk_display_x11_finalize (GObject *object); + +static gpointer parent_class = NULL; + +GType +gdk_display_x11_get_type () +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (GdkDisplayX11Class), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) gdk_display_x11_finalize, + (GClassInitFunc) gdk_display_x11_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkDisplayX11), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (GDK_TYPE_DISPLAY, + "GdkDisplayX11", + &object_info, 0); + } + + return object_type; +} + +static void +gdk_display_x11_class_init (GdkDisplayX11Class * class) +{ + GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (class); + + display_class->get_display_name = gdk_display_x11_get_display_name; + display_class->get_n_screens = gdk_display_x11_get_n_screens; + display_class->get_screen = gdk_display_x11_get_screen; + display_class->get_default_screen = gdk_display_x11_get_default_screen; + + G_OBJECT_CLASS (class)->finalize = gdk_display_x11_finalize; + + parent_class = g_type_class_peek_parent (class); +} + +#ifdef HAS_XINERAMA +static gboolean +check_solaris_xinerama (GdkScreen *screen) +{ +#ifdef HAS_SOLARIS_XINERAMA + if (XineramaGetState (GDK_SCREEN_XDISPLAY (screen), + gdk_screen_get_number (screen))) + { + XRectangle monitors[MAXFRAMEBUFFERS]; + char hints[16]; + + result = XineramaGetInfo (GDK_SCREEN_XDISPLAY (screen), + gdk_screen_get_number (screen), + monitors, hints, + &screen_x11->num_monitors); + if (result != Success) + { + /* FIXME: We need to trap errors, since XINERAMA isn't always XINERAMA. + */ + g_error ("error while retrieving Xinerama information"); + } + else + { + int i; + screen_x11->use_virtual_screen = TRUE; + screen_x11->monitors = g_new0 (GdkRectangle, screen_x11->num_monitors); + + for (i = 0; i < screen_x11->num_monitors; i++) + { + screen_x11->monitors[i].x = monitors[i].x; + screen_x11->monitors[i].y = monitors[i].y; + screen_x11->monitors[i].width = monitors[i].width; + screen_x11->monitors[i].height = monitors[i].height; + } + + return TRUE; + } + } +#endif /* HAS_SOLARIS_XINERAMA */ + + return FALSE; +} + +static gboolean +check_xfree_xinerama (GdkScreen *screen) +{ +#ifdef HAS_XFREE_XINERAMA + if (XineramaIsActive (GDK_SCREEN_XDISPLAY (screen))) + { + XineramaScreenInfo *monitors = XineramaQueryScreens (GDK_SCREEN_XDISPLAY (screen), + &screen_x11->num_monitors); + if (screen_x11->num_monitors <= 0) + { + /* FIXME: We need to trap errors, since XINERAMA isn't always XINERAMA. + * I don't think the num_monitors <= 0 check has any validity. + */ + g_error ("error while retrieving Xinerama information"); + } + else + { + int i; + screen_x11->use_virtual_screen = TRUE; + screen_x11->monitors = g_new0 (GdkRectangle, screen_x11->num_monitors); + + for (i = 0; i < screen_x11->num_monitors; i++) + { + screen_x11->monitors[i].x = monitors[i].x_org; + screen_x11->monitors[i].y = monitors[i].y_org; + screen_x11->monitors[i].width = monitors[i].width; + screen_x11->monitors[i].height = monitors[i].height; + } + + XFree (monitors); + + return TRUE; + } + } +#endif /* HAS_XFREE_XINERAMA */ + + return FALSE; +} +#endif /* HAS_XINERAMA */ + +static void +init_xinerama_support (GdkScreen * screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + +#ifdef HAS_XINERAMA + int opcode, firstevent, firsterror; + gint result; + + if (XQueryExtension (GDK_SCREEN_XDISPLAY (screen), "XINERAMA", + &opcode, &firstevent, &firsterror)) + { + if (check_solaris_xinerama (screen) || + check_xfree_xinerama (screen)) + return; + } +#endif /* HAS_XINERAMA */ + + /* No Xinerama + */ + screen_x11->use_virtual_screen = FALSE; + screen_x11->num_monitors = 1; + screen_x11->monitors = g_new0 (GdkRectangle, 1); + screen_x11->monitors[0].x = 0; + screen_x11->monitors[0].y = 0; + screen_x11->monitors[0].width = WidthOfScreen (screen_x11->xscreen); + screen_x11->monitors[0].height = HeightOfScreen (screen_x11->xscreen); +} + +GdkDisplay * +gdk_open_display (const gchar *display_name) +{ + GdkDisplay *display; + GdkDisplayX11 *display_x11; + gint argc; + gchar **argv; + + XClassHint *class_hint; + XKeyboardState keyboard_state; + gulong pid; + gint i; + + display = g_object_new (GDK_TYPE_DISPLAY_X11, NULL); + display_x11 = GDK_DISPLAY_X11 (display); + + display_x11->use_xft = -1; + display_x11->xdisplay = XOpenDisplay (display_name); + + if (!display_x11->xdisplay) + { + g_object_unref (display); + return NULL; + } + + /* populate the screen list and set default */ + for (i = 0; i < ScreenCount (display_x11->xdisplay); i++) + { + GdkScreen *screen; + GdkScreenX11 *screen_x11; + + screen = g_object_new (GDK_TYPE_SCREEN_X11, NULL); + + screen_x11 = GDK_SCREEN_X11 (screen); + screen_x11->display = display; + screen_x11->xdisplay = display_x11->xdisplay; + screen_x11->xscreen = ScreenOfDisplay (display_x11->xdisplay, i); + screen_x11->screen_num = i; + screen_x11->xroot_window = (Window) RootWindow (display_x11->xdisplay, i); + screen_x11->wmspec_check_window = None; + screen_x11->visual_initialised = FALSE; + screen_x11->colormap_initialised = FALSE; + + + init_xinerama_support (screen); + if (screen_x11->xscreen == DefaultScreenOfDisplay (display_x11->xdisplay)) + { + display_x11->default_screen = screen; + display_x11->leader_window = XCreateSimpleWindow (display_x11->xdisplay, + screen_x11->xroot_window, + 10, 10, 10, 10, 0, 0, 0); + } + + display_x11->screen_list = g_slist_prepend (display_x11->screen_list, screen); + } + + if (_gdk_synchronize) + XSynchronize (display_x11->xdisplay, True); + + class_hint = XAllocClassHint(); + class_hint->res_name = g_get_prgname (); + + class_hint->res_class = (char *)gdk_get_program_class (); + _gdk_get_command_line_args (&argc, &argv); + XmbSetWMProperties (display_x11->xdisplay, + display_x11->leader_window, + NULL, NULL, argv, argc, NULL, NULL, + class_hint); + XFree (class_hint); + + pid = getpid (); + XChangeProperty (display_x11->xdisplay, + display_x11->leader_window, + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"), + XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1); + + XGetKeyboardControl (display_x11->xdisplay, &keyboard_state); + +#ifdef HAVE_XKB + { + gint xkb_major = XkbMajorVersion; + gint xkb_minor = XkbMinorVersion; + if (XkbLibraryVersion (&xkb_major, &xkb_minor)) + { + xkb_major = XkbMajorVersion; + xkb_minor = XkbMinorVersion; + + if (XkbQueryExtension (display_x11->xdisplay, + NULL, &display_x11->xkb_event_type, NULL, + &xkb_major, &xkb_minor)) + { + Bool detectable_autorepeat_supported; + + display_x11->use_xkb = TRUE; + + XkbSelectEvents (display_x11->xdisplay, + XkbUseCoreKbd, + XkbMapNotifyMask | XkbStateNotifyMask, + XkbMapNotifyMask | XkbStateNotifyMask); + + XkbSetDetectableAutoRepeat (display_x11->xdisplay, + True, + &detectable_autorepeat_supported); + + GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.", + detectable_autorepeat_supported ? + "supported" : "not supported")); + + display_x11->have_xkb_autorepeat = detectable_autorepeat_supported; + } + } + } +#endif + + _gdk_visual_init (display_x11->default_screen); + _gdk_windowing_window_init (display_x11->default_screen); + _gdk_windowing_image_init (display); + _gdk_events_init (display); + _gdk_input_init (display); + _gdk_dnd_init (display); + + return display; +} + +static G_CONST_RETURN gchar* +gdk_display_x11_get_display_name (GdkDisplay * display) +{ + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + + return (gchar *) DisplayString (display_x11->xdisplay); +} + +static gint +gdk_display_x11_get_n_screens (GdkDisplay * display) +{ + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + + return ScreenCount (display_x11->xdisplay); +} + +static GdkScreen * +gdk_display_x11_get_screen (GdkDisplay *display, + gint screen_num) +{ + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + Screen *desired_screen; + GSList *tmp_list; + + g_return_val_if_fail (ScreenCount (display_x11->xdisplay) > screen_num, NULL); + + desired_screen = ScreenOfDisplay (display_x11->xdisplay, screen_num); + + tmp_list = display_x11->screen_list; + while (tmp_list) + { + GdkScreenX11 *screen_x11 = tmp_list->data; + GdkScreen *screen = tmp_list->data; + + if (screen_x11->xscreen == desired_screen) + { + if (!screen_x11->visual_initialised) + _gdk_visual_init (screen); + if (!screen_x11->colormap_initialised) + _gdk_windowing_window_init (screen); + + if (!screen_x11->xsettings_client) + _gdk_x11_events_init_screen (screen); + + return screen; + } + + tmp_list = tmp_list->next; + } + + g_assert_not_reached (); + return NULL; +} + +static GdkScreen * +gdk_display_x11_get_default_screen (GdkDisplay * display) +{ + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + + return display_x11->default_screen; +} + +gboolean +_gdk_x11_display_is_root_window (GdkDisplay *display, + Window xroot_window) +{ + GdkDisplayX11 *display_x11; + GSList *tmp_list; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + display_x11 = GDK_DISPLAY_X11 (display); + + tmp_list = display_x11->screen_list; + while (tmp_list) + { + GdkScreenX11 *screen_x11 = tmp_list->data; + + if (screen_x11->xroot_window == xroot_window) + return TRUE; + + tmp_list = tmp_list->next; + } + + return FALSE; +} + +/** + * gdk_display_pointer_ungrab: + * @display : a #GdkDisplay. + * @time: a timestap (e.g. GDK_CURRENT_TIME). + * + * Release any pointer grab. + */ +void +gdk_display_pointer_ungrab (GdkDisplay *display, + guint32 time) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + + _gdk_input_ungrab_pointer (display, time); + XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time); + GDK_DISPLAY_X11 (display)->pointer_xgrab_window = NULL; +} + +/** + * gdk_display_pointer_is_grabbed : + * @display : a #GdkDisplay + * + * Test if the pointer is grabbed. + * + * Returns : TRUE if an active X pointer grab is in effect + */ +gboolean +gdk_display_pointer_is_grabbed (GdkDisplay * display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE); + + return (GDK_DISPLAY_X11 (display)->pointer_xgrab_window != NULL); +} + +/** + * gdk_display_keyboard_ungrab: + * @display : a #GdkDisplay. + * @time : a timestap (e.g #GDK_CURRENT_TIME). + * + * Release any keyboard grab + */ +void +gdk_display_keyboard_ungrab (GdkDisplay *display, + guint32 time) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + + XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time); + GDK_DISPLAY_X11 (display)->keyboard_xgrab_window = NULL; +} + +/** + * gdk_display_beep: + * @display: a #GdkDisplay + * + * Emits a short beep on @display + * + */ +void +gdk_display_beep (GdkDisplay * display) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + + XBell (GDK_DISPLAY_XDISPLAY (display), 0); +} + +/** + * gdk_display_sync : + * @display : a #GdkDisplay + * + * Flushes any requests queued for the windowing system and waits until all + * requests have been handled. This is often used for making sure that the + * display is synchronized with the current state of the program. Calling + * gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors + * generated from earlier requests are handled before the error trap is removed. + * + * This is most useful for X11. On windowing systems where requests handled + * synchronously, this function will do nothing. + */ +void +gdk_display_sync (GdkDisplay * display) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + + XSync (GDK_DISPLAY_XDISPLAY (display), False); +} + +void +gdk_x11_display_grab (GdkDisplay * display) +{ + GdkDisplayX11 *display_x11; + + g_return_if_fail (GDK_IS_DISPLAY (display)); + + display_x11 = GDK_DISPLAY_X11 (display); + + if (display_x11->grab_count == 0) + XGrabServer (display_x11->xdisplay); + display_x11->grab_count++; +} + +void +gdk_x11_display_ungrab (GdkDisplay * display) +{ + GdkDisplayX11 *display_x11; + + g_return_if_fail (GDK_IS_DISPLAY (display)); + + display_x11 = GDK_DISPLAY_X11 (display);; + g_return_if_fail (display_x11->grab_count > 0); + + display_x11->grab_count--; + if (display_x11->grab_count == 0) + XUngrabServer (display_x11->xdisplay); +} + +static void +gdk_display_x11_finalize (GObject *object) +{ + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object); + int i; + GList *tmp; + GSList *stmp; + /* FIXME need to write GdkKeymap finalize fct + g_object_unref (display_x11->keymap); + */ + /* Free motif Dnd */ + if (display_x11->motif_target_lists) + { + for (i = 0; i < display_x11->motif_n_target_lists; i++) + g_list_free (display_x11->motif_target_lists[i]); + g_free (display_x11->motif_target_lists); + } + + /* Atom Hashtable */ + g_hash_table_destroy (display_x11->atom_from_virtual); + g_hash_table_destroy (display_x11->atom_to_virtual); + /* Leader Window */ + XDestroyWindow (display_x11->xdisplay, display_x11->leader_window); + /* list of filters for client messages */ + g_list_free (display_x11->client_filters); + /* X ID hashtable */ + g_hash_table_destroy (display_x11->xid_ht); + /* input GdkDevice list */ + /* FIXME need to write finalize fct */ + for (tmp = display_x11->input_devices; tmp; tmp = tmp->next) + g_object_unref (G_OBJECT (tmp->data)); + g_list_free (display_x11->input_devices); + /* input GdkWindow list */ + for (tmp = display_x11->input_windows; tmp; tmp = tmp->next) + g_object_unref (G_OBJECT (tmp->data)); + g_list_free (display_x11->input_windows); + /* Free all GdkScreens */ + for (stmp = display_x11->screen_list; stmp; stmp = stmp->next) + g_object_unref (G_OBJECT (stmp->data)); + g_slist_free (display_x11->screen_list); + XCloseDisplay (display_x11->xdisplay); + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +/** + * gdk_x11_lookup_xdisplay: + * @xdisplay: a pointer to an X Display + * + * Find the #GdkDisplay corresponding to @display, if any exists. + * + * Return value: the #GdkDisplay, if found, otherwise %NULL. + **/ +GdkDisplay * +gdk_x11_lookup_xdisplay (Display *xdisplay) +{ + GSList *tmp_list; + + for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next) + { + if (GDK_DISPLAY_XDISPLAY (tmp_list->data) == xdisplay) + return tmp_list->data; + } + + return NULL; +} + +/** + * _gdk_x11_display_screen_for_xrootwin: + * @display: a #Display + * @xrootwin: window ID for one of of the screen's of the display. + * + * Given the root window ID of one of the screen's of a #GdkDisplay, + * finds the screen. + * + * Return value: the #GdkScreen corresponding to @xrootwin, or %NULL. + **/ +GdkScreen * +_gdk_x11_display_screen_for_xrootwin (GdkDisplay *display, + Window xrootwin) +{ + gint n_screens, i; + + n_screens = gdk_display_get_n_screens (display); + for (i = 0; i < n_screens; i++) + { + GdkScreen *screen = gdk_display_get_screen (display, i); + if (GDK_SCREEN_XROOTWIN (screen) == xrootwin) + return screen; + } + + return NULL; +} + +Display * +gdk_x11_display_get_xdisplay (GdkDisplay *display) +{ + return GDK_DISPLAY_X11 (display)->xdisplay; +} diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h new file mode 100644 index 000000000..cfdf490ea --- /dev/null +++ b/gdk/x11/gdkdisplay-x11.h @@ -0,0 +1,142 @@ +/* + * gdkdisplay-x11.h + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede <erwann.chenede@sun.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GDK_DISPLAY_X11__ +#define __GDK_DISPLAY_X11__ + +#include <X11/X.h> +#include <X11/Xlib.h> +#include <glib.h> +#include <gdk/gdkdisplay.h> +#include <gdk/gdkkeys.h> +#include <gdk/gdkwindow.h> +#include <gdk/gdk.h> /* For gdk_get_program_class() */ + +G_BEGIN_DECLS + +typedef struct _GdkDisplayX11 GdkDisplayX11; +typedef struct _GdkDisplayX11Class GdkDisplayX11Class; + +#define GDK_TYPE_DISPLAY_X11 (gdk_display_x11_get_type()) +#define GDK_DISPLAY_X11(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DISPLAY_X11, GdkDisplayX11)) +#define GDK_DISPLAY_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DISPLAY_X11, GdkDisplayX11Class)) +#define GDK_IS_DISPLAY_X11(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DISPLAY_X11)) +#define GDK_IS_DISPLAY_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DISPLAY_X11)) +#define GDK_DISPLAY_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DISPLAY_X11, GdkDisplayX11Class)) + +struct _GdkDisplayX11 +{ + GdkDisplay parent_instance; + Display *xdisplay; + GdkScreen *default_screen; + GSList *screen_list; + + gint grab_count; + + /* Keyboard related information */ + + gint xkb_event_type; + gboolean use_xkb; + + /* Whether we were able to turn on detectable-autorepeat using + * XkbSetDetectableAutorepeat. If FALSE, we'll fall back + * to checking the next event with XPending(). */ + gboolean have_xkb_autorepeat; + + GdkKeymap *keymap; + guint keymap_serial; + + gboolean use_xshm; + gboolean have_shm_pixmaps; + gint have_shape; + + /* Information about current pointer and keyboard grabs held by this + * client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window + * window is NULL, then the other associated fields are ignored + */ + GdkWindowObject *pointer_xgrab_window; + gulong pointer_xgrab_serial; + gboolean pointer_xgrab_owner_events; + + GdkWindowObject *keyboard_xgrab_window; + gulong keyboard_xgrab_serial; + gboolean keyboard_xgrab_owner_events; + + /* drag and drop information */ + GdkDragContext *current_dest_drag; + + /* data needed for MOTIF DnD */ + + Window motif_drag_window; + GdkWindow *motif_drag_gdk_window; + GList **motif_target_lists; + gint motif_n_target_lists; + + /* Mapping to/from virtual atoms */ + + GHashTable *atom_from_virtual; + GHashTable *atom_to_virtual; + + /* Session Management leader window see ICCCM */ + Window leader_window; + + /* list of filters for client messages */ + GList *client_filters; + + /* X ID hashtable */ + GHashTable *xid_ht; + + /* translation queue */ + GQueue *translate_queue; + + /* Input device */ + /* input GdkDevice list */ + GList *input_devices; + + /* input GdkWindow list */ + GList *input_windows; + + gint input_ignore_core; + /* information about network port and host for gxid daemon */ + gchar *input_gxid_host; + gint input_gxid_port; + + gint use_xft; +}; + +struct _GdkDisplayX11Class +{ + GdkDisplayClass parent_class; +}; + +GType gdk_display_x11_get_type (void); + +void gdk_x11_display_grab (GdkDisplay *display); +void gdk_x11_display_ungrab (GdkDisplay *display); + +GdkScreen *_gdk_x11_display_screen_for_xrootwin (GdkDisplay *display, + Window xrootwin); + +G_END_DECLS + +#endif /* __GDK_DISPLAY_X11__ */ diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index fd61beeed..7aa0bbf87 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -29,10 +29,13 @@ #include <string.h> #include "gdk.h" /* For gdk_flush() */ +#include "gdkx.h" #include "gdkdnd.h" #include "gdkproperty.h" -#include "gdkinternals.h" #include "gdkprivate-x11.h" +#include "gdkinternals.h" +#include "gdkscreen-x11.h" +#include "gdkdisplay-x11.h" typedef struct _GdkDragContextPrivateX11 GdkDragContextPrivateX11; @@ -53,6 +56,7 @@ typedef struct { GList *children; GHashTable *child_hash; guint old_event_mask; + GdkScreen *screen; } GdkWindowCache; /* Structure that holds information about a drag in progress. @@ -84,13 +88,12 @@ struct _GdkDragContextPrivateX11 { #define PRIVATE_DATA(context) ((GdkDragContextPrivateX11 *) GDK_DRAG_CONTEXT (context)->windowing_data) -static GdkDragContext *current_dest_drag = NULL; - /* Forward declarations */ static void gdk_window_cache_destroy (GdkWindowCache *cache); -static void motif_read_target_table (void); +static void motif_read_target_table (GdkDisplay *display); + static GdkFilterReturn motif_dnd_filter (GdkXEvent *xev, GdkEvent *event, gpointer data); @@ -235,9 +238,10 @@ gdk_drag_context_unref (GdkDragContext *context) } static GdkDragContext * -gdk_drag_context_find (gboolean is_source, - Window source_xid, - Window dest_xid) +gdk_drag_context_find (GdkDisplay *display, + gboolean is_source, + Window source_xid, + Window dest_xid) { GList *tmp_list = contexts; GdkDragContext *context; @@ -249,6 +253,10 @@ gdk_drag_context_find (gboolean is_source, context = (GdkDragContext *)tmp_list->data; private = PRIVATE_DATA (context); + if ((context->source_window && gdk_drawable_get_display (context->source_window) != display) || + (context->dest_window && gdk_drawable_get_display (context->dest_window) != display)) + continue; + context_dest_xid = context->dest_window ? (private->drop_xid ? private->drop_xid : @@ -407,28 +415,30 @@ gdk_window_cache_filter (GdkXEvent *xev, } static GdkWindowCache * -gdk_window_cache_new (void) +gdk_window_cache_new (GdkScreen *screen) { XWindowAttributes xwa; Window root, parent, *children; unsigned int nchildren; int i; + Display *xdisplay = GDK_SCREEN_XDISPLAY (screen); + GdkWindow *root_window = gdk_screen_get_root_window (screen); GdkWindowCache *result = g_new (GdkWindowCache, 1); result->children = NULL; result->child_hash = g_hash_table_new (g_direct_hash, NULL); + result->screen = screen; - XGetWindowAttributes (gdk_display, _gdk_root_window, &xwa); + XGetWindowAttributes (xdisplay, GDK_WINDOW_XWINDOW (root_window), &xwa); result->old_event_mask = xwa.your_event_mask; - XSelectInput (gdk_display, _gdk_root_window, + XSelectInput (xdisplay, GDK_WINDOW_XWINDOW (root_window), result->old_event_mask | SubstructureNotifyMask); - gdk_window_add_filter (_gdk_parent_root, - gdk_window_cache_filter, result); + gdk_window_add_filter (root_window, gdk_window_cache_filter, result); gdk_error_trap_push (); - if (!XQueryTree(gdk_display, _gdk_root_window, + if (!XQueryTree(xdisplay, GDK_WINDOW_XWINDOW (root_window), &root, &parent, &children, &nchildren)) { gdk_error_trap_pop (); @@ -437,7 +447,7 @@ gdk_window_cache_new (void) for (i = 0; i < nchildren ; i++) { - if (XGetWindowAttributes (gdk_display, children[i], &xwa)) + if (XGetWindowAttributes (xdisplay, children[i], &xwa)) gdk_window_cache_add (result, children[i], xwa.x, xwa.y, xwa.width, xwa.height, xwa.map_state != IsUnmapped); @@ -452,9 +462,12 @@ gdk_window_cache_new (void) static void gdk_window_cache_destroy (GdkWindowCache *cache) { - XSelectInput (gdk_display, _gdk_root_window, cache->old_event_mask); - gdk_window_remove_filter (_gdk_parent_root, - gdk_window_cache_filter, cache); + GdkWindow *root_window = gdk_screen_get_root_window (cache->screen); + + XSelectInput (GDK_WINDOW_XDISPLAY (root_window), + GDK_WINDOW_XWINDOW (root_window), + cache->old_event_mask); + gdk_window_remove_filter (root_window, gdk_window_cache_filter, cache); g_list_foreach (cache->children, (GFunc)g_free, NULL); g_list_free (cache->children); @@ -464,9 +477,10 @@ gdk_window_cache_destroy (GdkWindowCache *cache) } static Window -get_client_window_at_coords_recurse (Window win, - gint x, - gint y) +get_client_window_at_coords_recurse (GdkDisplay *display, + Window win, + gint x, + gint y) { Window root, tmp_parent, *children; unsigned int nchildren; @@ -477,13 +491,9 @@ get_client_window_at_coords_recurse (Window win, unsigned long nitems, after; unsigned char *data; - static Atom wm_state_atom = None; - - if (!wm_state_atom) - wm_state_atom = gdk_x11_get_xatom_by_name ("WM_STATE"); - - if (XGetWindowProperty (gdk_display, win, - wm_state_atom, 0, 0, False, AnyPropertyType, + if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY(display), win, + gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"), + 0, 0, False, AnyPropertyType, &type, &format, &nitems, &after, &data) != Success) return None; @@ -500,15 +510,16 @@ get_client_window_at_coords_recurse (Window win, return None; #else - if (!XQueryTree(gdk_display, win, - &root, &tmp_parent, &children, &nchildren)) + if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), win, + &root, &tmp_parent, &children, &nchildren)) return 0; for (i = nchildren - 1; (i >= 0) && (child == None); i--) { XWindowAttributes xwa; - if (XGetWindowAttributes (gdk_display, children[i], &xwa)) + if (XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (display), + children[i], &xwa)) { if ((xwa.map_state == IsViewable) && (xwa.class == InputOutput) && (x >= xwa.x) && (x < xwa.x + (gint)xwa.width) && @@ -525,7 +536,7 @@ get_client_window_at_coords_recurse (Window win, #endif if (child) - return get_client_window_at_coords_recurse (child, x, y); + return get_client_window_at_coords_recurse (display, child, x, y); else return None; } @@ -552,8 +563,9 @@ get_client_window_at_coords (GdkWindowCache *cache, if ((x_root >= child->x) && (x_root < child->x + child->width) && (y_root >= child->y) && (y_root < child->y + child->height)) { - retval = get_client_window_at_coords_recurse (child->xid, - x_root - child->x, + retval = get_client_window_at_coords_recurse (gdk_screen_get_display (cache->screen), + child->xid, + x_root - child->x, y_root - child->y); if (!retval) retval = child->xid; @@ -568,7 +580,7 @@ get_client_window_at_coords (GdkWindowCache *cache, if (retval) return retval; else - return _gdk_root_window; + return GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (cache->screen)); } /************************************************************* @@ -622,10 +634,6 @@ enum { XmDROP_INTERRUPT }; -/* Static data for MOTIF DND */ -static GList **motif_target_lists = NULL; -static gint motif_n_target_lists = -1; - /* Byte swapping routines. The motif specification leaves it * up to us to save a few bytes in the client messages */ @@ -717,12 +725,6 @@ typedef struct _MotifDragReceiverInfo { guint32 total_size; } MotifDragReceiverInfo; -static Window motif_drag_window = None; -static GdkWindow *motif_drag_gdk_window = NULL; - -static Atom motif_drag_targets_atom = None; -static Atom motif_drag_receiver_info_atom = None; - /* Target table handling */ static GdkFilterReturn @@ -731,27 +733,27 @@ motif_drag_window_filter (GdkXEvent *xevent, gpointer data) { XEvent *xev = (XEvent *)xevent; + GdkDisplay *display = GDK_WINDOW_DISPLAY (event->any.window); + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); switch (xev->xany.type) { case DestroyNotify: - motif_drag_window = None; - motif_drag_gdk_window = NULL; + display_x11->motif_drag_window = None; + display_x11->motif_drag_gdk_window = NULL; break; case PropertyNotify: - if (motif_target_lists && - motif_drag_targets_atom && - (xev->xproperty.atom == motif_drag_targets_atom)) - motif_read_target_table(); + if (display_x11->motif_target_lists && + (xev->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_TARGETS"))) + motif_read_target_table (display); break; } return GDK_FILTER_REMOVE; } -static Atom motif_drag_window_atom = None; - static Window -motif_lookup_drag_window (Display *display) +motif_lookup_drag_window (GdkDisplay *display, + Display *lookup_xdisplay) { Window retval = None; gulong bytes_after, nitems; @@ -759,7 +761,8 @@ motif_lookup_drag_window (Display *display) gint format; guchar *data; - XGetWindowProperty (gdk_display, _gdk_root_window, motif_drag_window_atom, + XGetWindowProperty (lookup_xdisplay, DefaultRootWindow (lookup_xdisplay), + gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_WINDOW"), 0, 1, FALSE, XA_WINDOW, &type, &format, &nitems, &bytes_after, &data); @@ -767,8 +770,8 @@ motif_lookup_drag_window (Display *display) if ((format == 32) && (nitems == 1) && (bytes_after == 0)) { retval = *(Window *)data; - GDK_NOTE(DND, - g_message ("Found drag window %#lx\n", motif_drag_window)); + GDK_NOTE (DND, + g_message ("Found drag window %#lx\n", GDK_DISPLAY_X11 (display)->motif_drag_window)); } if (type != None) @@ -781,89 +784,93 @@ motif_lookup_drag_window (Display *display) * If it doesn't exist and 'create' is TRUE, create one. */ static Window -motif_find_drag_window (gboolean create) +motif_find_drag_window (GdkDisplay *display, + gboolean create) { - if (!motif_drag_window) + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + + if (!display_x11->motif_drag_window) { - if (!motif_drag_window_atom) - motif_drag_window_atom = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_WINDOW"); - - motif_drag_window = motif_lookup_drag_window (gdk_display); + Atom motif_drag_window_atom = gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_WINDOW"); + display_x11->motif_drag_window = motif_lookup_drag_window (display, display_x11->xdisplay); - if (!motif_drag_window && create) + if (!display_x11->motif_drag_window && create) { /* Create a persistant window. (Copied from LessTif) */ - Display *display; + Display *persistant_xdisplay; XSetWindowAttributes attr; - display = XOpenDisplay (_gdk_display_name); - XSetCloseDownMode (display, RetainPermanent); + persistant_xdisplay = XOpenDisplay (gdk_display_get_name (display)); + XSetCloseDownMode (persistant_xdisplay, RetainPermanent); - XGrabServer (display); + XGrabServer (persistant_xdisplay); - motif_drag_window = motif_lookup_drag_window (display); + display_x11->motif_drag_window = motif_lookup_drag_window (display, persistant_xdisplay); - if (!motif_drag_window) + if (!display_x11->motif_drag_window) { attr.override_redirect = True; attr.event_mask = PropertyChangeMask; - motif_drag_window = - XCreateWindow(display, DefaultRootWindow(display), + display_x11->motif_drag_window = + XCreateWindow (persistant_xdisplay, + DefaultRootWindow (persistant_xdisplay), -100, -100, 10, 10, 0, 0, InputOnly, CopyFromParent, (CWOverrideRedirect | CWEventMask), &attr); GDK_NOTE (DND, - g_message ("Created drag window %#lx\n", motif_drag_window)); + g_message ("Created drag window %#lx\n", display_x11->motif_drag_window)); - XChangeProperty (display, _gdk_root_window, + XChangeProperty (persistant_xdisplay, + DefaultRootWindow (persistant_xdisplay), motif_drag_window_atom, XA_WINDOW, 32, PropModeReplace, (guchar *)&motif_drag_window_atom, 1); } - XUngrabServer (display); - XCloseDisplay (display); + XUngrabServer (persistant_xdisplay); + XCloseDisplay (persistant_xdisplay); } /* There is a miniscule race condition here if the drag window * gets destroyed exactly now. */ - if (motif_drag_window) + if (display_x11->motif_drag_window) { - motif_drag_gdk_window = gdk_window_foreign_new (motif_drag_window); - gdk_window_add_filter (motif_drag_gdk_window, + display_x11->motif_drag_gdk_window = + gdk_window_foreign_new_for_display (display, display_x11->motif_drag_window); + gdk_window_add_filter (display_x11->motif_drag_gdk_window, motif_drag_window_filter, NULL); } } - return motif_drag_window; + return display_x11->motif_drag_window; } static void -motif_read_target_table (void) +motif_read_target_table (GdkDisplay *display) { + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); gulong bytes_after, nitems; Atom type; gint format; gint i, j; + + Atom motif_drag_targets_atom = gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_TARGETS"); - if (!motif_drag_targets_atom) - motif_drag_targets_atom = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_TARGETS"); - - if (motif_target_lists) + if (display_x11->motif_target_lists) { - for (i=0; i<motif_n_target_lists; i++) - g_list_free (motif_target_lists[i]); + for (i=0; i<display_x11->motif_n_target_lists; i++) + g_list_free (display_x11->motif_target_lists[i]); - g_free (motif_target_lists); - motif_target_lists = NULL; - motif_n_target_lists = 0; + g_free (display_x11->motif_target_lists); + display_x11->motif_target_lists = NULL; + display_x11->motif_n_target_lists = 0; } - if (motif_find_drag_window (FALSE)) + if (motif_find_drag_window (display, FALSE)) { MotifTargetTableHeader *header = NULL; guchar *target_bytes = NULL; @@ -871,7 +878,8 @@ motif_read_target_table (void) gboolean success = FALSE; gdk_error_trap_push (); - XGetWindowProperty (gdk_display, motif_drag_window, + XGetWindowProperty (display_x11->xdisplay, + display_x11->motif_drag_window, motif_drag_targets_atom, 0, (sizeof(MotifTargetTableHeader)+3)/4, FALSE, motif_drag_targets_atom, @@ -885,7 +893,9 @@ motif_read_target_table (void) header->total_size = card32_to_host (header->total_size, header->byte_order); gdk_error_trap_push (); - XGetWindowProperty (gdk_display, motif_drag_window, motif_drag_targets_atom, + XGetWindowProperty (display_x11->xdisplay, + display_x11->motif_drag_window, + motif_drag_targets_atom, (sizeof(MotifTargetTableHeader)+3)/4, (header->total_size + 3)/4 - (sizeof(MotifTargetTableHeader) + 3)/4, FALSE, @@ -896,8 +906,8 @@ motif_read_target_table (void) (nitems != header->total_size - sizeof(MotifTargetTableHeader))) goto error; - motif_n_target_lists = header->n_lists; - motif_target_lists = g_new0 (GList *, motif_n_target_lists); + display_x11->motif_n_target_lists = header->n_lists; + display_x11->motif_target_lists = g_new0 (GList *, display_x11->motif_n_target_lists); p = target_bytes; for (i=0; i<header->n_lists; i++) @@ -921,12 +931,12 @@ motif_read_target_table (void) goto error; for (j=0; j<n_targets; j++) - motif_target_lists[i] = - g_list_prepend (motif_target_lists[i], - GUINT_TO_POINTER (card32_to_host (targets[j], + display_x11->motif_target_lists[i] = + g_list_prepend (display_x11->motif_target_lists[i], + GUINT_TO_POINTER (card32_to_host (targets[j], header->byte_order))); g_free (targets); - motif_target_lists[i] = g_list_reverse (motif_target_lists[i]); + display_x11->motif_target_lists[i] = g_list_reverse (display_x11->motif_target_lists[i]); } success = TRUE; @@ -940,11 +950,11 @@ motif_read_target_table (void) if (!success) { - if (motif_target_lists) + if (display_x11->motif_target_lists) { - g_free (motif_target_lists); - motif_target_lists = NULL; - motif_n_target_lists = 0; + g_free (display_x11->motif_target_lists); + display_x11->motif_target_lists = NULL; + display_x11->motif_n_target_lists = 0; } g_warning ("Error reading Motif target table\n"); } @@ -960,14 +970,16 @@ targets_sort_func (gconstpointer a, gconstpointer b) /* Check if given (sorted) list is in the targets table */ static gboolean -motif_target_table_check (GList *sorted) +motif_target_table_check (GdkDisplay *display, + GList *sorted) { + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); GList *tmp_list1, *tmp_list2; gint i; - for (i=0; i<motif_n_target_lists; i++) + for (i=0; i<display_x11->motif_n_target_lists; i++) { - tmp_list1 = motif_target_lists[i]; + tmp_list1 = display_x11->motif_target_lists[i]; tmp_list2 = sorted; while (tmp_list1 && tmp_list2) @@ -986,8 +998,10 @@ motif_target_table_check (GList *sorted) } static gint -motif_add_to_target_table (GList *targets) /* targets is list of GdkAtom */ +motif_add_to_target_table (GdkDisplay *display, + GList *targets) /* targets is list of GdkAtom */ { + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); GList *sorted = NULL; gint index = -1; gint i; @@ -997,15 +1011,15 @@ motif_add_to_target_table (GList *targets) /* targets is list of GdkAtom */ while (targets) { - Atom xatom = gdk_x11_atom_to_xatom (GDK_POINTER_TO_ATOM (targets->data)); + Atom xatom = gdk_x11_atom_to_xatom_for_display (display, GDK_POINTER_TO_ATOM (targets->data)); sorted = g_list_insert_sorted (sorted, GUINT_TO_POINTER (xatom), targets_sort_func); targets = targets->next; } /* First check if it is their already */ - if (motif_target_lists) - index = motif_target_table_check (sorted); + if (display_x11->motif_target_lists) + index = motif_target_table_check (display, sorted); /* We need to grab the server while doing this, to ensure * atomiticity. Ugh @@ -1017,15 +1031,15 @@ motif_add_to_target_table (GList *targets) /* targets is list of GdkAtom */ * server, since we can't open a new connection after we * grab the server. */ - motif_find_drag_window (TRUE); + motif_find_drag_window (display, TRUE); - gdk_x11_grab_server (); - motif_read_target_table(); + gdk_x11_display_grab (display); + motif_read_target_table (display); /* Check again, in case it was added in the meantime */ - if (motif_target_lists) - index = motif_target_table_check (sorted); + if (display_x11->motif_target_lists) + index = motif_target_table_check (display, sorted); if (index < 0) { @@ -1035,24 +1049,24 @@ motif_add_to_target_table (GList *targets) /* targets is list of GdkAtom */ guint16 *p16; MotifTargetTableHeader *header; - if (!motif_target_lists) + if (!display_x11->motif_target_lists) { - motif_target_lists = g_new (GList *, 1); - motif_n_target_lists = 1; + display_x11->motif_target_lists = g_new (GList *, 1); + display_x11->motif_n_target_lists = 1; } else { - motif_n_target_lists++; - motif_target_lists = g_realloc (motif_target_lists, - sizeof(GList *) * motif_n_target_lists); + display_x11->motif_n_target_lists++; + display_x11->motif_target_lists = g_realloc (display_x11->motif_target_lists, + sizeof(GList *) * display_x11->motif_n_target_lists); } - motif_target_lists[motif_n_target_lists - 1] = sorted; + display_x11->motif_target_lists[display_x11->motif_n_target_lists - 1] = sorted; sorted = NULL; - index = motif_n_target_lists - 1; + index = display_x11->motif_n_target_lists - 1; total_size = sizeof (MotifTargetTableHeader); - for (i = 0; i < motif_n_target_lists ; i++) - total_size += sizeof(guint16) + sizeof(guint32) * g_list_length (motif_target_lists[i]); + for (i = 0; i < display_x11->motif_n_target_lists ; i++) + total_size += sizeof(guint16) + sizeof(guint32) * g_list_length (display_x11->motif_target_lists[i]); data = g_malloc (total_size); @@ -1061,16 +1075,16 @@ motif_add_to_target_table (GList *targets) /* targets is list of GdkAtom */ header->byte_order = local_byte_order; header->protocol_version = 0; - header->n_lists = motif_n_target_lists; + header->n_lists = display_x11->motif_n_target_lists; header->total_size = total_size; - for (i = 0; i < motif_n_target_lists ; i++) + for (i = 0; i < display_x11->motif_n_target_lists ; i++) { - guint16 n_targets = g_list_length (motif_target_lists[i]); + guint16 n_targets = g_list_length (display_x11->motif_target_lists[i]); guint32 *targets = g_new (guint32, n_targets); guint32 *p32 = targets; - tmp_list = motif_target_lists[i]; + tmp_list = display_x11->motif_target_lists[i]; while (tmp_list) { *p32 = GPOINTER_TO_UINT (tmp_list->data); @@ -1089,13 +1103,14 @@ motif_add_to_target_table (GList *targets) /* targets is list of GdkAtom */ g_free (targets); } - XChangeProperty (gdk_display, motif_drag_window, - motif_drag_targets_atom, - motif_drag_targets_atom, + XChangeProperty (display_x11->xdisplay, + display_x11->motif_drag_window, + gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_TARGETS"), + gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_TARGETS"), 8, PropModeReplace, data, total_size); } - gdk_x11_ungrab_server (); + gdk_x11_display_ungrab (display); } g_list_free (sorted); @@ -1174,23 +1189,20 @@ motif_set_targets (GdkDragContext *context) GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); MotifDragInitiatorInfo info; gint i; - static Atom motif_drag_initiator_info = None; - - if (!motif_drag_initiator_info) - motif_drag_initiator_info = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_INITIATOR_INFO"); - + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); + info.byte_order = local_byte_order; info.protocol_version = 0; - info.targets_index = motif_add_to_target_table (context->targets); + info.targets_index = motif_add_to_target_table (display, context->targets); for (i=0; ; i++) { gchar buf[20]; g_snprintf(buf, 20, "_GDK_SELECTION_%d", i); - private->motif_selection = gdk_x11_get_xatom_by_name (buf); - if (!XGetSelectionOwner (gdk_display, private->motif_selection)) + private->motif_selection = gdk_x11_get_xatom_by_name_for_display (display, buf); + if (!XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), private->motif_selection)) break; } @@ -1199,26 +1211,26 @@ motif_set_targets (GdkDragContext *context) XChangeProperty (GDK_DRAWABLE_XDISPLAY (context->source_window), GDK_DRAWABLE_XID (context->source_window), private->motif_selection, - motif_drag_initiator_info, 8, PropModeReplace, + gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_INITIATOR_INFO"), + 8, PropModeReplace, (guchar *)&info, sizeof (info)); private->motif_targets_set = 1; } static guint32 -motif_check_dest (Window win) +motif_check_dest (GdkDisplay *display, + Window win) { gboolean retval = FALSE; MotifDragReceiverInfo *info; Atom type = None; int format; unsigned long nitems, after; - - if (!motif_drag_receiver_info_atom) - motif_drag_receiver_info_atom = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_RECEIVER_INFO"); + Atom motif_drag_receiver_info_atom = gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_RECEIVER_INFO"); gdk_error_trap_push (); - XGetWindowProperty (gdk_display, win, + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), win, motif_drag_receiver_info_atom, 0, (sizeof(*info)+3)/4, False, AnyPropertyType, &type, &format, &nitems, &after, @@ -1253,11 +1265,12 @@ static void motif_send_enter (GdkDragContext *context, guint32 time) { - XEvent xev; GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); + XEvent xev; xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_AND_DROP_MESSAGE"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_AND_DROP_MESSAGE"); xev.xclient.format = 8; xev.xclient.window = GDK_DRAWABLE_XID (context->dest_window); @@ -1272,8 +1285,9 @@ motif_send_enter (GdkDragContext *context, MOTIF_XCLIENT_LONG (&xev, 3) = private->motif_selection; - if (!gdk_send_xevent (GDK_DRAWABLE_XID (context->dest_window), - FALSE, 0, &xev)) + if (!_gdk_send_xevent (display, + GDK_DRAWABLE_XID (context->dest_window), + FALSE, 0, &xev)) GDK_NOTE (DND, g_message ("Send event to %lx failed", GDK_DRAWABLE_XID (context->dest_window))); @@ -1283,10 +1297,11 @@ static void motif_send_leave (GdkDragContext *context, guint32 time) { + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); XEvent xev; xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_AND_DROP_MESSAGE"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_AND_DROP_MESSAGE"); xev.xclient.format = 8; xev.xclient.window = GDK_DRAWABLE_XID (context->dest_window); @@ -1297,8 +1312,9 @@ motif_send_leave (GdkDragContext *context, MOTIF_XCLIENT_LONG (&xev, 2) = GDK_DRAWABLE_XID (context->source_window); MOTIF_XCLIENT_LONG (&xev, 3) = 0; - if (!gdk_send_xevent (GDK_DRAWABLE_XID (context->dest_window), - FALSE, 0, &xev)) + if (!_gdk_send_xevent (display, + GDK_DRAWABLE_XID (context->dest_window), + FALSE, 0, &xev)) GDK_NOTE (DND, g_message ("Send event to %lx failed", GDK_DRAWABLE_XID (context->dest_window))); @@ -1311,12 +1327,13 @@ motif_send_motion (GdkDragContext *context, GdkDragAction action, guint32 time) { + GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); gboolean retval; XEvent xev; - GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_AND_DROP_MESSAGE"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_AND_DROP_MESSAGE"); xev.xclient.format = 8; xev.xclient.window = GDK_DRAWABLE_XID (context->dest_window); @@ -1343,8 +1360,9 @@ motif_send_motion (GdkDragContext *context, retval = FALSE; } - if (!gdk_send_xevent (GDK_DRAWABLE_XID (context->dest_window), - FALSE, 0, &xev)) + if (!_gdk_send_xevent (display, + GDK_DRAWABLE_XID (context->dest_window), + FALSE, 0, &xev)) GDK_NOTE (DND, g_message ("Send event to %lx failed", GDK_DRAWABLE_XID (context->dest_window))); @@ -1355,11 +1373,12 @@ motif_send_motion (GdkDragContext *context, static void motif_send_drop (GdkDragContext *context, guint32 time) { - XEvent xev; GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); + XEvent xev; xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_AND_DROP_MESSAGE"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_AND_DROP_MESSAGE"); xev.xclient.format = 8; xev.xclient.window = GDK_DRAWABLE_XID (context->dest_window); @@ -1374,8 +1393,9 @@ motif_send_drop (GdkDragContext *context, guint32 time) MOTIF_XCLIENT_LONG (&xev, 3) = private->motif_selection; MOTIF_XCLIENT_LONG (&xev, 4) = GDK_DRAWABLE_XID (context->source_window); - if (!gdk_send_xevent (GDK_DRAWABLE_XID (context->dest_window), - FALSE, 0, &xev)) + if (!_gdk_send_xevent (display, + GDK_DRAWABLE_XID (context->dest_window), + FALSE, 0, &xev)) GDK_NOTE (DND, g_message ("Send event to %lx failed", GDK_DRAWABLE_XID (context->dest_window))); @@ -1384,27 +1404,25 @@ motif_send_drop (GdkDragContext *context, guint32 time) /* Target Side */ static gboolean -motif_read_initiator_info (Window source_window, - Atom atom, - GList **targets, /* GdkAtom */ - Atom *selection) +motif_read_initiator_info (GdkDisplay *display, + Window source_window, + Atom atom, + GList **targets, + Atom *selection) { GList *tmp_list; - static Atom motif_drag_initiator_info = None; Atom type; gint format; gulong nitems; gulong bytes_after; - MotifDragInitiatorInfo *initiator_info; - - if (!motif_drag_initiator_info) - motif_drag_initiator_info = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_INITIATOR_INFO"); - + + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + gdk_error_trap_push (); - XGetWindowProperty (gdk_display, source_window, atom, + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), source_window, atom, 0, sizeof(*initiator_info), FALSE, - motif_drag_initiator_info, + gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_INITIATOR_INFO"), &type, &format, &nitems, &bytes_after, (guchar **)&initiator_info); @@ -1414,26 +1432,26 @@ motif_read_initiator_info (Window source_window, return FALSE; } - motif_read_target_table (); + motif_read_target_table (display); initiator_info->targets_index = card16_to_host (initiator_info->targets_index, initiator_info->byte_order); initiator_info->selection_atom = card32_to_host (initiator_info->selection_atom, initiator_info->byte_order); - if (initiator_info->targets_index >= motif_n_target_lists) + if (initiator_info->targets_index >= display_x11->motif_n_target_lists) { g_warning ("Invalid target index in TOP_LEVEL_ENTER MESSAGE"); XFree (initiator_info); return GDK_FILTER_REMOVE; } - tmp_list = g_list_last (motif_target_lists[initiator_info->targets_index]); + tmp_list = g_list_last (display_x11->motif_target_lists[initiator_info->targets_index]); *targets = NULL; while (tmp_list) { - GdkAtom atom = gdk_x11_xatom_to_atom (GPOINTER_TO_UINT (tmp_list->data)); + GdkAtom atom = gdk_x11_xatom_to_atom_for_display (display, GPOINTER_TO_UINT (tmp_list->data)); *targets = g_list_prepend (*targets, GDK_ATOM_TO_POINTER (atom)); tmp_list = tmp_list->prev; } @@ -1458,16 +1476,18 @@ motif_drag_context_new (GdkWindow *dest_window, { GdkDragContext *new_context; GdkDragContextPrivateX11 *private; + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (dest_window); + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); /* FIXME, current_dest_drag really shouldn't be NULL'd * if we error below. */ - if (current_dest_drag != NULL) + if (display_x11->current_dest_drag != NULL) { - if (timestamp >= current_dest_drag->start_time) + if (timestamp >= display_x11->current_dest_drag->start_time) { - gdk_drag_context_unref (current_dest_drag); - current_dest_drag = NULL; + gdk_drag_context_unref (display_x11->current_dest_drag); + display_x11->current_dest_drag = NULL; } else return NULL; @@ -1479,12 +1499,12 @@ motif_drag_context_new (GdkWindow *dest_window, new_context->protocol = GDK_DRAG_PROTO_MOTIF; new_context->is_source = FALSE; - new_context->source_window = gdk_window_lookup (source_window); + new_context->source_window = gdk_window_lookup_for_display (display, source_window); if (new_context->source_window) gdk_window_ref (new_context->source_window); else { - new_context->source_window = gdk_window_foreign_new (source_window); + new_context->source_window = gdk_window_foreign_new_for_display (display, source_window); if (!new_context->source_window) { gdk_drag_context_unref (new_context); @@ -1496,7 +1516,8 @@ motif_drag_context_new (GdkWindow *dest_window, gdk_window_ref (dest_window); new_context->start_time = timestamp; - if (!motif_read_initiator_info (source_window, + if (!motif_read_initiator_info (GDK_WINDOW_DISPLAY (dest_window), + source_window, atom, &new_context->targets, &private->motif_selection)) @@ -1522,6 +1543,7 @@ motif_top_level_enter (GdkEvent *event, guint32 source_window, guint32 atom) { + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window)); GdkDragContext *new_context; GDK_NOTE(DND, g_message ("Motif DND top level enter: flags: %#4x time: %d source_widow: %#4x atom: %d", @@ -1535,7 +1557,7 @@ motif_top_level_enter (GdkEvent *event, event->dnd.context = new_context; gdk_drag_context_ref (new_context); - current_dest_drag = new_context; + display_x11->current_dest_drag = new_context; return GDK_FILTER_TRANSLATE; } @@ -1545,18 +1567,20 @@ motif_top_level_leave (GdkEvent *event, guint16 flags, guint32 timestamp) { + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window)); + GDK_NOTE(DND, g_message ("Motif DND top level leave: flags: %#4x time: %d", flags, timestamp)); - if ((current_dest_drag != NULL) && - (current_dest_drag->protocol == GDK_DRAG_PROTO_MOTIF) && - (timestamp >= current_dest_drag->start_time)) + if ((display_x11->current_dest_drag != NULL) && + (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_MOTIF) && + (timestamp >= display_x11->current_dest_drag->start_time)) { event->dnd.type = GDK_DRAG_LEAVE; /* Pass ownership of context to the event */ - event->dnd.context = current_dest_drag; + event->dnd.context = display_x11->current_dest_drag; - current_dest_drag = NULL; + display_x11->current_dest_drag = NULL; return GDK_FILTER_TRANSLATE; } @@ -1572,23 +1596,24 @@ motif_motion (GdkEvent *event, gint16 y_root) { GdkDragContextPrivateX11 *private; - + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window)); + GDK_NOTE(DND, g_message ("Motif DND motion: flags: %#4x time: %d (%d, %d)", flags, timestamp, x_root, y_root)); - if ((current_dest_drag != NULL) && - (current_dest_drag->protocol == GDK_DRAG_PROTO_MOTIF) && - (timestamp >= current_dest_drag->start_time)) + if ((display_x11->current_dest_drag != NULL) && + (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_MOTIF) && + (timestamp >= display_x11->current_dest_drag->start_time)) { - private = PRIVATE_DATA (current_dest_drag); + private = PRIVATE_DATA (display_x11->current_dest_drag); event->dnd.type = GDK_DRAG_MOTION; - event->dnd.context = current_dest_drag; - gdk_drag_context_ref (current_dest_drag); + event->dnd.context = display_x11->current_dest_drag; + gdk_drag_context_ref (display_x11->current_dest_drag); event->dnd.time = timestamp; - motif_dnd_translate_flags (current_dest_drag, flags); + motif_dnd_translate_flags (display_x11->current_dest_drag, flags); event->dnd.x_root = x_root; event->dnd.y_root = y_root; @@ -1610,23 +1635,23 @@ motif_operation_changed (GdkEvent *event, guint32 timestamp) { GdkDragContextPrivateX11 *private; - + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window)); GDK_NOTE(DND, g_message ("Motif DND operation changed: flags: %#4x time: %d", flags, timestamp)); - if ((current_dest_drag != NULL) && - (current_dest_drag->protocol == GDK_DRAG_PROTO_MOTIF) && - (timestamp >= current_dest_drag->start_time)) + if ((display_x11->current_dest_drag != NULL) && + (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_MOTIF) && + (timestamp >= display_x11->current_dest_drag->start_time)) { event->dnd.type = GDK_DRAG_MOTION; event->dnd.send_event = FALSE; - event->dnd.context = current_dest_drag; - gdk_drag_context_ref (current_dest_drag); + event->dnd.context = display_x11->current_dest_drag; + gdk_drag_context_ref (display_x11->current_dest_drag); event->dnd.time = timestamp; - private = PRIVATE_DATA (current_dest_drag); + private = PRIVATE_DATA (display_x11->current_dest_drag); - motif_dnd_translate_flags (current_dest_drag, flags); + motif_dnd_translate_flags (display_x11->current_dest_drag, flags); event->dnd.x_root = private->last_x; event->dnd.y_root = private->last_y; @@ -1649,7 +1674,7 @@ motif_drop_start (GdkEvent *event, gint16 y_root) { GdkDragContext *new_context; - + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window)); GDK_NOTE(DND, g_message ("Motif DND drop start: flags: %#4x time: %d (%d, %d) source_widow: %#4x atom: %d", flags, timestamp, x_root, y_root, source_window, atom)); @@ -1667,7 +1692,7 @@ motif_drop_start (GdkEvent *event, event->dnd.y_root = y_root; gdk_drag_context_ref (new_context); - current_dest_drag = new_context; + display_x11->current_dest_drag = new_context; return GDK_FILTER_TRANSLATE; } @@ -1678,13 +1703,16 @@ motif_drag_status (GdkEvent *event, guint32 timestamp) { GdkDragContext *context; + GdkDisplay *display; GDK_NOTE (DND, g_message ("Motif status message: flags %x", flags)); - context = gdk_drag_context_find (TRUE, - GDK_DRAWABLE_XID (event->any.window), - None); + display = gdk_drawable_get_display (event->any.window); + if (!display) + return GDK_FILTER_REMOVE; + + context = gdk_drag_context_find (display, TRUE, GDK_DRAWABLE_XID (event->any.window), None); if (context) { @@ -1811,7 +1839,7 @@ motif_dnd_filter (GdkXEvent *xev, static struct { gchar *name; - Atom atom; + GdkAtom atom; GdkDragAction action; } xdnd_actions_table[] = { { "XdndActionCopy", None, GDK_ACTION_COPY }, @@ -1831,12 +1859,14 @@ xdnd_initialize_actions (void) xdnd_actions_initialized = TRUE; for (i=0; i < xdnd_n_actions; i++) - xdnd_actions_table[i].atom = gdk_x11_get_xatom_by_name (xdnd_actions_table[i].name); + xdnd_actions_table[i].atom = gdk_atom_intern (xdnd_actions_table[i].name, FALSE); } static GdkDragAction -xdnd_action_from_atom (Atom atom) +xdnd_action_from_atom (GdkDisplay *display, + Atom xatom) { + GdkAtom atom = gdk_x11_xatom_to_atom_for_display (display, xatom); gint i; if (!xdnd_actions_initialized) @@ -1850,7 +1880,8 @@ xdnd_action_from_atom (Atom atom) } static Atom -xdnd_action_to_atom (GdkDragAction action) +xdnd_action_to_atom (GdkDisplay *display, + GdkDragAction action) { gint i; @@ -1859,13 +1890,11 @@ xdnd_action_to_atom (GdkDragAction action) for (i=0; i<xdnd_n_actions; i++) if (action == xdnd_actions_table[i].action) - return xdnd_actions_table[i].atom; + return gdk_x11_atom_to_xatom_for_display (display, xdnd_actions_table[i].atom); return None; } -static Atom xdnd_aware_atom = None; - /* Source side */ static GdkFilterReturn @@ -1873,6 +1902,7 @@ xdnd_status_filter (GdkXEvent *xev, GdkEvent *event, gpointer data) { + GdkDisplay *display; XEvent *xevent = (XEvent *)xev; guint32 dest_window = xevent->xclient.data.l[0]; guint32 flags = xevent->xclient.data.l[1]; @@ -1883,8 +1913,12 @@ xdnd_status_filter (GdkXEvent *xev, g_message ("XdndStatus: dest_window: %#x action: %ld", dest_window, action)); + display = gdk_drawable_get_display (event->any.window); + if (!display) + return GDK_FILTER_REMOVE; + + context = gdk_drag_context_find (display, TRUE, xevent->xclient.window, dest_window); - context = gdk_drag_context_find (TRUE, xevent->xclient.window, dest_window); if (context) { GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); @@ -1904,7 +1938,7 @@ xdnd_status_filter (GdkXEvent *xev, action = 0; } - context->action = xdnd_action_from_atom (action); + context->action = xdnd_action_from_atom (display, action); return GDK_FILTER_TRANSLATE; } @@ -1917,6 +1951,7 @@ xdnd_finished_filter (GdkXEvent *xev, GdkEvent *event, gpointer data) { + GdkDisplay *display; XEvent *xevent = (XEvent *)xev; guint32 dest_window = xevent->xclient.data.l[0]; GdkDragContext *context; @@ -1924,7 +1959,12 @@ xdnd_finished_filter (GdkXEvent *xev, GDK_NOTE (DND, g_message ("XdndFinished: dest_window: %#x", dest_window)); - context = gdk_drag_context_find (TRUE, xevent->xclient.window, dest_window); + display = gdk_drawable_get_display (event->any.window); + if (!display) + return GDK_FILTER_REMOVE; + + context = gdk_drag_context_find (display, TRUE, xevent->xclient.window, dest_window); + if (context) { event->dnd.type = GDK_DROP_FINISHED; @@ -1945,19 +1985,20 @@ xdnd_set_targets (GdkDragContext *context) GList *tmp_list = context->targets; gint i; gint n_atoms = g_list_length (context->targets); + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); atomlist = g_new (Atom, n_atoms); i = 0; while (tmp_list) { - atomlist[i] = gdk_x11_atom_to_xatom (GDK_POINTER_TO_ATOM (tmp_list->data)); + atomlist[i] = gdk_x11_atom_to_xatom_for_display (display, GDK_POINTER_TO_ATOM (tmp_list->data)); tmp_list = tmp_list->next; i++; } XChangeProperty (GDK_DRAWABLE_XDISPLAY (context->source_window), GDK_DRAWABLE_XID (context->source_window), - gdk_x11_get_xatom_by_name ("XdndTypeList"), + gdk_x11_get_xatom_by_name_for_display (display, "XdndTypeList"), XA_ATOM, 32, PropModeReplace, (guchar *)atomlist, n_atoms); @@ -1974,6 +2015,7 @@ xdnd_set_actions (GdkDragContext *context) gint i; gint n_atoms; guint actions; + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); if (!xdnd_actions_initialized) xdnd_initialize_actions(); @@ -1998,14 +2040,14 @@ xdnd_set_actions (GdkDragContext *context) if (actions & xdnd_actions_table[i].action) { actions &= ~xdnd_actions_table[i].action; - atomlist[n_atoms] = xdnd_actions_table[i].atom; + atomlist[n_atoms] = gdk_x11_atom_to_xatom_for_display (display, xdnd_actions_table[i].atom); n_atoms++; } } XChangeProperty (GDK_DRAWABLE_XDISPLAY (context->source_window), GDK_DRAWABLE_XID (context->source_window), - gdk_x11_get_xatom_by_name ("XdndActionList"), + gdk_x11_get_xatom_by_name_for_display (display, "XdndActionList"), XA_ATOM, 32, PropModeReplace, (guchar *)atomlist, n_atoms); @@ -2025,14 +2067,16 @@ xdnd_set_actions (GdkDragContext *context) * results: *************************************************************/ -static gint -xdnd_send_xevent (Window window, gboolean propagate, - XEvent *event_send) +static gboolean +xdnd_send_xevent (GdkDisplay *display, + Window window, + gboolean propagate, + XEvent *event_send) { - if (window == _gdk_root_window) - return gdk_send_xevent (window, propagate, ButtonPressMask, event_send); + if (_gdk_x11_display_is_root_window (display, window)) + return _gdk_send_xevent (display, window, propagate, ButtonPressMask, event_send); else - return gdk_send_xevent (window, propagate, 0, event_send); + return _gdk_send_xevent (display, window, propagate, 0, event_send); } static void @@ -2040,9 +2084,10 @@ xdnd_send_enter (GdkDragContext *context) { XEvent xev; GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->dest_window); xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("XdndEnter"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndEnter"); xev.xclient.format = 32; xev.xclient.window = private->drop_xid ? private->drop_xid : @@ -2054,7 +2099,7 @@ xdnd_send_enter (GdkDragContext *context) xev.xclient.data.l[4] = 0; if (!private->xdnd_selection) - private->xdnd_selection = gdk_x11_get_xatom_by_name ("XdndSelection"); + private->xdnd_selection = gdk_x11_get_xatom_by_name_for_display (display, "XdndSelection"); if (g_list_length (context->targets) > 3) { @@ -2069,13 +2114,15 @@ xdnd_send_enter (GdkDragContext *context) while (tmp_list) { - xev.xclient.data.l[i] = gdk_x11_atom_to_xatom (GDK_POINTER_TO_ATOM (tmp_list->data)); + xev.xclient.data.l[i] = gdk_x11_atom_to_xatom_for_display (display, + GDK_POINTER_TO_ATOM (tmp_list->data)); tmp_list = tmp_list->next; i++; } } - if (!xdnd_send_xevent (GDK_DRAWABLE_XID (context->dest_window), + if (!xdnd_send_xevent (display, + GDK_DRAWABLE_XID (context->dest_window), FALSE, &xev)) { GDK_NOTE (DND, @@ -2089,12 +2136,13 @@ xdnd_send_enter (GdkDragContext *context) static void xdnd_send_leave (GdkDragContext *context) { + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); XEvent xev; GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("XdndLeave"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndLeave"); xev.xclient.format = 32; xev.xclient.window = private->drop_xid ? private->drop_xid : @@ -2105,7 +2153,8 @@ xdnd_send_leave (GdkDragContext *context) xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - if (!xdnd_send_xevent (GDK_DRAWABLE_XID (context->dest_window), + if (!xdnd_send_xevent (display, + GDK_DRAWABLE_XID (context->dest_window), FALSE, &xev)) { GDK_NOTE (DND, @@ -2120,10 +2169,11 @@ static void xdnd_send_drop (GdkDragContext *context, guint32 time) { GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); XEvent xev; xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("XdndDrop"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndDrop"); xev.xclient.format = 32; xev.xclient.window = private->drop_xid ? private->drop_xid : @@ -2134,7 +2184,8 @@ xdnd_send_drop (GdkDragContext *context, guint32 time) xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - if (!xdnd_send_xevent (GDK_DRAWABLE_XID (context->dest_window), + if (!xdnd_send_xevent (display, + GDK_DRAWABLE_XID (context->dest_window), FALSE, &xev)) { GDK_NOTE (DND, @@ -2153,10 +2204,11 @@ xdnd_send_motion (GdkDragContext *context, guint32 time) { GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); XEvent xev; xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("XdndPosition"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndPosition"); xev.xclient.format = 32; xev.xclient.window = private->drop_xid ? private->drop_xid : @@ -2165,9 +2217,10 @@ xdnd_send_motion (GdkDragContext *context, xev.xclient.data.l[1] = 0; xev.xclient.data.l[2] = (x_root << 16) | y_root; xev.xclient.data.l[3] = time; - xev.xclient.data.l[4] = xdnd_action_to_atom (action); + xev.xclient.data.l[4] = xdnd_action_to_atom (display, action); - if (!xdnd_send_xevent (GDK_DRAWABLE_XID (context->dest_window), + if (!xdnd_send_xevent (display, + GDK_DRAWABLE_XID (context->dest_window), FALSE, &xev)) { GDK_NOTE (DND, @@ -2180,7 +2233,8 @@ xdnd_send_motion (GdkDragContext *context, } static guint32 -xdnd_check_dest (Window win) +xdnd_check_dest (GdkDisplay *display, + Window win) { gboolean retval = FALSE; Atom type = None; @@ -2189,19 +2243,14 @@ xdnd_check_dest (Window win) Atom *version; Window *proxy_data; Window proxy; - static Atom xdnd_proxy_atom = None; - - if (!xdnd_proxy_atom) - xdnd_proxy_atom = gdk_x11_get_xatom_by_name ("XdndProxy"); - - if (!xdnd_aware_atom) - xdnd_aware_atom = gdk_x11_get_xatom_by_name ("XdndAware"); + Atom xdnd_proxy_atom = gdk_x11_get_xatom_by_name_for_display (display, "XdndProxy"); + Atom xdnd_aware_atom = gdk_x11_get_xatom_by_name_for_display (display, "XdndAware"); proxy = None; gdk_error_trap_push (); - if (XGetWindowProperty (gdk_display, win, + if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), win, xdnd_proxy_atom, 0, 1, False, AnyPropertyType, &type, &format, &nitems, &after, @@ -2215,12 +2264,13 @@ xdnd_check_dest (Window win) } else GDK_NOTE (DND, - g_warning ("Invalid XdndOwner property on window %ld\n", win)); + g_warning ("Invalid XdndOwner " + "property on window %ld\n", win)); XFree (proxy_data); } - if ((XGetWindowProperty (gdk_display, proxy ? proxy : win, + if ((XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), proxy ? proxy : win, xdnd_aware_atom, 0, 1, False, AnyPropertyType, &type, &format, &nitems, &after, @@ -2250,6 +2300,7 @@ xdnd_check_dest (Window win) static void xdnd_read_actions (GdkDragContext *context) { + GdkDisplay *display = GDK_WINDOW_DISPLAY (context->source_window); Atom type; int format; gulong nitems, after; @@ -2263,7 +2314,8 @@ xdnd_read_actions (GdkDragContext *context) if (XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (context->source_window), GDK_DRAWABLE_XID (context->source_window), - gdk_x11_get_xatom_by_name ("XdndActionList"), 0, 65536, + gdk_x11_get_xatom_by_name_for_display (display, "XdndActionList"), + 0, 65536, False, XA_ATOM, &type, &format, &nitems, &after, (guchar **)&data) == Success && type == XA_ATOM) @@ -2271,7 +2323,7 @@ xdnd_read_actions (GdkDragContext *context) context->actions = 0; for (i=0; i<nitems; i++) - context->actions |= xdnd_action_from_atom (data[i]); + context->actions |= xdnd_action_from_atom (display, data[i]); (PRIVATE_DATA (context))->xdnd_have_actions = TRUE; @@ -2312,9 +2364,10 @@ xdnd_source_window_filter (GdkXEvent *xev, { XEvent *xevent = (XEvent *)xev; GdkDragContext *context = cb_data; + GdkDisplay *display = GDK_WINDOW_DISPLAY(event->any.window); if ((xevent->xany.type == PropertyNotify) && - (xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("XdndActionList"))) + (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "XdndActionList"))) { xdnd_read_actions (context); @@ -2353,7 +2406,7 @@ xdnd_manage_source_filter (GdkDragContext *context, } } - gdk_flush (); + gdk_display_sync (gdk_drawable_get_display (window)); gdk_error_trap_pop (); } @@ -2362,6 +2415,8 @@ xdnd_enter_filter (GdkXEvent *xev, GdkEvent *event, gpointer cb_data) { + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (event->any.window); + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); XEvent *xevent = (XEvent *)xev; GdkDragContext *new_context; gint i; @@ -2386,22 +2441,22 @@ xdnd_enter_filter (GdkXEvent *xev, return GDK_FILTER_REMOVE; } - if (current_dest_drag != NULL) + if (display_x11->current_dest_drag != NULL) { - gdk_drag_context_unref (current_dest_drag); - current_dest_drag = NULL; + gdk_drag_context_unref (display_x11->current_dest_drag); + display_x11->current_dest_drag = NULL; } new_context = gdk_drag_context_new (); new_context->protocol = GDK_DRAG_PROTO_XDND; new_context->is_source = FALSE; - new_context->source_window = gdk_window_lookup (source_window); + new_context->source_window = gdk_window_lookup_for_display (display, source_window); if (new_context->source_window) gdk_window_ref (new_context->source_window); else { - new_context->source_window = gdk_window_foreign_new (source_window); + new_context->source_window = gdk_window_foreign_new_for_display (display, source_window); if (!new_context->source_window) { gdk_drag_context_unref (new_context); @@ -2417,7 +2472,8 @@ xdnd_enter_filter (GdkXEvent *xev, gdk_error_trap_push (); XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (event->any.window), source_window, - gdk_x11_get_xatom_by_name ("XdndTypeList"), 0, 65536, + gdk_x11_get_xatom_by_name_for_display (display, "XdndTypeList"), + 0, 65536, False, XA_ATOM, &type, &format, &nitems, &after, (guchar **)&data); @@ -2428,8 +2484,10 @@ xdnd_enter_filter (GdkXEvent *xev, } for (i=0; i<nitems; i++) - new_context->targets = g_list_append (new_context->targets, - GDK_ATOM_TO_POINTER (gdk_x11_xatom_to_atom (data[i]))); + new_context->targets = + g_list_append (new_context->targets, + GDK_ATOM_TO_POINTER (gdk_x11_xatom_to_atom_for_display (display, + data[i]))); XFree(data); } @@ -2437,8 +2495,10 @@ xdnd_enter_filter (GdkXEvent *xev, { for (i=0; i<3; i++) if (xevent->xclient.data.l[2+i]) - new_context->targets = g_list_append (new_context->targets, - GDK_ATOM_TO_POINTER (gdk_x11_xatom_to_atom (xevent->xclient.data.l[2+i]))); + new_context->targets = + g_list_append (new_context->targets, + GDK_ATOM_TO_POINTER (gdk_x11_xatom_to_atom_for_display (display, + xevent->xclient.data.l[2+i]))); } #ifdef G_ENABLE_DEBUG @@ -2453,10 +2513,10 @@ xdnd_enter_filter (GdkXEvent *xev, event->dnd.context = new_context; gdk_drag_context_ref (new_context); - current_dest_drag = new_context; - (PRIVATE_DATA (new_context))->xdnd_selection = - gdk_x11_get_xatom_by_name ("XdndSelection"); + display_x11->current_dest_drag = new_context; + (PRIVATE_DATA (new_context))->xdnd_selection = + gdk_x11_get_xatom_by_name_for_display (display, "XdndSelection"); return GDK_FILTER_TRANSLATE; } @@ -2467,20 +2527,21 @@ xdnd_leave_filter (GdkXEvent *xev, { XEvent *xevent = (XEvent *)xev; guint32 source_window = xevent->xclient.data.l[0]; - + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window)); + GDK_NOTE (DND, g_message ("XdndLeave: source_window: %#x", source_window)); - if ((current_dest_drag != NULL) && - (current_dest_drag->protocol == GDK_DRAG_PROTO_XDND) && - (GDK_DRAWABLE_XID (current_dest_drag->source_window) == source_window)) + if ((display_x11->current_dest_drag != NULL) && + (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_XDND) && + (GDK_DRAWABLE_XID (display_x11->current_dest_drag->source_window) == source_window)) { event->dnd.type = GDK_DRAG_LEAVE; /* Pass ownership of context to the event */ - event->dnd.context = current_dest_drag; + event->dnd.context = display_x11->current_dest_drag; - current_dest_drag = NULL; + display_x11->current_dest_drag = NULL; return GDK_FILTER_TRANSLATE; } @@ -2499,31 +2560,35 @@ xdnd_position_filter (GdkXEvent *xev, gint16 y_root = xevent->xclient.data.l[2] & 0xffff; guint32 time = xevent->xclient.data.l[3]; Atom action = xevent->xclient.data.l[4]; - + + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (event->any.window); + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + GDK_NOTE (DND, - g_message ("XdndPosition: source_window: %#x position: (%d, %d) time: %d action: %ld", + g_message ("XdndPosition: source_window: %#x position: (%d, %d) time: %d action: %ld", source_window, x_root, y_root, time, action)); - if ((current_dest_drag != NULL) && - (current_dest_drag->protocol == GDK_DRAG_PROTO_XDND) && - (GDK_DRAWABLE_XID (current_dest_drag->source_window) == source_window)) + if ((display_x11->current_dest_drag != NULL) && + (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_XDND) && + (GDK_DRAWABLE_XID (display_x11->current_dest_drag->source_window) == source_window)) { event->dnd.type = GDK_DRAG_MOTION; - event->dnd.context = current_dest_drag; - gdk_drag_context_ref (current_dest_drag); + event->dnd.context = display_x11->current_dest_drag; + gdk_drag_context_ref (display_x11->current_dest_drag); event->dnd.time = time; - current_dest_drag->suggested_action = xdnd_action_from_atom (action); - if (!(PRIVATE_DATA (current_dest_drag))->xdnd_have_actions) - current_dest_drag->actions = current_dest_drag->suggested_action; + display_x11->current_dest_drag->suggested_action = xdnd_action_from_atom (display, action); + + if (!(PRIVATE_DATA (display_x11->current_dest_drag))->xdnd_have_actions) + display_x11->current_dest_drag->actions = display_x11->current_dest_drag->suggested_action; event->dnd.x_root = x_root; event->dnd.y_root = y_root; - (PRIVATE_DATA (current_dest_drag))->last_x = x_root; - (PRIVATE_DATA (current_dest_drag))->last_y = y_root; + (PRIVATE_DATA (display_x11->current_dest_drag))->last_x = x_root; + (PRIVATE_DATA (display_x11->current_dest_drag))->last_y = y_root; return GDK_FILTER_TRANSLATE; } @@ -2539,22 +2604,23 @@ xdnd_drop_filter (GdkXEvent *xev, XEvent *xevent = (XEvent *)xev; guint32 source_window = xevent->xclient.data.l[0]; guint32 time = xevent->xclient.data.l[2]; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_DRAWABLE_DISPLAY (event->any.window)); GDK_NOTE (DND, g_message ("XdndDrop: source_window: %#x time: %d", source_window, time)); - if ((current_dest_drag != NULL) && - (current_dest_drag->protocol == GDK_DRAG_PROTO_XDND) && - (GDK_DRAWABLE_XID (current_dest_drag->source_window) == source_window)) + if ((display_x11->current_dest_drag != NULL) && + (display_x11->current_dest_drag->protocol == GDK_DRAG_PROTO_XDND) && + (GDK_DRAWABLE_XID (display_x11->current_dest_drag->source_window) == source_window)) { GdkDragContextPrivateX11 *private; - private = PRIVATE_DATA (current_dest_drag); + private = PRIVATE_DATA (display_x11->current_dest_drag); event->dnd.type = GDK_DROP_START; - event->dnd.context = current_dest_drag; - gdk_drag_context_ref (current_dest_drag); + event->dnd.context = display_x11->current_dest_drag; + gdk_drag_context_ref (display_x11->current_dest_drag); event->dnd.time = time; event->dnd.x_root = private->last_x; @@ -2569,31 +2635,37 @@ xdnd_drop_filter (GdkXEvent *xev, /************************************************************* ************************** Public API *********************** *************************************************************/ - void -_gdk_dnd_init (void) +_gdk_dnd_init (GdkDisplay *display) { - init_byte_order(); + init_byte_order (); - gdk_add_client_message_filter ( + gdk_display_add_client_message_filter ( + display, gdk_atom_intern ("_MOTIF_DRAG_AND_DROP_MESSAGE", FALSE), motif_dnd_filter, NULL); - gdk_add_client_message_filter ( + gdk_display_add_client_message_filter ( + display, gdk_atom_intern ("XdndEnter", FALSE), xdnd_enter_filter, NULL); - gdk_add_client_message_filter ( + gdk_display_add_client_message_filter ( + display, gdk_atom_intern ("XdndLeave", FALSE), xdnd_leave_filter, NULL); - gdk_add_client_message_filter ( + gdk_display_add_client_message_filter ( + display, gdk_atom_intern ("XdndPosition", FALSE), xdnd_position_filter, NULL); - gdk_add_client_message_filter ( + gdk_display_add_client_message_filter ( + display, gdk_atom_intern ("XdndStatus", FALSE), xdnd_status_filter, NULL); - gdk_add_client_message_filter ( + gdk_display_add_client_message_filter ( + display, gdk_atom_intern ("XdndFinished", FALSE), xdnd_finished_filter, NULL); - gdk_add_client_message_filter ( + gdk_display_add_client_message_filter ( + display, gdk_atom_intern ("XdndDrop", FALSE), xdnd_drop_filter, NULL); } @@ -2644,18 +2716,20 @@ gdk_drag_begin (GdkWindow *window, } guint32 -gdk_drag_get_protocol (guint32 xid, - GdkDragProtocol *protocol) +gdk_drag_get_protocol_for_display (GdkDisplay *display, + guint32 xid, + GdkDragProtocol *protocol) { guint32 retval; + g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE); - if ((retval = xdnd_check_dest (xid))) + if ((retval = xdnd_check_dest (display, xid))) { *protocol = GDK_DRAG_PROTO_XDND; GDK_NOTE (DND, g_message ("Entering dnd window %#x\n", xid)); return retval; } - else if ((retval = motif_check_dest (xid))) + else if ((retval = motif_check_dest (display, xid))) { *protocol = GDK_DRAG_PROTO_MOTIF; GDK_NOTE (DND, g_message ("Entering motif window %#x\n", xid)); @@ -2671,15 +2745,15 @@ gdk_drag_get_protocol (guint32 xid, unsigned long nitems, after; unsigned char *data; - if (xid == _gdk_root_window) + if (_gdk_x11_display_is_root_window (display, (Window) xid)) rootwin = TRUE; gdk_error_trap_push (); if (!rootwin) { - if (XGetWindowProperty (gdk_display, xid, - gdk_x11_get_xatom_by_name ("ENLIGHTENMENT_DESKTOP"), + if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xid, + gdk_x11_get_xatom_by_name_for_display (display, "ENLIGHTENMENT_DESKTOP"), 0, 0, False, AnyPropertyType, &type, &format, &nitems, &after, &data) == Success && type != None) @@ -2718,6 +2792,13 @@ gdk_drag_get_protocol (guint32 xid, return None; } +guint32 +gdk_drag_get_protocol (guint32 xid, + GdkDragProtocol *protocol) +{ + return gdk_drag_get_protocol_for_display (gdk_get_default_display (), xid, protocol); +} + void gdk_drag_find_window (GdkDragContext *context, GdkWindow *drag_window, @@ -2727,12 +2808,15 @@ gdk_drag_find_window (GdkDragContext *context, GdkDragProtocol *protocol) { GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); + GdkDisplay *display; Window dest; g_return_if_fail (context != NULL); + display = GDK_WINDOW_DISPLAY (context->source_window); + if (!private->window_cache) - private->window_cache = gdk_window_cache_new(); + private->window_cache = gdk_window_cache_new (gdk_drawable_get_screen (context->source_window)); dest = get_client_window_at_coords (private->window_cache, drag_window ? @@ -2752,13 +2836,13 @@ gdk_drag_find_window (GdkDragContext *context, * two are passed explicitely, the third implicitly through * protocol->dest_xid. */ - if ((recipient = gdk_drag_get_protocol (dest, protocol))) + if ((recipient = gdk_drag_get_protocol_for_display (display, dest, protocol))) { - *dest_window = gdk_window_lookup (recipient); + *dest_window = gdk_window_lookup_for_display (display, recipient); if (*dest_window) gdk_window_ref (*dest_window); else - *dest_window = gdk_window_foreign_new (recipient); + *dest_window = gdk_window_foreign_new_for_display (display, recipient); } else *dest_window = NULL; @@ -2963,17 +3047,20 @@ gdk_drag_status (GdkDragContext *context, { GdkDragContextPrivateX11 *private; XEvent xev; + GdkDisplay *display; g_return_if_fail (context != NULL); private = PRIVATE_DATA (context); - - context->action = action; + display = GDK_DRAWABLE_DISPLAY (context->source_window); + context->action = action; + if (context->protocol == GDK_DRAG_PROTO_MOTIF) { xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_AND_DROP_MESSAGE"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, + "_MOTIF_DRAG_AND_DROP_MESSAGE"); xev.xclient.format = 8; xev.xclient.window = GDK_DRAWABLE_XID (context->source_window); @@ -3021,8 +3108,9 @@ gdk_drag_status (GdkDragContext *context, MOTIF_XCLIENT_SHORT (&xev, 4) = private->last_x; MOTIF_XCLIENT_SHORT (&xev, 5) = private->last_y; - if (!gdk_send_xevent (GDK_DRAWABLE_XID (context->source_window), - FALSE, 0, &xev)) + if (!_gdk_send_xevent (display, + GDK_DRAWABLE_XID (context->source_window), + FALSE, 0, &xev)) GDK_NOTE (DND, g_message ("Send event to %lx failed", GDK_DRAWABLE_XID (context->source_window))); @@ -3030,7 +3118,7 @@ gdk_drag_status (GdkDragContext *context, else if (context->protocol == GDK_DRAG_PROTO_XDND) { xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("XdndStatus"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndStatus"); xev.xclient.format = 32; xev.xclient.window = GDK_DRAWABLE_XID (context->source_window); @@ -3038,9 +3126,10 @@ gdk_drag_status (GdkDragContext *context, xev.xclient.data.l[1] = (action != 0) ? (2 | 1) : 0; xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = xdnd_action_to_atom (action); - - if (!xdnd_send_xevent (GDK_DRAWABLE_XID (context->source_window), + xev.xclient.data.l[4] = xdnd_action_to_atom (display, action); + + if (!xdnd_send_xevent (display, + GDK_DRAWABLE_XID (context->source_window), FALSE, &xev)) GDK_NOTE (DND, g_message ("Send event to %lx failed", @@ -3063,10 +3152,12 @@ gdk_drop_reply (GdkDragContext *context, if (context->protocol == GDK_DRAG_PROTO_MOTIF) { + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); XEvent xev; xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_AND_DROP_MESSAGE"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, + "_MOTIF_DRAG_AND_DROP_MESSAGE"); xev.xclient.format = 8; MOTIF_XCLIENT_BYTE (&xev, 0) = XmDROP_START | 0x80; @@ -3084,8 +3175,9 @@ gdk_drop_reply (GdkDragContext *context, MOTIF_XCLIENT_SHORT (&xev, 2) = private->last_x; MOTIF_XCLIENT_SHORT (&xev, 3) = private->last_y; - gdk_send_xevent (GDK_DRAWABLE_XID (context->source_window), - FALSE, 0, &xev); + _gdk_send_xevent (display, + GDK_DRAWABLE_XID (context->source_window), + FALSE, 0, &xev); } } @@ -3098,20 +3190,22 @@ gdk_drop_finish (GdkDragContext *context, if (context->protocol == GDK_DRAG_PROTO_XDND) { + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window); XEvent xev; xev.xclient.type = ClientMessage; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("XdndFinished"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndFinished"); xev.xclient.format = 32; xev.xclient.window = GDK_DRAWABLE_XID (context->source_window); - + xev.xclient.data.l[0] = GDK_DRAWABLE_XID (context->dest_window); xev.xclient.data.l[1] = 0; xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - if (!xdnd_send_xevent (GDK_DRAWABLE_XID (context->source_window), + if (!xdnd_send_xevent (display, + GDK_DRAWABLE_XID (context->source_window), FALSE, &xev)) GDK_NOTE (DND, g_message ("Send event to %lx failed", @@ -3125,6 +3219,8 @@ gdk_window_register_dnd (GdkWindow *window) { static gulong xdnd_version = 3; MotifDragReceiverInfo info; + Atom motif_drag_receiver_info_atom; + GdkDisplay *display = gdk_drawable_get_display (window); g_return_if_fail (window != NULL); @@ -3135,9 +3231,8 @@ gdk_window_register_dnd (GdkWindow *window) /* Set Motif drag receiver information property */ - if (!motif_drag_receiver_info_atom) - motif_drag_receiver_info_atom = gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_RECEIVER_INFO"); - + motif_drag_receiver_info_atom = gdk_x11_get_xatom_by_name_for_display (display, + "_MOTIF_DRAG_RECEIVER_INFO"); info.byte_order = local_byte_order; info.protocol_version = 0; info.protocol_style = XmDRAG_DYNAMIC; @@ -3145,7 +3240,7 @@ gdk_window_register_dnd (GdkWindow *window) info.num_drop_sites = 0; info.total_size = sizeof(info); - XChangeProperty (gdk_display, GDK_DRAWABLE_XID (window), + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_DRAWABLE_XID (window), motif_drag_receiver_info_atom, motif_drag_receiver_info_atom, 8, PropModeReplace, @@ -3154,14 +3249,11 @@ gdk_window_register_dnd (GdkWindow *window) /* Set XdndAware */ - if (!xdnd_aware_atom) - xdnd_aware_atom = gdk_x11_get_xatom_by_name ("XdndAware"); - /* The property needs to be of type XA_ATOM, not XA_INTEGER. Blech */ - XChangeProperty (GDK_DRAWABLE_XDISPLAY (window), + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_DRAWABLE_XID (window), - xdnd_aware_atom, XA_ATOM, - 32, PropModeReplace, + gdk_x11_get_xatom_by_name_for_display (display, "XdndAware"), + XA_ATOM, 32, PropModeReplace, (guchar *)&xdnd_version, 1); } @@ -3173,16 +3265,18 @@ gdk_window_register_dnd (GdkWindow *window) * results: *************************************************************/ -GdkAtom +GdkAtom gdk_drag_get_selection (GdkDragContext *context) { g_return_val_if_fail (context != NULL, GDK_NONE); if (context->protocol == GDK_DRAG_PROTO_MOTIF) - return gdk_x11_xatom_to_atom ((PRIVATE_DATA (context))->motif_selection); + return gdk_x11_xatom_to_atom_for_display (GDK_DRAWABLE_DISPLAY (context->source_window), + (PRIVATE_DATA (context))->motif_selection); else if (context->protocol == GDK_DRAG_PROTO_XDND) - return gdk_x11_xatom_to_atom ((PRIVATE_DATA (context))->xdnd_selection); - else + return gdk_x11_xatom_to_atom_for_display (GDK_DRAWABLE_DISPLAY (context->source_window), + (PRIVATE_DATA (context))->xdnd_selection); + else return GDK_NONE; } diff --git a/gdk/x11/gdkdrawable-x11.c b/gdk/x11/gdkdrawable-x11.c index 147a356f7..585d1669e 100644 --- a/gdk/x11/gdkdrawable-x11.c +++ b/gdk/x11/gdkdrawable-x11.c @@ -48,6 +48,8 @@ #include "gdkprivate-x11.h" #include "gdkdrawable-x11.h" #include "gdkpixmap-x11.h" +#include "gdkscreen-x11.h" +#include "gdkdisplay-x11.h" static void gdk_x11_draw_rectangle (GdkDrawable *drawable, GdkGC *gc, @@ -139,9 +141,8 @@ static void gdk_x11_set_colormap (GdkDrawable *drawable, GdkColormap *colormap); static GdkColormap* gdk_x11_get_colormap (GdkDrawable *drawable); - static gint gdk_x11_get_depth (GdkDrawable *drawable); - +static GdkScreen * gdk_x11_get_screen (GdkDrawable *drawable); static GdkVisual* gdk_x11_get_visual (GdkDrawable *drawable); static void gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass); @@ -208,6 +209,7 @@ gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass) drawable_class->get_colormap = gdk_x11_get_colormap; drawable_class->get_depth = gdk_x11_get_depth; + drawable_class->get_screen = gdk_x11_get_screen; drawable_class->get_visual = gdk_x11_get_visual; drawable_class->_copy_to_image = _gdk_x11_copy_to_image; @@ -223,14 +225,15 @@ gdk_drawable_impl_x11_finalize (GObject *object) #ifdef HAVE_XFT gboolean -_gdk_x11_have_render (void) +_gdk_x11_have_render (GdkDisplay *display) { /* This check is cheap, but if we have to do version checks, we will * need to cache the result since version checks are round-trip */ int event_base, error_base; - return XRenderQueryExtension (gdk_display, &event_base, &error_base); + return XRenderQueryExtension (GDK_DISPLAY_XDISPLAY (display), + &event_base, &error_base); } static Picture @@ -238,7 +241,7 @@ gdk_x11_drawable_get_picture (GdkDrawable *drawable) { GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable); - if (!_gdk_x11_have_render ()) + if (!_gdk_x11_have_render (gdk_drawable_get_display (drawable))) return None; if (impl->picture == None) @@ -256,9 +259,11 @@ gdk_x11_drawable_get_picture (GdkDrawable *drawable) return None; } - format = XRenderFindVisualFormat (impl->xdisplay, GDK_VISUAL_XVISUAL (visual)); + format = XRenderFindVisualFormat (GDK_SCREEN_XDISPLAY (impl->screen), + gdk_x11_visual_get_xvisual(visual)); if (format) - impl->picture = XRenderCreatePicture (impl->xdisplay, impl->xid, format, 0, NULL); + impl->picture = XRenderCreatePicture (GDK_SCREEN_XDISPLAY (impl->screen), + impl->xid, format, 0, NULL); } return impl->picture; @@ -287,7 +292,8 @@ gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable, rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y; } - XRenderSetPictureClipRectangles (impl->xdisplay, picture, 0, 0, rects, n_boxes); + XRenderSetPictureClipRectangles (GDK_SCREEN_XDISPLAY (impl->screen), + picture, 0, 0, rects, n_boxes); g_free (rects); } @@ -295,7 +301,8 @@ gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable, { XRenderPictureAttributes pa; pa.clip_mask = None; - XRenderChangePicture (impl->xdisplay, picture, CPClipMask, &pa); + XRenderChangePicture (GDK_SCREEN_XDISPLAY (impl->screen), + picture, CPClipMask, &pa); } } #endif @@ -349,10 +356,10 @@ gdk_x11_draw_rectangle (GdkDrawable *drawable, impl = GDK_DRAWABLE_IMPL_X11 (drawable); if (filled) - XFillRectangle (impl->xdisplay, impl->xid, + XFillRectangle (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), x, y, width, height); else - XDrawRectangle (impl->xdisplay, impl->xid, + XDrawRectangle (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), x, y, width, height); } @@ -373,10 +380,10 @@ gdk_x11_draw_arc (GdkDrawable *drawable, if (filled) - XFillArc (impl->xdisplay, impl->xid, + XFillArc (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2); else - XDrawArc (impl->xdisplay, impl->xid, + XDrawArc (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2); } @@ -415,10 +422,10 @@ gdk_x11_draw_polygon (GdkDrawable *drawable, } if (filled) - XFillPolygon (impl->xdisplay, impl->xid, + XFillPolygon (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, Complex, CoordModeOrigin); else - XDrawLines (impl->xdisplay, impl->xid, + XDrawLines (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, CoordModeOrigin); g_free (tmp_points); @@ -440,28 +447,30 @@ gdk_x11_draw_text (GdkDrawable *drawable, gint text_length) { GdkDrawableImplX11 *impl; + Display *xdisplay; impl = GDK_DRAWABLE_IMPL_X11 (drawable); + xdisplay = GDK_SCREEN_XDISPLAY (impl->screen); if (font->type == GDK_FONT_FONT) { XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font); - XSetFont(impl->xdisplay, GDK_GC_GET_XGC (gc), xfont->fid); + XSetFont(xdisplay, GDK_GC_GET_XGC (gc), xfont->fid); if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) { - XDrawString (impl->xdisplay, impl->xid, + XDrawString (xdisplay, impl->xid, GDK_GC_GET_XGC (gc), x, y, text, text_length); } else { - XDrawString16 (impl->xdisplay, impl->xid, + XDrawString16 (xdisplay, impl->xid, GDK_GC_GET_XGC (gc), x, y, (XChar2b *) text, text_length / 2); } } else if (font->type == GDK_FONT_FONTSET) { XFontSet fontset = (XFontSet) GDK_FONT_XFONT (font); - XmbDrawString (impl->xdisplay, impl->xid, + XmbDrawString (xdisplay, impl->xid, fontset, GDK_GC_GET_XGC (gc), x, y, text, text_length); } else @@ -478,18 +487,20 @@ gdk_x11_draw_text_wc (GdkDrawable *drawable, gint text_length) { GdkDrawableImplX11 *impl; + Display *xdisplay; impl = GDK_DRAWABLE_IMPL_X11 (drawable); + xdisplay = GDK_SCREEN_XDISPLAY (impl->screen); if (font->type == GDK_FONT_FONT) { XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font); gchar *text_8bit; gint i; - XSetFont(impl->xdisplay, GDK_GC_GET_XGC (gc), xfont->fid); + XSetFont(xdisplay, GDK_GC_GET_XGC (gc), xfont->fid); text_8bit = g_new (gchar, text_length); for (i=0; i<text_length; i++) text_8bit[i] = text[i]; - XDrawString (impl->xdisplay, impl->xid, + XDrawString (xdisplay, impl->xid, GDK_GC_GET_XGC (gc), x, y, text_8bit, text_length); g_free (text_8bit); } @@ -497,7 +508,7 @@ gdk_x11_draw_text_wc (GdkDrawable *drawable, { if (sizeof(GdkWChar) == sizeof(wchar_t)) { - XwcDrawString (impl->xdisplay, impl->xid, + XwcDrawString (xdisplay, impl->xid, (XFontSet) GDK_FONT_XFONT (font), GDK_GC_GET_XGC (gc), x, y, (wchar_t *)text, text_length); } @@ -507,7 +518,7 @@ gdk_x11_draw_text_wc (GdkDrawable *drawable, gint i; text_wchar = g_new (wchar_t, text_length); for (i=0; i<text_length; i++) text_wchar[i] = text[i]; - XwcDrawString (impl->xdisplay, impl->xid, + XwcDrawString (xdisplay, impl->xid, (XFontSet) GDK_FONT_XFONT (font), GDK_GC_GET_XGC (gc), x, y, text_wchar, text_length); g_free (text_wchar); @@ -542,7 +553,7 @@ gdk_x11_draw_drawable (GdkDrawable *drawable, if (src_depth == 1) { - XCopyArea (impl->xdisplay, + XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen), src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src), impl->xid, GDK_GC_GET_XGC (gc), @@ -552,7 +563,7 @@ gdk_x11_draw_drawable (GdkDrawable *drawable, } else if (dest_depth != 0 && src_depth == dest_depth) { - XCopyArea (impl->xdisplay, + XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen), src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src), impl->xid, GDK_GC_GET_XGC (gc), @@ -581,7 +592,7 @@ gdk_x11_draw_points (GdkDrawable *drawable, */ if (npoints == 1) { - XDrawPoint (impl->xdisplay, + XDrawPoint (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), points[0].x, points[0].y); @@ -597,7 +608,7 @@ gdk_x11_draw_points (GdkDrawable *drawable, tmp_points[i].y = points[i].y; } - XDrawPoints (impl->xdisplay, + XDrawPoints (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), tmp_points, @@ -624,7 +635,7 @@ gdk_x11_draw_segments (GdkDrawable *drawable, */ if (nsegs == 1) { - XDrawLine (impl->xdisplay, impl->xid, + XDrawLine (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), segs[0].x1, segs[0].y1, segs[0].x2, segs[0].y2); } @@ -641,7 +652,7 @@ gdk_x11_draw_segments (GdkDrawable *drawable, tmp_segs[i].y2 = segs[i].y2; } - XDrawSegments (impl->xdisplay, + XDrawSegments (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), tmp_segs, nsegs); @@ -669,7 +680,7 @@ gdk_x11_draw_lines (GdkDrawable *drawable, tmp_points[i].y = points[i].y; } - XDrawLines (impl->xdisplay, + XDrawLines (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), tmp_points, npoints, @@ -701,11 +712,13 @@ gdk_x11_draw_glyphs (GdkDrawable *drawable, gdk_x11_drawable_update_picture_clip (drawable, gc); dest_picture = gdk_x11_drawable_get_picture (drawable); - pango_xft_picture_render (impl->xdisplay, src_picture, dest_picture, font, glyphs, x, y); + pango_xft_picture_render (GDK_SCREEN_XDISPLAY (impl->screen), + src_picture, dest_picture, + font, glyphs, x, y); } else #endif /* !HAVE_XFT */ - pango_x_render (impl->xdisplay, + pango_x_render (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), font, glyphs, x, y); @@ -727,11 +740,11 @@ gdk_x11_draw_image (GdkDrawable *drawable, impl = GDK_DRAWABLE_IMPL_X11 (drawable); if (image->type == GDK_IMAGE_SHARED) - XShmPutImage (impl->xdisplay, impl->xid, + XShmPutImage (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image), xsrc, ysrc, xdest, ydest, width, height, False); else - XPutImage (impl->xdisplay, impl->xid, + XPutImage (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image), xsrc, ysrc, xdest, ydest, width, height); } @@ -744,14 +757,8 @@ gdk_x11_get_depth (GdkDrawable *drawable) return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper); } -static GdkVisual* -gdk_x11_get_visual (GdkDrawable *drawable) -{ - return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper); -} -Display * -gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable) +static GdkDrawable * get_impl_drawable (GdkDrawable *drawable) { GdkDrawable *impl; @@ -762,10 +769,34 @@ gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable) else { g_warning (G_STRLOC " drawable is not a pixmap or window"); - return NULL; + return None; } + return impl; +} + + +static GdkScreen* +gdk_x11_get_screen (GdkDrawable *drawable) +{ + if (GDK_IS_DRAWABLE_IMPL_X11 (drawable)) + return GDK_DRAWABLE_IMPL_X11 (drawable)->screen; + else + return GDK_DRAWABLE_IMPL_X11 (get_impl_drawable (drawable))->screen; +} - return ((GdkDrawableImplX11 *)impl)->xdisplay; +static GdkVisual* +gdk_x11_get_visual (GdkDrawable *drawable) +{ + return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper); +} + +Display * +gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable) +{ + if (GDK_IS_DRAWABLE_IMPL_X11 (drawable)) + return GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (drawable)->screen); + else + return GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (get_impl_drawable (drawable))->screen); } XID @@ -800,13 +831,14 @@ typedef enum { } FormatType; static FormatType -select_format (Display *xdisplay, +select_format (GdkDisplay *display, XRenderPictFormat **format, XRenderPictFormat **mask) { + Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); XRenderPictFormat pf; - if (!_gdk_x11_have_render ()) + if (!_gdk_x11_have_render (display)) return FORMAT_NONE; /* Look for a 32-bit xRGB and Axxx formats that exactly match the @@ -1098,7 +1130,8 @@ draw_with_images (GdkDrawable *drawable, gint width, gint height) { - Display *xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay; + GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen; + Display *xdisplay = GDK_SCREEN_XDISPLAY (screen); GdkImage *image; GdkPixmap *pix; GdkGC *pix_gc; @@ -1107,7 +1140,8 @@ draw_with_images (GdkDrawable *drawable, Picture mask = None; gint x0, y0; - pix = gdk_pixmap_new (NULL, width, height, 32); + pix = gdk_pixmap_new (gdk_screen_get_root_window (screen), width, height, 32); + pict = XRenderCreatePicture (xdisplay, GDK_PIXMAP_XID (pix), format, 0, NULL); @@ -1129,7 +1163,7 @@ draw_with_images (GdkDrawable *drawable, gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH); - image = _gdk_image_get_scratch (width1, height1, 32, &xs0, &ys0); + image = _gdk_image_get_scratch (screen, width1, height1, 32, &xs0, &ys0); convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride, image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl, @@ -1221,7 +1255,7 @@ draw_with_pixmaps (GdkDrawable *drawable, gint width, gint height) { - Display *xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay; + Display *xdisplay = GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (drawable)->screen); GdkImage *image; Pixmap pix; Picture pict; @@ -1240,7 +1274,8 @@ draw_with_pixmaps (GdkDrawable *drawable, gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH); - image = _gdk_image_get_scratch (width1, height1, 32, &xs0, &ys0); + image = _gdk_image_get_scratch (GDK_DRAWABLE_IMPL_X11 (drawable)->screen, + width1, height1, 32, &xs0, &ys0); if (!get_shm_pixmap_for_image (xdisplay, image, format, mask_format, &pix, &pict, &mask)) return FALSE; @@ -1273,7 +1308,6 @@ gdk_x11_draw_pixbuf (GdkDrawable *drawable, gint x_dither, gint y_dither) { - Display *xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay; FormatType format_type; XRenderPictFormat *format, *mask_format; gint rowstride; @@ -1281,7 +1315,8 @@ gdk_x11_draw_pixbuf (GdkDrawable *drawable, gboolean use_pixmaps = TRUE; #endif /* USE_SHM */ - format_type = select_format (xdisplay, &format, &mask_format); + format_type = select_format (gdk_drawable_get_display (drawable), + &format, &mask_format); if (format_type == FORMAT_NONE || !gdk_pixbuf_get_has_alpha (pixbuf) || diff --git a/gdk/x11/gdkdrawable-x11.h b/gdk/x11/gdkdrawable-x11.h index aa681585d..abdcbb42b 100644 --- a/gdk/x11/gdkdrawable-x11.h +++ b/gdk/x11/gdkdrawable-x11.h @@ -30,7 +30,6 @@ #include <config.h> #include <gdk/gdkdrawable.h> -#include <gdk/x11/gdkx.h> #ifdef HAVE_XFT #include <X11/extensions/Xrender.h> @@ -62,7 +61,7 @@ struct _GdkDrawableImplX11 GdkColormap *colormap; Window xid; - Display *xdisplay; + GdkScreen *screen; #ifdef HAVE_XFT Picture picture; diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index 0197c6233..1d9e57f8a 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -28,6 +28,8 @@ #include "gdkprivate-x11.h" #include "gdkinternals.h" #include "gdkx.h" +#include "gdkscreen-x11.h" +#include "gdkdisplay-x11.h" #include "gdkkeysyms.h" @@ -50,6 +52,7 @@ typedef struct _GdkIOClosure GdkIOClosure; typedef struct _GdkEventPrivate GdkEventPrivate; +typedef struct _GdkDisplaySource GdkDisplaySource; #define DOUBLE_CLICK_TIME 250 #define TRIPLE_CLICK_TIME 500 @@ -78,6 +81,14 @@ struct _GdkEventPrivate guint flags; }; +struct _GdkDisplaySource +{ + GSource source; + + GdkDisplay *display; + GPollFD event_poll_fd; +}; + /* * Private function declarations */ @@ -85,14 +96,10 @@ struct _GdkEventPrivate static gint gdk_event_apply_filters (XEvent *xevent, GdkEvent *event, GList *filters); -static gint gdk_event_translate (GdkEvent *event, - XEvent *xevent, - gboolean return_exposes); -#if 0 -static Bool gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg); -#endif +static gboolean gdk_event_translate (GdkDisplay *display, + GdkEvent *event, + XEvent *xevent, + gboolean return_exposes); static gboolean gdk_event_prepare (GSource *source, gint *timeout); @@ -105,6 +112,9 @@ static GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev, GdkEvent *event, gpointer data); +static GSource *gdk_display_source_new (GdkDisplay *display); +static gboolean gdk_check_xpending (GdkDisplay *display); + static void gdk_xsettings_watch_cb (Window window, Bool is_start, long mask, @@ -117,13 +127,7 @@ static void gdk_xsettings_notify_cb (const char *name, /* Private variable declarations */ -static int connection_number = 0; /* The file descriptor number of our - * connection to the X server. This - * is used so that we may determine - * when events are pending by using - * the "select" system call. - */ -static GList *client_filters; /* Filters for client messages */ +static GList *display_sources; static GSourceFuncs event_funcs = { gdk_event_prepare, @@ -132,86 +136,105 @@ static GSourceFuncs event_funcs = { NULL }; -static GPollFD event_poll_fd; - -static Window wmspec_check_window = None; +static GSource * +gdk_display_source_new (GdkDisplay *display) +{ + GSource *source = g_source_new (&event_funcs, sizeof (GdkDisplaySource)); + GdkDisplaySource *display_source = (GdkDisplaySource *)source; + + display_source->display = display; + + return source; +} -static XSettingsClient *xsettings_client; +static gboolean +gdk_check_xpending (GdkDisplay *display) +{ + return XPending (GDK_DISPLAY_XDISPLAY (display)); +} /********************************************* * Functions for maintaining the event queue * *********************************************/ +void +_gdk_x11_events_init_screen (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + screen_x11->xsettings_client = xsettings_client_new (screen_x11->xdisplay, + screen_x11->screen_num, + gdk_xsettings_notify_cb, + gdk_xsettings_watch_cb, + screen); +} + void -_gdk_events_init (void) +_gdk_events_init (GdkDisplay *display) { GSource *source; + GdkDisplaySource *display_source; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); - connection_number = ConnectionNumber (gdk_display); - GDK_NOTE (MISC, - g_message ("connection number: %d", connection_number)); + int connection_number = ConnectionNumber (display_x11->xdisplay); + GDK_NOTE (MISC, g_message ("connection number: %d", connection_number)); - source = g_source_new (&event_funcs, sizeof (GSource)); + source = gdk_display_source_new (display); + display_source = (GdkDisplaySource*) source; g_source_set_priority (source, GDK_PRIORITY_EVENTS); - event_poll_fd.fd = connection_number; - event_poll_fd.events = G_IO_IN; + display_source->event_poll_fd.fd = connection_number; + display_source->event_poll_fd.events = G_IO_IN; - g_source_add_poll (source, &event_poll_fd); + g_source_add_poll (source, &display_source->event_poll_fd); g_source_set_can_recurse (source, TRUE); g_source_attach (source, NULL); - _gdk_wm_window_protocols[0] = gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW"); - _gdk_wm_window_protocols[1] = gdk_x11_get_xatom_by_name ("WM_TAKE_FOCUS"); - _gdk_wm_window_protocols[2] = gdk_x11_get_xatom_by_name ("_NET_WM_PING"); - - gdk_add_client_message_filter (gdk_atom_intern ("WM_PROTOCOLS", FALSE), - gdk_wm_protocols_filter, NULL); + display_sources = g_list_prepend (display_sources,display_source); + + gdk_display_add_client_message_filter ( + display, + gdk_atom_intern ("WM_PROTOCOLS", FALSE), + gdk_wm_protocols_filter, + NULL); - xsettings_client = xsettings_client_new (gdk_display, DefaultScreen (gdk_display), - gdk_xsettings_notify_cb, - gdk_xsettings_watch_cb, - NULL); + _gdk_x11_events_init_screen (display_x11->default_screen); } -/* - *-------------------------------------------------------------- - * gdk_events_pending - * - * Returns if events are pending on the queue. - * - * Arguments: - * - * Results: - * Returns TRUE if events are pending - * - * Side effects: - * - *-------------------------------------------------------------- - */ +/** + * gdk_events_pending: + * + * Checks if any events are ready to be processed for any display. + * + * Return value: %TRUE if any events are pending. + **/ gboolean gdk_events_pending (void) { - return (_gdk_event_queue_find_first() || XPending (gdk_display)); -} + GList *tmp_list; -/* - *-------------------------------------------------------------- - * gdk_event_get_graphics_expose - * - * Waits for a GraphicsExpose or NoExpose event - * - * Arguments: - * - * Results: - * For GraphicsExpose events, returns a pointer to the event - * converted into a GdkEvent Otherwise, returns NULL. - * - * Side effects: - * - *-------------------------------------------------------------- */ + for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next) + { + GdkDisplaySource *tmp_source = tmp_list->data; + GdkDisplay *display = tmp_source->display; + + if (_gdk_event_queue_find_first (display)) + return TRUE; + } + + for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next) + { + GdkDisplaySource *tmp_source = tmp_list->data; + GdkDisplay *display = tmp_source->display; + + if (gdk_check_xpending (display)) + return TRUE; + } + + return FALSE; +} static Bool graphics_expose_predicate (Display *display, @@ -226,6 +249,17 @@ graphics_expose_predicate (Display *display, return False; } +/** + * gdk_event_get_graphics_expose: + * @window: the #GdkWindow to wait for the events for. + * + * Waits for a GraphicsExpose or NoExpose event from the X server. + * This is used in the #GtkText and #GtkCList widgets in GTK+ to make sure any + * GraphicsExpose events are handled before the widget is scrolled. + * + * Return value: a #GdkEventExpose if a GraphicsExpose was received, or %NULL if a + * NoExpose event was received. + **/ GdkEvent* gdk_event_get_graphics_expose (GdkWindow *window) { @@ -234,13 +268,15 @@ gdk_event_get_graphics_expose (GdkWindow *window) g_return_val_if_fail (window != NULL, NULL); - XIfEvent (gdk_display, &xevent, graphics_expose_predicate, (XPointer) window); + XIfEvent (GDK_WINDOW_XDISPLAY (window), &xevent, + graphics_expose_predicate, (XPointer) window); if (xevent.xany.type == GraphicsExpose) { event = _gdk_event_new (); - if (gdk_event_translate (event, &xevent, TRUE)) + if (gdk_event_translate (GDK_WINDOW_DISPLAY (window), event, + &xevent, TRUE)) return event; else gdk_event_free (event); @@ -272,22 +308,56 @@ gdk_event_apply_filters (XEvent *xevent, return GDK_FILTER_CONTINUE; } +/** + * gdk_display_add_client_message_filter: + * @display: a #GdkDisplay for which this message filter applies + * @message_type: the type of ClientMessage events to receive. + * This will be checked against the @message_type field + * of the XClientMessage event struct. + * @func: the function to call to process the event. + * @data: user data to pass to @func. + * + * Adds a filter to be called when X ClientMessage events are received. + * + **/ void -gdk_add_client_message_filter (GdkAtom message_type, - GdkFilterFunc func, - gpointer data) +gdk_display_add_client_message_filter (GdkDisplay *display, + GdkAtom message_type, + GdkFilterFunc func, + gpointer data) { - GdkClientFilter *filter = g_new (GdkClientFilter, 1); + GdkClientFilter *filter; + g_return_if_fail (GDK_IS_DISPLAY (display)); + filter = g_new (GdkClientFilter, 1); filter->type = message_type; filter->function = func; filter->data = data; - client_filters = g_list_prepend (client_filters, filter); + GDK_DISPLAY_X11(display)->client_filters = + g_list_prepend (GDK_DISPLAY_X11 (display)->client_filters, + filter); } -static Atom wm_state_atom = 0; -static Atom wm_desktop_atom = 0; +/** + * gdk_add_client_message_filter: + * @message_type: the type of ClientMessage events to receive. This will be + * checked against the <structfield>message_type</structfield> field of the + * XClientMessage event struct. + * @func: the function to call to process the event. + * @data: user data to pass to @func. + * + * Adds a filter to the default display to be called when X ClientMessage events + * are received. See gdk_display_add_client_message_filter(). + **/ +void +gdk_add_client_message_filter (GdkAtom message_type, + GdkFilterFunc func, + gpointer data) +{ + gdk_display_add_client_message_filter (gdk_get_default_display (), + message_type, func, data); +} static void gdk_check_wm_state_changed (GdkWindow *window) @@ -298,37 +368,28 @@ gdk_check_wm_state_changed (GdkWindow *window) gulong bytes_after; Atom *atoms = NULL; gulong i; - Atom sticky_atom; - Atom maxvert_atom; - Atom maxhorz_atom; gboolean found_sticky, found_maxvert, found_maxhorz; GdkWindowState old_state; + GdkDisplay *display = GDK_WINDOW_DISPLAY (window); if (GDK_WINDOW_DESTROYED (window)) return; - if (wm_state_atom == 0) - wm_state_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE"); - - if (wm_desktop_atom == 0) - wm_desktop_atom = gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP"); + found_sticky = FALSE; + found_maxvert = FALSE; + found_maxhorz = FALSE; XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - wm_state_atom, 0, G_MAXLONG, - False, XA_ATOM, &type, &format, &nitems, + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"), + 0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems, &bytes_after, (guchar **)&atoms); if (type != None) { + Atom sticky_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY"); + Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT"); + Atom maxhorz_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ"); - sticky_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_STICKY"); - maxvert_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MAXIMIZED_VERT"); - maxhorz_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MAXIMIZED_HORZ"); - - found_sticky = FALSE; - found_maxvert = FALSE; - found_maxhorz = FALSE; - i = 0; while (i < nitems) { @@ -344,12 +405,6 @@ gdk_check_wm_state_changed (GdkWindow *window) XFree (atoms); } - else - { - found_sticky = FALSE; - found_maxvert = FALSE; - found_maxhorz = FALSE; - } /* For found_sticky to remain TRUE, we have to also be on desktop * 0xFFFFFFFF @@ -359,9 +414,12 @@ gdk_check_wm_state_changed (GdkWindow *window) { gulong *desktop; - XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - wm_desktop_atom, 0, G_MAXLONG, - False, XA_CARDINAL, &type, &format, &nitems, + XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display + (display, "_NET_WM_DESKTOP"), + 0, G_MAXLONG, False, XA_CARDINAL, &type, + &format, &nitems, &bytes_after, (guchar **)&desktop); if (type != None) @@ -425,10 +483,11 @@ generate_focus_event (GdkWindow *window, gdk_event_put (&event); } -static gint -gdk_event_translate (GdkEvent *event, - XEvent *xevent, - gboolean return_exposes) +static gboolean +gdk_event_translate (GdkDisplay *display, + GdkEvent *event, + XEvent *xevent, + gboolean return_exposes) { GdkWindow *window; @@ -440,6 +499,9 @@ gdk_event_translate (GdkEvent *event, char buf[16]; gint return_val; gint xoffset, yoffset; + GdkScreen *screen = NULL; + GdkScreenX11 *screen_x11 = NULL; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); return_val = FALSE; @@ -480,9 +542,15 @@ gdk_event_translate (GdkEvent *event, /* Find the GdkWindow that this event occurred in. */ - window = gdk_window_lookup (xevent->xany.window); + window = gdk_window_lookup_for_display (display, xevent->xany.window); window_private = (GdkWindowObject *) window; - + + if (window) + { + screen = GDK_WINDOW_SCREEN (window); + screen_x11 = GDK_SCREEN_X11 (screen); + } + if (window != NULL) { /* Window may be a pixmap, so check its type. @@ -505,7 +573,7 @@ gdk_event_translate (GdkEvent *event, xevent->xany.window = GDK_WINDOW_XID (window); break; default: - return False; + return FALSE; } } } @@ -538,11 +606,11 @@ gdk_event_translate (GdkEvent *event, } } - if (wmspec_check_window != None && - xevent->xany.window == wmspec_check_window) + if (screen_x11 && screen_x11->wmspec_check_window != None && + xevent->xany.window == screen_x11->wmspec_check_window) { if (xevent->type == DestroyNotify) - wmspec_check_window = None; + screen_x11->wmspec_check_window = None; /* Eat events on this window unless someone had wrapped * it as a foreign window @@ -555,14 +623,14 @@ gdk_event_translate (GdkEvent *event, } if (window && - _gdk_moveresize_window && (xevent->xany.type == MotionNotify || xevent->xany.type == ButtonRelease)) { - _gdk_moveresize_handle_event (xevent); - - return_val = FALSE; - goto done; + if (_gdk_moveresize_handle_event (xevent)) + { + return_val = FALSE; + goto done; + } } /* We do a "manual" conversion of the XEvent to a @@ -630,7 +698,7 @@ gdk_event_translate (GdkEvent *event, #define KEYBOARD_GROUP_SHIFT 13 #define KEYBOARD_GROUP_MASK ((1 << 13) | (1 << 14)) - event->key.group = _gdk_x11_get_group_for_state (xevent->xkey.state); + event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state); break; @@ -649,11 +717,11 @@ gdk_event_translate (GdkEvent *event, * keycode and timestamp, and if so, ignoring the event. */ - if (!_gdk_have_xkb_autorepeat && XPending (gdk_display)) + if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display)) { XEvent next_event; - XPeekEvent (gdk_display, &next_event); + XPeekEvent (xevent->xkey.display, &next_event); if (next_event.type == KeyPress && next_event.xkey.keycode == xevent->xkey.keycode && @@ -692,7 +760,7 @@ gdk_event_translate (GdkEvent *event, if (window_private == NULL || ((window_private->extension_events != 0) && - _gdk_input_ignore_core)) + display_x11->input_ignore_core)) { return_val = FALSE; break; @@ -740,7 +808,7 @@ gdk_event_translate (GdkEvent *event, event->button.button = xevent->xbutton.button; event->button.device = _gdk_core_pointer; - _gdk_event_button_generate (event); + _gdk_event_button_generate (display, event); break; } @@ -755,7 +823,7 @@ gdk_event_translate (GdkEvent *event, if (window_private == NULL || ((window_private->extension_events != 0) && - _gdk_input_ignore_core)) + display_x11->input_ignore_core)) { return_val = FALSE; break; @@ -792,7 +860,7 @@ gdk_event_translate (GdkEvent *event, if (window_private == NULL || ((window_private->extension_events != 0) && - _gdk_input_ignore_core)) + display_x11->input_ignore_core)) { return_val = FALSE; break; @@ -852,7 +920,7 @@ gdk_event_translate (GdkEvent *event, * lookup the corresponding GdkWindow. */ if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); + event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow); else event->crossing.subwindow = NULL; @@ -939,7 +1007,7 @@ gdk_event_translate (GdkEvent *event, * lookup the corresponding GdkWindow. */ if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); + event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow); else event->crossing.subwindow = NULL; @@ -1107,7 +1175,6 @@ gdk_event_translate (GdkEvent *event, else { _gdk_window_process_expose (window, xevent->xexpose.serial, &expose_rect); - return_val = FALSE; } @@ -1238,11 +1305,12 @@ gdk_event_translate (GdkEvent *event, return_val = window_private && !GDK_WINDOW_DESTROYED (window); - if (window && GDK_WINDOW_XID (window) != GDK_ROOT_WINDOW()) + if (window && GDK_WINDOW_XID (window) != screen_x11->xroot_window) gdk_window_destroy_notify (window); } else return_val = FALSE; + break; case UnmapNotify: @@ -1258,12 +1326,15 @@ gdk_event_translate (GdkEvent *event, * an unmap, it means we hid the window ourselves, so we * will have already flipped the iconified bit off. */ - if (window && GDK_WINDOW_IS_MAPPED (window)) - gdk_synthesize_window_state (window, - 0, - GDK_WINDOW_STATE_ICONIFIED); + if (window) + { + if (GDK_WINDOW_IS_MAPPED (window)) + gdk_synthesize_window_state (window, + 0, + GDK_WINDOW_STATE_ICONIFIED); - _gdk_xgrab_check_unmap (window, xevent->xany.serial); + _gdk_xgrab_check_unmap (window, xevent->xany.serial); + } break; @@ -1338,7 +1409,7 @@ gdk_event_translate (GdkEvent *event, gdk_error_trap_push (); if (XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window), - _gdk_root_window, + screen_x11->xroot_window, 0, 0, &tx, &ty, &child_window)) @@ -1365,9 +1436,8 @@ gdk_event_translate (GdkEvent *event, { window_private->resize_count -= 1; - if (window_private->resize_count == 0 && - window == _gdk_moveresize_window) - _gdk_moveresize_configure_done (); + if (window_private->resize_count == 0) + _gdk_moveresize_configure_done (display, window); } } break; @@ -1378,7 +1448,7 @@ gdk_event_translate (GdkEvent *event, xevent->xproperty.window, xevent->xproperty.atom, "\"", - gdk_x11_get_xatom_name (xevent->xproperty.atom), + gdk_x11_get_xatom_name_for_display (display, xevent->xproperty.atom), "\"")); if (window_private == NULL) @@ -1389,18 +1459,12 @@ gdk_event_translate (GdkEvent *event, event->property.type = GDK_PROPERTY_NOTIFY; event->property.window = window; - event->property.atom = gdk_x11_xatom_to_atom (xevent->xproperty.atom); + event->property.atom = gdk_x11_xatom_to_atom_for_display (display, xevent->xproperty.atom); event->property.time = xevent->xproperty.time; event->property.state = xevent->xproperty.state; - if (wm_state_atom == 0) - wm_state_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE"); - - if (wm_desktop_atom == 0) - wm_desktop_atom = gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP"); - - if (xevent->xproperty.atom == wm_state_atom || - xevent->xproperty.atom == wm_desktop_atom) + if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE") || + xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP")) { /* If window state changed, then synthesize those events. */ gdk_check_wm_state_changed (event->property.window); @@ -1417,7 +1481,7 @@ gdk_event_translate (GdkEvent *event, { event->selection.type = GDK_SELECTION_CLEAR; event->selection.window = window; - event->selection.selection = gdk_x11_xatom_to_atom (xevent->xselectionclear.selection); + event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionclear.selection); event->selection.time = xevent->xselectionclear.time; } else @@ -1432,9 +1496,9 @@ gdk_event_translate (GdkEvent *event, event->selection.type = GDK_SELECTION_REQUEST; event->selection.window = window; - event->selection.selection = gdk_x11_xatom_to_atom (xevent->xselectionrequest.selection); - event->selection.target = gdk_x11_xatom_to_atom (xevent->xselectionrequest.target); - event->selection.property = gdk_x11_xatom_to_atom (xevent->xselectionrequest.property); + event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection); + event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.target); + event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.property); event->selection.requestor = xevent->xselectionrequest.requestor; event->selection.time = xevent->xselectionrequest.time; @@ -1448,9 +1512,9 @@ gdk_event_translate (GdkEvent *event, event->selection.type = GDK_SELECTION_NOTIFY; event->selection.window = window; - event->selection.selection = gdk_x11_xatom_to_atom (xevent->xselection.selection); - event->selection.target = gdk_x11_xatom_to_atom (xevent->xselection.target); - event->selection.property = gdk_x11_xatom_to_atom (xevent->xselection.property); + event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection); + event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target); + event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property); event->selection.time = xevent->xselection.time; break; @@ -1468,13 +1532,13 @@ gdk_event_translate (GdkEvent *event, { GList *tmp_list; GdkFilterReturn result = GDK_FILTER_CONTINUE; - GdkAtom message_type = gdk_x11_xatom_to_atom (xevent->xclient.message_type); + GdkAtom message_type = gdk_x11_xatom_to_atom_for_display (display, xevent->xclient.message_type); GDK_NOTE (EVENTS, g_message ("client message:\twindow: %ld", xevent->xclient.window)); - tmp_list = client_filters; + tmp_list = display_x11->client_filters; while (tmp_list) { GdkClientFilter *filter = tmp_list->data; @@ -1523,25 +1587,26 @@ gdk_event_translate (GdkEvent *event, /* Let XLib know that there is a new keyboard mapping. */ XRefreshKeyboardMapping (&xevent->xmapping); - ++_gdk_keymap_serial; + ++display_x11->keymap_serial; return_val = FALSE; break; default: #ifdef HAVE_XKB - if (xevent->type == _gdk_xkb_event_type) + if (xevent->type == display_x11->xkb_event_type) { XkbEvent *xkb_event = (XkbEvent *)xevent; switch (xkb_event->any.xkb_type) { case XkbMapNotify: - ++_gdk_keymap_serial; + ++display_x11->keymap_serial; + return_val = FALSE; break; case XkbStateNotify: - _gdk_keymap_state_changed (); + _gdk_keymap_state_changed (display); break; } } @@ -1590,8 +1655,10 @@ gdk_wm_protocols_filter (GdkXEvent *xev, gpointer data) { XEvent *xevent = (XEvent *)xev; + GdkWindow *win = event->any.window; + GdkDisplay *display = GDK_WINDOW_DISPLAY (win); - if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW")) + if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW")) { /* The delete window request specifies a window * to delete. We don't actually destroy the @@ -1609,7 +1676,7 @@ gdk_wm_protocols_filter (GdkXEvent *xev, return GDK_FILTER_TRANSLATE; } - else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name ("WM_TAKE_FOCUS")) + else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS")) { GdkWindow *win = event->any.window; Window focus_win = GDK_WINDOW_IMPL_X11(((GdkWindowObject *)win)->impl)->focus_window; @@ -1625,46 +1692,31 @@ gdk_wm_protocols_filter (GdkXEvent *xev, XSync (GDK_WINDOW_XDISPLAY (win), False); gdk_error_trap_pop (); } - else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name ("_NET_WM_PING")) + else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING")) { XEvent xev = *xevent; - xev.xclient.window = _gdk_root_window; - XSendEvent (gdk_display, _gdk_root_window, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + xev.xclient.window = GDK_WINDOW_XROOTWIN (win); + XSendEvent (GDK_WINDOW_XDISPLAY (win), + xev.xclient.window, + False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev); } return GDK_FILTER_REMOVE; } -#if 0 -static Bool -gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg) -{ - GdkEvent event; - GdkPredicate *pred; - - if (gdk_event_translate (&event, xevent, FALSE)) - { - pred = (GdkPredicate*) arg; - return (* pred->func) (&event, pred->data); - } - - return FALSE; -} -#endif - void -_gdk_events_queue (void) +_gdk_events_queue (GdkDisplay *display) { GList *node; GdkEvent *event; XEvent xevent; + Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); - while (!_gdk_event_queue_find_first() && XPending (gdk_display)) + while (!_gdk_event_queue_find_first(display) && XPending (xdisplay)) { - XNextEvent (gdk_display, &xevent); + XNextEvent (xdisplay, &xevent); switch (xevent.type) { @@ -1684,16 +1736,15 @@ _gdk_events_queue (void) ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; - _gdk_event_queue_append (event); - node = _gdk_queued_tail; + node = _gdk_event_queue_append (display, event); - if (gdk_event_translate (event, &xevent, FALSE)) + if (gdk_event_translate (display, event, &xevent, FALSE)) { ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; } else { - _gdk_event_queue_remove_link (node); + _gdk_event_queue_remove_link (display, node); g_list_free_1 (node); gdk_event_free (event); } @@ -1704,28 +1755,31 @@ static gboolean gdk_event_prepare (GSource *source, gint *timeout) { + GdkDisplay *display = ((GdkDisplaySource*)source)->display; gboolean retval; GDK_THREADS_ENTER (); *timeout = -1; - - retval = (_gdk_event_queue_find_first () != NULL) || XPending (gdk_display); - + retval = (_gdk_event_queue_find_first (display) != NULL || + gdk_check_xpending (display)); + GDK_THREADS_LEAVE (); return retval; } static gboolean -gdk_event_check (GSource *source) +gdk_event_check (GSource *source) { + GdkDisplaySource *display_source = (GdkDisplaySource*)source; gboolean retval; - + GDK_THREADS_ENTER (); - if (event_poll_fd.revents & G_IO_IN) - retval = (_gdk_event_queue_find_first () != NULL) || XPending (gdk_display); + if (display_source->event_poll_fd.revents & G_IO_IN) + retval = (_gdk_event_queue_find_first (display_source->display) != NULL || + gdk_check_xpending (display_source->display)); else retval = FALSE; @@ -1739,12 +1793,13 @@ gdk_event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) { + GdkDisplay *display = ((GdkDisplaySource*)source)->display; GdkEvent *event; GDK_THREADS_ENTER (); - _gdk_events_queue(); - event = _gdk_event_unqueue(); + _gdk_events_queue (display); + event = _gdk_event_unqueue (display); if (event) { @@ -1759,32 +1814,69 @@ gdk_event_dispatch (GSource *source, return TRUE; } -/* Sends a ClientMessage to all toplevel client windows */ +/** + * gdk_event_send_client_message: + * @event: the #GdkEvent to send, which should be a #GdkEventClient. + * @xid: the window to send the X ClientMessage event to. + * + * Sends an X ClientMessage event to a given window (which must be + * on the default #GdkDisplay.) + * This could be used for communicating between different applications, + * though the amount of data is limited to 20 bytes. + * + * Return value: non-zero on success. + **/ gboolean gdk_event_send_client_message (GdkEvent *event, guint32 xid) { + g_return_val_if_fail (event != NULL, FALSE); + + return gdk_event_send_client_message_for_display (gdk_get_default_display (), + event, xid); +} + +/** + * gdk_event_send_client_message_for_display : + * @display : the #GdkDisplay for the window where the message is to be sent. + * @event : the #GdkEvent to send, which should be a #GdkEventClient. + * @xid : the X window to send the X ClientMessage event to. + * + * Sends an X ClientMessage event to a given window. + * + * This could be used for communicating between different applications, + * though the amount of data is limited to 20 bytes. + * + * Returns : non-zero on success. + */ +gboolean +gdk_event_send_client_message_for_display (GdkDisplay *display, + GdkEvent *event, + guint32 xid) +{ XEvent sev; g_return_val_if_fail(event != NULL, FALSE); - + /* Set up our event to send, with the exception of its target window */ sev.xclient.type = ClientMessage; - sev.xclient.display = gdk_display; + sev.xclient.display = GDK_DISPLAY_XDISPLAY (display); sev.xclient.format = event->client.data_format; sev.xclient.window = xid; - memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data)); - sev.xclient.message_type = gdk_x11_atom_to_xatom (event->client.message_type); + memcpy(&sev.xclient.data, &event->client.data, sizeof (sev.xclient.data)); + sev.xclient.message_type = gdk_x11_atom_to_xatom_for_display (display, event->client.message_type); - return gdk_send_xevent (xid, False, NoEventMask, &sev); + return _gdk_send_xevent (display, xid, False, NoEventMask, &sev); } + + /* Sends a ClientMessage to all toplevel client windows */ gboolean -gdk_event_send_client_message_to_all_recurse (XEvent *xev, - guint32 xid, - guint level) +gdk_event_send_client_message_to_all_recurse (GdkDisplay *display, + XEvent *xev, + guint32 xid, + guint level) { - static Atom wm_state_atom = None; Atom type = None; int format; unsigned long nitems, after; @@ -1795,16 +1887,15 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev, gboolean found = FALSE; gboolean result = FALSE; int i; - - if (!wm_state_atom) - wm_state_atom = gdk_x11_get_xatom_by_name ("WM_STATE"); - + gdk_error_trap_push (); - if (XGetWindowProperty (gdk_display, xid, wm_state_atom, 0, 0, False, AnyPropertyType, + if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xid, + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"), + 0, 0, False, AnyPropertyType, &type, &format, &nitems, &after, &data) != Success) goto out; - + if (type) { send = TRUE; @@ -1813,12 +1904,13 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev, else { /* OK, we're all set, now let's find some windows to send this to */ - if (!XQueryTree (gdk_display, xid, &ret_root, &ret_parent, - &ret_children, &ret_nchildren)) + if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xid, + &ret_root, &ret_parent, + &ret_children, &ret_nchildren)) goto out; for(i = 0; i < ret_nchildren; i++) - if (gdk_event_send_client_message_to_all_recurse (xev, ret_children[i], level + 1)) + if (gdk_event_send_client_message_to_all_recurse (display, xev, ret_children[i], level + 1)) found = TRUE; XFree (ret_children); @@ -1827,7 +1919,7 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev, if (send || (!found && (level == 1))) { xev->xclient.window = xid; - gdk_send_xevent (xid, False, NoEventMask, xev); + _gdk_send_xevent (display, xid, False, NoEventMask, xev); } result = send || found; @@ -1838,21 +1930,63 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev, return result; } +/** + * gdk_event_send_clientmessage_toall: + * @event: the #GdkEvent to send, which should be a #GdkEventClient. + * + * Sends an X ClientMessage event to all toplevel windows on the default + * #GdkScreen. + * + * Toplevel windows are determined by checking for the WM_STATE property, as + * described in the Inter-Client Communication Conventions Manual (ICCCM). + * If no windows are found with the WM_STATE property set, the message is sent + * to all children of the root window. + **/ void gdk_event_send_clientmessage_toall (GdkEvent *event) { + g_return_if_fail (event != NULL); + + gdk_screen_broadcast_client_message (gdk_get_default_screen (), event); +} + +/** + * gdk_screen_broadcast_client_message: + * @screen : the #GdkScreen where the event will be broadcasted. + * @event : the #GdkEvent. + * + * Sends an X ClientMessage event to all toplevel windows on @screen. + * + * Toplevel windows are determined by checking for the WM_STATE property, + * as described in the Inter-Client Communication Conventions Manual (ICCCM). + * If no windows are found with the WM_STATE property set, the message is + * sent to all children of the root window. + */ + +void +gdk_screen_broadcast_client_message (GdkScreen *screen, + GdkEvent *event) +{ XEvent sev; + GdkWindow *root_window; - g_return_if_fail(event != NULL); + g_return_if_fail (event != NULL); + + root_window = gdk_screen_get_root_window (screen); /* Set up our event to send, with the exception of its target window */ sev.xclient.type = ClientMessage; - sev.xclient.display = gdk_display; + sev.xclient.display = GDK_WINDOW_XDISPLAY (root_window); sev.xclient.format = event->client.data_format; - memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data)); - sev.xclient.message_type = gdk_x11_atom_to_xatom (event->client.message_type); - - gdk_event_send_client_message_to_all_recurse(&sev, _gdk_root_window, 0); + memcpy(&sev.xclient.data, &event->client.data, sizeof (sev.xclient.data)); + sev.xclient.message_type = + gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (root_window), + event->client.message_type); + + gdk_event_send_client_message_to_all_recurse (gdk_screen_get_display (screen), + &sev, + GDK_WINDOW_XID (root_window), + 0); } /* @@ -1876,21 +2010,27 @@ gdk_event_send_clientmessage_toall (GdkEvent *event) void gdk_flush (void) { - XSync (gdk_display, False); + GSList *tmp_list = _gdk_displays; + + while (tmp_list) + { + XSync (GDK_DISPLAY_XDISPLAY (tmp_list->data), False); + tmp_list = tmp_list->next; + } } -static Atom timestamp_prop_atom = 0; - static Bool timestamp_predicate (Display *display, XEvent *xevent, XPointer arg) { Window xwindow = GPOINTER_TO_UINT (arg); + GdkDisplay *gdk_display = gdk_x11_lookup_xdisplay (display); if (xevent->type == PropertyNotify && xevent->xproperty.window == xwindow && - xevent->xproperty.atom == timestamp_prop_atom) + xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display + (gdk_display, "GDK_TIMESTAMP_PROP")) return True; return False; @@ -1913,18 +2053,19 @@ gdk_x11_get_server_time (GdkWindow *window) Window xwindow; guchar c = 'a'; XEvent xevent; + Atom timestamp_prop_atom; g_return_val_if_fail (GDK_IS_WINDOW (window), 0); g_return_val_if_fail (!GDK_WINDOW_DESTROYED (window), 0); - if (!timestamp_prop_atom) - timestamp_prop_atom = gdk_x11_get_xatom_by_name ("GDK_TIMESTAMP_PROP"); - xdisplay = GDK_WINDOW_XDISPLAY (window); xwindow = GDK_WINDOW_XWINDOW (window); + timestamp_prop_atom = + gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "GDK_TIMESTAMP_PROP"); - XChangeProperty (xdisplay, xwindow, - timestamp_prop_atom, timestamp_prop_atom, + XChangeProperty (xdisplay, xwindow, timestamp_prop_atom, + timestamp_prop_atom, 8, PropModeReplace, &c, 1); XIfEvent (xdisplay, &xevent, @@ -1933,10 +2074,18 @@ gdk_x11_get_server_time (GdkWindow *window) return xevent.xproperty.time; } +typedef struct _NetWmSupportedAtoms NetWmSupportedAtoms; + +struct _NetWmSupportedAtoms +{ + Atom *atoms; + gulong n_atoms; +}; /** - * gdk_net_wm_supports: - * @property: a property atom + * gdk_x11_screen_supports_net_wm_hint: + * @screen : the relevant #GdkScreen. + * @property: a property atom. * * This function is specific to the X11 backend of GDK, and indicates * whether the window manager supports a certain hint from the @@ -1953,42 +2102,53 @@ gdk_x11_get_server_time (GdkWindow *window) * Return value: %TRUE if the window manager supports @property **/ gboolean -gdk_net_wm_supports (GdkAtom property) +gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen, + GdkAtom property) { - static Atom wmspec_check_atom = 0; - static Atom wmspec_supported_atom = 0; - static Atom *atoms = NULL; - static gulong n_atoms = 0; - Atom xproperty = gdk_x11_atom_to_xatom (property); Atom type; gint format; gulong nitems; gulong bytes_after; Window *xwindow; gulong i; + GdkScreenX11 *screen_x11; + NetWmSupportedAtoms *supported_atoms; + GdkDisplay *display; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE); + + screen_x11 = GDK_SCREEN_X11 (screen); + display = screen_x11->display; - if (wmspec_check_window != None) + supported_atoms = g_object_get_data (G_OBJECT (screen), "gdk-net-wm-supported-atoms"); + if (!supported_atoms) { - if (atoms == NULL) - return FALSE; + supported_atoms = g_new0 (NetWmSupportedAtoms, 1); + g_object_set_data (G_OBJECT (screen), "net-wm-supported-atoms", supported_atoms); + } + if (screen_x11->wmspec_check_window != None) + { + if (supported_atoms->atoms == NULL) + return FALSE; + i = 0; - while (i < n_atoms) + while (i < supported_atoms->n_atoms) { - if (atoms[i] == xproperty) + if (supported_atoms->atoms[i] == gdk_x11_atom_to_xatom_for_display (display, property)) return TRUE; ++i; } - + return FALSE; } - if (atoms) - XFree (atoms); + if (supported_atoms->atoms) + XFree (supported_atoms->atoms); - atoms = NULL; - n_atoms = 0; + supported_atoms->atoms = NULL; + supported_atoms->n_atoms = 0; /* This function is very slow on every call if you are not running a * spec-supporting WM. For now not optimized, because it isn't in @@ -1998,47 +2158,59 @@ gdk_net_wm_supports (GdkAtom property) * _NET_SUPPORTING_WM_CHECK only once every 10 seconds or something. */ - if (wmspec_check_atom == 0) - wmspec_check_atom = gdk_x11_get_xatom_by_name ("_NET_SUPPORTING_WM_CHECK"); - - if (wmspec_supported_atom == 0) - wmspec_supported_atom = gdk_x11_get_xatom_by_name ("_NET_SUPPORTED"); + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_x11->xroot_window, + gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"), + 0, G_MAXLONG, False, XA_WINDOW, &type, &format, + &nitems, &bytes_after, (guchar **) & xwindow); - XGetWindowProperty (gdk_display, _gdk_root_window, - wmspec_check_atom, 0, G_MAXLONG, - False, XA_WINDOW, &type, &format, &nitems, - &bytes_after, (guchar **)&xwindow); - if (type != XA_WINDOW) return FALSE; gdk_error_trap_push (); /* Find out if this WM goes away, so we can reset everything. */ - XSelectInput (gdk_display, *xwindow, - StructureNotifyMask); - - gdk_flush (); + XSelectInput (screen_x11->xdisplay, *xwindow, StructureNotifyMask); + + gdk_display_sync (screen_x11->display); if (gdk_error_trap_pop ()) { XFree (xwindow); return FALSE; } - - XGetWindowProperty (gdk_display, _gdk_root_window, - wmspec_supported_atom, 0, G_MAXLONG, - False, XA_ATOM, &type, &format, &n_atoms, - &bytes_after, (guchar **)&atoms); + + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_x11->xroot_window, + gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTED"), + 0, G_MAXLONG, False, XA_ATOM, &type, &format, + &supported_atoms->n_atoms, &bytes_after, + (guchar **)&supported_atoms->atoms); if (type != XA_ATOM) return FALSE; - wmspec_check_window = *xwindow; + screen_x11->wmspec_check_window = *xwindow; XFree (xwindow); /* since wmspec_check_window != None this isn't infinite. ;-) */ - return gdk_net_wm_supports (property); + return gdk_x11_screen_supports_net_wm_hint (screen, property); +} + +/** + * gdk_net_wm_supports: + * @screen : the relevant #GdkScreen. + * @property: a property atom. + * + * This function is specific to the X11 backend of GDK, and indicates + * whether the window manager for the default screen supports a certain + * hint from the Extended Window Manager Hints Specification. See + * gdk_x11_screen_supports_net_wm_hint() for complete details. + * + * Return value: %TRUE if the window manager supports @property + **/ +gboolean +gdk_net_wm_supports (GdkAtom property) +{ + return gdk_x11_screen_supports_net_wm_hint (gdk_get_default_screen (), property); } static struct @@ -2060,16 +2232,17 @@ static struct }; static void -gdk_xsettings_notify_cb (const char *name, - XSettingsAction action, - XSettingsSetting *setting, - void *data) +gdk_xsettings_notify_cb (const char *name, + XSettingsAction action, + XSettingsSetting *setting, + void *data) { GdkEvent new_event; + GdkScreen *screen = data; int i; new_event.type = GDK_SETTING; - new_event.setting.window = NULL; + new_event.setting.window = gdk_screen_get_root_window (screen); new_event.setting.send_event = FALSE; new_event.setting.name = NULL; @@ -2116,16 +2289,56 @@ check_transform (const gchar *xsettings_name, return TRUE; } +/** + * gdk_setting_get: + * @name: the name of the setting. + * @value: location to store the value of the setting. + * + * Obtains a desktop-wide setting, such as the double-click time, + * for the default screen. See gdk_screen_get_setting(). + * + * Returns : %TRUE if the setting existed and a value was stored + * in @value, %FALSE otherwise. + **/ gboolean gdk_setting_get (const gchar *name, GValue *value) { + return gdk_screen_get_setting (gdk_get_default_screen (), name, value); +} + +/** + * gdk_screen_get_setting: + * @screen: the #GdkScreen where the setting is located + * @name: the name of the setting + * @value: location to store the value of the setting + * + * Retrieves a desktop-wide setting such as double-click time + * for the #GdkScreen @screen. + * + * FIXME needs a list of valid settings here, or a link to + * more information. + * + * Returns : %TRUE if the setting existed and a value was stored + * in @value, %FALSE otherwise. + **/ +gboolean +gdk_screen_get_setting (GdkScreen *screen, + const gchar *name, + GValue *value) +{ + const char *xsettings_name = NULL; XSettingsResult result; XSettingsSetting *setting; + GdkScreenX11 *screen_x11; gboolean success = FALSE; gint i; GValue tmp_val = { 0, }; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE); + + screen_x11 = GDK_SCREEN_X11 (screen); for (i = 0; i < G_N_ELEMENTS (settings_map) ; i++) if (strcmp (settings_map[i].gdk_name, name) == 0) @@ -2137,7 +2350,8 @@ gdk_setting_get (const gchar *name, if (!xsettings_name) return FALSE; - result = xsettings_client_get_setting (xsettings_client, xsettings_name, &setting); + result = xsettings_client_get_setting (screen_x11->xsettings_client, + xsettings_name, &setting); if (result != XSETTINGS_SUCCESS) return FALSE; @@ -2196,23 +2410,27 @@ gdk_xsettings_client_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) { - if (xsettings_client_process_event (xsettings_client, (XEvent *)xevent)) + GdkScreenX11 *screen = data; + + if (xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent)) return GDK_FILTER_REMOVE; else return GDK_FILTER_CONTINUE; } static void -gdk_xsettings_watch_cb (Window window, - Bool is_start, - long mask, - void *cb_data) +gdk_xsettings_watch_cb (Window window, + Bool is_start, + long mask, + void *cb_data) { GdkWindow *gdkwin; + GdkScreen *screen = cb_data; - gdkwin = gdk_window_lookup (window); + gdkwin = gdk_window_lookup_for_display (gdk_screen_get_display (screen), window); + if (is_start) - gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, NULL); + gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, screen); else - gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, NULL); + gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen); } diff --git a/gdk/x11/gdkfont-x11.c b/gdk/x11/gdkfont-x11.c index 420a6c6e3..825934e8d 100644 --- a/gdk/x11/gdkfont-x11.c +++ b/gdk/x11/gdkfont-x11.c @@ -30,8 +30,12 @@ #include <pango/pangox.h> +#include "gdkx.h" #include "gdkfont.h" #include "gdkprivate-x11.h" +#include "gdkinternals.h" +#include "gdkdisplay-x11.h" +#include "gdkscreen-x11.h" typedef struct _GdkFontPrivateX GdkFontPrivateX; @@ -41,35 +45,86 @@ struct _GdkFontPrivateX /* XFontStruct *xfont; */ /* generic pointer point to XFontStruct or XFontSet */ gpointer xfont; - Display *xdisplay; + GdkDisplay *display; GSList *names; }; -static GHashTable *font_name_hash = NULL; -static GHashTable *fontset_name_hash = NULL; +static GHashTable * +gdk_font_name_hash_get (GdkDisplay *display) +{ + GHashTable *result; + static GQuark font_name_quark = 0; + + if (!font_name_quark) + font_name_quark = g_quark_from_static_string ("gdk-font-hash"); + + result = g_object_get_qdata (G_OBJECT (display), font_name_quark); + + if (!result) + { + result = g_hash_table_new (g_str_hash, g_str_equal); + g_object_set_qdata (G_OBJECT (display), font_name_quark, result); + } + + return result; +} + +static GHashTable * +gdk_fontset_name_hash_get (GdkDisplay *display) +{ + GHashTable *result; + static GQuark fontset_name_quark = 0; + + if (!fontset_name_quark) + fontset_name_quark = g_quark_from_static_string ("gdk-fontset-hash"); + + result = g_object_get_qdata (G_OBJECT (display), fontset_name_quark); + + if (!result) + { + result = g_hash_table_new (g_str_hash, g_str_equal); + g_object_set_qdata (G_OBJECT (display), fontset_name_quark, result); + } + + return result; +} + +/** + * gdk_font_get_display: + * @font: the #GdkFont. + * + * Returns the #GdkDisplay for @font. + * + * Returns : the corresponding #GdkDisplay. + **/ +GdkDisplay* +gdk_font_get_display (GdkFont* font) +{ + return ((GdkFontPrivateX *)font)->display; +} static void -gdk_font_hash_insert (GdkFontType type, GdkFont *font, const gchar *font_name) +gdk_font_hash_insert (GdkFontType type, + GdkFont *font, + const gchar *font_name) { GdkFontPrivateX *private = (GdkFontPrivateX *)font; - GHashTable **hashp = (type == GDK_FONT_FONT) ? - &font_name_hash : &fontset_name_hash; - - if (!*hashp) - *hashp = g_hash_table_new (g_str_hash, g_str_equal); + GHashTable *hash = (type == GDK_FONT_FONT) ? + gdk_font_name_hash_get (private->display) : gdk_fontset_name_hash_get (private->display); private->names = g_slist_prepend (private->names, g_strdup (font_name)); - g_hash_table_insert (*hashp, private->names->data, font); + g_hash_table_insert (hash, private->names->data, font); } static void -gdk_font_hash_remove (GdkFontType type, GdkFont *font) +gdk_font_hash_remove (GdkFontType type, + GdkFont *font) { GdkFontPrivateX *private = (GdkFontPrivateX *)font; GSList *tmp_list; GHashTable *hash = (type == GDK_FONT_FONT) ? - font_name_hash : fontset_name_hash; + gdk_font_name_hash_get (private->display) : gdk_fontset_name_hash_get (private->display); tmp_list = private->names; while (tmp_list) @@ -85,12 +140,16 @@ gdk_font_hash_remove (GdkFontType type, GdkFont *font) } static GdkFont * -gdk_font_hash_lookup (GdkFontType type, const gchar *font_name) +gdk_font_hash_lookup (GdkDisplay *display, + GdkFontType type, + const gchar *font_name) { GdkFont *result; - GHashTable *hash = (type == GDK_FONT_FONT) ? - font_name_hash : fontset_name_hash; + GHashTable *hash; + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + hash = (type == GDK_FONT_FONT) ? gdk_font_name_hash_get (display) : + gdk_fontset_name_hash_get (display); if (!hash) return NULL; else @@ -103,36 +162,38 @@ gdk_font_hash_lookup (GdkFontType type, const gchar *font_name) } } -GdkFont* -gdk_font_load (const gchar *font_name) +GdkFont * +gdk_font_load_for_display (GdkDisplay *display, + const gchar *font_name) { GdkFont *font; GdkFontPrivateX *private; XFontStruct *xfont; + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); g_return_val_if_fail (font_name != NULL, NULL); - - font = gdk_font_hash_lookup (GDK_FONT_FONT, font_name); + + font = gdk_font_hash_lookup (display, GDK_FONT_FONT, font_name); if (font) return font; - xfont = XLoadQueryFont (gdk_display, font_name); + xfont = XLoadQueryFont (GDK_DISPLAY_XDISPLAY (display), font_name); if (xfont == NULL) return NULL; - font = gdk_font_lookup (xfont->fid); - if (font != NULL) + font = gdk_font_lookup_for_display (display, xfont->fid); + if (font != NULL) { private = (GdkFontPrivateX *) font; if (xfont != private->xfont) - XFreeFont (gdk_display, xfont); + XFreeFont (GDK_DISPLAY_XDISPLAY (display), xfont); gdk_font_ref (font); } else { private = g_new (GdkFontPrivateX, 1); - private->xdisplay = gdk_display; + private->display = display; private->xfont = xfont; private->base.ref_count = 1; private->names = NULL; @@ -141,8 +202,8 @@ gdk_font_load (const gchar *font_name) font->type = GDK_FONT_FONT; font->ascent = xfont->ascent; font->descent = xfont->descent; - - gdk_xid_table_insert (&xfont->fid, font); + + _gdk_xid_table_insert (display, &xfont->fid, font); } gdk_font_hash_insert (GDK_FONT_FONT, font, font_name); @@ -150,6 +211,12 @@ gdk_font_load (const gchar *font_name) return font; } +GdkFont* +gdk_font_load (const gchar *font_name) +{ + return gdk_font_load_for_display (gdk_get_default_display(), font_name); +} + static char * gdk_font_charset_for_locale (void) { @@ -187,29 +254,18 @@ gdk_font_charset_for_locale (void) return g_strdup ("iso8859-1"); }; -/** - * gdk_font_from_description: - * @font_desc: a #PangoFontDescription. - * - * Load a #GdkFont based on a Pango font description. This font will - * only be an approximation of the Pango font, and - * internationalization will not be handled correctly. This function - * should only be used for legacy code that cannot be easily converted - * to use Pango. Using Pango directly will produce better results. - * - * Return value: the newly loaded font, or %NULL if the font - * cannot be loaded. - **/ -GdkFont* -gdk_font_from_description (PangoFontDescription *font_desc) +GdkFont * +gdk_font_from_description_for_display (GdkDisplay *display, + PangoFontDescription *font_desc) { PangoFontMap *font_map; PangoFont *font; GdkFont *result = NULL; + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); g_return_val_if_fail (font_desc != NULL, NULL); - font_map = pango_x_font_map_for_display (GDK_DISPLAY ()); + font_map = pango_x_font_map_for_display (GDK_DISPLAY_XDISPLAY (display)); font = pango_font_map_load_font (font_map, NULL, font_desc); if (font) @@ -224,12 +280,13 @@ gdk_font_from_description (PangoFontDescription *font_desc) if (n_subfonts > 0) { gchar *xlfd = pango_x_font_subfont_xlfd (font, subfont_ids[0]); - result = gdk_font_load (xlfd); + result = gdk_font_load_for_display (display, xlfd); g_free (xlfd); } g_free (subfont_ids); + g_free (subfont_charsets); g_free (charset); @@ -239,8 +296,28 @@ gdk_font_from_description (PangoFontDescription *font_desc) return result; } +/** + * gdk_font_from_description: + * @font_desc: a #PangoFontDescription. + * + * Load a #GdkFont based on a Pango font description. This font will + * only be an approximation of the Pango font, and + * internationalization will not be handled correctly. This function + * should only be used for legacy code that cannot be easily converted + * to use Pango. Using Pango directly will produce better results. + * + * Return value: the newly loaded font, or %NULL if the font + * cannot be loaded. + **/ GdkFont* -gdk_fontset_load (const gchar *fontset_name) +gdk_font_from_description (PangoFontDescription *font_desc) +{ + return gdk_font_from_description_for_display (gdk_get_default_display (),font_desc); +} + +GdkFont * +gdk_fontset_load_for_display (GdkDisplay *display, + const gchar *fontset_name) { GdkFont *font; GdkFontPrivateX *private; @@ -249,15 +326,17 @@ gdk_fontset_load (const gchar *fontset_name) gchar **missing_charset_list; gchar *def_string; - font = gdk_font_hash_lookup (GDK_FONT_FONTSET, fontset_name); + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + font = gdk_font_hash_lookup (display, GDK_FONT_FONTSET, fontset_name); if (font) return font; private = g_new (GdkFontPrivateX, 1); font = (GdkFont*) private; - private->xdisplay = gdk_display; - fontset = XCreateFontSet (gdk_display, fontset_name, + private->display = display; + fontset = XCreateFontSet (GDK_DISPLAY_XDISPLAY (display), fontset_name, &missing_charset_list, &missing_charset_count, &def_string); @@ -297,7 +376,7 @@ gdk_fontset_load (const gchar *fontset_name) font->ascent = MAX (font->ascent, font_structs[i]->ascent); font->descent = MAX (font->descent, font_structs[i]->descent); } - + private->names = NULL; gdk_font_hash_insert (GDK_FONT_FONTSET, font, fontset_name); @@ -305,6 +384,12 @@ gdk_fontset_load (const gchar *fontset_name) } } +GdkFont* +gdk_fontset_load (const gchar *fontset_name) +{ + return gdk_fontset_load_for_display (gdk_get_default_display (), fontset_name); +} + void _gdk_font_destroy (GdkFont *font) { @@ -315,11 +400,13 @@ _gdk_font_destroy (GdkFont *font) switch (font->type) { case GDK_FONT_FONT: - gdk_xid_table_remove (((XFontStruct *) private->xfont)->fid); - XFreeFont (private->xdisplay, (XFontStruct *) private->xfont); + _gdk_xid_table_remove (private->display, ((XFontStruct *) private->xfont)->fid); + XFreeFont (GDK_DISPLAY_XDISPLAY (private->display), + (XFontStruct *) private->xfont); break; case GDK_FONT_FONTSET: - XFreeFontSet (private->xdisplay, (XFontSet) private->xfont); + XFreeFontSet (GDK_DISPLAY_XDISPLAY (private->display), + (XFontSet) private->xfont); break; default: g_error ("unknown font type."); @@ -670,7 +757,7 @@ gdk_x11_font_get_xdisplay (GdkFont *font) { g_return_val_if_fail (font != NULL, NULL); - return ((GdkFontPrivateX *)font)->xdisplay; + return GDK_DISPLAY_XDISPLAY (((GdkFontPrivateX *)font)->display); } gpointer diff --git a/gdk/x11/gdkgc-x11.c b/gdk/x11/gdkgc-x11.c index 3605718e1..8367a650a 100644 --- a/gdk/x11/gdkgc-x11.c +++ b/gdk/x11/gdkgc-x11.c @@ -29,6 +29,7 @@ #include "gdkgc.h" #include "gdkprivate-x11.h" #include "gdkregion-generic.h" +#include "gdkx.h" #include <string.h> @@ -110,7 +111,7 @@ gdk_gc_x11_finalize (GObject *object) #if HAVE_XFT if (x11_gc->fg_picture != None) - XRenderFreePicture (x11_gc->xdisplay, x11_gc->fg_picture); + XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), x11_gc->fg_picture); #endif XFreeGC (GDK_GC_XDISPLAY (x11_gc), GDK_GC_XGC (x11_gc)); @@ -141,7 +142,7 @@ _gdk_x11_gc_new (GdkDrawable *drawable, private->dirty_mask = 0; private->clip_region = NULL; - private->xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay; + private->screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen; if (values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN)) { @@ -230,7 +231,8 @@ gdk_x11_gc_get_values (GdkGC *gc, { values->foreground.pixel = xvalues.foreground; values->background.pixel = xvalues.background; - values->font = gdk_font_lookup (xvalues.font); + values->font = gdk_font_lookup_for_display (GDK_GC_DISPLAY (gc), + xvalues.font); switch (xvalues.function) { @@ -300,8 +302,10 @@ gdk_x11_gc_get_values (GdkGC *gc, break; } - values->tile = gdk_pixmap_lookup (xvalues.tile); - values->stipple = gdk_pixmap_lookup (xvalues.stipple); + values->tile = gdk_pixmap_lookup_for_display (GDK_GC_DISPLAY (gc), + xvalues.tile); + values->stipple = gdk_pixmap_lookup_for_display (GDK_GC_DISPLAY (gc), + xvalues.stipple); values->clip_mask = NULL; values->subwindow_mode = xvalues.subwindow_mode; values->ts_x_origin = xvalues.ts_x_origin; @@ -731,12 +735,28 @@ gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc) x11_dst_gc->fg_pixel = x11_src_gc->fg_pixel; } +/** + * gdk_gc_get_screen: + * @gc: a #GdkGC. + * + * Gets the #GdkScreen for which @gc was created + * + * Returns: the #GdkScreen for @gc. + */ +GdkScreen * +gdk_gc_get_screen (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC_X11 (gc), NULL); + + return GDK_GC_X11 (gc)->screen; +} + Display * gdk_x11_gc_get_xdisplay (GdkGC *gc) { g_return_val_if_fail (GDK_IS_GC_X11 (gc), NULL); - return GDK_GC_X11(gc)->xdisplay; + return GDK_SCREEN_XDISPLAY (gdk_gc_get_screen (gc)); } GC @@ -804,7 +824,7 @@ _gdk_x11_gc_get_fg_picture (GdkGC *gc) g_return_val_if_fail (GDK_IS_GC_X11 (gc), None); - if (!_gdk_x11_have_render ()) + if (!_gdk_x11_have_render (GDK_GC_DISPLAY (gc))) return None; x11_gc = GDK_GC_X11 (gc); @@ -818,14 +838,15 @@ _gdk_x11_gc_get_fg_picture (GdkGC *gc) if (!pix_format) return None; - pix = XCreatePixmap (x11_gc->xdisplay, _gdk_root_window, + pix = XCreatePixmap (GDK_GC_XDISPLAY (gc), + GDK_SCREEN_XROOTWIN (x11_gc->screen), 1, 1, pix_format->depth); pa.repeat = True; - x11_gc->fg_picture = XRenderCreatePicture (x11_gc->xdisplay, + x11_gc->fg_picture = XRenderCreatePicture (GDK_GC_XDISPLAY (gc), pix, pix_format, CPRepeat, &pa); - XFreePixmap (x11_gc->xdisplay, pix); + XFreePixmap (GDK_GC_XDISPLAY (gc), pix); new = TRUE; } @@ -842,7 +863,7 @@ _gdk_x11_gc_get_fg_picture (GdkGC *gc) x11_gc->fg_picture_color.blue = color.blue; x11_gc->fg_picture_color.alpha = 0xffff; - XRenderFillRectangle (x11_gc->xdisplay, PictOpSrc, + XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc, x11_gc->fg_picture, &x11_gc->fg_picture_color, 0, 0, 1, 1); } diff --git a/gdk/x11/gdkgeometry-x11.c b/gdk/x11/gdkgeometry-x11.c index 7859c8633..87ad93dcf 100644 --- a/gdk/x11/gdkgeometry-x11.c +++ b/gdk/x11/gdkgeometry-x11.c @@ -134,6 +134,8 @@ #include "gdkx.h" #include "gdkregion.h" #include "gdkinternals.h" +#include "gdkscreen-x11.h" +#include "gdkdisplay-x11.h" typedef struct _GdkWindowQueueItem GdkWindowQueueItem; typedef struct _GdkWindowParentPos GdkWindowParentPos; @@ -186,8 +188,6 @@ static void gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle *new_clip); -static GQueue *translate_queue = NULL; - void _gdk_windowing_window_get_offsets (GdkWindow *window, gint *x_offset, @@ -915,17 +915,19 @@ static void gdk_window_queue (GdkWindow *window, GdkWindowQueueItem *item) { - if (!translate_queue) - translate_queue = g_queue_new (); + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); + + if (!display_x11->translate_queue) + display_x11->translate_queue = g_queue_new (); /* Keep length of queue finite by, if it grows too long, * figuring out the latest relevant serial and discarding * irrelevant queue items. */ - if (translate_queue->length >= 64 ) + if (display_x11->translate_queue->length >= 64) { gulong serial = find_current_serial (GDK_WINDOW_XDISPLAY (window)); - GList *tmp_list = translate_queue->head; + GList *tmp_list = display_x11->translate_queue->head; while (tmp_list) { @@ -934,7 +936,7 @@ gdk_window_queue (GdkWindow *window, if (serial > item->serial) { - queue_delete_link (translate_queue, tmp_list); + queue_delete_link (display_x11->translate_queue, tmp_list); queue_item_free (item); } @@ -948,9 +950,9 @@ gdk_window_queue (GdkWindow *window, * discard anti-expose items. (We can't discard translate * items */ - if (translate_queue->length >= 64 ) + if (display_x11->translate_queue->length >= 64) { - GList *tmp_list = translate_queue->head; + GList *tmp_list = display_x11->translate_queue->head; while (tmp_list) { @@ -959,7 +961,7 @@ gdk_window_queue (GdkWindow *window, if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE) { - queue_delete_link (translate_queue, tmp_list); + queue_delete_link (display_x11->translate_queue, tmp_list); queue_item_free (item); } @@ -972,7 +974,7 @@ gdk_window_queue (GdkWindow *window, item->window = window; item->serial = NextRequest (GDK_WINDOW_XDISPLAY (window)); - g_queue_push_tail (translate_queue, item); + g_queue_push_tail (display_x11->translate_queue, item); } static void @@ -1009,12 +1011,12 @@ _gdk_window_process_expose (GdkWindow *window, GdkWindowImplX11 *impl; GdkRegion *invalidate_region = gdk_region_rectangle (area); GdkRegion *clip_region; - + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); impl = GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl); - if (translate_queue) + if (display_x11->translate_queue) { - GList *tmp_list = translate_queue->head; + GList *tmp_list = display_x11->translate_queue->head; while (tmp_list) { @@ -1033,7 +1035,8 @@ _gdk_window_process_expose (GdkWindow *window, } else { - queue_delete_link (translate_queue, translate_queue->head); + queue_delete_link (display_x11->translate_queue, + display_x11->translate_queue->head); queue_item_free (item); } } diff --git a/gdk/x11/gdkglobals-x11.c b/gdk/x11/gdkglobals-x11.c index 2efdaca07..7dd2a468a 100644 --- a/gdk/x11/gdkglobals-x11.c +++ b/gdk/x11/gdkglobals-x11.c @@ -28,17 +28,8 @@ #include "gdktypes.h" #include "gdkprivate-x11.h" -#include "config.h" -gboolean _gdk_use_xshm = TRUE; -gchar *_gdk_display_name = NULL; +gboolean _gdk_use_xshm = TRUE; /* used as a cmd line arg */ Display *gdk_display = NULL; -gint _gdk_screen; -Window _gdk_root_window; -Window _gdk_leader_window; -Atom _gdk_wm_window_protocols[3]; GdkAtom _gdk_selection_property; - -GdkWindowObject *_gdk_xgrab_window = NULL; /* Window that currently holds the - * x pointer grab - */ +gboolean _gdk_synchronize = FALSE; diff --git a/gdk/x11/gdkim-x11.c b/gdk/x11/gdkim-x11.c index 4a8f421a1..187e75621 100644 --- a/gdk/x11/gdkim-x11.c +++ b/gdk/x11/gdkim-x11.c @@ -27,10 +27,12 @@ #include <locale.h> #include <stdlib.h> +#include "gdkx.h" #include "gdk.h" /* For gdk_flush() */ +#include "gdkx.h" #include "gdkpixmap.h" #include "gdkinternals.h" -#include "gdkprivate-x11.h" +#include "gdkdisplay-x11.h" #if HAVE_CONFIG_H # include <config.h> @@ -108,6 +110,17 @@ gdk_set_locale (void) return setlocale (LC_ALL, NULL); } +static GdkDisplay * +find_a_display () +{ + GdkDisplay *display = gdk_get_default_display (); + + if (!display) + display = _gdk_displays->data; + + return display; +} + /* * gdk_wcstombs * @@ -123,6 +136,8 @@ gdk_wcstombs (const GdkWChar *src) if (gdk_use_mb) { + GdkDisplay *display = find_a_display (); + Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); XTextProperty tpr; if (sizeof(wchar_t) != sizeof(GdkWChar)) @@ -133,7 +148,7 @@ gdk_wcstombs (const GdkWChar *src) src_alt = g_new (wchar_t, i+1); for (; i>=0; i--) src_alt[i] = src[i]; - if (XwcTextListToTextProperty (gdk_display, &src_alt, 1, XTextStyle, &tpr) + if (XwcTextListToTextProperty (xdisplay, &src_alt, 1, XTextStyle, &tpr) != Success) { g_free (src_alt); @@ -143,7 +158,7 @@ gdk_wcstombs (const GdkWChar *src) } else { - if (XwcTextListToTextProperty (gdk_display, (wchar_t**)&src, 1, + if (XwcTextListToTextProperty (xdisplay, (wchar_t**)&src, 1, XTextStyle, &tpr) != Success) { return NULL; @@ -185,18 +200,20 @@ gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max) { if (gdk_use_mb) { + GdkDisplay *display = find_a_display (); + Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); XTextProperty tpr; wchar_t **wstrs, *wstr_src; gint num_wstrs; gint len_cpy; - if (XmbTextListToTextProperty (gdk_display, (char **)&src, 1, XTextStyle, + if (XmbTextListToTextProperty (xdisplay, (char **)&src, 1, XTextStyle, &tpr) != Success) { /* NoMem or LocaleNotSupp */ return -1; } - if (XwcTextPropertyToTextList (gdk_display, &tpr, &wstrs, &num_wstrs) + if (XwcTextPropertyToTextList (xdisplay, &tpr, &wstrs, &num_wstrs) != Success) { /* InvalidChar */ diff --git a/gdk/x11/gdkimage-x11.c b/gdk/x11/gdkimage-x11.c index 8b3bf6036..a813d27fa 100644 --- a/gdk/x11/gdkimage-x11.c +++ b/gdk/x11/gdkimage-x11.c @@ -48,23 +48,25 @@ #include <errno.h> #include "gdk.h" /* For gdk_error_trap_* / gdk_flush_* */ +#include "gdkx.h" #include "gdkimage.h" #include "gdkprivate.h" #include "gdkprivate-x11.h" +#include "gdkdisplay-x11.h" +#include "gdkscreen-x11.h" typedef struct _GdkImagePrivateX11 GdkImagePrivateX11; struct _GdkImagePrivateX11 { XImage *ximage; - Display *xdisplay; + GdkScreen *screen; gpointer x_shm_info; Pixmap shm_pixmap; }; static GList *image_list = NULL; static gpointer parent_class = NULL; -static gboolean have_shm_pixmaps; static void gdk_x11_image_destroy (GdkImage *image); static void gdk_image_init (GdkImage *image); @@ -151,7 +153,7 @@ gdk_image_new_bitmap(GdkVisual *visual, gpointer data, gint w, gint h) GdkImagePrivateX11 *private; image = g_object_new (gdk_image_get_type (), NULL); private = PRIVATE_DATA (image); - private->xdisplay = gdk_display; + private->screen = visual->screen; image->type = GDK_IMAGE_NORMAL; image->visual = visual; image->width = w; @@ -159,8 +161,9 @@ gdk_image_new_bitmap(GdkVisual *visual, gpointer data, gint w, gint h) image->depth = 1; image->bits_per_pixel = 1; xvisual = ((GdkVisualPrivate*) visual)->xvisual; - private->ximage = XCreateImage(private->xdisplay, xvisual, 1, XYBitmap, - 0, 0, w ,h, 8, 0); + private->ximage = XCreateImage (GDK_SCREEN_XDISPLAY (visual->screen), + xvisual, 1, XYBitmap, + 0, 0, w ,h, 8, 0); private->ximage->data = data; private->ximage->bitmap_bit_order = MSBFirst; private->ximage->byte_order = MSBFirst; @@ -196,21 +199,24 @@ gdk_image_check_xshm(Display *display) } void -_gdk_windowing_image_init (void) +_gdk_windowing_image_init (GdkDisplay *display) { - if (_gdk_use_xshm) + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + + if (display_x11->use_xshm) { - gint res = gdk_image_check_xshm (gdk_display); - + gint res = gdk_image_check_xshm (GDK_DISPLAY_XDISPLAY (display)); + if (!res) - _gdk_use_xshm = FALSE; - else - have_shm_pixmaps = (res == 2); + display_x11->use_xshm = False; + else + display_x11->have_shm_pixmaps = (res == 2); } } GdkImage* -_gdk_image_new_for_depth (GdkImageType type, +_gdk_image_new_for_depth (GdkScreen *screen, + GdkImageType type, GdkVisual *visual, gint width, gint height, @@ -222,20 +228,27 @@ _gdk_image_new_for_depth (GdkImageType type, XShmSegmentInfo *x_shm_info; #endif /* USE_SHM */ Visual *xvisual = NULL; + GdkDisplayX11 *display_x11; + GdkScreenX11 *screen_x11; g_return_val_if_fail (!visual || GDK_IS_VISUAL (visual), NULL); g_return_val_if_fail (visual || depth != -1, NULL); - + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + screen_x11 = GDK_SCREEN_X11 (screen); + display_x11 = GDK_DISPLAY_X11 (screen_x11->display); + if (visual) depth = visual->depth; switch (type) { case GDK_IMAGE_FASTEST: - image = _gdk_image_new_for_depth (GDK_IMAGE_SHARED, visual, width, height, depth); - + image = _gdk_image_new_for_depth (screen, GDK_IMAGE_SHARED, + visual, width, height, depth); if (!image) - image = _gdk_image_new_for_depth (GDK_IMAGE_NORMAL, visual, width, height, depth); + image = _gdk_image_new_for_depth (screen, GDK_IMAGE_NORMAL, + visual, width, height, depth); break; default: @@ -243,7 +256,7 @@ _gdk_image_new_for_depth (GdkImageType type, private = PRIVATE_DATA (image); - private->xdisplay = gdk_display; + private->screen = screen; image->type = type; image->visual = visual; @@ -258,20 +271,20 @@ _gdk_image_new_for_depth (GdkImageType type, { case GDK_IMAGE_SHARED: #ifdef USE_SHM - if (_gdk_use_xshm) + if (display_x11->use_xshm) { private->x_shm_info = g_new (XShmSegmentInfo, 1); x_shm_info = private->x_shm_info; x_shm_info->shmid = -1; x_shm_info->shmaddr = (char*) -1; - private->ximage = XShmCreateImage (private->xdisplay, xvisual, depth, + private->ximage = XShmCreateImage (screen_x11->xdisplay, xvisual, depth, ZPixmap, NULL, x_shm_info, width, height); if (private->ximage == NULL) { g_warning ("XShmCreateImage failed"); - _gdk_use_xshm = FALSE; - + display_x11->use_xshm = FALSE; + goto error; } @@ -289,7 +302,7 @@ _gdk_image_new_for_depth (GdkImageType type, if (errno != EINVAL) { g_warning ("shmget failed: error %d (%s)", errno, g_strerror (errno)); - _gdk_use_xshm = FALSE; + display_x11->use_xshm = FALSE; } goto error; @@ -306,19 +319,19 @@ _gdk_image_new_for_depth (GdkImageType type, * EMFILE, which would mean that we've exceeded the per-process * Shm segment limit. */ - _gdk_use_xshm = FALSE; + display_x11->use_xshm = FALSE; goto error; } gdk_error_trap_push (); - XShmAttach (private->xdisplay, x_shm_info); - XSync (private->xdisplay, False); + XShmAttach (screen_x11->xdisplay, x_shm_info); + XSync (screen_x11->xdisplay, False); if (gdk_error_trap_pop ()) { /* this is the common failure case so omit warning */ - _gdk_use_xshm = FALSE; + display_x11->use_xshm = FALSE; goto error; } @@ -338,7 +351,7 @@ _gdk_image_new_for_depth (GdkImageType type, goto error; break; case GDK_IMAGE_NORMAL: - private->ximage = XCreateImage (private->xdisplay, xvisual, depth, + private->ximage = XCreateImage (screen_x11->xdisplay, xvisual, depth, ZPixmap, 0, 0, width, height, 32, 0); /* Use malloc, not g_malloc here, because X will call free() @@ -395,13 +408,17 @@ Pixmap _gdk_x11_image_get_shm_pixmap (GdkImage *image) { GdkImagePrivateX11 *private = PRIVATE_DATA (image); + GdkDisplay *display = GDK_SCREEN_DISPLAY (private->screen); #ifdef USE_SHM /* Future: do we need one of these per-screen per-image? ShmPixmaps - * are the same for every screen, but can they be shared? + * are the same for every screen, but can they be shared? Not a concern + * right now since we tie images to a particular screen. */ - if (!private->shm_pixmap && image->type == GDK_IMAGE_SHARED && have_shm_pixmaps) - private->shm_pixmap = XShmCreatePixmap (private->xdisplay, _gdk_root_window, + if (!private->shm_pixmap && image->type == GDK_IMAGE_SHARED && + GDK_DISPLAY_X11 (display)->have_shm_pixmaps) + private->shm_pixmap = XShmCreatePixmap (GDK_SCREEN_XDISPLAY (private->screen), + GDK_SCREEN_XROOTWIN (private->screen), image->mem, private->x_shm_info, image->width, image->height, image->depth); @@ -417,7 +434,8 @@ gdk_image_new (GdkImageType type, gint width, gint height) { - return _gdk_image_new_for_depth (type, visual, width, height, -1); + return _gdk_image_new_for_depth (visual->screen, type, + visual, width, height, -1); } static GdkImage* @@ -434,7 +452,7 @@ get_full_image (GdkDrawable *drawable, impl = GDK_DRAWABLE_IMPL_X11 (drawable); - ximage = XGetImage (impl->xdisplay, + ximage = XGetImage (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, src_x, src_y, width, height, AllPlanes, ZPixmap); @@ -446,7 +464,7 @@ get_full_image (GdkDrawable *drawable, private = PRIVATE_DATA (image); - private->xdisplay = gdk_display; + private->screen = impl->screen; private->ximage = ximage; image->type = GDK_IMAGE_NORMAL; @@ -491,11 +509,11 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable, have_grab = FALSE; -#define UNGRAB() G_STMT_START { \ - if (have_grab) { \ - gdk_x11_ungrab_server (); \ - XFlush (impl->xdisplay); \ - have_grab = FALSE; } \ +#define UNGRAB() G_STMT_START { \ + if (have_grab) { \ + gdk_x11_display_ungrab (GDK_DRAWABLE_DISPLAY (drawable)); \ + XFlush (GDK_DRAWABLE_DISPLAY (drawable)); \ + have_grab = FALSE; } \ } G_STMT_END if (!image && !GDK_IS_WINDOW_IMPL_X11 (drawable)) @@ -506,19 +524,20 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable, shm_pixmap = _gdk_x11_image_get_shm_pixmap (image); if (shm_pixmap) { + Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen); GC xgc; XGCValues values; /* Again easy, we can just XCopyArea, and don't have to worry about clipping */ values.subwindow_mode = IncludeInferiors; - xgc = XCreateGC (impl->xdisplay, impl->xid, GCSubwindowMode, &values); + xgc = XCreateGC (xdisplay, impl->xid, GCSubwindowMode, &values); - XCopyArea (impl->xdisplay, impl->xid, shm_pixmap, xgc, + XCopyArea (xdisplay, impl->xid, shm_pixmap, xgc, src_x, src_y, width, height, dest_x, dest_y); - XSync (impl->xdisplay, FALSE); + XSync (xdisplay, FALSE); - XFreeGC (impl->xdisplay, xgc); + XFreeGC (xdisplay, xgc); return image; } @@ -534,18 +553,18 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable, Window child; have_grab = TRUE; - gdk_x11_grab_server (); + gdk_x11_display_grab (gdk_screen_get_display (impl->screen)); /* Translate screen area into window coordinates */ - XTranslateCoordinates (gdk_display, - _gdk_root_window, - impl->xid, + XTranslateCoordinates (GDK_SCREEN_XDISPLAY (impl->screen), + GDK_SCREEN_XROOTWIN (impl->screen), + impl->xid, 0, 0, &screen_rect.x, &screen_rect.y, &child); - screen_rect.width = gdk_screen_width (); - screen_rect.height = gdk_screen_height (); + screen_rect.width = gdk_screen_get_width (visual->screen); + screen_rect.height = gdk_screen_get_height (visual->screen); gdk_error_trap_push (); @@ -603,7 +622,8 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable, if (!image) { - image = _gdk_image_new_for_depth (GDK_IMAGE_NORMAL, visual, width, height, + image = _gdk_image_new_for_depth (impl->screen, GDK_IMAGE_NORMAL, + visual, width, height, gdk_drawable_get_depth (drawable)); created_image = TRUE; } @@ -613,7 +633,7 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable, /* In the ShmImage but no ShmPixmap case, we could use XShmGetImage when * we are getting the entire image. */ - if (XGetSubImage (impl->xdisplay, + if (XGetSubImage (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, req.x, req.y, req.width, req.height, AllPlanes, ZPixmap, @@ -631,8 +651,8 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable, if (have_grab) { - gdk_x11_ungrab_server (); - XFlush (impl->xdisplay); + gdk_x11_display_ungrab (gdk_drawable_get_display (drawable)); + XFlush (GDK_DRAWABLE_XDISPLAY (drawable)); have_grab = FALSE; } @@ -641,7 +661,8 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable, if (success && !image) { /* We "succeeded", but could get no content for the image so return junk */ - image = _gdk_image_new_for_depth (GDK_IMAGE_NORMAL, visual, width, height, + image = _gdk_image_new_for_depth (impl->screen, GDK_IMAGE_NORMAL, + visual, width, height, gdk_drawable_get_depth (drawable)); } @@ -708,13 +729,13 @@ gdk_x11_image_destroy (GdkImage *image) case GDK_IMAGE_SHARED: #ifdef USE_SHM - gdk_flush(); + gdk_display_sync (GDK_SCREEN_DISPLAY (private->screen)); if (private->shm_pixmap) - XFreePixmap (private->xdisplay, private->shm_pixmap); + XFreePixmap (GDK_SCREEN_XDISPLAY (private->screen), private->shm_pixmap); image_list = g_list_remove (image_list, image); - XShmDetach (private->xdisplay, private->x_shm_info); + XShmDetach (GDK_SCREEN_XDISPLAY (private->screen), private->x_shm_info); XDestroyImage (private->ximage); x_shm_info = private->x_shm_info; @@ -746,7 +767,7 @@ gdk_x11_image_get_xdisplay (GdkImage *image) private = PRIVATE_DATA (image); - return private->xdisplay; + return GDK_SCREEN_XDISPLAY (private->screen); } XImage * @@ -762,12 +783,13 @@ gdk_x11_image_get_ximage (GdkImage *image) } gint -_gdk_windowing_get_bits_for_depth (gint depth) +_gdk_windowing_get_bits_for_depth (GdkDisplay *display, + gint depth) { XPixmapFormatValues *formats; gint count, i; - formats = XListPixmapFormats (gdk_display, &count); + formats = XListPixmapFormats (GDK_DISPLAY_XDISPLAY (display), &count); for (i = 0; i < count; i++) if (formats[i].depth == depth) @@ -780,3 +802,4 @@ _gdk_windowing_get_bits_for_depth (gint depth) g_assert_not_reached (); return -1; } + diff --git a/gdk/x11/gdkinput-gxi.c b/gdk/x11/gdkinput-gxi.c deleted file mode 100644 index 44e3acdd9..000000000 --- a/gdk/x11/gdkinput-gxi.c +++ /dev/null @@ -1,574 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include <stdlib.h> - -#include "gdkinputprivate.h" -#include "gdkx.h" - -/* #define DEBUG_SWITCHING */ - -#include <gxid_lib.h> - -/* Forward declarations */ -static void gdk_input_gxi_select_notify (GdkDevicePrivate *gdkdev); -static gint gdk_input_is_extension_device (GdkDevicePrivate *device_private); -static void gdk_input_gxi_update_device (GdkDevicePrivate *gdkdev); - -static Window gdk_input_find_root_child(Display *dpy, Window w); -static void gdk_input_compute_obscuring(GdkInputWindow *input_window); -static gint gdk_input_is_obscured(GdkInputWindow *input_window, gdouble x, - gdouble y); - -/* Local variables */ - -static GdkDevicePrivate *gdk_input_current_device; -static GdkDevicePrivate *gdk_input_core_pointer; - -void -_gdk_input_init(void) -{ - GList *tmp_list; - - _gdk_init_input_core (); - _gdk_input_ignore_core = FALSE; - gdk_input_core_pointer = NULL; - - if (!_gdk_input_gxid_host) - { - _gdk_input_gxid_host = getenv("GXID_HOST"); - } - if (!_gdk_input_gxid_port) - { - char *t = getenv("GXID_PORT"); - if (t) - _gdk_input_gxid_port = atoi(t); - } - - gdk_input_common_init(TRUE); - - /* find initial core pointer */ - - for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next) - { - GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)tmp_list->data; - if (gdk_input_is_extension_device (gdkdev)) - { - gdk_input_gxi_select_notify (gdkdev); - } - else - { - if (!GDK_IS_CORE (gdkdev)) - gdk_input_core_pointer = gdkdev; - } - } -} - -static void -gdk_input_gxi_select_notify (GdkDevicePrivate *gdkdev) -{ - XEventClass class; - - ChangeDeviceNotify (gdkdev->xdevice, gdkdev->changenotify_type, class); - - XSelectExtensionEvent (gdk_display, _gdk_root_window, &class, 1); -} - -/* Set the core pointer. Device should already be enabled. */ -static gint -gdk_input_gxi_set_core_pointer(GdkDevicePrivate *gdkdev) -{ - gint x_axis = -1; - gint y_axis = -1; - gint i; - - g_return_val_if_fail(gdkdev->xdevice,FALSE); - - for (i=0; i<gdkdev->info.num_axes; i++) - { - if (gdkdev->info.axes[i].use == GDK_AXIS_X) - x_axis = i; - else if (gdkdev->info.axes[i].use == GDK_AXIS_Y) - y_axis = i; - } - - g_return_val_if_fail (x_axis != -1 && y_axis != -1,FALSE); - - /* core_pointer might not be up to date so we check with the server - before change the pointer */ - - if (!gdk_input_is_extension_device (gdkdev)) - { -#if 0 - if (gdkdev != gdk_input_core_pointer) - g_warning("core pointer inconsistency"); -#endif - return TRUE; - } - - if ( XChangePointerDevice(gdk_display,gdkdev->xdevice, x_axis, y_axis) - != Success ) - { - return FALSE; - } - else - { - gdk_input_gxi_update_device (gdk_input_core_pointer); - gdk_input_core_pointer = gdkdev; - return TRUE; - } -} - - -/* FIXME, merge with the XFree implementation */ - -gboolean -gdk_device_set_mode (GdkDevice *device, - GdkInputMode mode) -{ - GList *tmp_list; - GdkDevicePrivate *gdkdev; - GdkInputMode old_mode; - GdkInputWindow *input_window; - - if (GDK_IS_CORE (device)) - return FALSE; - - gdkdev = (GdkDevicePrivate *)device; - - if (device->mode == mode) - return TRUE; - - old_mode = device->mode; - device->mode = mode; - - if (old_mode != GDK_MODE_DISABLED) - { - for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next) - { - input_window = (GdkInputWindow *)tmp_list->data; - if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR) - _gdk_input_disable_window (input_window->window, gdkdev); - } - } - - if (mode != GDK_MODE_DISABLED) - { - for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next) - { - input_window = (GdkInputWindow *)tmp_list->data; - if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR) - if (!_gdk_input_enable_window(input_window->window, gdkdev)) - { - gdk_device_set_mode (device, old_mode); - return FALSE; - } - } - } - - return TRUE; -} - -gint -gdk_input_is_extension_device (GdkDevicePrivate *private) -{ - XDeviceInfo *devices; - int num_devices, loop; - - if (GDK_IS_CORE (private)) - return FALSE; - - devices = XListInputDevices(gdk_display, &num_devices); - for(loop=0; loop<num_devices; loop++) - { - if ((devices[loop].id == private->deviceid) && - (devices[loop].use == IsXExtensionDevice)) - { - XFreeDeviceList(devices); - return TRUE; - } - } - - XFreeDeviceList(devices); - return FALSE; -} - -void -_gdk_input_configure_event (XConfigureEvent *xevent, GdkWindow *window) -{ - GdkInputWindow *input_window; - gint root_x, root_y; - - input_window = gdk_input_window_find(window); - g_return_if_fail (input_window != NULL); - - gdk_input_get_root_relative_geometry(gdk_display,GDK_WINDOW_XWINDOW(window), - &root_x, &root_y, NULL, NULL); - input_window->root_x = root_x; - input_window->root_y = root_y; - gdk_input_compute_obscuring(input_window); -} - -void -_gdk_input_enter_event (XCrossingEvent *xevent, GdkWindow *window) -{ - GdkInputWindow *input_window; - - input_window = gdk_input_window_find(window); - g_return_if_fail (input_window != NULL); - - gdk_input_compute_obscuring(input_window); -} - -gint -_gdk_input_other_event (GdkEvent *event, - XEvent *xevent, - GdkWindow *window) -{ - GdkInputWindow *input_window; - GdkWindowImplX11 *impl; - - GdkDevicePrivate *gdkdev; - gint return_val; - - input_window = gdk_input_window_find(window); - g_return_val_if_fail (window != NULL, -1); - - impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *) input_window->window)->impl); - - /* This is a sort of a hack, as there isn't any XDeviceAnyEvent - - but it's potentially faster than scanning through the types of - every device. If we were deceived, then it won't match any of - the types for the device anyways */ - gdkdev = gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid); - - if (!gdkdev) - { - return -1; /* we don't handle it - not an XInput event */ - } - - if (gdkdev->info.mode == GDK_MODE_DISABLED || - input_window->mode == GDK_EXTENSION_EVENTS_CURSOR) - return FALSE; - - if (gdkdev != gdk_input_current_device && - xevent->type != gdkdev->changenotify_type) - { - gdk_input_current_device = gdkdev; - } - - return_val = gdk_input_common_other_event (event, xevent, - input_window, gdkdev); - - if (return_val > 0 && event->type == GDK_MOTION_NOTIFY && - (!gdkdev->button_state) && (!input_window->grabbed) && - ((event->motion.x < 0) || (event->motion.y < 0) || - (event->motion.x > impl->width) || - (event->motion.y > impl->height) || - gdk_input_is_obscured(input_window,event->motion.x,event->motion.y))) - { -#ifdef DEBUG_SWITCHING - g_print("gdkinput: Setting core pointer to %d on motion at (%f,%f)\n", - gdkdev->info.deviceid,event->motion.x,event->motion.y); - g_print(" window geometry is: %dx%d\n", - ((GdkWindowPrivate *)window)->width, - ((GdkWindowPrivate *)window)->height); -#endif - gdk_input_gxi_set_core_pointer(gdkdev); - return FALSE; - } - else - return return_val; - -} - -static void -gdk_input_gxi_update_device (GdkDevicePrivate *gdkdev) -{ - GList *t; - - if (gdk_input_is_extension_device (gdkdev)) - { - if (!gdkdev->xdevice) - { - gdkdev->xdevice = XOpenDevice(gdk_display, gdkdev->deviceid); - gdk_input_gxi_select_notify (gdkdev); - gdkdev->needs_update = 1; - } - if (gdkdev->needs_update && gdkdev->xdevice) - { - for (t = _gdk_input_windows; t; t = t->next) - gdk_input_common_select_events (((GdkInputWindow *)t->data)->window, - gdkdev); - gdkdev->needs_update = 0; - } - } -} - -gint -_gdk_input_window_none_event (GdkEvent *event, XEvent *xevent) -{ - GdkDevicePrivate *gdkdev = - gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid); - - if (!gdkdev) { - return -1; /* we don't handle it - not an XInput event */ - } - - if (xevent->type == gdkdev->changenotify_type) - { - if (gdk_input_core_pointer != gdkdev) - { -#ifdef DEBUG_SWITCHING - g_print("ChangeNotify from %d to %d:\n", - gdk_input_core_pointer->info.deviceid, - gdkdev->info.deviceid); -#endif - gdk_input_gxi_update_device (gdk_input_core_pointer); - gdk_input_core_pointer = gdkdev; - } - } - - return FALSE; -} - -gboolean -_gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev) -{ - GdkInputWindow *input_window; - - input_window = gdk_input_window_find (window); - g_return_val_if_fail (input_window != NULL, FALSE); - - if (!gdkdev->claimed) - { - if (_gxid_claim_device(_gdk_input_gxid_host, _gdk_input_gxid_port, - gdkdev->deviceid, - GDK_WINDOW_XWINDOW(window), FALSE) != - GXID_RETURN_OK) - { - g_warning("Could not get device (is gxid running?)\n"); - return FALSE; - } - gdkdev->claimed = TRUE; - } - - if (gdkdev->xdevice && gdkdev != gdk_input_core_pointer) - gdk_input_common_select_events(window, gdkdev); - else - gdkdev->needs_update = TRUE; - - return TRUE; -} - -gboolean -_gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev) -{ - GdkInputWindow *input_window; - - input_window = gdk_input_window_find (window); - g_return_val_if_fail (input_window != NULL, FALSE); - - if (gdkdev->claimed) - { - _gxid_release_device(_gdk_input_gxid_host, _gdk_input_gxid_port, - gdkdev->deviceid, - GDK_WINDOW_XWINDOW(window)); - - gdkdev->claimed = FALSE; - } - - if (gdkdev->xdevice && gdkdev != gdk_input_core_pointer) - gdk_input_common_select_events(window, gdkdev); - else - gdkdev->needs_update = TRUE; - - return TRUE; -} - -static gint -gdk_input_is_obscured(GdkInputWindow *input_window, gdouble x, gdouble y) -{ - int i; - for (i=0;i<input_window->num_obscuring;i++) - { - GdkRectangle *rect = &input_window->obscuring[i]; - if ((x >= rect->x) && - (y >= rect->y) && - (x < rect->x + rect->width) && - (y < rect->y + rect->height)) - return TRUE; - } - return FALSE; -} - -/* If this routine needs fixing, the corresponding routine - in gxid.c will need it too. */ - -static Window -gdk_input_find_root_child(Display *dpy, Window w) -{ - Window root,parent; - Window *children; - int nchildren; - - parent = w; - do - { - w = parent; - XQueryTree(dpy,w,&root,&parent,&children,&nchildren); - if (children) XFree(children); - } - while (parent != root); - - return w; -} - -static void -gdk_input_compute_obscuring(GdkInputWindow *input_window) -{ - int i; - int x,y,width,height; - int xc,yc,widthc,heightc,border_widthc,depthc; - - Window root,parent; - Window *children; - int nchildren; - - Window w = GDK_WINDOW_XWINDOW(input_window->window); - Window root_child = gdk_input_find_root_child(gdk_display,w); - gdk_input_get_root_relative_geometry(gdk_display,w,&x,&y,&width,&height); - - input_window->root_x = x; - input_window->root_y = y; - - XQueryTree(gdk_display,GDK_ROOT_WINDOW(), - &root,&parent,&children,&nchildren); - - - if (input_window->obscuring) - g_free(input_window->obscuring); - input_window->obscuring = 0; - input_window->num_obscuring = 0; - - for (i=0;i<nchildren;i++) - if (children[i] == root_child) - break; - - if (i>=nchildren-1) - { - if (nchildren) - XFree(children); - return; - } - - input_window->obscuring = g_new(GdkRectangle,(nchildren-i-1)); - - for (i=i+1;i<nchildren;i++) - { - int xmin, xmax, ymin, ymax; - XGetGeometry(gdk_display,children[i],&root,&xc,&yc,&widthc,&heightc, - &border_widthc, &depthc); - xmin = xc>x ? xc : x; - xmax = (xc+widthc)<(x+width) ? xc+widthc : x+width; - ymin = yc>y ? yc : y; - ymax = (yc+heightc)<(y+height) ? yc+heightc : y+height; - if ((xmin < xmax) && (ymin < ymax)) - { - XWindowAttributes attributes; - XGetWindowAttributes(gdk_display,children[i],&attributes); - if (attributes.map_state == IsViewable) - { - GdkRectangle *rect = &input_window->obscuring[input_window->num_obscuring]; - - /* we store the whole window, not just the obscuring part */ - rect->x = xc - x; - rect->y = yc - y; - rect->width = widthc; - rect->height = heightc; - input_window->num_obscuring++; - } - } - } - - if (nchildren) - XFree(children); -} - -gint -_gdk_input_grab_pointer (GdkWindow * window, - gint owner_events, - GdkEventMask event_mask, - GdkWindow * confine_to, - guint32 time) -{ - GList *tmp_list; - GdkInputWindow *input_window; - GdkDevicePrivate *gdkdev; - - tmp_list = _gdk_input_windows; - while (tmp_list) - { - input_window = (GdkInputWindow *)tmp_list->data; - - if (input_window->window == window) - input_window->grabbed = TRUE; - else if (input_window->grabbed) - input_window->grabbed = FALSE; - - tmp_list = tmp_list->next; - } - - tmp_list = _gdk_input_devices; - while (tmp_list) - { - gdkdev = (GdkDevicePrivate *)tmp_list->data; - if (!GDK_IS_CORE (gdkdev) && - gdkdev->xdevice && - (gdkdev->button_state != 0)) - gdkdev->button_state = 0; - - tmp_list = tmp_list->next; - } - - return Success; -} - -void -_gdk_input_ungrab_pointer (guint32 time) -{ - GdkInputWindow *input_window; - GList *tmp_list; - - tmp_list = _gdk_input_windows; - while (tmp_list) - { - input_window = (GdkInputWindow *)tmp_list->data; - if (input_window->grabbed) - input_window->grabbed = FALSE; - tmp_list = tmp_list->next; - } -} diff --git a/gdk/x11/gdkinput-none.c b/gdk/x11/gdkinput-none.c index 616809afc..d63ef577b 100644 --- a/gdk/x11/gdkinput-none.c +++ b/gdk/x11/gdkinput-none.c @@ -18,6 +18,7 @@ */ #include "gdkinputprivate.h" +#include "gdkdisplay-x11.h" /* * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS @@ -27,12 +28,14 @@ */ void -_gdk_input_init (void) +_gdk_input_init (GdkDisplay *display) { + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + _gdk_init_input_core (); - _gdk_input_devices = g_list_append (NULL, _gdk_core_pointer); - - _gdk_input_ignore_core = FALSE; + + display_x11->input_devices = g_list_append (NULL, _gdk_core_pointer); + display_x11->input_ignore_core = FALSE; } void @@ -117,7 +120,8 @@ _gdk_input_grab_pointer (GdkWindow * window, } void -_gdk_input_ungrab_pointer (guint32 time) +_gdk_input_ungrab_pointer (GdkDisplay *display, + guint32 time) { } diff --git a/gdk/x11/gdkinput-x11.c b/gdk/x11/gdkinput-x11.c index 770c9b874..b1a72182d 100644 --- a/gdk/x11/gdkinput-x11.c +++ b/gdk/x11/gdkinput-x11.c @@ -28,26 +28,28 @@ #include "gdkinternals.h" #include "gdkx.h" #include "gdk.h" /* For gdk_error_trap_push()/pop() */ +#include "gdkdisplay-x11.h" #include <string.h> /* Forward declarations */ -static GdkDevicePrivate *gdk_input_device_new(XDeviceInfo *device, - gint include_core); -static void gdk_input_translate_coordinates(GdkDevicePrivate *gdkdev, - GdkInputWindow *input_window, - gint *axis_data, - gdouble *axis_out, - gdouble *x_out, - gdouble *y_out); -static guint gdk_input_translate_state(guint state, guint device_state); - -/* Global variables */ +static GdkDevicePrivate *gdk_input_device_new (GdkDisplay *display, + XDeviceInfo *device, + gint include_core); +static void gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, + GdkInputWindow *input_window, + gint *axis_data, + gdouble *axis_out, + gdouble *x_out, + gdouble *y_out); +static guint gdk_input_translate_state (guint state, + guint device_state); GdkDevicePrivate * -gdk_input_find_device (guint32 id) +gdk_input_find_device (GdkDisplay *display, + guint32 id) { - GList *tmp_list = _gdk_input_devices; + GList *tmp_list = GDK_DISPLAY_X11 (display)->input_devices; GdkDevicePrivate *gdkdev; while (tmp_list) { @@ -60,7 +62,7 @@ gdk_input_find_device (guint32 id) } void -gdk_input_get_root_relative_geometry(Display *dpy, Window w, int *x_ret, int *y_ret, +gdk_input_get_root_relative_geometry(Display *display, Window w, int *x_ret, int *y_ret, int *width_ret, int *height_ret) { Window root, parent, child; @@ -70,13 +72,13 @@ gdk_input_get_root_relative_geometry(Display *dpy, Window w, int *x_ret, int *y_ guint width, height; guint border_widthc, depthc; - XQueryTree (dpy, w, &root, &parent, &children, &nchildren); + XQueryTree (display, w, &root, &parent, &children, &nchildren); if (children) XFree(children); - XGetGeometry (dpy, w, &root, &x, &y, &width, &height, &border_widthc, &depthc); + XGetGeometry (display, w, &root, &x, &y, &width, &height, &border_widthc, &depthc); - XTranslateCoordinates (dpy, w, root, 0, 0, &x, &y, &child); + XTranslateCoordinates (display, w, root, 0, 0, &x, &y, &child); if (x_ret) *x_ret = x; @@ -89,7 +91,9 @@ gdk_input_get_root_relative_geometry(Display *dpy, Window w, int *x_ret, int *y_ } static GdkDevicePrivate * -gdk_input_device_new (XDeviceInfo *device, gint include_core) +gdk_input_device_new (GdkDisplay *display, + XDeviceInfo *device, + gint include_core) { GdkDevicePrivate *gdkdev; gchar *tmp_name; @@ -99,6 +103,8 @@ gdk_input_device_new (XDeviceInfo *device, gint include_core) gdkdev = g_object_new (GDK_TYPE_DEVICE, NULL); gdkdev->deviceid = device->id; + gdkdev->display = display; + if (device->name[0]) gdkdev->info.name = g_strdup (device->name); else @@ -218,7 +224,8 @@ gdk_input_device_new (XDeviceInfo *device, gint include_core) if (device->use != IsXPointer) { gdk_error_trap_push (); - gdkdev->xdevice = XOpenDevice(gdk_display, gdkdev->deviceid); + gdkdev->xdevice = XOpenDevice (GDK_DISPLAY_XDISPLAY (display), + gdkdev->deviceid); /* return NULL if device is not ready */ if (gdk_error_trap_pop ()) @@ -263,7 +270,7 @@ gdk_input_common_find_events(GdkWindow *window, i = 0; /* We have to track press and release events in pairs to keep track of button state correctly and implement grabbing for - the gxi support */ + the gxi support. FIXME - is this needed any more since gxi is gone? */ if (mask & GDK_BUTTON_PRESS_MASK || mask & GDK_BUTTON_RELEASE_MASK) { DeviceButtonPress (gdkdev->xdevice, gdkdev->buttonpress_type, @@ -366,44 +373,46 @@ gdk_input_common_select_events(GdkWindow *window, ((GdkWindowObject *)window)->extension_events, classes, &num_classes); - XSelectExtensionEvent (gdk_display, - GDK_WINDOW_XWINDOW(window), + XSelectExtensionEvent (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XWINDOW (window), classes, num_classes); } gint -gdk_input_common_init(gint include_core) +gdk_input_common_init (GdkDisplay *display, + gint include_core) { char **extensions; XDeviceInfo *devices; int num_devices; int num_extensions, loop; - Display *display = gdk_display; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); /* Init XInput extension */ - extensions = XListExtensions(display, &num_extensions); + extensions = XListExtensions(display_x11->xdisplay, &num_extensions); for (loop = 0; loop < num_extensions && (strcmp(extensions[loop], "XInputExtension") != 0); loop++); XFreeExtensionList(extensions); - _gdk_input_devices = NULL; + display_x11->input_devices = NULL; if (loop < num_extensions) { /* XInput extension found */ - devices = XListInputDevices(display, &num_devices); + devices = XListInputDevices(display_x11->xdisplay, &num_devices); for(loop=0; loop<num_devices; loop++) { - GdkDevicePrivate *gdkdev = gdk_input_device_new(&devices[loop], - include_core); + GdkDevicePrivate *gdkdev = gdk_input_device_new(display, + &devices[loop], + include_core); if (gdkdev) - _gdk_input_devices = g_list_append(_gdk_input_devices, gdkdev); + display_x11->input_devices = g_list_append(display_x11->input_devices, gdkdev); } XFreeDeviceList(devices); } - _gdk_input_devices = g_list_append (_gdk_input_devices, _gdk_core_pointer); + display_x11->input_devices = g_list_append (display_x11->input_devices, _gdk_core_pointer); return TRUE; } @@ -448,8 +457,8 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, if (gdkdev->info.mode == GDK_MODE_SCREEN) { - x_scale = gdk_screen_width() / device_width; - y_scale = gdk_screen_height() / device_height; + x_scale = gdk_screen_get_width (gdk_drawable_get_screen (input_window->window)) / device_width; + y_scale = gdk_screen_get_height (gdk_drawable_get_screen (input_window->window)) / device_height; x_offset = - input_window->root_x; y_offset = - input_window->root_y; @@ -690,7 +699,7 @@ _gdk_device_get_history (GdkDevice *device, g_return_val_if_fail (input_window != NULL, FALSE); - device_coords = XGetDeviceMotionEvents (gdk_display, + device_coords = XGetDeviceMotionEvents (GDK_WINDOW_XDISPLAY (window), gdkdev->xdevice, start, stop, n_events, &mode_return, @@ -756,7 +765,8 @@ gdk_device_get_state (GdkDevice *device, input_window = gdk_input_window_find (window); g_return_if_fail (input_window != NULL); - state = XQueryDeviceState (gdk_display, gdkdev->xdevice); + state = XQueryDeviceState (GDK_WINDOW_XDISPLAY (window), + gdkdev->xdevice); input_class = state->data; for (i=0; i<state->num_classes; i++) { diff --git a/gdk/x11/gdkinput-xfree.c b/gdk/x11/gdkinput-xfree.c index 48b0784c6..499222678 100644 --- a/gdk/x11/gdkinput-xfree.c +++ b/gdk/x11/gdkinput-xfree.c @@ -18,6 +18,7 @@ */ #include "gdkinputprivate.h" +#include "gdkdisplay-x11.h" /* * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS @@ -28,14 +29,14 @@ /* forward declarations */ -static void gdk_input_check_proximity (void); +static void gdk_input_check_proximity (GdkDisplay *display); void -_gdk_input_init(void) +_gdk_input_init(GdkDisplay *display) { _gdk_init_input_core (); - _gdk_input_ignore_core = FALSE; - gdk_input_common_init(FALSE); + GDK_DISPLAY_X11 (display)->input_ignore_core = FALSE; + gdk_input_common_init (display, FALSE); } gboolean @@ -46,6 +47,7 @@ gdk_device_set_mode (GdkDevice *device, GdkDevicePrivate *gdkdev; GdkInputMode old_mode; GdkInputWindow *input_window; + GdkDisplayX11 *display_impl; if (GDK_IS_CORE (device)) return FALSE; @@ -58,10 +60,12 @@ gdk_device_set_mode (GdkDevice *device, old_mode = device->mode; device->mode = mode; + display_impl = GDK_DISPLAY_X11 (gdkdev->display); + if (mode == GDK_MODE_WINDOW) { device->has_cursor = FALSE; - for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next) + for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next) { input_window = (GdkInputWindow *)tmp_list->data; if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR) @@ -74,13 +78,13 @@ gdk_device_set_mode (GdkDevice *device, else if (mode == GDK_MODE_SCREEN) { device->has_cursor = TRUE; - for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next) + for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next) _gdk_input_enable_window (((GdkInputWindow *)tmp_list->data)->window, gdkdev); } else /* mode == GDK_MODE_DISABLED */ { - for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next) + for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next) { input_window = (GdkInputWindow *)tmp_list->data; if (old_mode != GDK_MODE_WINDOW || @@ -94,10 +98,11 @@ gdk_device_set_mode (GdkDevice *device, } static void -gdk_input_check_proximity (void) +gdk_input_check_proximity (GdkDisplay *display) { gint new_proximity = 0; - GList *tmp_list = _gdk_input_devices; + GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display); + GList *tmp_list = display_impl->input_devices; while (tmp_list && !new_proximity) { @@ -107,7 +112,7 @@ gdk_input_check_proximity (void) && !GDK_IS_CORE (gdkdev) && gdkdev->xdevice) { - XDeviceState *state = XQueryDeviceState(GDK_DISPLAY(), + XDeviceState *state = XQueryDeviceState(display_impl->xdisplay, gdkdev->xdevice); XInputClass *xic; int i; @@ -132,7 +137,7 @@ gdk_input_check_proximity (void) tmp_list = tmp_list->next; } - _gdk_input_ignore_core = new_proximity; + display_impl->input_ignore_core = new_proximity; } void @@ -145,9 +150,9 @@ _gdk_input_configure_event (XConfigureEvent *xevent, input_window = gdk_input_window_find(window); g_return_if_fail (window != NULL); - gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window), - &root_x, - &root_y, NULL, NULL); + gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XWINDOW (window), + &root_x, &root_y, NULL, NULL); input_window->root_x = root_x; input_window->root_y = root_y; @@ -160,14 +165,14 @@ _gdk_input_enter_event (XCrossingEvent *xevent, GdkInputWindow *input_window; gint root_x, root_y; - input_window = gdk_input_window_find(window); + input_window = gdk_input_window_find (window); g_return_if_fail (window != NULL); - gdk_input_check_proximity(); + gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window)); - gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window), - &root_x, - &root_y, NULL, NULL); + gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XWINDOW(window), + &root_x, &root_y, NULL, NULL); input_window->root_x = root_x; input_window->root_y = root_y; @@ -182,6 +187,7 @@ _gdk_input_other_event (GdkEvent *event, GdkDevicePrivate *gdkdev; gint return_val; + GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); input_window = gdk_input_window_find(window); g_return_val_if_fail (window != NULL, -1); @@ -190,8 +196,8 @@ _gdk_input_other_event (GdkEvent *event, but it's potentially faster than scanning through the types of every device. If we were deceived, then it won't match any of the types for the device anyways */ - gdkdev = gdk_input_find_device (((XDeviceButtonEvent *)xevent)->deviceid); - + gdkdev = gdk_input_find_device (GDK_WINDOW_DISPLAY (window), + ((XDeviceButtonEvent *)xevent)->deviceid); if (!gdkdev) return -1; /* we don't handle it - not an XInput event */ @@ -202,15 +208,15 @@ _gdk_input_other_event (GdkEvent *event, && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)) return FALSE; - if (!_gdk_input_ignore_core) - gdk_input_check_proximity(); + if (!display_impl->input_ignore_core) + gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window)); return_val = gdk_input_common_other_event (event, xevent, input_window, gdkdev); if (return_val > 0 && event->type == GDK_PROXIMITY_OUT && - _gdk_input_ignore_core) - gdk_input_check_proximity(); + display_impl->input_ignore_core) + gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window)); return return_val; } @@ -244,8 +250,9 @@ _gdk_input_grab_pointer (GdkWindow * window, XEventClass event_classes[GDK_MAX_DEVICE_CLASSES]; gint num_classes; gint result; + GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); - tmp_list = _gdk_input_windows; + tmp_list = display_impl->input_windows; new_window = NULL; need_ungrab = FALSE; @@ -268,7 +275,7 @@ _gdk_input_grab_pointer (GdkWindow * window, { new_window->grabbed = TRUE; - tmp_list = _gdk_input_devices; + tmp_list = display_impl->input_devices; while (tmp_list) { gdkdev = (GdkDevicePrivate *)tmp_list->data; @@ -282,7 +289,7 @@ _gdk_input_grab_pointer (GdkWindow * window, result = GrabSuccess; else #endif - result = XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice, + result = XGrabDevice (display_impl->xdisplay, gdkdev->xdevice, GDK_WINDOW_XWINDOW (window), owner_events, num_classes, event_classes, GrabModeAsync, GrabModeAsync, time); @@ -297,14 +304,14 @@ _gdk_input_grab_pointer (GdkWindow * window, } else { - tmp_list = _gdk_input_devices; + tmp_list = display_impl->input_devices; while (tmp_list) { gdkdev = (GdkDevicePrivate *)tmp_list->data; if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice && ((gdkdev->button_state != 0) || need_ungrab)) { - XUngrabDevice( gdk_display, gdkdev->xdevice, time); + XUngrabDevice (display_impl->xdisplay, gdkdev->xdevice, time); gdkdev->button_state = 0; } @@ -317,13 +324,15 @@ _gdk_input_grab_pointer (GdkWindow * window, } void -_gdk_input_ungrab_pointer (guint32 time) +_gdk_input_ungrab_pointer (GdkDisplay *display, + guint32 time) { GdkInputWindow *input_window = NULL; /* Quiet GCC */ GdkDevicePrivate *gdkdev; GList *tmp_list; + GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display); - tmp_list = _gdk_input_windows; + tmp_list = display_impl->input_windows; while (tmp_list) { input_window = (GdkInputWindow *)tmp_list->data; @@ -336,12 +345,12 @@ _gdk_input_ungrab_pointer (guint32 time) { input_window->grabbed = FALSE; - tmp_list = _gdk_input_devices; + tmp_list = display_impl->input_devices; while (tmp_list) { gdkdev = (GdkDevicePrivate *)tmp_list->data; if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice) - XUngrabDevice( gdk_display, gdkdev->xdevice, time); + XUngrabDevice( display_impl->xdisplay, gdkdev->xdevice, time); tmp_list = tmp_list->next; } diff --git a/gdk/x11/gdkinput.c b/gdk/x11/gdkinput.c index 13f7722e2..818d9409e 100644 --- a/gdk/x11/gdkinput.c +++ b/gdk/x11/gdkinput.c @@ -33,6 +33,8 @@ #include "gdkinput.h" #include "gdkprivate.h" #include "gdkinputprivate.h" +#include "gdkscreen-x11.h" +#include "gdkdisplay-x11.h" static GdkDeviceAxis gdk_input_core_axes[] = { { GDK_AXIS_X, 0, 0 }, @@ -41,16 +43,6 @@ static GdkDeviceAxis gdk_input_core_axes[] = { GdkDevice *_gdk_core_pointer = NULL; -/* Global variables */ - -/* information about network port and host for gxid daemon */ -gchar *_gdk_input_gxid_host; -gint _gdk_input_gxid_port; -gint _gdk_input_ignore_core; - -GList *_gdk_input_devices; -GList *_gdk_input_windows; - void _gdk_init_input_core (void) { @@ -94,10 +86,35 @@ gdk_device_get_type (void) return object_type; } +/** + * gdk_devices_list: + * + * Returns the list of available input devices for the default display. + * The list is statically allocated and should not be freed. + * + * Return value: a list of #GdkDevice + **/ GList * gdk_devices_list (void) { - return _gdk_input_devices; + return gdk_display_list_devices (gdk_get_default_display ()); +} + +/** + * gdk_display_list_devices: + * @display : a #GdkDisplay + * + * Returns the list of available input devices attached to @display. + * The list is statically allocated and should not be freed. + * + * Return value: a list of #GdkDevice + **/ +GList * +gdk_display_list_devices (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + return GDK_DISPLAY_X11 (display)->input_devices; } void @@ -232,8 +249,9 @@ GdkInputWindow * gdk_input_window_find(GdkWindow *window) { GList *tmp_list; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); - for (tmp_list=_gdk_input_windows; tmp_list; tmp_list=tmp_list->next) + for (tmp_list=display_x11->input_windows; tmp_list; tmp_list=tmp_list->next) if (((GdkInputWindow *)(tmp_list->data))->window == window) return (GdkInputWindow *)(tmp_list->data); @@ -253,11 +271,13 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask, GdkWindowObject *window_private; GList *tmp_list; GdkInputWindow *iw; + GdkDisplayX11 *display_x11; g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); window_private = (GdkWindowObject*) window; + display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); if (GDK_WINDOW_DESTROYED (window)) return; @@ -275,7 +295,7 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask, iw->num_obscuring = 0; iw->grabbed = FALSE; - _gdk_input_windows = g_list_append(_gdk_input_windows,iw); + display_x11->input_windows = g_list_append(display_x11->input_windows,iw); window_private->extension_events = mask; /* Add enter window events to the event mask */ @@ -289,14 +309,14 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask, iw = gdk_input_window_find (window); if (iw) { - _gdk_input_windows = g_list_remove(_gdk_input_windows,iw); + display_x11->input_windows = g_list_remove(display_x11->input_windows,iw); g_free(iw); } window_private->extension_events = 0; } - for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next) + for (tmp_list = display_x11->input_devices; tmp_list; tmp_list = tmp_list->next) { GdkDevicePrivate *gdkdev = tmp_list->data; @@ -315,11 +335,12 @@ void gdk_input_window_destroy (GdkWindow *window) { GdkInputWindow *input_window; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); input_window = gdk_input_window_find (window); g_return_if_fail (input_window != NULL); - _gdk_input_windows = g_list_remove (_gdk_input_windows,input_window); + display_x11->input_windows = g_list_remove (display_x11->input_windows, input_window); g_free(input_window); } @@ -327,31 +348,37 @@ void _gdk_input_exit (void) { GList *tmp_list; + GSList *display_list; GdkDevicePrivate *gdkdev; - for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next) + for (display_list = _gdk_displays ; display_list ; display_list = display_list->next) { - gdkdev = (GdkDevicePrivate *)(tmp_list->data); - if (!GDK_IS_CORE (gdkdev)) + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display_list->data); + + for (tmp_list = display_x11->input_devices; tmp_list; tmp_list = tmp_list->next) { - gdk_device_set_mode (&gdkdev->info, GDK_MODE_DISABLED); - - g_free(gdkdev->info.name); + gdkdev = (GdkDevicePrivate *)(tmp_list->data); + if (!GDK_IS_CORE (gdkdev)) + { + gdk_device_set_mode (&gdkdev->info, GDK_MODE_DISABLED); + + g_free(gdkdev->info.name); #ifndef XINPUT_NONE - g_free(gdkdev->axes); + g_free(gdkdev->axes); #endif - g_free(gdkdev->info.axes); - g_free(gdkdev->info.keys); - g_free(gdkdev); + g_free(gdkdev->info.axes); + g_free(gdkdev->info.keys); + g_free(gdkdev); + } } + + g_list_free(display_x11->input_devices); + + for (tmp_list = display_x11->input_windows; tmp_list; tmp_list = tmp_list->next) + g_free(tmp_list->data); + + g_list_free(display_x11->input_windows); } - - g_list_free(_gdk_input_devices); - - for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next) - g_free(tmp_list->data); - - g_list_free(_gdk_input_windows); } /** diff --git a/gdk/x11/gdkinputprivate.h b/gdk/x11/gdkinputprivate.h index cb19db41e..8ed7a97f4 100644 --- a/gdk/x11/gdkinputprivate.h +++ b/gdk/x11/gdkinputprivate.h @@ -67,6 +67,8 @@ struct _GdkDevicePrivate GdkDevice info; guint32 deviceid; + + GdkDisplay *display; #ifndef XINPUT_NONE @@ -126,14 +128,6 @@ struct _GdkInputWindow #define GDK_IS_CORE(d) (((GdkDevice *)(d)) == _gdk_core_pointer) -extern GList *_gdk_input_devices; -extern GList *_gdk_input_windows; - -/* information about network port and host for gxid daemon */ -extern gchar *_gdk_input_gxid_host; -extern gint _gdk_input_gxid_port; -extern gint _gdk_input_ignore_core; - /* Function declarations */ GdkInputWindow *gdk_input_window_find (GdkWindow *window); @@ -163,7 +157,8 @@ gint _gdk_input_grab_pointer (GdkWindow *window, GdkEventMask event_mask, GdkWindow *confine_to, guint32 time); -void _gdk_input_ungrab_pointer (guint32 time); +void _gdk_input_ungrab_pointer (GdkDisplay *display, + guint32 time); gboolean _gdk_device_get_history (GdkDevice *device, GdkWindow *window, guint32 start, @@ -175,9 +170,11 @@ gboolean _gdk_device_get_history (GdkDevice *device, #define GDK_MAX_DEVICE_CLASSES 13 -gint gdk_input_common_init (gint include_core); -GdkDevicePrivate * gdk_input_find_device (guint32 id); -void gdk_input_get_root_relative_geometry (Display *dpy, +gint gdk_input_common_init (GdkDisplay *display, + gint include_core); +GdkDevicePrivate * gdk_input_find_device (GdkDisplay *display, + guint32 id); +void gdk_input_get_root_relative_geometry (Display *display, Window w, int *x_ret, int *y_ret, diff --git a/gdk/x11/gdkkeys-x11.c b/gdk/x11/gdkkeys-x11.c index c499d9620..d0bf2794a 100644 --- a/gdk/x11/gdkkeys-x11.c +++ b/gdk/x11/gdkkeys-x11.c @@ -32,56 +32,131 @@ #include <errno.h> #include "gdk.h" +#include "gdkx.h" #include "gdkprivate-x11.h" #include "gdkinternals.h" +#include "gdkdisplay-x11.h" #include "gdkkeysyms.h" #include "config.h" -guint _gdk_keymap_serial = 0; +#ifdef HAVE_XKB +#include <X11/XKBlib.h> +#endif + +typedef struct _GdkKeymapX11 GdkKeymapX11; + +#define GDK_TYPE_KEYMAP_X11 (gdk_keymap_x11_get_type ()) +#define GDK_KEYMAP_X11(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_KEYMAP_X11, GdkKeymapX11)) +#define GDK_IS_KEYMAP_X11(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_KEYMAP_X11)) + +struct _GdkKeymapX11 +{ + GdkKeymap parent_instance; + + gint min_keycode; + gint max_keycode; + KeySym* keymap; + gint keysyms_per_keycode; + XModifierKeymap* mod_keymap; + GdkModifierType group_switch_mask; + PangoDirection current_direction; + gboolean have_direction; + guint current_serial; + +#ifdef HAVE_XKB + XkbDescPtr xkb_desc; +#endif +}; + +#define KEYMAP_USE_XKB(keymap) GDK_DISPLAY_X11 ((keymap)->display)->use_xkb +#define KEYMAP_XDISPLAY(keymap) GDK_DISPLAY_XDISPLAY ((keymap)->display) + +static GType gdk_keymap_x11_get_type (void); +static void gdk_keymap_x11_init (GdkKeymapX11 *keymap); + +static GType +gdk_keymap_x11_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (GdkKeymapClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkKeymapX11), + 0, /* n_preallocs */ + (GInstanceInitFunc) gdk_keymap_x11_init, + }; + + object_type = g_type_register_static (GDK_TYPE_KEYMAP, + "GdkKeymapX11", + &object_info, 0); + } + + return object_type; +} + +static void +gdk_keymap_x11_init (GdkKeymapX11 *keymap) +{ + keymap->min_keycode = 0; + keymap->max_keycode = 0; + + keymap->keymap = NULL; + keymap->keysyms_per_keycode = 0; + keymap->mod_keymap = NULL; + + keymap->group_switch_mask = 0; + keymap->have_direction = FALSE; + keymap->xkb_desc = NULL; -static gint min_keycode = 0; -static gint max_keycode = 0; + keymap->current_serial = 0; +} static inline void -update_keyrange (void) +update_keyrange (GdkKeymapX11 *keymap_x11) { - if (max_keycode == 0) - XDisplayKeycodes (gdk_display, &min_keycode, &max_keycode); + if (keymap_x11->max_keycode == 0) + XDisplayKeycodes (KEYMAP_XDISPLAY (GDK_KEYMAP (keymap_x11)), + &keymap_x11->min_keycode, &keymap_x11->max_keycode); } #ifdef HAVE_XKB -#include <X11/XKBlib.h> - -gboolean _gdk_use_xkb = FALSE; -gint _gdk_xkb_event_type; -static XkbDescPtr xkb_desc = NULL; static XkbDescPtr -get_xkb (void) +get_xkb (GdkKeymapX11 *keymap_x11) { - static guint current_serial = 0; - - update_keyrange (); + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_KEYMAP (keymap_x11)->display); + Display *xdisplay = display_x11->xdisplay; + + update_keyrange (keymap_x11); - if (xkb_desc == NULL) + if (keymap_x11->xkb_desc == NULL) { - xkb_desc = XkbGetMap (gdk_display, XkbKeySymsMask | XkbKeyTypesMask, XkbUseCoreKbd); - if (xkb_desc == NULL) - g_error ("Failed to get keymap"); + keymap_x11->xkb_desc = XkbGetMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask, XkbUseCoreKbd); + if (keymap_x11->xkb_desc == NULL) + g_error ("Failed to get keymap"); - XkbGetNames (gdk_display, XkbGroupNamesMask, xkb_desc); + XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc); } - else if (current_serial != _gdk_keymap_serial) + else if (keymap_x11->current_serial != display_x11->keymap_serial) { - XkbGetUpdatedMap (gdk_display, XkbKeySymsMask | XkbKeyTypesMask, xkb_desc); - XkbGetNames (gdk_display, XkbGroupNamesMask, xkb_desc); + XkbGetUpdatedMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask, + keymap_x11->xkb_desc); + XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc); } - current_serial = _gdk_keymap_serial; + keymap_x11->current_serial = display_x11->keymap_serial; - return xkb_desc; + return keymap_x11->xkb_desc; } #endif /* HAVE_XKB */ @@ -89,66 +164,71 @@ get_xkb (void) * XkbSetDetectableAutorepeat. If FALSE, we'll fall back * to checking the next event with XPending(). */ -gboolean _gdk_have_xkb_autorepeat = FALSE; -static KeySym* keymap = NULL; -static gint keysyms_per_keycode = 0; -static XModifierKeymap* mod_keymap = NULL; -static GdkModifierType group_switch_mask = 0; -static PangoDirection current_direction; -static gboolean have_direction = FALSE; -static GdkKeymap *default_keymap = NULL; - -/** - * gdk_keymap_get_default: - * - * Gets the #GdkKeymap for the default display. - * - * Return value: the default keymap +/** + * gdk_keymap_get_for_display : + * @display : the #GdkDisplay. + * + * Returns the GdkKeymap attached to @display. + * + * Returns : the GdkKeymap attached to @display. **/ GdkKeymap* -gdk_keymap_get_default (void) +gdk_keymap_get_for_display (GdkDisplay *display) { - if (default_keymap == NULL) - default_keymap = g_object_new (gdk_keymap_get_type (), NULL); + GdkDisplayX11 *display_x11; + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + display_x11 = GDK_DISPLAY_X11 (display); + + if (!display_x11->keymap) + display_x11->keymap = g_object_new (gdk_keymap_x11_get_type (), NULL); + + display_x11->keymap->display = display; - return default_keymap; + return display_x11->keymap; +} + +GdkKeymap* +gdk_keymap_get_default (void) +{ + return gdk_keymap_get_for_display (gdk_get_default_display ()); } /* Find the index of the group/level pair within the keysyms for a key. */ -#define KEYSYM_INDEX(group, level) \ - (2 * ((group) % (keysyms_per_keycode / 2)) + (level)) +#define KEYSYM_INDEX(keymap_impl, group, level) \ + (2 * ((group) % (keymap_impl->keysyms_per_keycode / 2)) + (level)) static void -update_keymaps (void) +update_keymaps (GdkKeymapX11 *keymap_x11) { - static guint current_serial = 0; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_KEYMAP (keymap_x11)->display); + Display *xdisplay = display_x11->xdisplay; #ifdef HAVE_XKB - g_assert (!_gdk_use_xkb); + g_assert (!KEYMAP_USE_XKB (GDK_KEYMAP (keymap_x11))); #endif - if (keymap == NULL || - current_serial != _gdk_keymap_serial) + if (keymap_x11->keymap == NULL || + keymap_x11->current_serial != display_x11->keymap_serial) { gint i; gint map_size; gint keycode; - - current_serial = _gdk_keymap_serial; - update_keyrange (); + keymap_x11->current_serial = display_x11->keymap_serial; + + update_keyrange (keymap_x11); - if (keymap) - XFree (keymap); + if (keymap_x11->keymap) + XFree (keymap_x11->keymap); - if (mod_keymap) - XFreeModifiermap (mod_keymap); + if (keymap_x11->mod_keymap) + XFreeModifiermap (keymap_x11->mod_keymap); - keymap = XGetKeyboardMapping (gdk_display, min_keycode, - max_keycode - min_keycode, - &keysyms_per_keycode); + keymap_x11->keymap = XGetKeyboardMapping (xdisplay, keymap_x11->min_keycode, + keymap_x11->max_keycode - keymap_x11->min_keycode, + &keymap_x11->keysyms_per_keycode); /* GDK_ISO_Left_Tab, as usually configured through XKB, really messes @@ -156,31 +236,31 @@ update_keymaps (void) * However, <shift>Tab is not usually GDK_ISO_Left_Tab without XKB, * we we fudge the map here. */ - keycode = min_keycode; - while (keycode < max_keycode) + keycode = keymap_x11->min_keycode; + while (keycode < keymap_x11->max_keycode) { - KeySym *syms = keymap + (keycode - min_keycode) * keysyms_per_keycode; + KeySym *syms = keymap_x11->keymap + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode; /* Check both groups */ for (i = 0 ; i < 2 ; i++) { - if (syms[KEYSYM_INDEX (i, 0)] == GDK_Tab) - syms[KEYSYM_INDEX (i, 1)] = GDK_ISO_Left_Tab; + if (syms[KEYSYM_INDEX (keymap_x11, i, 0)] == GDK_Tab) + syms[KEYSYM_INDEX (keymap_x11, i, 1)] = GDK_ISO_Left_Tab; } /* * If there is one keysym and the key symbol has upper and lower * case variants fudge the keymap */ - if (syms[KEYSYM_INDEX (0, 1)] == 0) + if (syms[KEYSYM_INDEX (keymap_x11, 0, 1)] == 0) { guint lower; guint upper; - gdk_keyval_convert_case (syms[KEYSYM_INDEX (0, 0)], &lower, &upper); + gdk_keyval_convert_case (syms[KEYSYM_INDEX (keymap_x11, 0, 0)], &lower, &upper); if (lower != upper) { - syms[KEYSYM_INDEX (0, 0)] = lower; - syms[KEYSYM_INDEX (0, 1)] = upper; + syms[KEYSYM_INDEX (keymap_x11, 0, 0)] = lower; + syms[KEYSYM_INDEX (keymap_x11, 0, 1)] = upper; } } @@ -188,30 +268,31 @@ update_keymaps (void) ++keycode; } - mod_keymap = XGetModifierMapping (gdk_display); + keymap_x11->mod_keymap = XGetModifierMapping (xdisplay); - group_switch_mask = 0; + keymap_x11->group_switch_mask = 0; /* there are 8 modifiers, and the first 3 are shift, shift lock, * and control */ - map_size = 8 * mod_keymap->max_keypermod; - i = 3 * mod_keymap->max_keypermod; + map_size = 8 * keymap_x11->mod_keymap->max_keypermod; + i = 3 * keymap_x11->mod_keymap->max_keypermod; while (i < map_size) { /* get the key code at this point in the map, * see if its keysym is GDK_Mode_switch, if so * we have the mode key */ - gint keycode = mod_keymap->modifiermap[i]; + gint keycode = keymap_x11->mod_keymap->modifiermap[i]; - if (keycode >= min_keycode && - keycode <= max_keycode) + if (keycode >= keymap_x11->min_keycode && + keycode <= keymap_x11->max_keycode) { gint j = 0; - KeySym *syms = keymap + (keycode - min_keycode) * keysyms_per_keycode; - while (j < keysyms_per_keycode) + KeySym *syms = keymap_x11->keymap + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode; + + while (j < keymap_x11->keysyms_per_keycode) { if (syms[j] == GDK_Mode_switch) { @@ -222,7 +303,7 @@ update_keymaps (void) * index */ - group_switch_mask |= (1 << ( i / mod_keymap->max_keypermod)); + keymap_x11->group_switch_mask |= (1 << ( i / keymap_x11->mod_keymap->max_keypermod)); break; } @@ -236,29 +317,32 @@ update_keymaps (void) } static const KeySym* -get_keymap (void) +get_keymap (GdkKeymapX11 *keymap_x11) { - update_keymaps (); + update_keymaps (keymap_x11); - return keymap; + return keymap_x11->keymap; } #if HAVE_XKB static PangoDirection -get_direction (void) +get_direction (GdkKeymapX11 *keymap_x11) { - XkbDescRec *xkb = get_xkb (); + XkbDescRec *xkb = get_xkb (keymap_x11); const char *name; XkbStateRec state_rec; PangoDirection result; - XkbGetState (gdk_display, XkbUseCoreKbd, &state_rec); + GdkDisplay *display = GDK_KEYMAP (keymap_x11)->display; + XkbGetState (GDK_DISPLAY_XDISPLAY (display), XkbUseCoreKbd, &state_rec); + if (xkb->names->groups[state_rec.locked_group] == None) result = PANGO_DIRECTION_LTR; else { - name = gdk_x11_get_xatom_name (xkb->names->groups[state_rec.locked_group]); + name = gdk_x11_get_xatom_name_for_display (display, xkb->names->groups[state_rec.locked_group]); + if (g_strcasecmp (name, "arabic") == 0 || g_strcasecmp (name, "hebrew") == 0 || g_strcasecmp (name, "israelian") == 0) @@ -271,17 +355,21 @@ get_direction (void) } void -_gdk_keymap_state_changed (void) +_gdk_keymap_state_changed (GdkDisplay *display) { - if (default_keymap) + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + + if (display_x11->keymap) { - PangoDirection new_direction = get_direction (); + GdkKeymapX11 *keymap_x11 = GDK_KEYMAP_X11 (display_x11->keymap); + + PangoDirection new_direction = get_direction (keymap_x11); - if (!have_direction || new_direction != current_direction) + if (!keymap_x11->have_direction || new_direction != keymap_x11->current_direction) { - have_direction = TRUE; - current_direction = new_direction; - g_signal_emit_by_name (G_OBJECT (default_keymap), "direction_changed"); + keymap_x11->have_direction = TRUE; + keymap_x11->current_direction = new_direction; + g_signal_emit_by_name (G_OBJECT (keymap_x11), "direction_changed"); } } } @@ -290,16 +378,26 @@ _gdk_keymap_state_changed (void) PangoDirection gdk_keymap_get_direction (GdkKeymap *keymap) { + if (!keymap) + { + keymap = gdk_keymap_get_for_display (gdk_get_default_display ()); + GDK_NOTE (MULTIHEAD, + g_message ("_multihead : reverting to default display keymap " + "in gdk_keymap_get_direction")); + } + #if HAVE_XKB - if (_gdk_use_xkb) + if (KEYMAP_USE_XKB (keymap)) { - if (!have_direction) + GdkKeymapX11 *keymap_x11 = GDK_KEYMAP_X11 (keymap); + + if (!keymap_x11->have_direction) { - current_direction = get_direction (); - have_direction = TRUE; + keymap_x11->current_direction = get_direction (keymap_x11); + keymap_x11->have_direction = TRUE; } - return current_direction; + return keymap_x11->current_direction; } else #endif /* HAVE_XKB */ @@ -334,25 +432,36 @@ gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap, gint *n_keys) { GArray *retval; + GdkKeymapX11 *keymap_x11; g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); g_return_val_if_fail (keys != NULL, FALSE); g_return_val_if_fail (n_keys != NULL, FALSE); g_return_val_if_fail (keyval != 0, FALSE); + + if (!keymap) + { + keymap = gdk_keymap_get_for_display (gdk_get_default_display ()); + GDK_NOTE (MULTIHEAD, + g_message ("_multihead : reverting to default display keymap " + "in gdk_keymap_get_entries_for_keyval\n")); + } + + keymap_x11 = GDK_KEYMAP_X11 (keymap); retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey)); #ifdef HAVE_XKB - if (_gdk_use_xkb) + if (KEYMAP_USE_XKB (keymap)) { /* See sec 15.3.4 in XKB docs */ - XkbDescRec *xkb = get_xkb (); + XkbDescRec *xkb = get_xkb (keymap_x11); gint keycode; - keycode = min_keycode; + keycode = keymap_x11->min_keycode; - while (keycode <= max_keycode) + while (keycode <= keymap_x11->max_keycode) { gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode); /* "key width" */ gint group = 0; @@ -383,7 +492,8 @@ gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap, g_array_append_val (retval, key); - g_assert (XkbKeySymEntry (xkb, keycode, level, group) == keyval); + g_assert (XkbKeySymEntry (xkb, keycode, level, group) == + keyval); } ++level; @@ -403,16 +513,16 @@ gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap, else #endif { - const KeySym *map = get_keymap (); + const KeySym *map = get_keymap (keymap_x11); gint keycode; - keycode = min_keycode; - while (keycode < max_keycode) + keycode = keymap_x11->min_keycode; + while (keycode < keymap_x11->max_keycode) { - const KeySym *syms = map + (keycode - min_keycode) * keysyms_per_keycode; + const KeySym *syms = map + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode; gint i = 0; - while (i < keysyms_per_keycode) + while (i < keymap_x11->keysyms_per_keycode) { if (syms[i] == keyval) { @@ -475,16 +585,28 @@ gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap, guint **keyvals, gint *n_entries) { + GdkKeymapX11 *keymap_x11; + GArray *key_array; GArray *keyval_array; g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); g_return_val_if_fail (n_entries != NULL, FALSE); - update_keyrange (); + if (!keymap) + { + keymap = gdk_keymap_get_for_display (gdk_get_default_display ()); + GDK_NOTE (MULTIHEAD, + g_message ("_multihead : reverting to default display keymap " + "in gdk_keymap_get_entries_for_keycode\n")); + } + + keymap_x11 = GDK_KEYMAP_X11 (keymap); + + update_keyrange (keymap_x11); - if (hardware_keycode < min_keycode || - hardware_keycode > max_keycode) + if (hardware_keycode < keymap_x11->min_keycode || + hardware_keycode > keymap_x11->max_keycode) { if (keys) *keys = NULL; @@ -506,11 +628,11 @@ gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap, keyval_array = NULL; #ifdef HAVE_XKB - if (_gdk_use_xkb) + if (KEYMAP_USE_XKB (keymap)) { /* See sec 15.3.4 in XKB docs */ - XkbDescRec *xkb = get_xkb (); + XkbDescRec *xkb = get_xkb (keymap_x11); gint max_shift_levels; gint group = 0; gint level = 0; @@ -560,13 +682,13 @@ gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap, else #endif { - const KeySym *map = get_keymap (); + const KeySym *map = get_keymap (keymap_x11); const KeySym *syms; gint i = 0; - syms = map + (hardware_keycode - min_keycode) * keysyms_per_keycode; + syms = map + (hardware_keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode; - while (i < keysyms_per_keycode) + while (i < keymap_x11->keysyms_per_keycode) { if (key_array) { @@ -639,23 +761,35 @@ guint gdk_keymap_lookup_key (GdkKeymap *keymap, const GdkKeymapKey *key) { + GdkKeymapX11 *keymap_x11; + g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), 0); g_return_val_if_fail (key != NULL, 0); g_return_val_if_fail (key->group < 4, 0); + if (!keymap) + { + keymap = gdk_keymap_get_for_display (gdk_get_default_display ()); + GDK_NOTE (MULTIHEAD, + g_message ("_multihead : reverting to default display keymap " + "in gdk_keymap_lookup_key\n")); + } + + keymap_x11 = GDK_KEYMAP_X11 (keymap); + #ifdef HAVE_XKB - if (_gdk_use_xkb) + if (KEYMAP_USE_XKB (keymap)) { - XkbDescRec *xkb = get_xkb (); + XkbDescRec *xkb = get_xkb (keymap_x11); return XkbKeySymEntry (xkb, key->keycode, key->level, key->group); } else #endif { - const KeySym *map = get_keymap (); - const KeySym *syms = map + (key->keycode - min_keycode) * keysyms_per_keycode; - return syms [KEYSYM_INDEX (key->group, key->level)]; + const KeySym *map = get_keymap (keymap_x11); + const KeySym *syms = map + (key->keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode; + return syms [KEYSYM_INDEX (keymap_x11, key->group, key->level)]; } } @@ -803,12 +937,15 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap, gint *level, GdkModifierType *consumed_modifiers) { + GdkKeymapX11 *keymap_x11; KeySym tmp_keyval = NoSymbol; guint tmp_modifiers; g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); g_return_val_if_fail (group < 4, FALSE); + keymap_x11 = GDK_KEYMAP_X11 (keymap); + if (keyval) *keyval = NoSymbol; if (effective_group) @@ -818,16 +955,16 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap, if (consumed_modifiers) *consumed_modifiers = 0; - update_keyrange (); + update_keyrange (keymap_x11); - if (hardware_keycode < min_keycode || - hardware_keycode > max_keycode) + if (hardware_keycode < keymap_x11->min_keycode || + hardware_keycode > keymap_x11->max_keycode) return FALSE; #ifdef HAVE_XKB - if (_gdk_use_xkb) + if (KEYMAP_USE_XKB (keymap)) { - XkbDescRec *xkb = get_xkb (); + XkbDescRec *xkb = get_xkb (keymap_x11); /* replace bits 13 and 14 with the provided group */ state &= ~(1 << 13 | 1 << 14); @@ -852,7 +989,7 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap, else #endif { - const KeySym *map = get_keymap (); + const KeySym *map = get_keymap (keymap_x11); const KeySym *syms; gint shift_level; gboolean ignore_shift = FALSE; @@ -867,24 +1004,24 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap, else shift_level = 0; - syms = map + (hardware_keycode - min_keycode) * keysyms_per_keycode; + syms = map + (hardware_keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode; -#define SYM(g,l) syms[KEYSYM_INDEX (g,l)] +#define SYM(k,g,l) syms[KEYSYM_INDEX (k,g,l)] /* Drop group and shift if there are no keysymbols on * the specified key. */ - if (!SYM (group, shift_level) && SYM (group, 0)) + if (!SYM (keymap_x11, group, shift_level) && SYM (keymap_x11, group, 0)) { shift_level = 0; ignore_shift = TRUE; } - if (!SYM (group, shift_level) && SYM (0, shift_level)) + if (!SYM (keymap_x11, group, shift_level) && SYM (keymap_x11, 0, shift_level)) { group = 0; ignore_group = TRUE; } - if (!SYM (group, shift_level) && SYM (0, 0)) + if (!SYM (keymap_x11, group, shift_level) && SYM (keymap_x11, 0, 0)) { shift_level = 0; group = 0; @@ -895,17 +1032,17 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap, /* See whether the group and shift level actually mattered * to know what to put in consumed_modifiers */ - if (!SYM (group, 1) || - SYM (group, 0) == SYM (group, 1)) + if (!SYM (keymap_x11, group, 1) || + SYM (keymap_x11, group, 0) == SYM (keymap_x11, group, 1)) ignore_shift = TRUE; - if (!SYM (1, shift_level) || - SYM (0, shift_level) == SYM (1, shift_level)) + if (!SYM (keymap_x11, 1, shift_level) || + SYM (keymap_x11, 0, shift_level) == SYM (keymap_x11, 1, shift_level)) ignore_group = TRUE; - tmp_keyval = SYM (group, shift_level); + tmp_keyval = SYM (keymap_x11, group, shift_level); - tmp_modifiers = ignore_group ? 0 : group_switch_mask; + tmp_modifiers = ignore_group ? 0 : keymap_x11->group_switch_mask; tmp_modifiers |= ignore_shift ? 0 : (GDK_SHIFT_MASK | GDK_LOCK_MASK); if (effective_group) @@ -984,17 +1121,21 @@ gdk_keyval_convert_case (guint symbol, #endif /* HAVE_XCONVERTCASE */ gint -_gdk_x11_get_group_for_state (GdkModifierType state) +_gdk_x11_get_group_for_state (GdkDisplay *display, + GdkModifierType state) { + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + #ifdef HAVE_XKB - if (_gdk_use_xkb) + if (display_x11->use_xkb) { return XkbGroupForCoreState (state); } else #endif { - update_keymaps (); - return (state & group_switch_mask) ? 1 : 0; + GdkKeymapX11 *keymap_impl = GDK_KEYMAP_X11 (gdk_keymap_get_for_display (display)); + update_keymaps (keymap_impl); + return (state & keymap_impl->group_switch_mask) ? 1 : 0; } } diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 0b87d8c0c..43a66b734 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -43,7 +43,8 @@ #include "gdk.h" -#include "gdkprivate-x11.h" +#include "gdkx.h" +#include "gdkdisplay-x11.h" #include "gdkinternals.h" #include "gdkregion-generic.h" #include "gdkinputprivate.h" @@ -86,111 +87,23 @@ static int gdk_x_io_error (Display *display); static int gdk_initialized = 0; /* 1 if the library is initialized, * 0 otherwise. */ - -static gint autorepeat; -static gboolean gdk_synchronize = FALSE; static GSList *gdk_error_traps = NULL; /* List of error traps */ static GSList *gdk_error_trap_free_list = NULL; /* Free list */ -/* Information about current pointer and keyboard grabs held by this - * client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window - * window is NULL, then the other associated fields are ignored - */ -static GdkWindowObject *gdk_pointer_xgrab_window = NULL; -static gulong gdk_pointer_xgrab_serial; -static gboolean gdk_pointer_xgrab_owner_events; - -static GdkWindowObject *gdk_keyboard_xgrab_window = NULL; -static gulong gdk_keyboard_xgrab_serial; -static gboolean gdk_keyboard_xgrab_owner_events; - GdkArgDesc _gdk_windowing_args[] = { - { "display", GDK_ARG_STRING, &_gdk_display_name, (GdkArgFunc)NULL }, - { "sync", GDK_ARG_BOOL, &gdk_synchronize, (GdkArgFunc)NULL }, - { "gxid-host", GDK_ARG_STRING, &_gdk_input_gxid_host, (GdkArgFunc)NULL }, - { "gxid-port", GDK_ARG_INT, &_gdk_input_gxid_port, (GdkArgFunc)NULL }, + { "sync", GDK_ARG_BOOL, &_gdk_synchronize, (GdkArgFunc)NULL }, { NULL } }; -gboolean -_gdk_windowing_init_check (int argc, char **argv) +void +_gdk_windowing_init (void) { - XKeyboardState keyboard_state; - XClassHint *class_hint; - gulong pid; - _gdk_x11_initialize_locale (); XSetErrorHandler (gdk_x_error); XSetIOErrorHandler (gdk_x_io_error); - - gdk_display = XOpenDisplay (_gdk_display_name); - if (!gdk_display) - return FALSE; - - if (gdk_synchronize) - XSynchronize (gdk_display, True); - - _gdk_screen = DefaultScreen (gdk_display); - _gdk_root_window = RootWindow (gdk_display, _gdk_screen); - - _gdk_leader_window = XCreateSimpleWindow(gdk_display, _gdk_root_window, - 10, 10, 10, 10, 0, 0 , 0); - class_hint = XAllocClassHint(); - class_hint->res_name = g_get_prgname (); - class_hint->res_class = (char *)gdk_get_program_class (); - XmbSetWMProperties (gdk_display, _gdk_leader_window, - NULL, NULL, argv, argc, - NULL, NULL, class_hint); - XFree (class_hint); - - pid = getpid(); - XChangeProperty (gdk_display, _gdk_leader_window, - gdk_x11_get_xatom_by_name ("_NET_WM_PID"), - XA_CARDINAL, 32, - PropModeReplace, - (guchar *)&pid, 1); - - _gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE); - - XGetKeyboardControl (gdk_display, &keyboard_state); - autorepeat = keyboard_state.global_auto_repeat; -#ifdef HAVE_XKB - { - gint xkb_major = XkbMajorVersion; - gint xkb_minor = XkbMinorVersion; - if (XkbLibraryVersion (&xkb_major, &xkb_minor)) - { - xkb_major = XkbMajorVersion; - xkb_minor = XkbMinorVersion; - - if (XkbQueryExtension (gdk_display, NULL, &_gdk_xkb_event_type, NULL, - &xkb_major, &xkb_minor)) - { - Bool detectable_autorepeat_supported; - - _gdk_use_xkb = TRUE; - - XkbSelectEvents (gdk_display, - XkbUseCoreKbd, - XkbMapNotifyMask | XkbStateNotifyMask, - XkbMapNotifyMask | XkbStateNotifyMask); - - XkbSetDetectableAutoRepeat (gdk_display, - True, - &detectable_autorepeat_supported); - - GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.", - detectable_autorepeat_supported ? "supported" : "not supported")); - - _gdk_have_xkb_autorepeat = detectable_autorepeat_supported; - } - } - } -#endif - - return TRUE; + _gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE); } void @@ -201,7 +114,7 @@ gdk_set_use_xshm (gboolean use_xshm) gboolean gdk_get_use_xshm (void) { - return _gdk_use_xshm; + return GDK_DISPLAY_X11 (gdk_get_default_display ())->use_xshm; } static GdkGrabStatus @@ -323,9 +236,10 @@ gdk_pointer_grab (GdkWindow * window, if (return_val == GrabSuccess) { - gdk_pointer_xgrab_window = (GdkWindowObject *)window; - gdk_pointer_xgrab_serial = serial; - gdk_pointer_xgrab_owner_events = owner_events; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); + display_x11->pointer_xgrab_window = (GdkWindowObject *)window; + display_x11->pointer_xgrab_serial = serial; + display_x11->pointer_xgrab_owner_events = owner_events; } return gdk_x11_convert_grab_status (return_val); @@ -349,10 +263,7 @@ gdk_pointer_grab (GdkWindow * window, void gdk_pointer_ungrab (guint32 time) { - _gdk_input_ungrab_pointer (time); - - XUngrabPointer (gdk_display, time); - gdk_pointer_xgrab_window = NULL; + gdk_display_pointer_ungrab (gdk_get_default_display (), time); } /* @@ -373,11 +284,12 @@ gdk_pointer_ungrab (guint32 time) gboolean gdk_pointer_is_grabbed (void) { - return gdk_pointer_xgrab_window != NULL; + return gdk_display_pointer_is_grabbed (gdk_get_default_display ()); } /** * gdk_pointer_grab_info_libgtk_only: + * @display: the #GdkDisplay for which to get the grab information * @grab_window: location to store current grab window * @owner_events: location to store boolean indicating whether * the @owner_events flag to gdk_pointer_grab() was %TRUE. @@ -389,15 +301,22 @@ gdk_pointer_is_grabbed (void) * pointer grabbed. **/ gboolean -gdk_pointer_grab_info_libgtk_only (GdkWindow **grab_window, +gdk_pointer_grab_info_libgtk_only (GdkDisplay *display, + GdkWindow **grab_window, gboolean *owner_events) { - if (gdk_pointer_xgrab_window) + GdkDisplayX11 *display_x11; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), False); + + display_x11 = GDK_DISPLAY_X11 (display); + + if (display_x11->pointer_xgrab_window) { if (grab_window) - *grab_window = (GdkWindow *)gdk_pointer_xgrab_window; + *grab_window = (GdkWindow *)display_x11->pointer_xgrab_window; if (owner_events) - *owner_events = gdk_pointer_xgrab_owner_events; + *owner_events = display_x11->pointer_xgrab_owner_events; return TRUE; } @@ -456,9 +375,10 @@ gdk_keyboard_grab (GdkWindow * window, if (return_val == GrabSuccess) { - gdk_keyboard_xgrab_window = (GdkWindowObject *)window; - gdk_keyboard_xgrab_serial = serial; - gdk_keyboard_xgrab_owner_events = owner_events; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window)); + display_x11->keyboard_xgrab_window = (GdkWindowObject *)window; + display_x11->keyboard_xgrab_serial = serial; + display_x11->keyboard_xgrab_owner_events = owner_events; } return gdk_x11_convert_grab_status (return_val); @@ -482,12 +402,12 @@ gdk_keyboard_grab (GdkWindow * window, void gdk_keyboard_ungrab (guint32 time) { - XUngrabKeyboard (gdk_display, time); - gdk_keyboard_xgrab_window = NULL; + gdk_display_keyboard_ungrab (gdk_get_default_display (), time); } /** * gdk_keyboard_grab_info_libgtk_only: + * @display: the display for which to get the grab information * @grab_window: location to store current grab window * @owner_events: location to store boolean indicating whether * the @owner_events flag to gdk_keyboard_grab() was %TRUE. @@ -499,15 +419,22 @@ gdk_keyboard_ungrab (guint32 time) * keyboard grabbed. **/ gboolean -gdk_keyboard_grab_info_libgtk_only (GdkWindow **grab_window, +gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display, + GdkWindow **grab_window, gboolean *owner_events) { - if (gdk_keyboard_xgrab_window) + GdkDisplayX11 *display_x11; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), False); + + display_x11 = GDK_DISPLAY_X11 (display); + + if (display_x11->keyboard_xgrab_window) { if (grab_window) - *grab_window = (GdkWindow *)gdk_keyboard_xgrab_window; + *grab_window = (GdkWindow *)display_x11->keyboard_xgrab_window; if (owner_events) - *owner_events = gdk_keyboard_xgrab_owner_events; + *owner_events = display_x11->keyboard_xgrab_owner_events; return TRUE; } @@ -529,30 +456,33 @@ void _gdk_xgrab_check_unmap (GdkWindow *window, gulong serial) { - if (gdk_pointer_xgrab_window && serial >= gdk_pointer_xgrab_serial) + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window)); + + if (display_x11->pointer_xgrab_window && + serial >= display_x11->pointer_xgrab_serial) { GdkWindowObject *private = GDK_WINDOW_OBJECT (window); - GdkWindowObject *tmp = gdk_pointer_xgrab_window; - + GdkWindowObject *tmp = display_x11->pointer_xgrab_window; while (tmp && tmp != private) tmp = tmp->parent; if (tmp) - gdk_pointer_xgrab_window = NULL; + display_x11->pointer_xgrab_window = NULL; } - if (gdk_keyboard_xgrab_window && serial >= gdk_keyboard_xgrab_serial) + if (display_x11->keyboard_xgrab_window && + serial >= display_x11->keyboard_xgrab_serial) { GdkWindowObject *private = GDK_WINDOW_OBJECT (window); - GdkWindowObject *tmp = gdk_keyboard_xgrab_window; + GdkWindowObject *tmp = display_x11->keyboard_xgrab_window; while (tmp && tmp != private) tmp = tmp->parent; if (tmp) - gdk_keyboard_xgrab_window = NULL; + display_x11->keyboard_xgrab_window = NULL; } } @@ -566,11 +496,13 @@ _gdk_xgrab_check_unmap (GdkWindow *window, void _gdk_xgrab_check_destroy (GdkWindow *window) { - if ((GdkWindowObject *)window == gdk_pointer_xgrab_window) - gdk_pointer_xgrab_window = NULL; + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window)); + + if ((GdkWindowObject *)window == display_x11->pointer_xgrab_window) + display_x11->pointer_xgrab_window = NULL; - if ((GdkWindowObject *)window == gdk_keyboard_xgrab_window) - gdk_keyboard_xgrab_window = NULL; + if ((GdkWindowObject *)window == display_x11->keyboard_xgrab_window) + display_x11->keyboard_xgrab_window = NULL; } /* @@ -591,11 +523,7 @@ _gdk_xgrab_check_destroy (GdkWindow *window) gint gdk_screen_width (void) { - gint return_val; - - return_val = DisplayWidth (gdk_display, _gdk_screen); - - return return_val; + return gdk_screen_get_width (gdk_get_default_screen()); } /* @@ -616,11 +544,7 @@ gdk_screen_width (void) gint gdk_screen_height (void) { - gint return_val; - - return_val = DisplayHeight (gdk_display, _gdk_screen); - - return return_val; + return gdk_screen_get_height (gdk_get_default_screen()); } /* @@ -641,11 +565,7 @@ gdk_screen_height (void) gint gdk_screen_width_mm (void) { - gint return_val; - - return_val = DisplayWidthMM (gdk_display, _gdk_screen); - - return return_val; + return gdk_screen_get_width_mm (gdk_get_default_screen()); } /* @@ -666,62 +586,82 @@ gdk_screen_width_mm (void) gint gdk_screen_height_mm (void) { - gint return_val; - - return_val = DisplayHeightMM (gdk_display, _gdk_screen); - - return return_val; + return gdk_screen_get_height_mm (gdk_get_default_screen ()); } -/* - *-------------------------------------------------------------- - * gdk_set_sm_client_id - * - * Set the SM_CLIENT_ID property on the WM_CLIENT_LEADER window - * so that the window manager can save our state using the - * X11R6 ICCCM session management protocol. A NULL value should - * be set following disconnection from the session manager to - * remove the SM_CLIENT_ID property. - * - * Arguments: +/** + * gdk_set_sm_client_id: + * @sm_client_id: the client id assigned by the session manager when the + * connection was opened, or %NULL to remove the property. * - * "sm_client_id" specifies the client id assigned to us by the - * session manager or NULL to remove the property. - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - + * Sets the <literal>SM_CLIENT_ID</literal> property on the application's leader window so that + * the window manager can save the application's state using the X11R6 ICCCM + * session management protocol. + * + * See the X Session Management Library documentation for more information on + * session management and the Inter-Client Communication Conventions Manual + * (ICCCM) for information on the <literal>WM_CLIENT_LEADER</literal> property. + * (Both documents are part of the X Window System distribution.) + **/ void gdk_set_sm_client_id (const gchar* sm_client_id) { + gdk_display_set_sm_client_id (gdk_get_default_display (),sm_client_id); +} + +/** + * gdk_display_set_sm_client_id: + * @display: a #GdkDisplay + * @sm_client_id: the client id assigned by the session manager when the + * connection was opened, or %NULL to remove the property. + * + * Sets the <literal>SM_CLIENT_ID</literal> property on the application's leader window + * so that the window manager can save the application's state using the X11R6 ICCCM + * session management protocol. + * + * See the X Session Management Library documentation for more information on + * session management and the Inter-Client Communication Conventions Manual + * (ICCCM) for information on the <literal>WM_CLIENT_LEADER</literal> property. + * (Both documents are part of the X Window System distribution.) + **/ +void +gdk_display_set_sm_client_id (GdkDisplay *display, + const gchar *sm_client_id) +{ + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + if (sm_client_id && strcmp (sm_client_id, "")) { - XChangeProperty (gdk_display, _gdk_leader_window, - gdk_x11_get_xatom_by_name ("SM_CLIENT_ID"), - XA_STRING, 8, PropModeReplace, - sm_client_id, strlen(sm_client_id)); + XChangeProperty (display_x11->xdisplay, display_x11->leader_window, + gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"), + XA_STRING, 8, PropModeReplace, sm_client_id, + strlen (sm_client_id)); } else - XDeleteProperty (gdk_display, _gdk_leader_window, - gdk_x11_get_xatom_by_name ("SM_CLIENT_ID")); + XDeleteProperty (display_x11->xdisplay, display_x11->leader_window, + gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID")); } void gdk_beep (void) { - XBell(gdk_display, 0); + gdk_display_beep (gdk_get_default_display ()); } +/* Close all open displays + */ void _gdk_windowing_exit (void) { - pango_x_shutdown_display (gdk_display); - - XCloseDisplay (gdk_display); + GSList *tmp_list = _gdk_displays; + + while (tmp_list) + { + pango_x_shutdown_display (GDK_DISPLAY_XDISPLAY (tmp_list->data)); + XCloseDisplay (GDK_DISPLAY_XDISPLAY (tmp_list->data)); + + tmp_list = tmp_list->next; + } } /* @@ -825,14 +765,14 @@ gdk_x_io_error (Display *display) "most likely the X server was shut down or you killed/destroyed\n" "the application.\n", g_get_prgname (), - gdk_display ? DisplayString (gdk_display) : gdk_get_display()); + display ? DisplayString (display) : gdk_get_display_arg_name ()); } else { fprintf (stderr, "%s: Fatal IO error %d (%s) on X server %s.\n", g_get_prgname (), errno, g_strerror (errno), - gdk_display ? DisplayString (gdk_display) : gdk_get_display()); + display ? DisplayString (display) : gdk_get_display_arg_name ()); } /* Disable the atexit shutdown for GDK */ @@ -917,18 +857,37 @@ gdk_error_trap_pop (void) gchar * gdk_get_display (void) { - return (gchar *)XDisplayName (_gdk_display_name); + return g_strdup (gdk_display_get_name (gdk_get_default_display ())); } +/** + * _gdk_send_xevent: + * @display: #GdkDisplay which @window is on + * @window: window ID to which to send the event + * @propagate: %TRUE if the event should be propagated if the target window + * doesn't handle it. + * @event_mask: event mask to match against, or 0 to send it to @window + * without regard to event masks. + * @event_send: #XEvent to send + * + * Send an event, like XSendEvent(), but trap errors and check + * the result. + * + * Return value: %TRUE if sending the event succeeded. + **/ gint -gdk_send_xevent (Window window, gboolean propagate, glong event_mask, - XEvent *event_send) +_gdk_send_xevent (GdkDisplay *display, + Window window, + gboolean propagate, + glong event_mask, + XEvent *event_send) { gboolean result; - + gdk_error_trap_push (); - result = XSendEvent (gdk_display, window, propagate, event_mask, event_send); - XSync (gdk_display, False); + result = XSendEvent (GDK_DISPLAY_XDISPLAY (display), window, + propagate, event_mask, event_send); + XSync (GDK_DISPLAY_XDISPLAY (display), False); return result && gdk_error_trap_pop() == Success; } @@ -956,24 +915,16 @@ _gdk_region_get_xrectangles (GdkRegion *region, *n_rects = region->numRects; } -/* FIXME put in GdkDisplay */ -static gint grab_count = 0; void -gdk_x11_grab_server (void) -{ - if (grab_count == 0) - XGrabServer (gdk_display); - ++grab_count; +gdk_x11_grab_server () +{ + gdk_x11_display_grab (gdk_get_default_display ()); } void -gdk_x11_ungrab_server (void) +gdk_x11_ungrab_server () { - g_return_if_fail (grab_count > 0); - - --grab_count; - if (grab_count == 0) - XUngrabServer (gdk_display); + gdk_x11_display_ungrab (gdk_get_default_display ()); } /** @@ -988,17 +939,17 @@ gdk_x11_ungrab_server (void) gint gdk_x11_get_default_screen (void) { - return _gdk_screen; + return gdk_screen_get_number (gdk_get_default_screen ()); } Window gdk_x11_get_default_root_xwindow (void) { - return _gdk_root_window; + return GDK_SCREEN_XROOTWIN (gdk_get_default_screen ()); } Display * gdk_x11_get_default_xdisplay (void) { - return gdk_display; + return GDK_DISPLAY_XDISPLAY (gdk_get_default_display ()); } diff --git a/gdk/x11/gdkpango-x11.c b/gdk/x11/gdkpango-x11.c index a823cf96a..bec7b5981 100644 --- a/gdk/x11/gdkpango-x11.c +++ b/gdk/x11/gdkpango-x11.c @@ -20,7 +20,8 @@ #include <config.h> #include <stdlib.h> -#include "gdkprivate-x11.h" +#include "gdkx.h" +#include "gdkdisplay-x11.h" #include "gdkpango.h" #include <pango/pangox.h> #ifdef HAVE_XFT @@ -28,9 +29,10 @@ #endif /** - * gdk_pango_context_get: + * gdk_pango_context_get_for_screen: + * @screen: the #GdkScreen for which the context is to be created. * - * Creates a #PangoContext for the default GDK display. + * Creates a #PangoContext for @screen. * * The context must be freed when you're finished with it. * @@ -38,23 +40,54 @@ * instead of this function, to get the appropriate context for * the widget you intend to render text onto. * - * Return value: a new #PangoContext for the default display + * Return value: a new #PangoContext for @screen **/ PangoContext * -gdk_pango_context_get (void) +gdk_pango_context_get_for_screen (GdkScreen *screen) { + PangoContext *context; + GdkDisplayX11 *display_x11; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + display_x11 = GDK_DISPLAY_X11 (GDK_SCREEN_DISPLAY (screen)); + #ifdef HAVE_XFT - static gint use_xft = -1; - if (use_xft == -1) + if (display_x11->use_xft == -1) { const char *val = g_getenv ("GDK_USE_XFT"); - use_xft = val && (atoi (val) != 0) && _gdk_x11_have_render (); + display_x11->use_xft = val && (atoi (val) != 0) && + _gdk_x11_have_render (GDK_SCREEN_DISPLAY (screen)); } - if (use_xft) - return pango_xft_get_context (GDK_DISPLAY (), DefaultScreen (GDK_DISPLAY ())); + if (display_x11->use_xft) + context = pango_xft_get_context (GDK_SCREEN_XDISPLAY (screen), + GDK_SCREEN_X11 (screen)->screen_num); else #endif /* HAVE_XFT */ - return pango_x_get_context (GDK_DISPLAY ()); + context = pango_x_get_context (GDK_SCREEN_XDISPLAY (screen)); + + g_object_set_data (G_OBJECT (context), "gdk-pango-screen", screen); + + return context; +} + +/** + * gdk_pango_context_get: + * + * Creates a #PangoContext for the default GDK screen. + * + * The context must be freed when you're finished with it. + * + * When using GTK+, normally you should use gtk_widget_get_pango_context() + * instead of this function, to get the appropriate context for + * the widget you intend to render text onto. + * + * Return value: a new #PangoContext for the default display + **/ +PangoContext * +gdk_pango_context_get (void) +{ + return gdk_pango_context_get_for_screen (gdk_get_default_screen ()); } diff --git a/gdk/x11/gdkpixmap-x11.c b/gdk/x11/gdkpixmap-x11.c index 1f335f220..450347c4a 100644 --- a/gdk/x11/gdkpixmap-x11.c +++ b/gdk/x11/gdkpixmap-x11.c @@ -36,6 +36,10 @@ #include "gdkpixmap-x11.h" #include "gdkprivate-x11.h" +#include "gdkscreen-x11.h" +#include "gdkdisplay-x11.h" + +#include <gdk/gdkinternals.h> typedef struct { @@ -127,14 +131,14 @@ gdk_pixmap_impl_x11_finalize (GObject *object) GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (impl); if (draw_impl->picture) - XRenderFreePicture (draw_impl->xdisplay, draw_impl->picture); + XRenderFreePicture (GDK_PIXMAP_XDISPLAY (wrapper), draw_impl->picture); } #endif /* HAVE_XFT */ if (!impl->is_foreign) XFreePixmap (GDK_PIXMAP_XDISPLAY (wrapper), GDK_PIXMAP_XID (wrapper)); - gdk_xid_table_remove (GDK_PIXMAP_XID (wrapper)); + _gdk_xid_table_remove (GDK_PIXMAP_DISPLAY (wrapper), GDK_PIXMAP_XID (wrapper)); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -167,7 +171,11 @@ gdk_pixmap_new (GdkWindow *window, g_return_val_if_fail ((width != 0) && (height != 0), NULL); if (!window) - window = _gdk_parent_root; + { + GDK_NOTE (MULTIHEAD, g_message ("need to specify the screen parent window " + "for gdk_pixmap_new() to be multihead safe")); + window = gdk_screen_get_root_window (gdk_get_default_screen ()); + } if (GDK_IS_WINDOW (window) && GDK_WINDOW_DESTROYED (window)) return NULL; @@ -181,7 +189,7 @@ gdk_pixmap_new (GdkWindow *window, pix_impl = GDK_PIXMAP_IMPL_X11 (GDK_PIXMAP_OBJECT (pixmap)->impl); draw_impl->wrapper = GDK_DRAWABLE (pixmap); - draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (window); + draw_impl->screen = GDK_WINDOW_SCREEN (window); draw_impl->xid = XCreatePixmap (GDK_PIXMAP_XDISPLAY (pixmap), GDK_WINDOW_XID (window), width, height, depth); @@ -198,8 +206,8 @@ gdk_pixmap_new (GdkWindow *window, gdk_drawable_set_colormap (pixmap, cmap); } - gdk_xid_table_insert (&draw_impl->xid, pixmap); - + _gdk_xid_table_insert (GDK_WINDOW_DISPLAY (window), + &GDK_PIXMAP_XID (pixmap), pixmap); return pixmap; } @@ -217,9 +225,13 @@ gdk_bitmap_create_from_data (GdkWindow *window, g_return_val_if_fail ((width != 0) && (height != 0), NULL); g_return_val_if_fail (window == NULL || GDK_IS_DRAWABLE (window), NULL); - if (!window) - window = _gdk_parent_root; - + if (!window) + { + GDK_NOTE (MULTIHEAD, g_message ("need to specify the screen parent window " + "for gdk_bitmap_create_from_data() to be multihead safe")); + window = gdk_screen_get_root_window (gdk_get_default_screen ()); + } + if (GDK_IS_WINDOW (window) && GDK_WINDOW_DESTROYED (window)) return NULL; @@ -233,13 +245,13 @@ gdk_bitmap_create_from_data (GdkWindow *window, pix_impl->height = height; GDK_PIXMAP_OBJECT (pixmap)->depth = 1; - draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (window); + draw_impl->screen = GDK_WINDOW_SCREEN (window); draw_impl->xid = XCreateBitmapFromData (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), (char *)data, width, height); - gdk_xid_table_insert (&draw_impl->xid, pixmap); - + _gdk_xid_table_insert (GDK_WINDOW_DISPLAY (window), + &GDK_PIXMAP_XID (pixmap), pixmap); return pixmap; } @@ -264,7 +276,11 @@ gdk_pixmap_create_from_data (GdkWindow *window, g_return_val_if_fail ((width != 0) && (height != 0), NULL); if (!window) - window = _gdk_parent_root; + { + GDK_NOTE (MULTIHEAD, g_message ("need to specify the screen parent window" + "for gdk_pixmap_create_from_data() to be multihead safe")); + window = gdk_screen_get_root_window (gdk_get_default_screen ()); + } if (GDK_IS_WINDOW (window) && GDK_WINDOW_DESTROYED (window)) return NULL; @@ -282,19 +298,20 @@ gdk_pixmap_create_from_data (GdkWindow *window, pix_impl->height = height; GDK_PIXMAP_OBJECT (pixmap)->depth = depth; - draw_impl->xdisplay = GDK_DRAWABLE_XDISPLAY (window); + draw_impl->screen = GDK_DRAWABLE_SCREEN (window); draw_impl->xid = XCreatePixmapFromBitmapData (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), (char *)data, width, height, fg->pixel, bg->pixel, depth); - gdk_xid_table_insert (&draw_impl->xid, pixmap); - + _gdk_xid_table_insert (GDK_WINDOW_DISPLAY (window), + &GDK_PIXMAP_XID (pixmap), pixmap); return pixmap; } /** - * gdk_pixmap_foreign_new: + * gdk_pixmap_foreign_new_for_display: + * @screen : The #GdkScreen the @anid is located. * @anid: a native pixmap handle. * * Wraps a native window in a #GdkPixmap. @@ -306,8 +323,9 @@ gdk_pixmap_create_from_data (GdkWindow *window, * Return value: the newly-created #GdkPixmap wrapper for the * native pixmap or %NULL if the pixmap has been destroyed. **/ -GdkPixmap* -gdk_pixmap_foreign_new (GdkNativeWindow anid) +GdkPixmap * +gdk_pixmap_foreign_new_for_display (GdkDisplay *display, + GdkNativeWindow anid) { GdkPixmap *pixmap; GdkDrawableImplX11 *draw_impl; @@ -317,27 +335,28 @@ gdk_pixmap_foreign_new (GdkNativeWindow anid) int x_ret, y_ret; unsigned int w_ret, h_ret, bw_ret, depth_ret; + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + /* check to make sure we were passed something at - least a little sane */ - g_return_val_if_fail((anid != 0), NULL); + * least a little sane */ + g_return_val_if_fail ((anid != 0), NULL); /* set the pixmap to the passed in value */ xpixmap = anid; /* get information about the Pixmap to fill in the structure for the gdk window */ - if (!XGetGeometry(GDK_DISPLAY(), - xpixmap, &root_return, - &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret)) - return NULL; + if (!XGetGeometry (GDK_SCREEN_XDISPLAY (display), + xpixmap, &root_return, + &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret)) + return NULL; pixmap = g_object_new (gdk_pixmap_get_type (), NULL); draw_impl = GDK_DRAWABLE_IMPL_X11 (GDK_PIXMAP_OBJECT (pixmap)->impl); pix_impl = GDK_PIXMAP_IMPL_X11 (GDK_PIXMAP_OBJECT (pixmap)->impl); draw_impl->wrapper = GDK_DRAWABLE (pixmap); - - draw_impl->xdisplay = GDK_DISPLAY (); + draw_impl->screen = _gdk_x11_display_screen_for_xrootwin (display, root_return); draw_impl->xid = xpixmap; pix_impl->is_foreign = TRUE; @@ -345,12 +364,45 @@ gdk_pixmap_foreign_new (GdkNativeWindow anid) pix_impl->height = h_ret; GDK_PIXMAP_OBJECT (pixmap)->depth = depth_ret; - gdk_xid_table_insert(&draw_impl->xid, pixmap); + _gdk_xid_table_insert (display, &GDK_PIXMAP_XID (pixmap), pixmap); return pixmap; } /** + * gdk_pixmap_foreign_new: + * @anid: a native pixmap handle. + * + * Wraps a native window for the default display in a #GdkPixmap. + * This may fail if the pixmap has been destroyed. + * + * For example in the X backend, a native pixmap handle is an Xlib + * <type>XID</type>. + * + * Return value: the newly-created #GdkPixmap wrapper for the + * native pixmap or %NULL if the pixmap has been destroyed. + **/ +GdkPixmap* +gdk_pixmap_foreign_new (GdkNativeWindow anid) +{ + return gdk_pixmap_foreign_new_for_display (gdk_get_default_display (), anid); +} + +/** + * gdk_pixmap_get_screen : + * @drawable : the #GdkPixmap. + * + * Returns the #GdkScreen for which the pixmap was created. + * + * Returns: the #GdkScreen for which the pixmap was created. + */ +GdkScreen* +gdk_pixmap_get_screen (GdkDrawable *drawable) +{ + return GDK_PIXMAP_SCREEN (drawable); +} + +/** * gdk_pixmap_lookup: * @anid: a native pixmap handle. * @@ -365,5 +417,25 @@ gdk_pixmap_foreign_new (GdkNativeWindow anid) GdkPixmap* gdk_pixmap_lookup (GdkNativeWindow anid) { - return (GdkPixmap*) gdk_xid_table_lookup (anid); + return (GdkPixmap*) gdk_xid_table_lookup_for_display (gdk_get_default_display (), anid); +} + +/** + * gdk_pixmap_lookup_for_display: + * @display : the #GdkDisplay associated with @anid + * @anid: a native pixmap handle. + * + * Looks up the #GdkPixmap that wraps the given native pixmap handle. + * + * For example in the X backend, a native pixmap handle is an Xlib + * <type>XID</type>. + * + * Return value: the #GdkWindow wrapper for the native window, + * or %NULL if there is none. + **/ +GdkPixmap* +gdk_pixmap_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + return (GdkPixmap*) gdk_xid_table_lookup_for_display (display, anid); } diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h index b7bb8a6b6..5b0447c3b 100644 --- a/gdk/x11/gdkprivate-x11.h +++ b/gdk/x11/gdkprivate-x11.h @@ -31,6 +31,7 @@ #ifndef __GDK_PRIVATE_X11_H__ #define __GDK_PRIVATE_X11_H__ +#include <gdk/gdkcursor.h> #include <gdk/gdkprivate.h> #include <gdk/x11/gdkwindow-x11.h> #include <gdk/x11/gdkpixmap-x11.h> @@ -60,7 +61,7 @@ struct _GdkGCX11 GdkGC parent_instance; GC xgc; - Display *xdisplay; + GdkScreen *screen; GdkRegion *clip_region; guint dirty_mask; @@ -80,7 +81,7 @@ struct _GdkCursorPrivate { GdkCursor cursor; Cursor xcursor; - Display *xdisplay; + GdkScreen *screen; }; struct _GdkVisualPrivate @@ -89,19 +90,22 @@ struct _GdkVisualPrivate Visual *xvisual; }; -void gdk_xid_table_insert (XID *xid, - gpointer data); -void gdk_xid_table_remove (XID xid); -gint gdk_send_xevent (Window window, - gboolean propagate, - glong event_mask, - XEvent *event_send); +void _gdk_xid_table_insert (GdkDisplay *display, + XID *xid, + gpointer data); +void _gdk_xid_table_remove (GdkDisplay *display, + XID xid); +gint _gdk_send_xevent (GdkDisplay *display, + Window window, + gboolean propagate, + glong event_mask, + XEvent *event_send); GType _gdk_gc_x11_get_type (void); #ifdef HAVE_XFT -gboolean _gdk_x11_have_render (void); -Picture _gdk_x11_gc_get_fg_picture (GdkGC *gc); +gboolean _gdk_x11_have_render (GdkDisplay *display); +Picture _gdk_x11_gc_get_fg_picture (GdkGC *gc); #endif /* HAVE_XFT */ GdkGC *_gdk_x11_gc_new (GdkDrawable *drawable, @@ -123,19 +127,6 @@ GdkImage *_gdk_x11_copy_to_image (GdkDrawable *drawable, gint height); Pixmap _gdk_x11_image_get_shm_pixmap (GdkImage *image); -/* Please see gdkwindow.c for comments on how to use */ -Window gdk_window_xid_at (Window base, - gint bx, - gint by, - gint x, - gint y, - GList *excludes, - gboolean excl_child); -Window gdk_window_xid_at_coords (gint x, - gint y, - GList *excludes, - gboolean excl_child); - /* Routines from gdkgeometry-x11.c */ void _gdk_window_init_position (GdkWindow *window); void _gdk_window_move_resize_child (GdkWindow *window, @@ -156,11 +147,13 @@ void _gdk_region_get_xrectangles (GdkRegion *region, XRectangle **rects, gint *n_rects); -void _gdk_moveresize_handle_event (XEvent *event); -void _gdk_moveresize_configure_done (void); +gboolean _gdk_moveresize_handle_event (XEvent *event); +gboolean _gdk_moveresize_configure_done (GdkDisplay *display, + GdkWindow *window); -void _gdk_keymap_state_changed (void); -gint _gdk_x11_get_group_for_state (GdkModifierType state); +void _gdk_keymap_state_changed (GdkDisplay *display); +gint _gdk_x11_get_group_for_state (GdkDisplay *display, + GdkModifierType state); GC _gdk_x11_gc_flush (GdkGC *gc); @@ -170,33 +163,36 @@ void _gdk_xgrab_check_unmap (GdkWindow *window, gulong serial); void _gdk_xgrab_check_destroy (GdkWindow *window); +gboolean _gdk_x11_display_is_root_window (GdkDisplay *display, + Window xroot_window); + +void _gdk_x11_events_init_screen (GdkScreen *screen); + +void _gdk_events_init (GdkDisplay *display); +void _gdk_windowing_window_init (GdkScreen *screen); +void _gdk_visual_init (GdkScreen *screen); +void _gdk_dnd_init (GdkDisplay *display); +void _gdk_windowing_image_init (GdkDisplay *display); +void _gdk_input_init (GdkDisplay *display); + extern GdkDrawableClass _gdk_x11_drawable_class; -extern Window _gdk_root_window; extern gboolean _gdk_use_xshm; -extern Atom _gdk_wm_window_protocols[]; extern const int _gdk_nenvent_masks; extern const int _gdk_event_mask_table[]; -extern gint _gdk_screen; extern GdkAtom _gdk_selection_property; -extern gchar *_gdk_display_name; - -extern Window _gdk_leader_window; - -/* Used to detect not-up-to-date keymap */ -extern guint _gdk_keymap_serial; - -#ifdef HAVE_XKB -extern gboolean _gdk_use_xkb; -extern gboolean _gdk_have_xkb_autorepeat; -extern gint _gdk_xkb_event_type; -#endif - -/* Whether we were able to turn on detectable-autorepeat using - * XkbSetDetectableAutorepeat. If FALSE, we'll fall back - * to checking the next event with XPending(). - */ -extern gboolean _gdk_have_xkb_autorepeat; - -extern GdkWindow *_gdk_moveresize_window; +extern gboolean _gdk_synchronize; + +#define GDK_PIXMAP_SCREEN(pix) (GDK_DRAWABLE_IMPL_X11 (((GdkPixmapObject *)pix)->impl)->screen) +#define GDK_PIXMAP_DISPLAY(pix) (GDK_SCREEN_X11 (GDK_PIXMAP_SCREEN (pix))->display) +#define GDK_PIXMAP_XROOTWIN(pix) (GDK_SCREEN_X11 (GDK_PIXMAP_SCREEN (pix))->xroot_window) +#define GDK_DRAWABLE_DISPLAY(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_DISPLAY (win) : GDK_PIXMAP_DISPLAY (win)) +#define GDK_DRAWABLE_SCREEN(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_SCREEN (win) : GDK_PIXMAP_SCREEN (win)) +#define GDK_DRAWABLE_XROOTWIN(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_XROOTWIN (win) : GDK_PIXMAP_XROOTWIN (win)) +#define GDK_SCREEN_DISPLAY(screen) (GDK_SCREEN_X11 (screen)->display) +#define GDK_SCREEN_XROOTWIN(screen) (GDK_SCREEN_X11 (screen)->xroot_window) +#define GDK_WINDOW_SCREEN(win) (GDK_DRAWABLE_IMPL_X11 (((GdkWindowObject *)win)->impl)->screen) +#define GDK_WINDOW_DISPLAY(win) (GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (win))->display) +#define GDK_WINDOW_XROOTWIN(win) (GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (win))->xroot_window) +#define GDK_GC_DISPLAY(gc) (GDK_SCREEN_DISPLAY (GDK_GC_X11(gc)->screen)) #endif /* __GDK_PRIVATE_X11_H__ */ diff --git a/gdk/x11/gdkproperty-x11.c b/gdk/x11/gdkproperty-x11.c index b5295d506..424c2baf5 100644 --- a/gdk/x11/gdkproperty-x11.c +++ b/gdk/x11/gdkproperty-x11.c @@ -32,11 +32,13 @@ #include "gdkx.h" #include "gdkproperty.h" #include "gdkprivate.h" +#include "gdkinternals.h" +#include "gdkdisplay-x11.h" +#include "gdkscreen-x11.h" +#include "gdkselection.h" /* only from predefined atom */ static GPtrArray *virtual_atom_array; static GHashTable *virtual_atom_hash; -static GHashTable *atom_to_virtual; -static GHashTable *atom_from_virtual; static gchar *XAtomsStrings[] = { /* These are all the standard predefined X atoms */ @@ -85,7 +87,8 @@ static gchar *XAtomsStrings[] = { "WM_ZOOM_HINTS", "MIN_SPACE", "NORM_SPACE", - "MAX_SPACE", "END_SPACE", + "MAX_SPACE", + "END_SPACE", "SUPERSCRIPT_X", "SUPERSCRIPT_Y", "SUBSCRIPT_X", @@ -120,40 +123,51 @@ static gchar *XAtomsStrings[] = { #define INDEX_TO_ATOM(atom) ((GdkAtom)GUINT_TO_POINTER(atom)) static void -insert_atom_pair (GdkAtom virtual_atom, +insert_atom_pair (GdkDisplay *display, + GdkAtom virtual_atom, Atom xatom) { - if (!atom_from_virtual) + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + + if (!display_x11->atom_from_virtual) { - atom_from_virtual = g_hash_table_new (g_direct_hash, NULL); - atom_to_virtual = g_hash_table_new (g_direct_hash, NULL); + display_x11->atom_from_virtual = g_hash_table_new (g_direct_hash, NULL); + display_x11->atom_to_virtual = g_hash_table_new (g_direct_hash, NULL); } - g_hash_table_insert (atom_from_virtual, - GDK_ATOM_TO_POINTER (virtual_atom), GUINT_TO_POINTER (xatom)); - g_hash_table_insert (atom_to_virtual, - GUINT_TO_POINTER (xatom), GDK_ATOM_TO_POINTER (virtual_atom)); + g_hash_table_insert (display_x11->atom_from_virtual, + GDK_ATOM_TO_POINTER (virtual_atom), + GUINT_TO_POINTER (xatom)); + g_hash_table_insert (display_x11->atom_to_virtual, + GUINT_TO_POINTER (xatom), + GDK_ATOM_TO_POINTER (virtual_atom)); } - /** - * gdk_x11_atom_to_xatom: + * gdk_x11_atom_to_xatom_for_display: + * @display: A #GdkDisplay * @atom: A #GdkAtom * - * Converts from a #GdkAtom to the X atom for the default GDK display + * Converts from a #GdkAtom to the X atom for a #GdkDisplay * with the same string value. * * Return value: the X atom corresponding to @atom. **/ Atom -gdk_x11_atom_to_xatom (GdkAtom atom) +gdk_x11_atom_to_xatom_for_display (GdkDisplay *display, + GdkAtom atom) { + GdkDisplayX11 *display_x11; Atom xatom = None; + g_return_val_if_fail (GDK_IS_DISPLAY (display), None); + + display_x11 = GDK_DISPLAY_X11 (display); + if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED) return ATOM_TO_INDEX (atom); - if (atom_from_virtual) - xatom = GPOINTER_TO_UINT (g_hash_table_lookup (atom_from_virtual, + if (display_x11->atom_from_virtual) + xatom = GPOINTER_TO_UINT (g_hash_table_lookup (display_x11->atom_from_virtual, GDK_ATOM_TO_POINTER (atom))); if (!xatom) { @@ -163,32 +177,54 @@ gdk_x11_atom_to_xatom (GdkAtom atom) name = g_ptr_array_index (virtual_atom_array, ATOM_TO_INDEX (atom)); - xatom = XInternAtom (gdk_display, name, FALSE); - insert_atom_pair (atom, xatom); + xatom = XInternAtom (GDK_DISPLAY_XDISPLAY (display), name, FALSE); + insert_atom_pair (display, atom, xatom); } return xatom; } /** - * gdk_x11_xatom_to_atom: - * @xatom: an X atom for the default GDK display + * gdk_x11_atom_to_xatom: + * @atom: A #GdkAtom * - * Converts from an X atom for the default display to the corresponding + * Converts from a #GdkAtom to the X atom for the default GDK display + * with the same string value. + * + * Return value: the X atom corresponding to @atom. + **/ +Atom +gdk_x11_atom_to_xatom (GdkAtom atom) +{ + return gdk_x11_atom_to_xatom_for_display (gdk_get_default_display (), atom); +} + +/** + * gdk_x11_xatom_to_atom_for_display: + * @display: A #GdkDisplay + * @xatom: an X atom + * + * Convert from an X atom for a #GdkDisplay to the corresponding * #GdkAtom. * * Return value: the corresponding #GdkAtom. **/ GdkAtom -gdk_x11_xatom_to_atom (Atom xatom) +gdk_x11_xatom_to_atom_for_display (GdkDisplay *display, + Atom xatom) { + GdkDisplayX11 *display_x11; GdkAtom virtual_atom = GDK_NONE; + g_return_val_if_fail (GDK_IS_DISPLAY (display), virtual_atom); + + display_x11 = GDK_DISPLAY_X11 (display); + if (xatom < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED) return INDEX_TO_ATOM (xatom); - if (atom_to_virtual) - virtual_atom = GDK_POINTER_TO_ATOM (g_hash_table_lookup (atom_to_virtual, + if (display_x11->atom_to_virtual) + virtual_atom = GDK_POINTER_TO_ATOM (g_hash_table_lookup (display_x11->atom_to_virtual, GUINT_TO_POINTER (xatom))); if (!virtual_atom) @@ -198,7 +234,7 @@ gdk_x11_xatom_to_atom (Atom xatom) */ char *name; gdk_error_trap_push (); - name = XGetAtomName (gdk_display, xatom); + name = XGetAtomName (GDK_DISPLAY_XDISPLAY (display), xatom); if (gdk_error_trap_pop ()) { g_warning (G_STRLOC " invalid X atom: %ld", xatom); @@ -208,13 +244,28 @@ gdk_x11_xatom_to_atom (Atom xatom) virtual_atom = gdk_atom_intern (name, FALSE); XFree (name); - insert_atom_pair (virtual_atom, xatom); + insert_atom_pair (display, virtual_atom, xatom); } } return virtual_atom; } +/** + * gdk_x11_xatom_to_atom: + * @xatom: an X atom for the default GDK display + * + * Convert from an X atom for the default display to the corresponding + * #GdkAtom. + * + * Return value: the corresponding G#dkAtom. + **/ +GdkAtom +gdk_x11_xatom_to_atom (Atom xatom) +{ + return gdk_x11_xatom_to_atom_for_display (gdk_get_default_display (), xatom); +} + static void virtual_atom_check_init (void) { @@ -275,6 +326,26 @@ gdk_atom_name (GdkAtom atom) } /** + * gdk_x11_get_xatom_by_name_for_display: + * @display: a #GdkDisplay + * @atom_name: a string + * + * Returns the X atom for a #GdkDisplay corresponding to @atom_name. + * This function caches the result, so if called repeatedly it is much + * faster than XInternAtom, which is a round trip to the server each time. + * + * Return value: a X atom for a #GdkDisplay + **/ +Atom +gdk_x11_get_xatom_by_name_for_display (GdkDisplay *display, + const gchar *atom_name) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), None); + return gdk_x11_atom_to_xatom_for_display (display, + gdk_atom_intern (atom_name, FALSE)); +} + +/** * gdk_x11_get_xatom_by_name: * @atom_name: a string * @@ -288,7 +359,30 @@ gdk_atom_name (GdkAtom atom) Atom gdk_x11_get_xatom_by_name (const gchar *atom_name) { - return gdk_x11_atom_to_xatom (gdk_atom_intern (atom_name, FALSE)); + return gdk_x11_get_xatom_by_name_for_display (gdk_get_default_display (), + atom_name); +} + +/** + * gdk_x11_get_xatom_name_for_display: + * @display : the #GdkDisplay where @xatom is defined + * @xatom: an X atom + * + * Returns the name of an X atom for its display. This + * function is meant mainly for debugging, so for convenience, unlike + * XAtomName() and gdk_atom_name(), the result doesn't need to + * be freed. + * + * Return value: name of the X atom; this string is owned by GTK+, + * so it shouldn't be modifed or freed. + **/ +G_CONST_RETURN gchar * +gdk_x11_get_xatom_name_for_display (GdkDisplay *display, + Atom xatom) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + return get_atom_name (gdk_x11_xatom_to_atom_for_display (display, xatom)); } /** @@ -322,59 +416,55 @@ gdk_property_get (GdkWindow *window, gint *actual_length, guchar **data) { - Display *xdisplay; - Window xwindow; - Atom xproperty; - Atom xtype; + GdkDisplay *display; Atom ret_prop_type; gint ret_format; gulong ret_nitems; gulong ret_bytes_after; gulong ret_length; guchar *ret_data; + Atom xproperty; + Atom xtype; g_return_val_if_fail (!window || GDK_IS_WINDOW (window), FALSE); - xproperty = gdk_x11_atom_to_xatom (property); - xtype = gdk_x11_atom_to_xatom (type); - - if (window) - { - if (GDK_WINDOW_DESTROYED (window)) - return FALSE; - - xdisplay = GDK_WINDOW_XDISPLAY (window); - xwindow = GDK_WINDOW_XID (window); - } - else + if (!window) { - xdisplay = gdk_display; - xwindow = _gdk_root_window; + GdkScreen *screen = gdk_get_default_screen (); + window = gdk_screen_get_root_window (screen); + + GDK_NOTE (MULTIHEAD, g_message ("gdk_property_get(): window is NULL\n")); } + display = gdk_drawable_get_display (window); + xproperty = gdk_x11_atom_to_xatom_for_display (display, property); + xtype = gdk_x11_atom_to_xatom_for_display (display, type); + ret_data = NULL; - XGetWindowProperty (xdisplay, xwindow, xproperty, + + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XWINDOW (window), xproperty, offset, (length + 3) / 4, pdelete, xtype, &ret_prop_type, &ret_format, &ret_nitems, &ret_bytes_after, &ret_data); - if ((ret_prop_type == None) && (ret_format == 0)) { - return FALSE; - } + if ((ret_prop_type == None) && (ret_format == 0)) + { + return FALSE; + } if (actual_property_type) - *actual_property_type = gdk_x11_xatom_to_atom (ret_prop_type); + *actual_property_type = gdk_x11_xatom_to_atom_for_display (display, ret_prop_type); if (actual_format_type) *actual_format_type = ret_format; - if ((type != AnyPropertyType) && (ret_prop_type != xtype)) + if ((xtype != AnyPropertyType) && (ret_prop_type != xtype)) { XFree (ret_data); - - g_warning("Couldn't match property type %s to %s\n", - gdk_x11_get_xatom_name (ret_prop_type), - gdk_x11_get_xatom_name (xtype)); + g_warning ("Couldn't match property type %s to %s\n", + gdk_x11_get_xatom_name_for_display (display, ret_prop_type), + gdk_x11_get_xatom_name_for_display (display, xtype)); return FALSE; } @@ -383,7 +473,7 @@ gdk_property_get (GdkWindow *window, if (data) { if (ret_prop_type == XA_ATOM || - ret_prop_type == gdk_x11_get_xatom_by_name ("ATOM_PAIR")) + ret_prop_type == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR")) { /* * data is an array of X atom, we need to convert it @@ -396,8 +486,8 @@ gdk_property_get (GdkWindow *window, *data = (guchar *)ret_atoms; for (i = 0; i < ret_nitems; i++) - ret_atoms[i] = gdk_x11_xatom_to_atom (xatoms[i]); - + ret_atoms[i] = gdk_x11_xatom_to_atom_for_display (display, xatoms[i]); + if (actual_length) *actual_length = ret_nitems * sizeof (GdkAtom); } @@ -441,31 +531,32 @@ gdk_property_change (GdkWindow *window, const guchar *data, gint nelements) { - Display *xdisplay; + GdkDisplay *display; Window xwindow; Atom xproperty; Atom xtype; g_return_if_fail (!window || GDK_IS_WINDOW (window)); - xproperty = gdk_x11_atom_to_xatom (property); - xtype = gdk_x11_atom_to_xatom (type); - - if (window) - { - if (GDK_WINDOW_DESTROYED (window)) - return; - - xdisplay = GDK_WINDOW_XDISPLAY (window); - xwindow = GDK_WINDOW_XID (window); - } - else + if (!window) { - xdisplay = gdk_display; - xwindow = _gdk_root_window; + GdkScreen *screen; + + screen = gdk_get_default_screen (); + window = gdk_screen_get_root_window (screen); + + GDK_NOTE (MULTIHEAD, g_message ("gdk_property_delete(): window is NULL\n")); } - if (xtype == XA_ATOM || xtype == gdk_x11_get_xatom_by_name ("ATOM_PAIR")) + + display = gdk_drawable_get_display (window); + + xproperty = gdk_x11_atom_to_xatom_for_display (display, property); + xtype = gdk_x11_atom_to_xatom_for_display (display, type); + xwindow = GDK_WINDOW_XID (window); + + if (xtype == XA_ATOM || + xtype == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR")) { /* * data is an array of GdkAtom, we need to convert it @@ -477,39 +568,37 @@ gdk_property_change (GdkWindow *window, xatoms = g_new (Atom, nelements); for (i = 0; i < nelements; i++) - xatoms[i] = gdk_x11_atom_to_xatom (atoms[i]); + xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]); - XChangeProperty (xdisplay, xwindow, xproperty, xtype, - format, mode, (guchar *)xatoms, nelements); + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow, + xproperty, xtype, + format, mode, (guchar *)xatoms, nelements); g_free (xatoms); } else - XChangeProperty (xdisplay, xwindow, xproperty, xtype, - format, mode, (guchar *)data, nelements); + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow, xproperty, + xtype, format, mode, (guchar *)data, nelements); } void gdk_property_delete (GdkWindow *window, GdkAtom property) { - Display *xdisplay; - Window xwindow; - g_return_if_fail (!window || GDK_IS_WINDOW (window)); - if (window) + if (!window) { - if (GDK_WINDOW_DESTROYED (window)) - return; - - xdisplay = GDK_WINDOW_XDISPLAY (window); - xwindow = GDK_WINDOW_XID (window); - } - else - { - xdisplay = gdk_display; - xwindow = _gdk_root_window; + GdkScreen *screen = gdk_get_default_screen (); + window = gdk_screen_get_root_window (screen); + + GDK_NOTE (MULTIHEAD, + g_message ("gdk_property_delete(): window is NULL\n")); } - XDeleteProperty (xdisplay, xwindow, gdk_x11_atom_to_xatom (property)); + if (GDK_WINDOW_DESTROYED (window)) + return; + + XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XWINDOW (window), + gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (window), + property)); } diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c new file mode 100644 index 000000000..eda13614c --- /dev/null +++ b/gdk/x11/gdkscreen-x11.c @@ -0,0 +1,350 @@ +/* + * gdkscreen-x11.c + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede <erwann.chenede@sun.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <glib.h> +#include "gdkscreen.h" +#include "gdkscreen-x11.h" +#include "gdkdisplay.h" +#include "gdkdisplay-x11.h" +#include "gdkx.h" + +static void gdk_screen_x11_class_init (GdkScreenX11Class *klass); +static GdkDisplay * gdk_screen_x11_get_display (GdkScreen *screen); +static gint gdk_screen_x11_get_width (GdkScreen *screen); +static gint gdk_screen_x11_get_height (GdkScreen *screen); +static gint gdk_screen_x11_get_width_mm (GdkScreen *screen); +static gint gdk_screen_x11_get_height_mm (GdkScreen *screen); +static gint gdk_screen_x11_get_default_depth (GdkScreen *screen); +static GdkWindow * gdk_screen_x11_get_root_window (GdkScreen *screen); +static gint gdk_screen_x11_get_screen_num (GdkScreen *screen); +static GdkColormap *gdk_screen_x11_get_default_colormap (GdkScreen *screen); +static void gdk_screen_x11_set_default_colormap (GdkScreen *screen, + GdkColormap *colormap); +static GdkWindow * gdk_screen_x11_get_window_at_pointer (GdkScreen *screen, + gint *win_x, + gint *win_y); +static void gdk_screen_x11_finalize (GObject *object); + +static gboolean gdk_screen_x11_use_virtual_screen (GdkScreen *screen); +static gint gdk_screen_x11_get_n_monitors (GdkScreen *screen); +static GdkRectangle *gdk_screen_x11_get_monitor_geometry (GdkScreen *screen, + gint num_monitor); +static gint gdk_screen_x11_get_monitor_at_point (GdkScreen *screen, + gint x, + gint y); +static gint gdk_screen_x11_get_monitor_at_window (GdkScreen *screen, + GdkNativeWindow anid); + +GType gdk_screen_x11_get_type (); +static gpointer parent_class = NULL; + +GType +gdk_screen_x11_get_type () +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (GdkScreenX11Class), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) gdk_screen_x11_finalize, + (GClassInitFunc) gdk_screen_x11_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkScreenX11), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + object_type = g_type_register_static (GDK_TYPE_SCREEN, + "GdkScreenX11", + &object_info, 0); + } + return object_type; +} + +void +gdk_screen_x11_class_init (GdkScreenX11Class * klass) +{ + GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass); + + screen_class->get_display = gdk_screen_x11_get_display; + screen_class->get_width = gdk_screen_x11_get_width; + screen_class->get_height = gdk_screen_x11_get_height; + screen_class->get_width_mm = gdk_screen_x11_get_width_mm; + screen_class->get_height_mm = gdk_screen_x11_get_height_mm; + screen_class->get_root_depth = gdk_screen_x11_get_default_depth; + screen_class->get_screen_num = gdk_screen_x11_get_screen_num; + screen_class->get_root_window = gdk_screen_x11_get_root_window; + screen_class->get_default_colormap = gdk_screen_x11_get_default_colormap; + screen_class->set_default_colormap = gdk_screen_x11_set_default_colormap; + screen_class->get_window_at_pointer = gdk_screen_x11_get_window_at_pointer; + screen_class->use_virtual_screen = gdk_screen_x11_use_virtual_screen; + screen_class->get_n_monitors = gdk_screen_x11_get_n_monitors; + screen_class->get_monitor_geometry = gdk_screen_x11_get_monitor_geometry; + screen_class->get_monitor_at_point = gdk_screen_x11_get_monitor_at_point; + screen_class->get_monitor_at_window = gdk_screen_x11_get_monitor_at_window; + + G_OBJECT_CLASS (klass)->finalize = gdk_screen_x11_finalize; + parent_class = g_type_class_peek_parent (klass); +} + +static GdkDisplay * +gdk_screen_x11_get_display (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + return screen_x11->display; +} + +static gint +gdk_screen_x11_get_width (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + return WidthOfScreen (screen_x11->xscreen); +} + +static gint +gdk_screen_x11_get_height (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + return HeightOfScreen (screen_x11->xscreen); +} + +static gint +gdk_screen_x11_get_width_mm (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + return WidthMMOfScreen (screen_x11->xscreen); +} + +static gint +gdk_screen_x11_get_height_mm (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + return HeightMMOfScreen (screen_x11->xscreen); +} + +static gint +gdk_screen_x11_get_default_depth (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + return DefaultDepthOfScreen (screen_x11->xscreen); +} + +static gint +gdk_screen_x11_get_screen_num (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + return screen_x11->screen_num; +} + +static GdkWindow * +gdk_screen_x11_get_root_window (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + gdk_drawable_ref (screen_x11->root_window); + return screen_x11->root_window; +} + +static GdkColormap * +gdk_screen_x11_get_default_colormap (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + return screen_x11->default_colormap; +} + +static void +gdk_screen_x11_set_default_colormap (GdkScreen *screen, + GdkColormap * colormap) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + screen_x11->default_colormap = colormap; +} + +static GdkWindow * +gdk_screen_x11_get_window_at_pointer (GdkScreen *screen, + gint *win_x, + gint *win_y) +{ + GdkWindow *window; + Window root; + Window xwindow; + Window xwindow_last = 0; + Display *xdisplay; + int rootx = -1, rooty = -1; + int winx, winy; + unsigned int xmask; + + xwindow = GDK_SCREEN_XROOTWIN (screen); + xdisplay = GDK_SCREEN_XDISPLAY (screen); + + XGrabServer (xdisplay); + while (xwindow) + { + xwindow_last = xwindow; + XQueryPointer (xdisplay, xwindow, + &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask); + } + XUngrabServer (xdisplay); + + window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY(screen), + xwindow_last); + if (win_x) + *win_x = window ? winx : -1; + if (win_y) + *win_y = window ? winy : -1; + + return window; +} + +static void +gdk_screen_x11_finalize (GObject *object) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (object); + /* int i; */ + g_object_unref (G_OBJECT (screen_x11->root_window)); + + /* Visual Part (Need to implement finalize for Visuals for a clean + * finalize) */ + /* for (i=0;i<screen_x11->nvisuals;i++) + g_object_unref (G_OBJECT (screen_x11->visuals[i]));*/ + g_free (screen_x11->visuals); + g_hash_table_destroy (screen_x11->visual_hash); + /* X settings */ + g_free (screen_x11->xsettings_client); + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gboolean +gdk_screen_x11_use_virtual_screen (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE); + return GDK_SCREEN_X11 (screen)->use_virtual_screen; +} + +static gint +gdk_screen_x11_get_n_monitors (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), 1); + return GDK_SCREEN_X11 (screen)->num_monitors; +} + +static GdkRectangle * +gdk_screen_x11_get_monitor_geometry (GdkScreen *screen, + gint num_monitor) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + g_return_val_if_fail (num_monitor < GDK_SCREEN_X11 (screen)->num_monitors, NULL); + + return &GDK_SCREEN_X11 (screen)->monitors[num_monitor]; +} + +static gint +gdk_screen_x11_get_monitor_at_point (GdkScreen *screen, + gint x, + gint y) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + int i; + GdkRectangle *monitor; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); + + for (i = 0, monitor = screen_x11->monitors; + i < screen_x11->num_monitors; + i++, monitor++) + { + if (x >= monitor->x && + x < monitor->x + monitor->width && + y >= monitor->y && + y < (monitor->y + monitor->height)) + return i; + } + + return -1; +} + +static gint +gdk_screen_x11_get_monitor_at_window (GdkScreen *screen, + GdkNativeWindow anid) +{ + gint x, y, width, height, depth; + gint left_monitor, right_monitor, diff_monitor; + GdkRectangle *left_monitor_rect, *right_monitor_rect; + + GdkWindow *window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY (screen), anid); + + gdk_window_get_geometry (window, &x, &y, &width, &height, &depth); + gdk_window_get_position (window, &x, &y); + + left_monitor = gdk_screen_x11_get_monitor_at_point (screen, x, y); + right_monitor = gdk_screen_x11_get_monitor_at_point (screen, x + width, + y + height); + left_monitor_rect = gdk_screen_x11_get_monitor_geometry (screen, + left_monitor); + right_monitor_rect = gdk_screen_x11_get_monitor_geometry (screen, + right_monitor); + + diff_monitor = right_monitor - left_monitor; + if (diff_monitor == 0) + { + return left_monitor; + } + if (diff_monitor == 1) + { + int dist_left, dist_right; + + dist_left = left_monitor_rect->x + left_monitor_rect->width - x; + dist_right = x + width - right_monitor_rect->x; + + if (dist_left >= dist_right) + return left_monitor; + + return right_monitor; + } + /* Window window span on at least 3 monitors */ + return left_monitor + 1; +} + +Screen * +gdk_x11_screen_get_xscreen (GdkScreen *screen) +{ + return GDK_SCREEN_X11 (screen)->xscreen; +} + +int +gdk_x11_screen_get_screen_number (GdkScreen *screen) +{ + return GDK_SCREEN_X11 (screen)->screen_num; +} diff --git a/gdk/x11/gdkscreen-x11.h b/gdk/x11/gdkscreen-x11.h new file mode 100644 index 000000000..a439b2b86 --- /dev/null +++ b/gdk/x11/gdkscreen-x11.h @@ -0,0 +1,92 @@ +/* + * gdkscreen-x11.h + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede <erwann.chenede@sun.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GDK_SCREEN_X11_H__ +#define __GDK_SCREEN_X11_H__ + +#include "gdkprivate-x11.h" +#include "xsettings-client.h" +#include <gdk/gdkscreen.h> +#include <gdk/gdkvisual.h> +#include <X11/X.h> +#include <X11/Xlib.h> + +G_BEGIN_DECLS + +typedef struct _GdkScreenX11 GdkScreenX11; +typedef struct _GdkScreenX11Class GdkScreenX11Class; + +#define GDK_TYPE_SCREEN_X11 (gdk_screen_x11_get_type ()) +#define GDK_SCREEN_X11(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SCREEN_X11, GdkScreenX11)) +#define GDK_SCREEN_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SCREEN_X11, GdkScreenX11Class)) +#define GDK_IS_SCREEN_X11(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SCREEN_X11)) +#define GDK_IS_SCREEN_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SCREEN_X11)) +#define GDK_SCREEN_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SCREEN_X11, GdkScreenX11Class)) + +struct _GdkScreenX11 +{ + GdkScreen parent_instance; + + GdkDisplay *display; + Display *xdisplay; + Screen *xscreen; + gint screen_num; + Window xroot_window; + GdkWindow *root_window; + Window wmspec_check_window; + + /* Visual Part */ + gboolean visual_initialised; + GdkVisualPrivate *system_visual; + GdkVisualPrivate **visuals; + gint nvisuals; + gint available_depths[7]; + gint navailable_depths; + GdkVisualType available_types[6]; + gint navailable_types; + GHashTable *visual_hash; + + /* Colormap Part */ + gboolean colormap_initialised; + GdkColormap *default_colormap; + GdkColormap *system_colormap; + + /* X settings */ + XSettingsClient *xsettings_client; + + /* Xinerama */ + gboolean use_virtual_screen; + gint num_monitors; + GdkRectangle *monitors; +}; + +struct _GdkScreenX11Class +{ + GdkScreenClass parent_class; +}; + +GType gdk_screen_x11_get_type (); + +G_END_DECLS + +#endif /* __GDK_SCREEN_X11_H__ */ diff --git a/gdk/x11/gdkselection-x11.c b/gdk/x11/gdkselection-x11.c index dc37ecc36..edb918b7d 100644 --- a/gdk/x11/gdkselection-x11.c +++ b/gdk/x11/gdkselection-x11.c @@ -28,10 +28,12 @@ #include <X11/Xatom.h> #include <string.h> +#include "gdkx.h" #include "gdkproperty.h" #include "gdkselection.h" #include "gdkprivate.h" #include "gdkprivate-x11.h" +#include "gdkdisplay-x11.h" typedef struct _OwnerInfo OwnerInfo; @@ -73,11 +75,14 @@ gboolean _gdk_selection_filter_clear_event (XSelectionClearEvent *event) { GSList *tmp_list = owner_list; - + GdkDisplay *display = gdk_x11_lookup_xdisplay (event->display); + while (tmp_list) { OwnerInfo *info = tmp_list->data; - if (info->selection == gdk_x11_xatom_to_atom (event->selection)) + + if (gdk_drawable_get_display (info->owner) == display && + info->selection == gdk_x11_xatom_to_atom_for_display (display, event->selection)) { if ((GDK_DRAWABLE_XID (info->owner) == event->window && event->serial >= info->serial)) @@ -94,12 +99,29 @@ _gdk_selection_filter_clear_event (XSelectionClearEvent *event) return FALSE; } - +/** + * gdk_selection_owner_set_for_display: + * @display : the #GdkDisplay. + * @owner : a GdkWindow or NULL to indicate that the the owner for + * the given should be unset. + * @selection : an atom identifying a selection. + * @time : timestamp to use when setting the selection. + * If this is older than the timestamp given last time the owner was + * set for the given selection, the request will be ignored. + * @send_event : if TRUE, and the new owner is different from the current + * owner, the current owner will be sent a SelectionClear event. + * + * Sets the #GdkWindow @owner as the current owner of the selection @selection. + * + * Returns : TRUE if the selection owner was succesfully changed to owner, + * otherwise FALSE. + */ gboolean -gdk_selection_owner_set (GdkWindow *owner, - GdkAtom selection, - guint32 time, - gboolean send_event) +gdk_selection_owner_set_for_display (GdkDisplay *display, + GdkWindow *owner, + GdkAtom selection, + guint32 time, + gboolean send_event) { Display *xdisplay; Window xwindow; @@ -107,27 +129,29 @@ gdk_selection_owner_set (GdkWindow *owner, GSList *tmp_list; OwnerInfo *info; - xselection = gdk_x11_atom_to_xatom (selection); - - if (owner) + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + if (owner) { if (GDK_WINDOW_DESTROYED (owner)) return FALSE; - + xdisplay = GDK_WINDOW_XDISPLAY (owner); xwindow = GDK_WINDOW_XID (owner); } - else + else { - xdisplay = gdk_display; + xdisplay = GDK_DISPLAY_XDISPLAY (display); xwindow = None; } + xselection = gdk_x11_atom_to_xatom_for_display (display, selection); + tmp_list = owner_list; while (tmp_list) { info = tmp_list->data; - if (info->selection == selection) + if (info->selection == selection) { owner_list = g_slist_remove (owner_list, info); g_free (info); @@ -151,16 +175,55 @@ gdk_selection_owner_set (GdkWindow *owner, return (XGetSelectionOwner (xdisplay, xselection) == xwindow); } -GdkWindow* -gdk_selection_owner_get (GdkAtom selection) +gboolean +gdk_selection_owner_set (GdkWindow *owner, + GdkAtom selection, + guint32 time, + gboolean send_event) +{ + return gdk_selection_owner_set_for_display (gdk_get_default_display (), + owner, selection, + time, send_event); +} + +/** + * gdk_selection_owner_get_for_display : + * @display : a #GdkDisplay. + * @selection : an atom indentifying a selection. + * + * Determine the owner of the given selection. + * + * <para> Note that the return value may be owned by a different + * process if a foreign window was previously created for that + * window, but a new foreign window will never be created by this call. + * </para> + * + * Returns :if there is a selection owner for this window, + * and it is a window known to the current process, the GdkWindow that owns + * the selection, otherwise NULL. + */ + +GdkWindow * +gdk_selection_owner_get_for_display (GdkDisplay *display, + GdkAtom selection) { Window xwindow; + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); - xwindow = XGetSelectionOwner (gdk_display, gdk_x11_atom_to_xatom (selection)); + xwindow = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), + gdk_x11_atom_to_xatom_for_display (display, + selection)); if (xwindow == None) return NULL; - return gdk_window_lookup (xwindow); + return gdk_window_lookup_for_display (display, xwindow); +} + +GdkWindow* +gdk_selection_owner_get (GdkAtom selection) +{ + return gdk_selection_owner_get_for_display (gdk_get_default_display (), + selection); } void @@ -169,13 +232,17 @@ gdk_selection_convert (GdkWindow *requestor, GdkAtom target, guint32 time) { + GdkDisplay *display; + if (GDK_WINDOW_DESTROYED (requestor)) return; + display = GDK_WINDOW_DISPLAY (requestor); + XConvertSelection (GDK_WINDOW_XDISPLAY (requestor), - gdk_x11_atom_to_xatom (selection), - gdk_x11_atom_to_xatom (target), - gdk_x11_atom_to_xatom (_gdk_selection_property), + gdk_x11_atom_to_xatom_for_display (display, selection), + gdk_x11_atom_to_xatom_for_display (display, target), + gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property), GDK_WINDOW_XID (requestor), time); } @@ -191,9 +258,12 @@ gdk_selection_property_get (GdkWindow *requestor, Atom prop_type; gint prop_format; guchar *t = NULL; + GdkDisplay *display; g_return_val_if_fail (requestor != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (requestor), 0); + + display = GDK_WINDOW_DISPLAY (requestor); /* If retrieved chunks are typically small, (and the ICCCM says the should be) it would be a win to try first with a buffer of @@ -205,13 +275,12 @@ gdk_selection_property_get (GdkWindow *requestor, t = NULL; XGetWindowProperty (GDK_WINDOW_XDISPLAY (requestor), GDK_WINDOW_XID (requestor), - gdk_x11_atom_to_xatom (_gdk_selection_property), + gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property), 0, 0, False, - AnyPropertyType, &prop_type, &prop_format, - &nitems, &nbytes, &t); - + AnyPropertyType, &prop_type, + &prop_format, &nitems, &nbytes, &t); if (ret_type) - *ret_type = gdk_x11_xatom_to_atom (prop_type); + *ret_type = gdk_x11_xatom_to_atom_for_display (display, prop_type); if (ret_format) *ret_format = prop_format; @@ -237,14 +306,17 @@ gdk_selection_property_get (GdkWindow *requestor, Otherwise there's no guarantee we'll win the race ... */ XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (requestor), GDK_DRAWABLE_XID (requestor), - gdk_x11_atom_to_xatom (_gdk_selection_property), + gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property), 0, (nbytes + 3) / 4, False, AnyPropertyType, &prop_type, &prop_format, &nitems, &nbytes, &t); if (prop_type != None) { - if (prop_type == XA_ATOM || prop_type == gdk_x11_get_xatom_by_name ("ATOM_PAIR")) + *data = g_new (guchar, length); + + if (prop_type == XA_ATOM || + prop_type == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR")) { Atom* atoms = (Atom*) t; GdkAtom* atoms_dest; @@ -257,7 +329,7 @@ gdk_selection_property_get (GdkWindow *requestor, atoms_dest = (GdkAtom *)(*data); for (i=0; i < num_atom; i++) - atoms_dest[i] = gdk_x11_xatom_to_atom (atoms[i]); + atoms_dest[i] = gdk_x11_xatom_to_atom_for_display (display, atoms[i]); } else { @@ -275,48 +347,98 @@ gdk_selection_property_get (GdkWindow *requestor, } } - +/** + * gdk_selection_send_notify_for_display : + * @display : the #GdkDisplay where @requestor is realized + * @requestor : window to which to deliver response. + * @selection : selection that was requested. + * @target : target that was selected. + * @property : property in which the selection owner stored the data, + * or GDK_NONE to indicate that the request was rejected. + * @time : timestamp. + * + * Send a response to SelectionRequest event. + **/ void -gdk_selection_send_notify (guint32 requestor, - GdkAtom selection, - GdkAtom target, - GdkAtom property, - guint32 time) +gdk_selection_send_notify_for_display (GdkDisplay *display, + guint32 requestor, + GdkAtom selection, + GdkAtom target, + GdkAtom property, + guint32 time) { XSelectionEvent xevent; + + g_return_if_fail (GDK_IS_DISPLAY (display)); xevent.type = SelectionNotify; xevent.serial = 0; xevent.send_event = True; - xevent.display = gdk_display; xevent.requestor = requestor; - xevent.selection = gdk_x11_atom_to_xatom (selection); - xevent.target = gdk_x11_atom_to_xatom (target); - xevent.property = gdk_x11_atom_to_xatom (property); + xevent.selection = gdk_x11_atom_to_xatom_for_display (display, selection); + xevent.target = gdk_x11_atom_to_xatom_for_display (display, target); + xevent.property = gdk_x11_atom_to_xatom_for_display (display, property); xevent.time = time; - gdk_send_xevent (requestor, False, NoEventMask, (XEvent*) &xevent); + _gdk_send_xevent (display, requestor, False, NoEventMask, (XEvent*) & xevent); } +void +gdk_selection_send_notify (guint32 requestor, + GdkAtom selection, + GdkAtom target, + GdkAtom property, + guint32 time) +{ + gdk_selection_send_notify_for_display (gdk_get_default_display (), + requestor, selection, + target, property, time); +} + +/** + * gdk_text_property_to_text_list_for_display: + * @display: The #GdkDisplay where the encoding is defined. + * @encoding: an atom representing the encoding. The most + * common values for this are STRING, or COMPOUND_TEXT. + * This is value used as the type for the property. + * @format: the format of the property. + * @text: The text data. + * @length: The number of items to transform. + * @list: location to store a terminated array of strings in + * the encoding of the current locale. This array should be + * freed using gdk_free_text_list(). + * + * Convert a text string from the encoding as it is stored + * in a property into an array of strings in the encoding of + * the current local. (The elements of the array represent the + * null-separated elements of the original text string.) + * + * Returns : he number of strings stored in list, or 0, + * if the conversion failed. + */ gint -gdk_text_property_to_text_list (GdkAtom encoding, - gint format, - const guchar *text, - gint length, - gchar ***list) +gdk_text_property_to_text_list_for_display (GdkDisplay *display, + GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list) { XTextProperty property; gint count = 0; gint res; gchar **local_list; + g_return_val_if_fail (GDK_IS_DISPLAY (display), 0); property.value = (guchar *)text; - property.encoding = gdk_x11_atom_to_xatom (encoding); + property.encoding = gdk_x11_atom_to_xatom_for_display (display, encoding); property.format = format; property.nitems = length; - res = XmbTextPropertyToTextList (GDK_DISPLAY(), &property, &local_list, &count); + res = XmbTextPropertyToTextList (GDK_DISPLAY_XDISPLAY (display), &property, + &local_list, &count); - if (res == XNoMemory || res == XLocaleNotSupported || res == XConverterNotFound) + if (res == XNoMemory || res == XLocaleNotSupported || + res == XConverterNotFound) { if (list) *list = NULL; @@ -334,6 +456,17 @@ gdk_text_property_to_text_list (GdkAtom encoding, } } +gint +gdk_text_property_to_text_list (GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list) +{ + return gdk_text_property_to_text_list_for_display (gdk_get_default_display (), + encoding, format, text, length, list); +} + void gdk_free_text_list (gchar **list) { @@ -412,7 +545,8 @@ make_list (const gchar *text, } /** - * gdk_text_property_to_utf8_list: + * gdk_text_property_to_utf8_list_for_display: + * @display: a #GdkDisplay * @encoding: an atom representing the encoding of the text * @format: the format of the property * @text: the text to convert @@ -427,14 +561,16 @@ make_list (const gchar *text, * list. **/ gint -gdk_text_property_to_utf8_list (GdkAtom encoding, - gint format, - const guchar *text, - gint length, - gchar ***list) +gdk_text_property_to_utf8_list_for_display (GdkDisplay *display, + GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list) { g_return_val_if_fail (text != NULL, 0); g_return_val_if_fail (length >= 0, 0); + g_return_val_if_fail (GDK_IS_DISPLAY (display), 0); if (encoding == GDK_TARGET_STRING) { @@ -456,11 +592,12 @@ gdk_text_property_to_utf8_list (GdkAtom encoding, /* Probably COMPOUND text, we fall back to Xlib routines */ - local_count = gdk_text_property_to_text_list (encoding, - format, - text, - length, - &local_list); + local_count = gdk_text_property_to_text_list_for_display (display, + encoding, + format, + text, + length, + &local_list); if (list) *list = g_new (gchar *, local_count + 1); @@ -504,17 +641,61 @@ gdk_text_property_to_utf8_list (GdkAtom encoding, } } +/** + * gdk_text_property_to_utf8_list: + * @encoding: an atom representing the encoding of the text + * @format: the format of the property + * @text: the text to convert + * @length: the length of @text, in bytes + * @list: location to store the list of strings or %NULL. The + * list should be freed with g_strfreev(). + * + * Convert a text property in the giving encoding to + * a list of UTF-8 strings. + * + * Return value: the number of strings in the resulting + * list. + **/ +gint +gdk_text_property_to_utf8_list (GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list) +{ + return gdk_text_property_to_utf8_list_for_display (gdk_get_default_display (), + encoding, format, text, length, list); +} + +/** + * gdk_string_to_compound_text_for_display: + * @display : the #GdkDisplay where the encoding is defined. + * @str : a null-terminated string. + * @encoding: location to store the encoding atom + * (to be used as the type for the property). + * @format: location to store the format of the property + * @ctext: location to store newly allocated data for the property. + * @length: the length of @text, in bytes + * + * Convert a string from the encoding of the current + * locale into a form suitable for storing in a window property. + * + * Returns : 0 upon sucess, non-zero upon failure. + **/ gint -gdk_string_to_compound_text (const gchar *str, - GdkAtom *encoding, - gint *format, - guchar **ctext, - gint *length) +gdk_string_to_compound_text_for_display (GdkDisplay *display, + const gchar *str, + GdkAtom *encoding, + gint *format, + guchar **ctext, + gint *length) { gint res; XTextProperty property; - res = XmbTextListToTextProperty (GDK_DISPLAY(), + g_return_val_if_fail (GDK_IS_DISPLAY (display), 0); + + res = XmbTextListToTextProperty (GDK_DISPLAY_XDISPLAY (display), (char **)&str, 1, XCompoundTextStyle, &property); if (res != Success) @@ -526,7 +707,7 @@ gdk_string_to_compound_text (const gchar *str, } if (encoding) - *encoding = gdk_x11_xatom_to_atom (property.encoding); + *encoding = gdk_x11_xatom_to_atom_for_display (display, property.encoding); if (format) *format = property.format; if (ctext) @@ -537,6 +718,18 @@ gdk_string_to_compound_text (const gchar *str, return res; } +gint +gdk_string_to_compound_text (const gchar *str, + GdkAtom *encoding, + gint *format, + guchar **ctext, + gint *length) +{ + return gdk_string_to_compound_text_for_display (gdk_get_default_display (), + str, encoding, format, + ctext, length); +} + /* The specifications for COMPOUND_TEXT and STRING specify that C0 and * C1 are not allowed except for \n and \t, however the X conversions * routines for COMPOUND_TEXT only enforce this in one direction, @@ -615,7 +808,8 @@ gdk_utf8_to_string_target (const gchar *str) } /** - * gdk_utf8_to_compound_text: + * gdk_utf8_to_compound_text_for_display: + * @display: a #GdkDisplay * @str: a UTF-8 string * @encoding: location to store resulting encoding * @format: location to store format of the result @@ -629,11 +823,12 @@ gdk_utf8_to_string_target (const gchar *str) * %FALSE. **/ gboolean -gdk_utf8_to_compound_text (const gchar *str, - GdkAtom *encoding, - gint *format, - guchar **ctext, - gint *length) +gdk_utf8_to_compound_text_for_display (GdkDisplay *display, + const gchar *str, + GdkAtom *encoding, + gint *format, + guchar **ctext, + gint *length) { gboolean need_conversion; const gchar *charset; @@ -642,6 +837,7 @@ gdk_utf8_to_compound_text (const gchar *str, gboolean result; g_return_val_if_fail (str != NULL, FALSE); + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); need_conversion = !g_get_charset (&charset); @@ -675,8 +871,9 @@ gdk_utf8_to_compound_text (const gchar *str, else locale_str = tmp_str; - result = gdk_string_to_compound_text (locale_str, - encoding, format, ctext, length); + result = gdk_string_to_compound_text_for_display (display, locale_str, + encoding, format, + ctext, length); result = (result == Success? TRUE : FALSE); g_free (locale_str); @@ -684,6 +881,32 @@ gdk_utf8_to_compound_text (const gchar *str, return result; } +/** + * gdk_utf8_to_compound_text: + * @str: a UTF-8 string + * @encoding: location to store resulting encoding + * @format: location to store format of the result + * @ctext: location to store the data of the result + * @length: location to store the length of the data + * stored in @ctext + * + * Convert from UTF-8 to compound text. + * + * Return value: %TRUE if the conversion succeeded, otherwise + * false. + **/ +gboolean +gdk_utf8_to_compound_text (const gchar *str, + GdkAtom *encoding, + gint *format, + guchar **ctext, + gint *length) +{ + return gdk_utf8_to_compound_text_for_display (gdk_get_default_display (), + str, encoding, format, + ctext, length); +} + void gdk_free_compound_text (guchar *ctext) { if (ctext) diff --git a/gdk/x11/gdkvisual-x11.c b/gdk/x11/gdkvisual-x11.c index 32d44dfb7..6161088b6 100644 --- a/gdk/x11/gdkvisual-x11.c +++ b/gdk/x11/gdkvisual-x11.c @@ -29,6 +29,7 @@ #include "gdkvisual.h" #include "gdkprivate-x11.h" +#include "gdkscreen-x11.h" #include "gdkinternals.h" struct _GdkVisualClass @@ -45,16 +46,6 @@ static gboolean gdk_visual_equal (Visual *a, Visual *b); -static GdkVisualPrivate *system_visual; -static GdkVisualPrivate **visuals; -static gint nvisuals; - -static gint available_depths[7]; -static gint navailable_depths; - -static GdkVisualType available_types[6]; -static gint navailable_types; - #ifdef G_ENABLE_DEBUG static const gchar* visual_names[] = @@ -69,8 +60,6 @@ static const gchar* visual_names[] = #endif /* G_ENABLE_DEBUG */ -static GHashTable *visual_hash = NULL; - static void gdk_visual_finalize (GObject *object) { @@ -114,7 +103,7 @@ gdk_visual_get_type (void) void -_gdk_visual_init (void) +_gdk_visual_init (GdkScreen *screen) { static const gint possible_depths[7] = { 32, 24, 16, 15, 8, 4, 1 }; static const GdkVisualType possible_types[6] = @@ -127,28 +116,33 @@ _gdk_visual_init (void) GDK_VISUAL_STATIC_GRAY }; - static const gint npossible_depths = sizeof(possible_depths)/sizeof(gint); - static const gint npossible_types = sizeof(possible_types)/sizeof(GdkVisualType); - + GdkScreenX11 *screen_x11; XVisualInfo *visual_list; XVisualInfo visual_template; GdkVisualPrivate *temp_visual; Visual *default_xvisual; + GdkVisualPrivate **visuals; int nxvisuals; + int nvisuals; int i, j; + + g_return_if_fail (GDK_IS_SCREEN (screen)); + screen_x11 = GDK_SCREEN_X11 (screen); - visual_template.screen = _gdk_screen; - visual_list = XGetVisualInfo (gdk_display, VisualScreenMask, &visual_template, &nxvisuals); + visual_template.screen = screen_x11->screen_num; + visual_list = XGetVisualInfo (screen_x11->xdisplay, VisualScreenMask, &visual_template, &nxvisuals); visuals = g_new (GdkVisualPrivate *, nxvisuals); for (i = 0; i < nxvisuals; i++) visuals[i] = g_object_new (GDK_TYPE_VISUAL, NULL); - default_xvisual = DefaultVisual (gdk_display, _gdk_screen); + default_xvisual = DefaultVisual (screen_x11->xdisplay, screen_x11->screen_num); nvisuals = 0; for (i = 0; i < nxvisuals; i++) { + visuals[nvisuals]->visual.screen = screen; + if (visual_list[i].depth >= 1) { #ifdef __cplusplus @@ -179,7 +173,7 @@ _gdk_visual_init (void) visuals[nvisuals]->visual.depth = visual_list[i].depth; visuals[nvisuals]->visual.byte_order = - (ImageByteOrder(gdk_display) == LSBFirst) ? + (ImageByteOrder(screen_x11->xdisplay) == LSBFirst) ? GDK_LSB_FIRST : GDK_MSB_FIRST; visuals[nvisuals]->visual.red_mask = visual_list[i].red_mask; visuals[nvisuals]->visual.green_mask = visual_list[i].green_mask; @@ -217,7 +211,7 @@ _gdk_visual_init (void) visuals[nvisuals]->visual.blue_shift = 0; visuals[nvisuals]->visual.blue_prec = 0; } - + nvisuals += 1; } } @@ -262,7 +256,7 @@ _gdk_visual_init (void) for (i = 0; i < nvisuals; i++) if (default_xvisual->visualid == visuals[i]->xvisual->visualid) { - system_visual = visuals[i]; + screen_x11->system_visual = visuals[i]; break; } @@ -274,30 +268,30 @@ _gdk_visual_init (void) visuals[i]->visual.depth); #endif /* G_ENABLE_DEBUG */ - navailable_depths = 0; - for (i = 0; i < npossible_depths; i++) + screen_x11->navailable_depths = 0; + for (i = 0; i < G_N_ELEMENTS (possible_depths); i++) { for (j = 0; j < nvisuals; j++) { if (visuals[j]->visual.depth == possible_depths[i]) { - available_depths[navailable_depths++] = visuals[j]->visual.depth; + screen_x11->available_depths[screen_x11->navailable_depths++] = visuals[j]->visual.depth; break; } } } - if (navailable_depths == 0) + if (screen_x11->navailable_depths == 0) g_error ("unable to find a usable depth"); - navailable_types = 0; - for (i = 0; i < npossible_types; i++) + screen_x11->navailable_types = 0; + for (i = 0; i < G_N_ELEMENTS (possible_types); i++) { for (j = 0; j < nvisuals; j++) { if (visuals[j]->visual.type == possible_types[i]) { - available_types[navailable_types++] = visuals[j]->visual.type; + screen_x11->available_types[screen_x11->navailable_types++] = visuals[j]->visual.type; break; } } @@ -306,14 +300,18 @@ _gdk_visual_init (void) for (i = 0; i < nvisuals; i++) gdk_visual_add ((GdkVisual*) visuals[i]); - if (npossible_types == 0) + if (screen_x11->navailable_types == 0) g_error ("unable to find a usable visual type"); + + screen_x11->visuals = visuals; + screen_x11->nvisuals = nvisuals; + screen_x11->visual_initialised = TRUE; } /** * gdk_visual_get_best_depth: * - * Get the best available depth for the default GDK display. "Best" + * Get the best available depth for the default GDK screen. "Best" * means "largest," i.e. 32 preferred over 24 preferred over 8 bits * per pixel. * @@ -322,27 +320,48 @@ _gdk_visual_init (void) gint gdk_visual_get_best_depth (void) { - return available_depths[0]; + GdkScreen *screen = gdk_get_default_screen(); + + return GDK_SCREEN_X11 (screen)->available_depths[0]; } /** * gdk_visual_get_best_type: * - * Return the best available visual type (the one with the most - * colors) for the default GDK display. + * Return the best available visual type for the default GDK screen. * * Return value: best visual type **/ GdkVisualType gdk_visual_get_best_type (void) { - return available_types[0]; + GdkScreen *screen = gdk_get_default_screen(); + + return GDK_SCREEN_X11 (screen)->available_types[0]; +} + +/** + * gdk_screen_get_system_visual: + * @screen : a #GdkScreen. + * + * Get the system's default visual for @screen. + * This is the visual for the root window of the display. + * The return value should not be freed. + * + * Return value: system visual + **/ +GdkVisual * +gdk_screen_get_system_visual (GdkScreen * screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return ((GdkVisual *) GDK_SCREEN_X11 (screen)->system_visual); } /** * gdk_visual_get_system: * - * Get the default or system visual for the default GDK display. + * Get the system'sdefault visual for the default GDK screen. * This is the visual for the root window of the display. * The return value should not be freed. * @@ -351,28 +370,30 @@ gdk_visual_get_best_type (void) GdkVisual* gdk_visual_get_system (void) { - return ((GdkVisual*) system_visual); + return gdk_screen_get_system_visual (gdk_get_default_screen()); } /** * gdk_visual_get_best: * * Get the visual with the most available colors for the default - * GDK display. The return value should not be freed. + * GDK screen. The return value should not be freed. * * Return value: best visual **/ GdkVisual* gdk_visual_get_best (void) { - return ((GdkVisual*) visuals[0]); + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen()); + + return (GdkVisual *)screen_x11->visuals[0]; } /** * gdk_visual_get_best_with_depth: * @depth: a bit depth * - * Get the best visual with depth @depth for the default GDK display. + * Get the best visual with depth @depth for the default GDK screen. * Color visuals and visuals with mutable colormaps are preferred * over grayscale or fixed-colormap visuals. The return value should not * be freed. %NULL may be returned if no visual supports @depth. @@ -382,14 +403,15 @@ gdk_visual_get_best (void) GdkVisual* gdk_visual_get_best_with_depth (gint depth) { + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ()); GdkVisual *return_val; int i; - + return_val = NULL; - for (i = 0; i < nvisuals; i++) - if (depth == visuals[i]->visual.depth) + for (i = 0; i < screen_x11->nvisuals; i++) + if (depth == screen_x11->visuals[i]->visual.depth) { - return_val = (GdkVisual*) visuals[i]; + return_val = (GdkVisual *) & (screen_x11->visuals[i]); break; } @@ -400,7 +422,7 @@ gdk_visual_get_best_with_depth (gint depth) * gdk_visual_get_best_with_type: * @visual_type: a visual type * - * Get the best visual of the given @visual_type for the default GDK display. + * Get the best visual of the given @visual_type for the default GDK screen. * Visuals with higher color depths are considered better. The return value * should not be freed. %NULL may be returned if no visual has type * @visual_type. @@ -410,14 +432,15 @@ gdk_visual_get_best_with_depth (gint depth) GdkVisual* gdk_visual_get_best_with_type (GdkVisualType visual_type) { + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ()); GdkVisual *return_val; int i; return_val = NULL; - for (i = 0; i < nvisuals; i++) - if (visual_type == visuals[i]->visual.type) + for (i = 0; i < screen_x11->nvisuals; i++) + if (visual_type == screen_x11->visuals[i]->visual.type) { - return_val = (GdkVisual*) visuals[i]; + return_val = (GdkVisual *) screen_x11->visuals[i]; break; } @@ -437,15 +460,16 @@ GdkVisual* gdk_visual_get_best_with_both (gint depth, GdkVisualType visual_type) { + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ()); GdkVisual *return_val; int i; return_val = NULL; - for (i = 0; i < nvisuals; i++) - if ((depth == visuals[i]->visual.depth) && - (visual_type == visuals[i]->visual.type)) + for (i = 0; i < screen_x11->nvisuals; i++) + if ((depth == screen_x11->visuals[i]->visual.depth) && + (visual_type == screen_x11->visuals[i]->visual.type)) { - return_val = (GdkVisual*) visuals[i]; + return_val = (GdkVisual *) screen_x11->visuals[i]; break; } @@ -458,7 +482,7 @@ gdk_visual_get_best_with_both (gint depth, * @count: return location for number of available depths * * This function returns the available bit depths for the default - * display. It's equivalent to listing the visuals + * screen. It's equivalent to listing the visuals * (gdk_list_visuals()) and then looking at the depth field in each * visual, removing duplicates. * @@ -469,8 +493,10 @@ void gdk_query_depths (gint **depths, gint *count) { - *count = navailable_depths; - *depths = available_depths; + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ()); + + *count = screen_x11->navailable_depths; + *depths = screen_x11->available_depths; } /** @@ -479,25 +505,27 @@ gdk_query_depths (gint **depths, * @count: return location for the number of available visual types * * This function returns the available visual types for the default - * display. It's equivalent to listing the visuals + * screen. It's equivalent to listing the visuals * (gdk_list_visuals()) and then looking at the type field in each * visual, removing duplicates. * * The array returned by this function should not be freed. - * **/ void gdk_query_visual_types (GdkVisualType **visual_types, gint *count) { - *count = navailable_types; - *visual_types = available_types; + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ()); + + *count = screen_x11->navailable_types; + *visual_types = screen_x11->available_types; } /** - * gdk_list_visuals: - * - * Lists the available visuals for the default display. + * gdk_screen_list_visuals: + * @screen : the relevant #GdkScreen. + * + * Lists the available visuals for the specified @screen. * A visual describes a hardware image data format. * For example, a visual might support 24-bit color, or 8-bit color, * and might expect pixels to be in a certain format. @@ -506,57 +534,97 @@ gdk_query_visual_types (GdkVisualType **visual_types, * * Return value: a list of visuals; the list must be freed, but not its contents **/ -GList* -gdk_list_visuals (void) +GList * +gdk_screen_list_visuals (GdkScreen *screen) { GList *list; + GdkScreenX11 *screen_x11; guint i; + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + screen_x11 = GDK_SCREEN_X11 (screen); + list = NULL; - for (i = 0; i < nvisuals; ++i) - list = g_list_append (list, (gpointer) visuals[i]); + + for (i = 0; i < screen_x11->nvisuals; ++i) + list = g_list_append (list, screen_x11->visuals[i]); return list; } +/** + * gdk_list_visuals: + * + * Lists the available visuals for the default screen. + * (See gdk_screen_list_visuals()) + * A visual describes a hardware image data format. + * For example, a visual might support 24-bit color, or 8-bit color, + * and might expect pixels to be in a certain format. + * + * Call g_list_free() on the return value when you're finished with it. + * + * Return value: a list of visuals; the list must be freed, but not its contents + **/ +GList* +gdk_list_visuals (void) +{ + return gdk_screen_list_visuals (gdk_get_default_screen ()); +} GdkVisual* -gdk_visual_lookup (Visual *xvisual) +gdk_visual_lookup (Visual *xvisual) { - GdkVisual *visual; - - if (!visual_hash) + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ()); + + if (!screen_x11->visual_hash) return NULL; - visual = g_hash_table_lookup (visual_hash, xvisual); - return visual; + return g_hash_table_lookup (screen_x11->visual_hash, xvisual); } -GdkVisual* -gdkx_visual_get (VisualID xvisualid) +/** + * gdkx_visual_get_for_screen: + * @screen: a #GdkScreen. + * @xvisualid: an X Visual ID. + * + * Returns a #GdkVisual from and X Visual id. + * + * Returns: a #GdkVisual. + */ +GdkVisual * +gdkx_visual_get_for_screen (GdkScreen *screen, + VisualID xvisualid) { int i; + GdkScreenX11 *screen_x11; + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + screen_x11 = GDK_SCREEN_X11 (screen); - for (i = 0; i < nvisuals; i++) - if (xvisualid == visuals[i]->xvisual->visualid) - return (GdkVisual*) visuals[i]; + for (i = 0; i < screen_x11->nvisuals; i++) + if (xvisualid == screen_x11->visuals[i]->xvisual->visualid) + return (GdkVisual *) screen_x11->visuals[i]; return NULL; } +GdkVisual* +gdkx_visual_get (VisualID xvisualid) +{ + return gdkx_visual_get_for_screen (gdk_get_default_screen (), xvisualid); +} static void gdk_visual_add (GdkVisual *visual) { GdkVisualPrivate *private; + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (visual->screen); + + if (!screen_x11->visual_hash) + screen_x11->visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash, + (GEqualFunc) gdk_visual_equal); - if (!visual_hash) - visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash, - (GEqualFunc) gdk_visual_equal); - - private = (GdkVisualPrivate*) visual; - - g_hash_table_insert (visual_hash, private->xvisual, visual); + private = (GdkVisualPrivate *) visual; + g_hash_table_insert (screen_x11->visual_hash, private->xvisual, visual); } static void diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 67b540cf5..c9e1fbb22 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -34,6 +34,7 @@ #include "gdkwindow.h" #include "gdkinputprivate.h" +#include "gdkdisplay-x11.h" #include "gdkprivate-x11.h" #include "gdkregion.h" #include "gdkinternals.h" @@ -76,11 +77,11 @@ const int _gdk_event_mask_table[21] = const int _gdk_nenvent_masks = sizeof (_gdk_event_mask_table) / sizeof (int); /* Forward declarations */ -static gboolean gdk_window_gravity_works (void); -static void gdk_window_set_static_win_gravity (GdkWindow *window, - gboolean on); -static gboolean gdk_window_have_shape_ext (void); -static gboolean gdk_window_icon_name_set (GdkWindow *window); +static gboolean gdk_window_gravity_works (GdkWindow *window); +static void gdk_window_set_static_win_gravity (GdkWindow *window, + gboolean on); +static gboolean gdk_window_have_shape_ext (GdkDisplay *display); +static gboolean gdk_window_icon_name_set (GdkWindow *window); static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable); static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable, @@ -173,9 +174,9 @@ gdk_window_impl_x11_finalize (GObject *object) if (!GDK_WINDOW_DESTROYED (wrapper)) { - gdk_xid_table_remove (draw_impl->xid); + _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (object), draw_impl->xid); if (window_impl->focus_window) - gdk_xid_table_remove (window_impl->focus_window); + _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (object), window_impl->focus_window); } G_OBJECT_CLASS (parent_class)->finalize (object); @@ -197,7 +198,7 @@ gdk_window_impl_x11_get_colormap (GdkDrawable *drawable) { XWindowAttributes window_attributes; - XGetWindowAttributes (drawable_impl->xdisplay, + XGetWindowAttributes (GDK_SCREEN_XDISPLAY (drawable_impl->screen), drawable_impl->xid, &window_attributes); drawable_impl->colormap = @@ -224,10 +225,10 @@ gdk_window_impl_x11_set_colormap (GdkDrawable *drawable, if (cmap) { - XSetWindowColormap (draw_impl->xdisplay, + XSetWindowColormap (GDK_SCREEN_XDISPLAY (draw_impl->screen), draw_impl->xid, GDK_COLORMAP_XCOLORMAP (cmap)); - + if (((GdkWindowObject*)draw_impl->wrapper)->window_type != GDK_WINDOW_TOPLEVEL) gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper)); @@ -265,11 +266,12 @@ gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable) } void -_gdk_windowing_window_init (void) +_gdk_windowing_window_init (GdkScreen * screen) { GdkWindowObject *private; GdkWindowImplX11 *impl; GdkDrawableImplX11 *draw_impl; + GdkScreenX11 *screen_x11; XWindowAttributes xattributes; unsigned int width; unsigned int height; @@ -277,39 +279,60 @@ _gdk_windowing_window_init (void) unsigned int depth; int x, y; - g_assert (_gdk_parent_root == NULL); - - XGetGeometry (gdk_display, _gdk_root_window, &_gdk_root_window, - &x, &y, &width, &height, &border_width, &depth); - XGetWindowAttributes (gdk_display, _gdk_root_window, &xattributes); + screen_x11 = GDK_SCREEN_X11 (screen); + + g_assert (screen_x11->root_window == NULL); - _gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL); - private = (GdkWindowObject *)_gdk_parent_root; + screen_x11->default_colormap = gdk_screen_get_system_colormap (screen); + + XGetGeometry (screen_x11->xdisplay, screen_x11->xroot_window, + &screen_x11->xroot_window, &x, &y, &width, &height, &border_width, &depth); + XGetWindowAttributes (screen_x11->xdisplay, screen_x11->xroot_window, &xattributes); + + screen_x11->root_window = g_object_new (GDK_TYPE_WINDOW, NULL); + private = (GdkWindowObject *)screen_x11->root_window; impl = GDK_WINDOW_IMPL_X11 (private->impl); draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); - draw_impl->xdisplay = gdk_display; - draw_impl->xid = _gdk_root_window; + draw_impl->screen = screen; + draw_impl->xid = screen_x11->xroot_window; draw_impl->wrapper = GDK_DRAWABLE (private); private->window_type = GDK_WINDOW_ROOT; private->depth = depth; impl->width = width; impl->height = height; + screen_x11->colormap_initialised = TRUE; - gdk_xid_table_insert (&_gdk_root_window, _gdk_parent_root); + _gdk_xid_table_insert (screen_x11->display, + &screen_x11->xroot_window, + screen_x11->root_window); } -static Atom wm_client_leader_atom = None; +static void +set_wm_protocols (GdkWindow *window) +{ + GdkDisplay *display = gdk_drawable_get_display (window); + Atom protocols[3]; + + protocols[0] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"); + protocols[1] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"); + protocols[2] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING"); + + XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, 3); +} /** * gdk_window_new: - * @parent: a #GdkWindow + * @parent: a #GdkWindow, or %NULL to create the window as a child of + * the default root window for the default display. * @attributes: attributes of the new window * @attributes_mask: mask indicating which fields in @attributes are valid * - * Creates a new #GdkWindow using the attributes from @attributes. See - * #GdkWindowAttr and #GdkWindowAttributesType for more details. + * Creates a new #GdkWindow using the attributes from + * @attributes. Seep #GdkWindowAttr and #GdkWindowAttributesType for + * more details. Note: to use this on displays other than the default + * display, @parent must be specified. * * Return value: the new #GdkWindow **/ @@ -322,6 +345,8 @@ gdk_window_new (GdkWindow *parent, GdkWindowObject *private; GdkWindowImplX11 *impl; GdkDrawableImplX11 *draw_impl; + GdkScreenX11 *screen_x11; + GdkScreen *screen; GdkVisual *visual; Window xparent; @@ -344,7 +369,17 @@ gdk_window_new (GdkWindow *parent, g_return_val_if_fail (attributes != NULL, NULL); if (!parent) - parent = _gdk_parent_root; + { + GDK_NOTE (MULTIHEAD, + g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window")); + + screen = gdk_get_default_screen (); + parent = gdk_screen_get_root_window (screen); + } + else + screen = gdk_drawable_get_screen (parent); + + screen_x11 = GDK_SCREEN_X11 (screen); g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL); @@ -358,14 +393,15 @@ gdk_window_new (GdkWindow *parent, impl = GDK_WINDOW_IMPL_X11 (private->impl); draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); draw_impl->wrapper = GDK_DRAWABLE (window); - - xdisplay = draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent); + + draw_impl->screen = screen; + xdisplay = screen_x11->xdisplay; /* Windows with a foreign parent are treated as if they are children * of the root window, except for actual creation. */ if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN) - parent = _gdk_parent_root; + parent = gdk_screen_get_root_window (screen); private->parent = (GdkWindowObject *)parent; @@ -407,7 +443,7 @@ gdk_window_new (GdkWindow *parent, if (attributes_mask & GDK_WA_VISUAL) visual = attributes->visual; else - visual = gdk_visual_get_system (); + visual = gdk_screen_get_system_visual (screen); xvisual = ((GdkVisualPrivate*) visual)->xvisual; xattributes.event_mask = StructureNotifyMask; @@ -446,7 +482,7 @@ gdk_window_new (GdkWindow *parent, { g_warning (G_STRLOC "Toplevel windows must be created as children of\n" "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN"); - xparent = _gdk_root_window; + xparent = GDK_SCREEN_XROOTWIN (screen); } case GDK_WINDOW_CHILD: break; @@ -470,25 +506,23 @@ gdk_window_new (GdkWindow *parent, } else { - if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual) + if ((((GdkVisualPrivate *)gdk_screen_get_system_visual (screen))->xvisual) == xvisual) { - draw_impl->colormap = - gdk_colormap_get_system (); + draw_impl->colormap = gdk_screen_get_system_colormap (screen); gdk_colormap_ref (draw_impl->colormap); } else { - draw_impl->colormap = - gdk_colormap_new (visual, FALSE); + draw_impl->colormap = gdk_colormap_new (visual, FALSE); } } - private->bg_color.pixel = BlackPixel (gdk_display, _gdk_screen); + private->bg_color.pixel = BlackPixel (xdisplay, screen_x11->screen_num); xattributes.background_pixel = private->bg_color.pixel; private->bg_pixmap = NULL; - xattributes.border_pixel = BlackPixel (gdk_display, _gdk_screen); + xattributes.border_pixel = BlackPixel (xdisplay, screen_x11->screen_num); xattributes_mask |= CWBorderPixel | CWBackPixel; if (private->guffaw_gravity) @@ -515,7 +549,7 @@ gdk_window_new (GdkWindow *parent, private->depth = 0; class = InputOnly; private->input_only = TRUE; - draw_impl->colormap = gdk_colormap_get_system (); + draw_impl->colormap = gdk_screen_get_system_colormap (screen); gdk_colormap_ref (draw_impl->colormap); } @@ -526,7 +560,7 @@ gdk_window_new (GdkWindow *parent, xattributes_mask, &xattributes); gdk_drawable_ref (window); - gdk_xid_table_insert (&draw_impl->xid, window); + _gdk_xid_table_insert (screen_x11->display, &draw_impl->xid, window); gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ? (attributes->cursor) : @@ -541,12 +575,11 @@ gdk_window_new (GdkWindow *parent, XSetTransientForHint (xdisplay, xid, xparent); case GDK_WINDOW_TOPLEVEL: case GDK_WINDOW_TEMP: - XSetWMProtocols (xdisplay, xid, - _gdk_wm_window_protocols, 3); + set_wm_protocols (window); break; case GDK_WINDOW_CHILD: if ((attributes->wclass == GDK_INPUT_OUTPUT) && - (draw_impl->colormap != gdk_colormap_get_system ()) && + (draw_impl->colormap != gdk_screen_get_system_colormap (screen)) && (draw_impl->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window)))) { GDK_NOTE (MISC, g_message ("adding colormap window\n")); @@ -574,7 +607,7 @@ gdk_window_new (GdkWindow *parent, KeyPressMask | KeyReleaseMask | FocusChangeMask); XMapWindow (xdisplay, impl->focus_window); - gdk_xid_table_insert (&impl->focus_window, window); + _gdk_xid_table_insert (screen_x11->display, &impl->focus_window, window); } size_hints.flags = PSize; @@ -582,7 +615,7 @@ gdk_window_new (GdkWindow *parent, size_hints.height = impl->height; wm_hints.flags = StateHint | WindowGroupHint; - wm_hints.window_group = _gdk_leader_window; + wm_hints.window_group = GDK_DISPLAY_X11 (screen_x11->display)->leader_window; wm_hints.input = True; wm_hints.initial_state = NormalState; @@ -594,23 +627,20 @@ gdk_window_new (GdkWindow *parent, XSetWMHints (xdisplay, xid, &wm_hints); - if (!wm_client_leader_atom) - wm_client_leader_atom = gdk_x11_get_xatom_by_name ("WM_CLIENT_LEADER"); - /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */ XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL); pid = getpid (); XChangeProperty (xdisplay, xid, - gdk_x11_get_xatom_by_name ("_NET_WM_PID"), + gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "_NET_WM_PID"), XA_CARDINAL, 32, PropModeReplace, (guchar *)&pid, 1); - XChangeProperty (xdisplay, xid, - wm_client_leader_atom, + XChangeProperty (xdisplay, xid, + gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "WM_CLIENT_LEADER"), XA_WINDOW, 32, PropModeReplace, - (guchar*) &_gdk_leader_window, 1); + (guchar *) &GDK_DISPLAY_X11 (screen_x11->display)->leader_window, 1); if (attributes_mask & GDK_WA_TITLE) title = attributes->title; @@ -647,7 +677,8 @@ x_event_mask_to_gdk_event_mask (long mask) } /** - * gdk_window_foreign_new: + * gdk_window_foreign_new_for_display: + * @display: the #GdkDisplay where the window handle comes from. * @anid: a native window handle. * * Wraps a native window in a #GdkWindow. @@ -660,27 +691,33 @@ x_event_mask_to_gdk_event_mask (long mask) * native window or %NULL if the window has been destroyed. **/ GdkWindow * -gdk_window_foreign_new (GdkNativeWindow anid) +gdk_window_foreign_new_for_display (GdkDisplay *display, + GdkNativeWindow anid) { GdkWindow *window; GdkWindowObject *private; GdkWindowImplX11 *impl; GdkDrawableImplX11 *draw_impl; + GdkDisplayX11 *display_x11; XWindowAttributes attrs; Window root, parent; Window *children = NULL; guint nchildren; gboolean result; + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + display_x11 = GDK_DISPLAY_X11 (display); + gdk_error_trap_push (); - result = XGetWindowAttributes (gdk_display, anid, &attrs); + result = XGetWindowAttributes (display_x11->xdisplay, anid, &attrs); if (gdk_error_trap_pop () || !result) return NULL; /* FIXME: This is pretty expensive. Maybe the caller should supply * the parent */ gdk_error_trap_push (); - result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren); + result = XQueryTree (display_x11->xdisplay, anid, &root, &parent, &children, &nchildren); if (gdk_error_trap_pop () || !result) return NULL; @@ -692,15 +729,16 @@ gdk_window_foreign_new (GdkNativeWindow anid) impl = GDK_WINDOW_IMPL_X11 (private->impl); draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); draw_impl->wrapper = GDK_DRAWABLE (window); + draw_impl->screen = _gdk_x11_display_screen_for_xrootwin (display, root); + + private->parent = gdk_xid_table_lookup_for_display (display, parent); - private->parent = gdk_xid_table_lookup (parent); if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN) - private->parent = (GdkWindowObject *)_gdk_parent_root; + private->parent = (GdkWindowObject *) gdk_screen_get_root_window (draw_impl->screen); private->parent->children = g_list_prepend (private->parent->children, window); draw_impl->xid = anid; - draw_impl->xdisplay = gdk_display; private->x = attrs.x; private->y = attrs.y; @@ -721,12 +759,49 @@ gdk_window_foreign_new (GdkNativeWindow anid) _gdk_window_init_position (GDK_WINDOW (private)); gdk_drawable_ref (window); - gdk_xid_table_insert (&GDK_WINDOW_XID (window), window); - + _gdk_xid_table_insert (display, &GDK_WINDOW_XID (window), window); return window; } /** + * gdk_window_foreign_new: + * @anid: a native window handle. + * + * Wraps a native window for the default display in a #GdkWindow. + * This may fail if the window has been destroyed. + * + * For example in the X backend, a native window handle is an Xlib + * <type>XID</type>. + * + * Return value: the newly-created #GdkWindow wrapper for the + * native window or %NULL if the window has been destroyed. + **/ +GdkWindow * +gdk_window_foreign_new (GdkNativeWindow anid) +{ + return gdk_window_foreign_new_for_display (gdk_get_default_display (), anid); +} + +/** + * gdk_window_lookup_for_display: + * @display: the #GdkDisplay corresponding to the window handle + * @anid: a native window handle. + * + * Looks up the #GdkWindow that wraps the given native window handle. + * + * For example in the X backend, a native window handle is an Xlib + * <type>XID</type>. + * + * Return value: the #GdkWindow wrapper for the native window, + * or %NULL if there is none. + **/ +GdkWindow * +gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid) +{ + return (GdkWindow*) gdk_xid_table_lookup_for_display (display, anid); +} + +/** * gdk_window_lookup: * @anid: a native window handle. * @@ -763,7 +838,7 @@ _gdk_windowing_window_destroy (GdkWindow *window, GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); if (draw_impl->picture) - XRenderFreePicture (draw_impl->xdisplay, draw_impl->picture); + XRenderFreePicture (GDK_WINDOW_XDISPLAY (window), draw_impl->picture); } #endif /* HAVE_XFT */ @@ -783,15 +858,17 @@ _gdk_windowing_window_destroy (GdkWindow *window, xevent.type = ClientMessage; xevent.window = GDK_WINDOW_XID (window); - xevent.message_type = gdk_x11_get_xatom_by_name ("WM_PROTOCOLS"); + xevent.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "WM_PROTOCOLS"); xevent.format = 32; - xevent.data.l[0] = gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW"); + xevent.data.l[0] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "WM_DELETE_WINDOW"); xevent.data.l[1] = CurrentTime; XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), False, 0, (XEvent *)&xevent); - gdk_flush (); + gdk_display_sync (GDK_WINDOW_DISPLAY (window)); gdk_error_trap_pop (); } } @@ -820,9 +897,9 @@ gdk_window_destroy_notify (GdkWindow *window) _gdk_window_destroy (window, TRUE); } - gdk_xid_table_remove (GDK_WINDOW_XID (window)); + _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), GDK_WINDOW_XID (window)); if (window_impl->focus_window) - gdk_xid_table_remove (window_impl->focus_window); + _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), window_impl->focus_window); _gdk_xgrab_check_destroy (window); @@ -864,21 +941,25 @@ set_initial_hints (GdkWindow *window) if (private->state & GDK_WINDOW_STATE_MAXIMIZED) { - atoms[i] = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MAXIMIZED_VERT"); + atoms[i] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "_NET_WM_STATE_MAXIMIZED_VERT"); ++i; - atoms[i] = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MAXIMIZED_HORZ"); + atoms[i] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "_NET_WM_STATE_MAXIMIZED_HORZ"); ++i; } if (private->state & GDK_WINDOW_STATE_STICKY) { - atoms[i] = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_STICKY"); + atoms[i] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "_NET_WM_STATE_STICKY"); ++i; } if (private->modal_hint) { - atoms[i] = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MODAL"); + atoms[i] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "_NET_WM_STATE_MODAL"); ++i; } @@ -886,7 +967,7 @@ set_initial_hints (GdkWindow *window) { XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("_NET_WM_STATE"), + gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), "_NET_WM_STATE"), XA_ATOM, 32, PropModeReplace, (guchar*) atoms, i); } @@ -896,7 +977,7 @@ set_initial_hints (GdkWindow *window) atoms[0] = 0xFFFFFFFF; XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP"), + gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), "_NET_WM_DESKTOP"), XA_CARDINAL, 32, PropModeReplace, (guchar*) atoms, 1); } @@ -1229,6 +1310,7 @@ gdk_window_reparent (GdkWindow *window, gint x, gint y) { + GdkDisplay *display; GdkWindowObject *window_private; GdkWindowObject *parent_private; GdkWindowObject *old_parent_private; @@ -1239,7 +1321,9 @@ gdk_window_reparent (GdkWindow *window, g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT); if (!new_parent) - new_parent = _gdk_parent_root; + new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window)); + + display = GDK_WINDOW_DISPLAY (window); window_private = (GdkWindowObject*) window; old_parent_private = (GdkWindowObject*)window_private->parent; @@ -1258,7 +1342,7 @@ gdk_window_reparent (GdkWindow *window, * the root window */ if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN) - new_parent = _gdk_parent_root; + new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window)); window_private->parent = (GdkWindowObject *)new_parent; @@ -1270,12 +1354,8 @@ gdk_window_reparent (GdkWindow *window, case GDK_WINDOW_FOREIGN: /* Now a toplevel */ if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) - { - GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL; - XSetWMProtocols (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - _gdk_wm_window_protocols, 3); - } + set_wm_protocols (window); + break; case GDK_WINDOW_TOPLEVEL: case GDK_WINDOW_CHILD: case GDK_WINDOW_DIALOG: @@ -1398,8 +1478,9 @@ gdk_window_focus (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; - - if (gdk_net_wm_supports (gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE))) + + if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), + gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE))) { XEvent xev; @@ -1407,12 +1488,12 @@ gdk_window_focus (GdkWindow *window, xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.window = GDK_WINDOW_XWINDOW (window); - xev.xclient.display = gdk_display; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "_NET_ACTIVE_WINDOW"); xev.xclient.format = 32; xev.xclient.data.l[0] = 0; - XSendEvent (gdk_display, _gdk_root_window, False, + XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } @@ -1517,6 +1598,7 @@ void gdk_window_set_type_hint (GdkWindow *window, GdkWindowTypeHint hint) { + GdkDisplay *display; Atom atom; g_return_if_fail (window != NULL); @@ -1525,28 +1607,29 @@ gdk_window_set_type_hint (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; + display = gdk_drawable_get_display (window); + switch (hint) { case GDK_WINDOW_TYPE_HINT_DIALOG: - atom = gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE_DIALOG"); + atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG"); break; case GDK_WINDOW_TYPE_HINT_MENU: - atom = gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE_MENU"); + atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU"); break; case GDK_WINDOW_TYPE_HINT_TOOLBAR: - atom = gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE_TOOLBAR"); + atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR"); break; default: g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint); /* Fall thru */ case GDK_WINDOW_TYPE_HINT_NORMAL: - atom = gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE_NORMAL"); + atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NORMAL"); break; } - XChangeProperty (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE"), + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"), XA_ATOM, 32, PropModeReplace, (guchar *)&atom, 1); } @@ -1558,8 +1641,9 @@ gdk_wmspec_change_state (gboolean add, GdkAtom state1, GdkAtom state2) { + GdkDisplay *display = GDK_WINDOW_DISPLAY (window); XEvent xev; - + #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define _NET_WM_STATE_ADD 1 /* add/set property */ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ @@ -1567,18 +1651,18 @@ gdk_wmspec_change_state (gboolean add, xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; - xev.xclient.display = gdk_display; xev.xclient.window = GDK_WINDOW_XID (window); - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_STATE"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"); xev.xclient.format = 32; xev.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; - xev.xclient.data.l[1] = gdk_x11_atom_to_xatom (state1); - xev.xclient.data.l[2] = gdk_x11_atom_to_xatom (state2); + xev.xclient.data.l[1] = gdk_x11_atom_to_xatom_for_display (display, state1); + xev.xclient.data.l[2] = gdk_x11_atom_to_xatom_for_display (display, state2); - XSendEvent (gdk_display, _gdk_root_window, False, + XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } + /** * gdk_window_set_modal_hint: * @window: A #GdkWindow @@ -1610,7 +1694,7 @@ gdk_window_set_modal_hint (GdkWindow *window, if (GDK_WINDOW_IS_MAPPED (window)) gdk_wmspec_change_state (modal, window, - gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE), + gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE), 0); } @@ -1829,9 +1913,11 @@ set_text_property (GdkWindow *window, { GdkAtom gdk_type; - gdk_utf8_to_compound_text (utf8_str, &gdk_type, &prop_format, - &prop_text, &prop_length); - prop_type = gdk_x11_atom_to_xatom (gdk_type); + gdk_utf8_to_compound_text_for_display (gdk_drawable_get_display (window), + utf8_str, &gdk_type, &prop_format, + &prop_text, &prop_length); + prop_type = gdk_x11_atom_to_xatom_for_display + (GDK_WINDOW_DISPLAY (window), gdk_type); } if (prop_text) @@ -1857,12 +1943,13 @@ set_text_property (GdkWindow *window, * (using gdk_window_set_icon_name()), the icon name will be set to * @title as well. @title must be in UTF-8 encoding (as with all * user-readable strings in GDK/GTK+). @title may not be %NULL. - * **/ void gdk_window_set_title (GdkWindow *window, const gchar *title) { + GdkDisplay *display; + g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (title != NULL); @@ -1870,23 +1957,27 @@ gdk_window_set_title (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; - XChangeProperty (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("_NET_WM_NAME"), - gdk_x11_get_xatom_by_name ("UTF8_STRING"), 8, - PropModeReplace, title, - strlen (title)); + display = gdk_drawable_get_display (window); - set_text_property (window, gdk_x11_get_xatom_by_name ("WM_NAME"), title); + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME"), + gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, + PropModeReplace, title, strlen (title)); + + set_text_property (window, + gdk_x11_get_xatom_by_name_for_display (display, "WM_NAME"), + title); + if (!gdk_window_icon_name_set (window)) { - XChangeProperty (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("_NET_WM_ICON_NAME"), - gdk_x11_get_xatom_by_name ("UTF8_STRING"), 8, - PropModeReplace, title, - strlen (title)); - set_text_property (window, gdk_x11_get_xatom_by_name ("WM_ICON_NAME"), title); + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"), + gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, + PropModeReplace, title, strlen (title)); + + set_text_property (window, + gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"), + title); } } @@ -1913,18 +2004,22 @@ void gdk_window_set_role (GdkWindow *window, const gchar *role) { + GdkDisplay *display; + g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); + display = gdk_drawable_get_display (window); + if (!GDK_WINDOW_DESTROYED (window)) { if (role) - XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("WM_WINDOW_ROLE"), XA_STRING, - 8, PropModeReplace, role, strlen (role)); + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"), + XA_STRING, 8, PropModeReplace, role, strlen (role)); else - XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("WM_WINDOW_ROLE")); + XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE")); } } @@ -2145,8 +2240,12 @@ gdk_window_get_geometry (GdkWindow *window, g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); if (!window) - window = _gdk_parent_root; - + { + GDK_NOTE (MULTIHEAD, + g_message ("gdk_window_get_geometry(): Window needs to be non-NULL to be multi head safe")); + window = gdk_screen_get_root_window ((gdk_get_default_screen ())); + } + if (!GDK_WINDOW_DESTROYED (window)) { XGetGeometry (GDK_WINDOW_XDISPLAY (window), @@ -2195,10 +2294,9 @@ gdk_window_get_origin (GdkWindow *window, { return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - _gdk_root_window, + GDK_WINDOW_XROOTWIN (window), 0, 0, &tx, &ty, &child); - } else return_val = 0; @@ -2237,7 +2335,7 @@ gdk_window_get_deskrelative_origin (GdkWindow *window, gint tx = 0; gint ty = 0; Atom type_return; - static Atom atom = 0; + Atom atom; gulong number_return, bytes_after_return; guchar *data_return; @@ -2246,8 +2344,8 @@ gdk_window_get_deskrelative_origin (GdkWindow *window, if (!GDK_WINDOW_DESTROYED (window)) { - if (!atom) - atom = gdk_x11_get_xatom_by_name ("ENLIGHTENMENT_DESKTOP"); + atom = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "ENLIGHTENMENT_DESKTOP"); win = GDK_WINDOW_XID (window); while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent, @@ -2268,6 +2366,7 @@ gdk_window_get_deskrelative_origin (GdkWindow *window, XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0, False, XA_CARDINAL, &type_return, &format_return, &number_return, &bytes_after_return, &data_return); + if (type_return == XA_CARDINAL) { XFree (data_return); @@ -2405,7 +2504,11 @@ _gdk_windowing_window_get_pointer (GdkWindow *window, g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL); if (!window) - window = _gdk_parent_root; + { + GDK_NOTE (MULTIHEAD, + g_message ("_gdk_windowing_window_get_pointer(): window arg is need for multihead safe operation")); + window = gdk_screen_get_root_window (gdk_get_default_screen ()); + } _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset); @@ -2416,7 +2519,7 @@ _gdk_windowing_window_get_pointer (GdkWindow *window, &root, &child, &rootx, &rooty, &winx, &winy, &xmask)) { if (child) - return_val = gdk_window_lookup (child); + return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child); } if (x) @@ -2434,38 +2537,7 @@ _gdk_windowing_window_at_pointer (GdkScreen *screen, gint *win_x, gint *win_y) { - GdkWindow *window; - Window root; - Window xwindow; - Window xwindow_last = 0; - Display *xdisplay; - int rootx = -1, rooty = -1; - int winx, winy; - unsigned int xmask; - - xwindow = GDK_ROOT_WINDOW (); - xdisplay = GDK_DISPLAY (); - - gdk_x11_grab_server (); - while (xwindow) - { - xwindow_last = xwindow; - XQueryPointer (xdisplay, xwindow, - &root, &xwindow, - &rootx, &rooty, - &winx, &winy, - &xmask); - } - gdk_x11_ungrab_server (); - - window = gdk_window_lookup (xwindow_last); - - if (win_x) - *win_x = window ? winx : -1; - if (win_y) - *win_y = window ? winy : -1; - - return window; + return gdk_screen_get_window_at_pointer (screen, win_x, win_y); } /** @@ -2583,21 +2655,25 @@ gdk_window_add_colormap_windows (GdkWindow *window) } static gboolean -gdk_window_have_shape_ext (void) +gdk_window_have_shape_ext (GdkDisplay *display) { enum { UNKNOWN, NO, YES }; - static gint have_shape = UNKNOWN; + GdkDisplayX11 *display_x11; - if (have_shape == UNKNOWN) + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + display_x11 = GDK_DISPLAY_X11 (display); + + if (display_x11->have_shape == UNKNOWN) { int ignore; - if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore)) - have_shape = YES; + if (XQueryExtension (display_x11->xdisplay, "SHAPE", &ignore, &ignore, &ignore)) + display_x11->have_shape = YES; else - have_shape = NO; + display_x11->have_shape = NO; } - return (have_shape == YES); + return (display_x11->have_shape == YES); } #define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.") @@ -2652,7 +2728,7 @@ gdk_window_shape_combine_mask (GdkWindow *window, return; } - if (gdk_window_have_shape_ext ()) + if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window))) { if (mask) { @@ -2726,7 +2802,7 @@ gdk_window_shape_combine_region (GdkWindow *window, return; } - if (gdk_window_have_shape_ext ()) + if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window))) { gint n_rects = 0; XRectangle *xrects = NULL; @@ -2811,11 +2887,14 @@ gdk_window_set_icon_list (GdkWindow *window, gint width, height, stride; gint x, y; gint n_channels; + GdkDisplay *display; g_return_if_fail (GDK_IS_WINDOW (window)); if (GDK_WINDOW_DESTROYED (window)) return; + + display = gdk_drawable_get_display (window); l = pixbufs; size = 0; @@ -2874,18 +2953,18 @@ gdk_window_set_icon_list (GdkWindow *window, if (size > 0) { - XChangeProperty (GDK_WINDOW_XDISPLAY (window), + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("_NET_WM_ICON"), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"), XA_CARDINAL, 32, PropModeReplace, (guchar*) data, size); } else { - XDeleteProperty (GDK_WINDOW_XDISPLAY (window), + XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("_NET_WM_ICON")); + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON")); } g_free (data); @@ -2963,28 +3042,34 @@ gdk_window_icon_name_set (GdkWindow *window) * name they display in their titlebar. Most of the time this is a bad * idea from a user interface standpoint. But you can set such a name * with this function, if you like. - * + * **/ void gdk_window_set_icon_name (GdkWindow *window, const gchar *name) { + GdkDisplay *display; + g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); if (GDK_WINDOW_DESTROYED (window)) return; + display = gdk_drawable_get_display (window); + g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"), GUINT_TO_POINTER (TRUE)); XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name ("_NET_WM_ICON_NAME"), - gdk_x11_get_xatom_by_name ("UTF8_STRING"), 8, - PropModeReplace, name, - strlen (name)); - set_text_property (window, gdk_x11_get_xatom_by_name ("WM_ICON_NAME"), name); + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"), + gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, + PropModeReplace, name, strlen (name)); + + set_text_property (window, + gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"), + name); } /** @@ -2999,7 +3084,6 @@ gdk_window_set_icon_name (GdkWindow *window, void gdk_window_iconify (GdkWindow *window) { - Display *display; GdkWindowObject *private; g_return_if_fail (window != NULL); @@ -3008,14 +3092,13 @@ gdk_window_iconify (GdkWindow *window) if (GDK_WINDOW_DESTROYED (window)) return; - display = GDK_WINDOW_XDISPLAY (window); - private = (GdkWindowObject*) window; if (GDK_WINDOW_IS_MAPPED (window)) { - XIconifyWindow (display, GDK_WINDOW_XWINDOW (window), DefaultScreen (display)); - + XIconifyWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XWINDOW (window), + gdk_screen_get_number (GDK_WINDOW_SCREEN (window))); } else { @@ -3040,7 +3123,6 @@ gdk_window_iconify (GdkWindow *window) void gdk_window_deiconify (GdkWindow *window) { - Display *display; GdkWindowObject *private; g_return_if_fail (window != NULL); @@ -3049,8 +3131,6 @@ gdk_window_deiconify (GdkWindow *window) if (GDK_WINDOW_DESTROYED (window)) return; - display = GDK_WINDOW_XDISPLAY (window); - private = (GdkWindowObject*) window; if (GDK_WINDOW_IS_MAPPED (window)) @@ -3107,13 +3187,14 @@ gdk_window_stick (GdkWindow *window) xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.window = GDK_WINDOW_XWINDOW (window); - xev.xclient.display = gdk_display; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP"); + xev.xclient.display = GDK_WINDOW_XDISPLAY (window); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "_NET_WM_DESKTOP"); xev.xclient.format = 32; xev.xclient.data.l[0] = 0xFFFFFFFF; - - XSendEvent (gdk_display, _gdk_root_window, False, + + XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } @@ -3150,6 +3231,7 @@ gdk_window_unstick (GdkWindow *window) gulong nitems; gulong bytes_after; gulong *current_desktop; + GdkDisplay *display = gdk_drawable_get_display (window); /* Request unstick from viewport */ gdk_wmspec_change_state (FALSE, window, @@ -3159,8 +3241,8 @@ gdk_window_unstick (GdkWindow *window) /* Get current desktop, then set it; this is a race, but not * one that matters much in practice. */ - XGetWindowProperty (gdk_display, _gdk_root_window, - gdk_x11_get_xatom_by_name ("_NET_CURRENT_DESKTOP"), + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"), 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, &bytes_after, (guchar **)¤t_desktop); @@ -3171,13 +3253,12 @@ gdk_window_unstick (GdkWindow *window) xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.window = GDK_WINDOW_XWINDOW (window); - xev.xclient.display = gdk_display; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP"); + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"); xev.xclient.format = 32; xev.xclient.data.l[0] = *current_desktop; - XSendEvent (gdk_display, _gdk_root_window, False, + XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); @@ -3305,7 +3386,8 @@ gdk_window_set_group (GdkWindow *window, static MotifWmHints * gdk_window_get_mwm_hints (GdkWindow *window) { - static Atom hints_atom = None; + GdkDisplay *display; + Atom hints_atom = None; MotifWmHints *hints; Atom type; gint format; @@ -3314,12 +3396,12 @@ gdk_window_get_mwm_hints (GdkWindow *window) if (GDK_WINDOW_DESTROYED (window)) return NULL; + + display = gdk_drawable_get_display (window); - if (!hints_atom) - hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window), - _XA_MOTIF_WM_HINTS, FALSE); - - XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), + hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS); + + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), hints_atom, 0, sizeof (MotifWmHints)/sizeof (long), False, AnyPropertyType, &type, &format, &nitems, &bytes_after, (guchar **)&hints); @@ -3334,7 +3416,8 @@ static void gdk_window_set_mwm_hints (GdkWindow *window, MotifWmHints *new_hints) { - static Atom hints_atom = None; + GdkDisplay *display; + Atom hints_atom = None; MotifWmHints *hints; Atom type; gint format; @@ -3344,10 +3427,10 @@ gdk_window_set_mwm_hints (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; - if (!hints_atom) - hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window), - _XA_MOTIF_WM_HINTS, FALSE); + display = gdk_drawable_get_display (window); + hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS); + XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), hints_atom, 0, sizeof (MotifWmHints)/sizeof (long), False, AnyPropertyType, &type, &format, &nitems, @@ -3810,7 +3893,7 @@ gdk_window_set_child_shapes (GdkWindow *window) #ifdef HAVE_SHAPE_EXT if (!GDK_WINDOW_DESTROYED (window) && - gdk_window_have_shape_ext ()) + gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window))) gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), FALSE); #endif @@ -3838,7 +3921,7 @@ gdk_window_merge_child_shapes (GdkWindow *window) #ifdef HAVE_SHAPE_EXT if (!GDK_WINDOW_DESTROYED (window) && - gdk_window_have_shape_ext ()) + gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window))) gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), TRUE); #endif @@ -3849,10 +3932,11 @@ gdk_window_merge_child_shapes (GdkWindow *window) */ static gboolean -gdk_window_gravity_works (void) +gdk_window_gravity_works (GdkWindow *window) { enum { UNKNOWN, NO, YES }; static gint gravity_works = UNKNOWN; + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (window); if (gravity_works == UNKNOWN) { @@ -3864,8 +3948,9 @@ gdk_window_gravity_works (void) /* This particular server apparently has a bug so that the test * works but the actual code crashes it */ - if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) && - (VendorRelease (gdk_display) == 3400)) + if ((!strcmp (XServerVendor (GDK_DISPLAY_XDISPLAY (display)), + "Sun Microsystems, Inc.")) && + (VendorRelease (GDK_DISPLAY_XDISPLAY (display)) == 3400)) { gravity_works = NO; return FALSE; @@ -3879,7 +3964,8 @@ gdk_window_gravity_works (void) attr.height = 100; attr.event_mask = 0; - parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y); + parent = gdk_window_new (gdk_screen_get_root_window (GDK_DRAWABLE_SCREEN (window)), + &attr, GDK_WA_X | GDK_WA_Y); attr.window_type = GDK_WINDOW_CHILD; child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y); @@ -3887,6 +3973,7 @@ gdk_window_gravity_works (void) gdk_window_set_static_win_gravity (child, TRUE); gdk_window_resize (parent, 100, 110); + gdk_window_move (parent, 0, -10); gdk_window_move_resize (parent, 0, 0, 100, 100); @@ -3965,7 +4052,7 @@ gdk_window_set_static_gravities (GdkWindow *window, if (!use_static == !private->guffaw_gravity) return TRUE; - if (use_static && !gdk_window_gravity_works ()) + if (use_static && !gdk_window_gravity_works (window)) return FALSE; private->guffaw_gravity = use_static; @@ -3986,135 +4073,6 @@ gdk_window_set_static_gravities (GdkWindow *window, return TRUE; } -/* internal function created for and used by gdk_window_xid_at_coords */ -Window -gdk_window_xid_at (Window base, - gint bx, - gint by, - gint x, - gint y, - GList *excludes, - gboolean excl_child) -{ - Display *xdisplay; - Window *list = NULL; - Window child = 0, parent_win = 0, root_win = 0; - int i; - unsigned int ww, wh, wb, wd, num; - int wx, wy; - - xdisplay = GDK_DISPLAY (); - if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd)) - return 0; - wx += bx; - wy += by; - - if (!((x >= wx) && - (y >= wy) && - (x < (int) (wx + ww)) && - (y < (int) (wy + wh)))) - return 0; - - if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num)) - return base; - - if (list) - { - for (i = num - 1; ; i--) - { - if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i]))) - { - if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0) - { - XFree (list); - return child; - } - } - if (!i) - break; - } - XFree (list); - } - return base; -} - -/* - * The following fucntion by The Rasterman <raster@redhat.com> - * This function returns the X Window ID in which the x y location is in - * (x and y being relative to the root window), excluding any windows listed - * in the GList excludes (this is a list of X Window ID's - gpointer being - * the Window ID). - * - * This is primarily designed for internal gdk use - for DND for example - * when using a shaped icon window as the drag object - you exclude the - * X Window ID of the "icon" (perhaps more if excludes may be needed) and - * You can get back an X Window ID as to what X Window ID is infact under - * those X,Y co-ordinates. - */ -Window -gdk_window_xid_at_coords (gint x, - gint y, - GList *excludes, - gboolean excl_child) -{ - GdkWindow *window; - Display *xdisplay; - Window *list = NULL; - Window root, child = 0, parent_win = 0, root_win = 0; - unsigned int num; - int i; - - window = _gdk_parent_root; - xdisplay = GDK_WINDOW_XDISPLAY (window); - root = GDK_WINDOW_XID (window); - num = g_list_length (excludes); - - gdk_x11_grab_server (); - if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num)) - { - gdk_x11_ungrab_server (); - return root; - } - if (list) - { - i = num - 1; - do - { - XWindowAttributes xwa; - - XGetWindowAttributes (xdisplay, list [i], &xwa); - - if (xwa.map_state != IsViewable) - continue; - - if (excl_child && g_list_find (excludes, (gpointer *) list[i])) - continue; - - if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0) - continue; - - if (excludes) - { - if (!g_list_find (excludes, (gpointer *) child)) - { - XFree (list); - gdk_x11_ungrab_server (); - return child; - } - } - else - { - XFree (list); - gdk_x11_ungrab_server (); - return child; - } - } while (--i > 0); - XFree (list); - } - gdk_x11_ungrab_server (); - return root; -} - static void wmspec_moveresize (GdkWindow *window, gint direction, @@ -4122,17 +4080,19 @@ wmspec_moveresize (GdkWindow *window, gint root_y, guint32 timestamp) { + GdkDisplay *display = GDK_WINDOW_DISPLAY (window); + XEvent xev; /* Release passive grab */ - gdk_pointer_ungrab (timestamp); - + gdk_display_pointer_ungrab (display, timestamp); + xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; - xev.xclient.display = gdk_display; xev.xclient.window = GDK_WINDOW_XID (window); - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_MOVERESIZE"); + xev.xclient.message_type = + gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE"); xev.xclient.format = 32; xev.xclient.data.l[0] = root_x; xev.xclient.data.l[1] = root_y; @@ -4140,11 +4100,34 @@ wmspec_moveresize (GdkWindow *window, xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - XSendEvent (gdk_display, _gdk_root_window, False, + XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } +typedef struct _MoveResizeData MoveResizeData; + +struct _MoveResizeData +{ + GdkDisplay *display; + + GdkWindow *moveresize_window; + GdkWindow *moveresize_emulation_window; + gboolean is_resize; + GdkWindowEdge resize_edge; + gint moveresize_button; + gint moveresize_x; + gint moveresize_y; + gint moveresize_orig_x; + gint moveresize_orig_y; + gint moveresize_orig_width; + gint moveresize_orig_height; + GdkWindowHints moveresize_geom_mask; + GdkGeometry moveresize_geometry; + Time moveresize_process_time; + XEvent *moveresize_pending_event; +}; + /* From the WM spec */ #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 #define _NET_WM_MOVERESIZE_SIZE_TOP 1 @@ -4213,94 +4196,99 @@ wmspec_resize_drag (GdkWindow *window, wmspec_moveresize (window, direction, root_x, root_y, timestamp); } -/* This is global for use in gdkevents-x11.c */ -GdkWindow *_gdk_moveresize_window; - -static GdkWindow *moveresize_emulation_window = NULL; -static gboolean is_resize = FALSE; -static GdkWindowEdge resize_edge; -static gint moveresize_button; -static gint moveresize_x; -static gint moveresize_y; -static gint moveresize_orig_x; -static gint moveresize_orig_y; -static gint moveresize_orig_width; -static gint moveresize_orig_height; -static GdkWindowHints moveresize_geom_mask = 0; -static GdkGeometry moveresize_geometry; -static Time moveresize_process_time; - -static XEvent *moveresize_pending_event; +static MoveResizeData * +get_move_resize_data (GdkDisplay *display) +{ + MoveResizeData *mv_resize; + static GQuark move_resize_quark = 0; + + if (!move_resize_quark) + move_resize_quark = g_quark_from_static_string ("gdk-window-moveresize"); + + mv_resize = g_object_get_qdata (G_OBJECT (display), move_resize_quark); + + if (!mv_resize) + { + mv_resize = g_new0 (MoveResizeData, 1); + mv_resize->display = display; + + g_object_set_qdata (G_OBJECT (display), move_resize_quark, mv_resize); + } + + return mv_resize; +} static void -update_pos (gint new_root_x, - gint new_root_y) +update_pos (MoveResizeData *mv_resize, + gint new_root_x, + gint new_root_y) { gint dx, dy; - - dx = new_root_x - moveresize_x; - dy = new_root_y - moveresize_y; - if (is_resize) + dx = new_root_x - mv_resize->moveresize_x; + dy = new_root_y - mv_resize->moveresize_y; + + if (mv_resize->is_resize) { gint w, h; - w = moveresize_orig_width; - h = moveresize_orig_height; - - switch (resize_edge) - { - case GDK_WINDOW_EDGE_SOUTH_EAST: - w += dx; - h += dy; - break; - } + w = mv_resize->moveresize_orig_width; + h = mv_resize->moveresize_orig_height; + + switch (mv_resize->resize_edge) + { + case GDK_WINDOW_EDGE_SOUTH_EAST: + w += dx; + h += dy; + break; + } w = MAX (w, 1); h = MAX (h, 1); - - if (moveresize_geom_mask) - { - gdk_window_constrain_size (&moveresize_geometry, - moveresize_geom_mask, - w, h, - &w, &h); - } - - gdk_window_resize (_gdk_moveresize_window, w, h); + + if (mv_resize->moveresize_geom_mask) + { + gdk_window_constrain_size (&mv_resize->moveresize_geometry, + mv_resize->moveresize_geom_mask, + w, h, &w, &h); + } + + gdk_window_resize (mv_resize->moveresize_window, w, h); } else { gint x, y; - x = moveresize_orig_x + dx; - y = moveresize_orig_y + dy; - - gdk_window_move (_gdk_moveresize_window, x, y); + x = mv_resize->moveresize_orig_x + dx; + y = mv_resize->moveresize_orig_y + dy; + + gdk_window_move (mv_resize->moveresize_window, x, y); } } static void -finish_drag (void) +finish_drag (MoveResizeData *mv_resize) { - gdk_window_destroy (moveresize_emulation_window); - moveresize_emulation_window = NULL; - _gdk_moveresize_window = NULL; + gdk_window_destroy (mv_resize->moveresize_emulation_window); + mv_resize->moveresize_emulation_window = NULL; + mv_resize->moveresize_window = NULL; - if (moveresize_pending_event) + if (mv_resize->moveresize_pending_event) { - g_free (moveresize_pending_event); - moveresize_pending_event = NULL; + g_free (mv_resize->moveresize_pending_event); + mv_resize->moveresize_pending_event = NULL; } } static int -lookahead_motion_predicate (Display *display, +lookahead_motion_predicate (Display *xdisplay, XEvent *event, XPointer arg) { gboolean *seen_release = (gboolean *)arg; - + GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay); + MoveResizeData *mv_resize = get_move_resize_data (display); + if (*seen_release) return False; @@ -4310,7 +4298,7 @@ lookahead_motion_predicate (Display *display, *seen_release = TRUE; break; case MotionNotify: - moveresize_process_time = event->xmotion.time; + mv_resize->moveresize_process_time = event->xmotion.time; break; default: break; @@ -4320,54 +4308,64 @@ lookahead_motion_predicate (Display *display, } static gboolean -moveresize_lookahead (XEvent *event) +moveresize_lookahead (MoveResizeData *mv_resize, + XEvent *event) { XEvent tmp_event; gboolean seen_release = FALSE; - if (moveresize_process_time) + if (mv_resize->moveresize_process_time) { - if (event->xmotion.time == moveresize_process_time) + if (event->xmotion.time == mv_resize->moveresize_process_time) { - moveresize_process_time = 0; + mv_resize->moveresize_process_time = 0; return TRUE; } else return FALSE; } - XCheckIfEvent (gdk_display, &tmp_event, - lookahead_motion_predicate, (XPointer)&seen_release); + XCheckIfEvent (event->xany.display, &tmp_event, + lookahead_motion_predicate, (XPointer) & seen_release); - return moveresize_process_time == 0; + return mv_resize->moveresize_process_time == 0; } -void +gboolean _gdk_moveresize_handle_event (XEvent *event) { guint button_mask = 0; - GdkWindowObject *window_private = (GdkWindowObject *) _gdk_moveresize_window; - - button_mask = GDK_BUTTON1_MASK << (moveresize_button - 1); - + GdkWindowObject *window_private; + GdkDisplay *display= gdk_x11_lookup_xdisplay (event->xany.display); + MoveResizeData *mv_resize = get_move_resize_data (display); + + if (!mv_resize->moveresize_window) + return FALSE; + + window_private = (GdkWindowObject *) mv_resize->moveresize_window; + + button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1); + switch (event->xany.type) { case MotionNotify: if (window_private->resize_count > 0) { - if (moveresize_pending_event) - *moveresize_pending_event = *event; + if (mv_resize->moveresize_pending_event) + *mv_resize->moveresize_pending_event = *event; else - moveresize_pending_event = g_memdup (event, sizeof (XEvent)); + mv_resize->moveresize_pending_event = + g_memdup (event, sizeof (XEvent)); break; } - if (!moveresize_lookahead (event)) + if (!moveresize_lookahead (mv_resize, event)) break; - - update_pos (event->xmotion.x_root, - event->xmotion.y_root); - + + update_pos (mv_resize, + event->xmotion.x_root, + event->xmotion.y_root); + /* This should never be triggered in normal cases, but in the * case where the drag started without an implicit grab being * in effect, we could miss the release if it occurs before @@ -4375,42 +4373,54 @@ _gdk_moveresize_handle_event (XEvent *event) * get a permanently stuck grab. */ if ((event->xmotion.state & button_mask) == 0) - finish_drag (); + finish_drag (mv_resize); break; case ButtonRelease: - update_pos (event->xbutton.x_root, - event->xbutton.y_root); - - if (event->xbutton.button == moveresize_button) - finish_drag (); + update_pos (mv_resize, + event->xbutton.x_root, + event->xbutton.y_root); + + if (event->xbutton.button == mv_resize->moveresize_button) + finish_drag (mv_resize); break; } + return TRUE; } -void -_gdk_moveresize_configure_done (void) +gboolean +_gdk_moveresize_configure_done (GdkDisplay *display, + GdkWindow *window) { XEvent *tmp_event; + MoveResizeData *mv_resize = get_move_resize_data (display); - if (moveresize_pending_event) + if (window != mv_resize->moveresize_window) + return FALSE; + + g_assert (mv_resize != NULL); + + if (mv_resize->moveresize_pending_event) { - tmp_event = moveresize_pending_event; - moveresize_pending_event = NULL; + tmp_event = mv_resize->moveresize_pending_event; + mv_resize->moveresize_pending_event = NULL; _gdk_moveresize_handle_event (tmp_event); g_free (tmp_event); } + + return TRUE; } static void -create_moveresize_window (guint32 timestamp) +create_moveresize_window (MoveResizeData *mv_resize, + guint32 timestamp) { GdkWindowAttr attributes; gint attributes_mask; GdkGrabStatus status; - g_assert (moveresize_emulation_window == NULL); - + g_assert (mv_resize->moveresize_emulation_window == NULL); + attributes.x = -100; attributes.y = -100; attributes.width = 10; @@ -4422,12 +4432,14 @@ create_moveresize_window (guint32 timestamp) attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR; - moveresize_emulation_window = - gdk_window_new (NULL, &attributes, attributes_mask); + mv_resize->moveresize_emulation_window = + gdk_window_new (gdk_screen_get_root_window (gdk_display_get_default_screen (mv_resize->display)), + &attributes, + attributes_mask); - gdk_window_show (moveresize_emulation_window); + gdk_window_show (mv_resize->moveresize_emulation_window); - status = gdk_pointer_grab (moveresize_emulation_window, + status = gdk_pointer_grab (mv_resize->moveresize_emulation_window, FALSE, GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, @@ -4440,11 +4452,11 @@ create_moveresize_window (guint32 timestamp) /* If this fails, some other client has grabbed the window * already. */ - gdk_window_destroy (moveresize_emulation_window); - moveresize_emulation_window = NULL; + gdk_window_destroy (mv_resize->moveresize_emulation_window); + mv_resize->moveresize_emulation_window = NULL; } - moveresize_process_time = 0; + mv_resize->moveresize_process_time = 0; } static void @@ -4455,21 +4467,25 @@ emulate_resize_drag (GdkWindow *window, gint root_y, guint32 timestamp) { - is_resize = TRUE; - moveresize_button = button; - resize_edge = edge; - moveresize_x = root_x; - moveresize_y = root_y; - _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window))); + MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window)); - gdk_window_get_size (window, &moveresize_orig_width, &moveresize_orig_height); - - moveresize_geom_mask = 0; + mv_resize->is_resize = TRUE; + mv_resize->moveresize_button = button; + mv_resize->resize_edge = edge; + mv_resize->moveresize_x = root_x; + mv_resize->moveresize_y = root_y; + mv_resize->moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window))); + + gdk_window_get_size (window, + &mv_resize->moveresize_orig_width, + &mv_resize->moveresize_orig_height); + + mv_resize->moveresize_geom_mask = 0; gdk_window_get_geometry_hints (window, - &moveresize_geometry, - &moveresize_geom_mask); - - create_moveresize_window (timestamp); + &mv_resize->moveresize_geometry, + &mv_resize->moveresize_geom_mask); + + create_moveresize_window (mv_resize, timestamp); } static void @@ -4479,17 +4495,21 @@ emulate_move_drag (GdkWindow *window, gint root_y, guint32 timestamp) { - is_resize = FALSE; - moveresize_button = button; - moveresize_x = root_x; - moveresize_y = root_y; - _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window))); - - gdk_window_get_deskrelative_origin (_gdk_moveresize_window, - &moveresize_orig_x, - &moveresize_orig_y); + MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window)); - create_moveresize_window (timestamp); + mv_resize->is_resize = FALSE; + mv_resize->moveresize_button = button; + mv_resize->moveresize_x = root_x; + mv_resize->moveresize_y = root_y; + + mv_resize->moveresize_window = + GDK_WINDOW (g_object_ref (G_OBJECT (window))); + + gdk_window_get_deskrelative_origin (mv_resize->moveresize_window, + &mv_resize->moveresize_orig_x, + &mv_resize->moveresize_orig_y); + + create_moveresize_window (mv_resize, timestamp); } /** @@ -4518,12 +4538,12 @@ gdk_window_begin_resize_drag (GdkWindow *window, guint32 timestamp) { g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (moveresize_emulation_window == NULL); - + if (GDK_WINDOW_DESTROYED (window)) return; - if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE))) + if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), + gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE))) wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp); else emulate_resize_drag (window, edge, button, root_x, root_y, timestamp); @@ -4553,14 +4573,14 @@ gdk_window_begin_move_drag (GdkWindow *window, guint32 timestamp) { g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (moveresize_emulation_window == NULL); - + if (GDK_WINDOW_DESTROYED (window)) return; - if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE))) - wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, - root_x, root_y, timestamp); + if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), + gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE))) + wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, root_x, root_y, + timestamp); else emulate_move_drag (window, button, root_x, root_y, timestamp); } diff --git a/gdk/x11/gdkx.h b/gdk/x11/gdkx.h index f38d2118f..c4b35c889 100644 --- a/gdk/x11/gdkx.h +++ b/gdk/x11/gdkx.h @@ -35,7 +35,9 @@ G_BEGIN_DECLS -extern Display *gdk_display; +#ifndef GDK_MULTIHEAD_SAFE +extern Display *gdk_display; +#endif Display *gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable); XID gdk_x11_drawable_get_xid (GdkDrawable *drawable); @@ -45,77 +47,122 @@ Display *gdk_x11_colormap_get_xdisplay (GdkColormap *colormap); Colormap gdk_x11_colormap_get_xcolormap (GdkColormap *colormap); Display *gdk_x11_cursor_get_xdisplay (GdkCursor *cursor); Cursor gdk_x11_cursor_get_xcursor (GdkCursor *cursor); +Display *gdk_x11_display_get_xdisplay (GdkDisplay *display); Visual * gdk_x11_visual_get_xvisual (GdkVisual *visual); Display *gdk_x11_gc_get_xdisplay (GdkGC *gc); GC gdk_x11_gc_get_xgc (GdkGC *gc); +Screen * gdk_x11_screen_get_xscreen (GdkScreen *screen); +int gdk_x11_screen_get_screen_number (GdkScreen *screen); +#ifndef GDK_MULTIHEAD_SAFE Window gdk_x11_get_default_root_xwindow (void); Display *gdk_x11_get_default_xdisplay (void); gint gdk_x11_get_default_screen (void); +#endif #define GDK_COLORMAP_XDISPLAY(cmap) (gdk_x11_colormap_get_xdisplay (cmap)) #define GDK_COLORMAP_XCOLORMAP(cmap) (gdk_x11_colormap_get_xcolormap (cmap)) #define GDK_CURSOR_XDISPLAY(cursor) (gdk_x11_cursor_get_xdisplay (cursor)) #define GDK_CURSOR_XCURSOR(cursor) (gdk_x11_cursor_get_xcursor (cursor)) -#define GDK_DISPLAY() gdk_display #define GDK_IMAGE_XDISPLAY(image) (gdk_x11_image_get_xdisplay (image)) #define GDK_IMAGE_XIMAGE(image) (gdk_x11_image_get_ximage (image)) +#ifndef GDK_MULTIHEAD_SAFE +#define GDK_DISPLAY() gdk_display +#endif + #ifdef INSIDE_GDK_X11 #include "gdkprivate-x11.h" +#include "gdkscreen-x11.h" -#define GDK_ROOT_WINDOW() _gdk_root_window -#undef GDK_ROOT_PARENT -#define GDK_ROOT_PARENT() ((GdkWindow *)_gdk_parent_root) -#define GDK_WINDOW_XDISPLAY(win) (GDK_DRAWABLE_IMPL_X11(((GdkWindowObject *)win)->impl)->xdisplay) +#define GDK_DISPLAY_XDISPLAY(display) (GDK_DISPLAY_X11(display)->xdisplay) + +#define GDK_WINDOW_XDISPLAY(win) (GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (win))->xdisplay) #define GDK_WINDOW_XID(win) (GDK_DRAWABLE_IMPL_X11(((GdkWindowObject *)win)->impl)->xid) -#define GDK_PIXMAP_XDISPLAY(win) (GDK_DRAWABLE_IMPL_X11(((GdkPixmapObject *)win)->impl)->xdisplay) -#define GDK_PIXMAP_XID(win) (GDK_DRAWABLE_IMPL_X11(((GdkPixmapObject *)win)->impl)->xid) +#define GDK_PIXMAP_XDISPLAY(pix) (GDK_SCREEN_X11 (GDK_PIXMAP_SCREEN (pix))->xdisplay) +#define GDK_PIXMAP_XID(pix) (GDK_DRAWABLE_IMPL_X11(((GdkPixmapObject *)pix)->impl)->xid) #define GDK_DRAWABLE_XDISPLAY(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_XDISPLAY (win) : GDK_PIXMAP_XDISPLAY (win)) #define GDK_DRAWABLE_XID(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_XID (win) : GDK_PIXMAP_XID (win)) -#define GDK_GC_XDISPLAY(gc) (GDK_GC_X11(gc)->xdisplay) +#define GDK_GC_XDISPLAY(gc) (GDK_SCREEN_XDISPLAY(GDK_GC_X11(gc)->screen)) +#define GDK_GC_XGC(gc) (GDK_GC_X11(gc)->xgc) +#define GDK_SCREEN_XDISPLAY(screen) (GDK_SCREEN_X11 (screen)->xdisplay) +#define GDK_SCREEN_XSCREEN(screen) (GDK_SCREEN_X11 (screen)->xscreen) +#define GDK_SCREEN_XNUMBER(screen) (GDK_SCREEN_X11 (screen)->screen_number) #define GDK_VISUAL_XVISUAL(vis) (((GdkVisualPrivate *) vis)->xvisual) -#define GDK_GC_XGC(gc) (GDK_GC_X11(gc)->xgc) -#define GDK_GC_GET_XGC(gc) (GDK_GC_X11(gc)->dirty_mask ? _gdk_x11_gc_flush (gc) : ((GdkGCX11 *)(gc))->xgc) -#define GDK_WINDOW_XWINDOW GDK_DRAWABLE_XID +#define GDK_GC_GET_XGC(gc) (GDK_GC_X11(gc)->dirty_mask ? _gdk_x11_gc_flush (gc) : ((GdkGCX11 *)(gc))->xgc) +#define GDK_WINDOW_XWINDOW GDK_DRAWABLE_XID #else /* INSIDE_GDK_X11 */ +#ifndef GDK_MULTIHEAD_SAFE #define GDK_ROOT_WINDOW() (gdk_x11_get_default_root_xwindow ()) -#define GDK_WINDOW_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (win)) +#endif + +#define GDK_DISPLAY_XDISPLAY(display) (gdk_x11_display_get_xdisplay (display)) + +#define GDK_WINDOW_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (((GdkWindowObject *)win)->impl)) #define GDK_WINDOW_XID(win) (gdk_x11_drawable_get_xid (win)) #define GDK_WINDOW_XWINDOW(win) (gdk_x11_drawable_get_xid (win)) -#define GDK_PIXMAP_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (win)) +#define GDK_PIXMAP_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (((GdkPixmapObject *)win)->impl)) #define GDK_PIXMAP_XID(win) (gdk_x11_drawable_get_xid (win)) #define GDK_DRAWABLE_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (win)) #define GDK_DRAWABLE_XID(win) (gdk_x11_drawable_get_xid (win)) -#define GDK_VISUAL_XVISUAL(visual) (gdk_x11_visual_get_xvisual (visual)) #define GDK_GC_XDISPLAY(gc) (gdk_x11_gc_get_xdisplay (gc)) #define GDK_GC_XGC(gc) (gdk_x11_gc_get_xgc (gc)) +#define GDK_SCREEN_XDISPLAY(screen) (gdk_x11_display_get_xdisplay (gdk_screen_get_display (screen))) +#define GDK_SCREEN_XSCREEN(screen) (gdk_x11_screen_get_xscreen (screen)) +#define GDK_SCREEN_XNUMBER(screen) (gdk_x11_screen_get_screen_number (screen)) +#define GDK_VISUAL_XVISUAL(visual) (gdk_x11_visual_get_xvisual (visual)) #endif /* INSIDE_GDK_X11 */ -GdkVisual* gdkx_visual_get (VisualID xvisualid); +GdkVisual* gdkx_visual_get_for_screen (GdkScreen *screen, + VisualID xvisualid); +#ifndef GDK_MULTIHEAD_SAFE +GdkVisual* gdkx_visual_get (VisualID xvisualid); +#endif + /* XXX: Do not use this function until it is fixed. An X Colormap * is useless unless we also have the visual. */ GdkColormap* gdkx_colormap_get (Colormap xcolormap); /* Return the Gdk* for a particular XID */ -gpointer gdk_xid_table_lookup (XID xid); - +gpointer gdk_xid_table_lookup_for_display (GdkDisplay *display, + XID xid); guint32 gdk_x11_get_server_time (GdkWindow *window); -/* FIXME should take a GdkDisplay* */ -void gdk_x11_grab_server (void); -void gdk_x11_ungrab_server (void); - /* returns TRUE if we support the given WM spec feature */ -gboolean gdk_net_wm_supports (GdkAtom property); +gboolean gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen, + GdkAtom property); + +#ifndef GDK_MULTIHEAD_SAFE +gpointer gdk_xid_table_lookup (XID xid); +gboolean gdk_net_wm_supports (GdkAtom property); +void gdk_x11_grab_server (); +void gdk_x11_ungrab_server (); + +#endif + +GdkDisplay *gdk_x11_lookup_xdisplay (Display *xdisplay); +GList *gdk_list_visuals_for_screen (GdkScreen *screen); + + +/* Functions to get the X Atom equivalent to the GdkAtom */ +Atom gdk_x11_atom_to_xatom_for_display (GdkDisplay *display, + GdkAtom virtual_atom); +GdkAtom gdk_x11_xatom_to_atom_for_display (GdkDisplay *display, + Atom xatom); +Atom gdk_x11_get_xatom_by_name_for_display (GdkDisplay *display, + const gchar *atom_name); +G_CONST_RETURN gchar *gdk_x11_get_xatom_name_for_display (GdkDisplay *display, + Atom xatom); +#ifndef GDK_MULTIHEAD_SAFE Atom gdk_x11_atom_to_xatom (GdkAtom atom); GdkAtom gdk_x11_xatom_to_atom (Atom xatom); Atom gdk_x11_get_xatom_by_name (const gchar *atom_name); G_CONST_RETURN gchar *gdk_x11_get_xatom_name (Atom xatom); +#endif #ifndef GDK_DISABLE_DEPRECATED @@ -126,8 +173,13 @@ G_CONST_RETURN char *gdk_x11_font_get_name (GdkFont *font); #define GDK_FONT_XDISPLAY(font) (gdk_x11_font_get_xdisplay (font)) #define GDK_FONT_XFONT(font) (gdk_x11_font_get_xfont (font)) +#ifndef GDK_MULTIHEAD_SAFE + #define gdk_font_lookup(xid) ((GdkFont*) gdk_xid_table_lookup (xid)) +#endif /* GDK_MULTIHEAD_SAFE */ +#define gdk_font_lookup_for_display(display, xid) ((GdkFont*) gdk_xid_table_lookup_for_display (display, xid)) + #endif /* GDK_DISABLE_DEPRECATED */ G_END_DECLS diff --git a/gdk/x11/gdkxid.c b/gdk/x11/gdkxid.c index 8c46073a2..0d8407371 100644 --- a/gdk/x11/gdkxid.c +++ b/gdk/x11/gdkxid.c @@ -25,6 +25,7 @@ */ #include "gdkprivate-x11.h" +#include "gdkdisplay-x11.h" #include <stdio.h> static guint gdk_xid_hash (XID *xid); @@ -32,43 +33,73 @@ static gboolean gdk_xid_equal (XID *a, XID *b); -static GHashTable *xid_ht = NULL; - - void -gdk_xid_table_insert (XID *xid, - gpointer data) +_gdk_xid_table_insert (GdkDisplay *display, + XID *xid, + gpointer data) { + GdkDisplayX11 *display_x11; + g_return_if_fail (xid != NULL); + g_return_if_fail (GDK_IS_DISPLAY (display)); + + display_x11 = GDK_DISPLAY_X11 (display); - if (!xid_ht) - xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash, - (GEqualFunc) gdk_xid_equal); + if (!display_x11->xid_ht) + display_x11->xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash, + (GEqualFunc) gdk_xid_equal); - g_hash_table_insert (xid_ht, xid, data); + g_hash_table_insert (display_x11->xid_ht, xid, data); } void -gdk_xid_table_remove (XID xid) +_gdk_xid_table_remove (GdkDisplay *display, + XID xid) { - if (!xid_ht) - xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash, - (GEqualFunc) gdk_xid_equal); + GdkDisplayX11 *display_x11; + + g_return_if_fail (GDK_IS_DISPLAY (display)); + + display_x11 = GDK_DISPLAY_X11 (display); + + if (!display_x11->xid_ht) + display_x11->xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash, + (GEqualFunc) gdk_xid_equal); - g_hash_table_remove (xid_ht, &xid); + g_hash_table_remove (display_x11->xid_ht, &xid); } +/** + * gdk_xid_table_lookup_for_display: + * @display : the #GdkDisplay. + * @xid : an X id. + * + * Returns the Gdk object associated with the given X id. + * + * Returns: an GdkObject associated with the given X id. + */ gpointer -gdk_xid_table_lookup (XID xid) +gdk_xid_table_lookup_for_display (GdkDisplay *display, + XID xid) { + GdkDisplayX11 *display_x11; gpointer data = NULL; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + display_x11 = GDK_DISPLAY_X11 (display); - if (xid_ht) - data = g_hash_table_lookup (xid_ht, &xid); + if (display_x11->xid_ht) + data = g_hash_table_lookup (display_x11->xid_ht, &xid); return data; } +gpointer +gdk_xid_table_lookup (XID xid) +{ + return gdk_xid_table_lookup_for_display (gdk_get_default_display (), xid); +} static guint gdk_xid_hash (XID *xid) diff --git a/gdk/x11/gxid.c b/gdk/x11/gxid.c deleted file mode 100644 index 2b0994cbc..000000000 --- a/gdk/x11/gxid.c +++ /dev/null @@ -1,865 +0,0 @@ -/* - * gxid version 0.3 - * - * Copyright 1997 Owen Taylor <owt1@cornell.edu> -*/ -#undef G_LOG_DOMAIN - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <X11/Xlib.h> -#include <X11/extensions/XInput.h> - -#include "gxid_proto.h" - -/* #define DEBUG_CLIENTS */ -/* #define DEBUG_EVENTS */ - -char *program_name; -Display *dpy; -Window root_window; /* default root window of dpy */ -int port = 0; /* port to listen on */ -int socket_fd = 0; /* file descriptor of socket */ -typedef struct GxidWindow_ GxidWindow; - -typedef struct GxidDevice_ GxidDevice; -struct GxidDevice_ { - XID id; - int exclusive; - int ispointer; - - XDevice *xdevice; - int motionnotify_type; - int changenotify_type; -}; - -struct GxidWindow_ { - Window xwindow; - /* Immediate child of root that is ancestor of window */ - Window root_child; - int num_devices; - GxidDevice **devices; -}; - -GxidDevice **devices = NULL; -int num_devices = 0; -GxidWindow **windows = NULL; -int num_windows = 0; - -void -handler(int signal) -{ - fprintf(stderr,"%s: dying on signal %d\n",program_name,signal); - if (socket_fd) - close(socket_fd); - exit(1); -} - -void -init_socket(void) -{ - struct sockaddr_in sin; - - socket_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); - if (socket_fd < 0) - { - fprintf (stderr, "%s: error getting socket\n", - program_name); - exit(1); - } - - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - sin.sin_addr.s_addr = INADDR_ANY; - - if (bind(socket_fd,(struct sockaddr *)(&sin), - sizeof(struct sockaddr_in)) < 0) - { - fprintf (stderr,"%s: cannot bind to port %d\n", - program_name,port); - exit(1); - } - - if (listen(socket_fd,5) < 0) - { - fprintf (stderr,"%s: error listening on socket\n", - program_name); - exit(1); - }; -} - -#define NUM_EVENTC 2 -static void -enable_device(GxidDevice *dev) -{ - XEventClass xevc[NUM_EVENTC]; - int num_eventc = NUM_EVENTC; - int i,j; - - if (!dev->xdevice) - { - if (dev->ispointer) return; - - dev->xdevice = XOpenDevice(dpy, dev->id); - if (!dev->xdevice) return; - - DeviceMotionNotify (dev->xdevice, dev->motionnotify_type, - xevc[0]); - ChangeDeviceNotify (dev->xdevice, dev->changenotify_type, - xevc[1]); - - /* compress out zero event classes */ - for (i=0,j=0;i<NUM_EVENTC;i++) - { - if (xevc[i]) { - xevc[j] = xevc[i]; - j++; - } - } - num_eventc = j; - - XSelectExtensionEvent (dpy, root_window, xevc, num_eventc); - } -} - -/* switch the core pointer from whatever it is now to something else, - return true on success, false otherwise */ -static int -switch_core_pointer(void) -{ - GxidDevice *old_pointer = 0; - GxidDevice *new_pointer = 0; - int result; - int i; - - for (i=0;i<num_devices;i++) - { - if (devices[i]->ispointer) - old_pointer = devices[i]; - else - if (!new_pointer && !devices[i]->exclusive) - new_pointer = devices[i]; - } - - if (!old_pointer || !new_pointer) - return 0; - -#ifdef DEBUG_EVENTS - fprintf(stderr,"gxid: Switching core from %ld to %ld\n", - old_pointer->id,new_pointer->id); -#endif - result = XChangePointerDevice(dpy,new_pointer->xdevice, 0, 1); - if (result != Success) - { - fprintf(stderr,"gxid: Error %d switching core from %ld to %ld\n", - result, old_pointer->id, new_pointer->id); - } - else - { - new_pointer->ispointer = 1; - old_pointer->ispointer = 0; - if (!old_pointer->xdevice) - enable_device(old_pointer); - } - - return 1; -} - -void -disable_device(GxidDevice *dev) -{ - if (dev->xdevice) - { - if (dev->ispointer) - return; - XCloseDevice(dpy,dev->xdevice); - dev->xdevice = 0; - } -} - -GxidDevice * -init_device(XDeviceInfo *xdevice) -{ - GxidDevice *dev = (GxidDevice *)malloc(sizeof(GxidDevice)); - XAnyClassPtr class; - int num_axes, i; - - dev->id = xdevice->id; - dev->exclusive = 0; - dev->xdevice = NULL; - - dev->ispointer = (xdevice->use == IsXPointer); - - /* step through the classes */ - - num_axes = 0; - class = xdevice->inputclassinfo; - for (i=0;i<xdevice->num_classes;i++) - { - if (class->class == ValuatorClass) - { - XValuatorInfo *xvi = (XValuatorInfo *)class; - num_axes = xvi->num_axes; - } - class = (XAnyClassPtr)(((char *)class) + class->length); - } - - /* return NULL if insufficient axes */ - if (num_axes < 2) - { - free((void *)dev); - return NULL; - } - - if (!dev->ispointer) - enable_device(dev); - return dev; -} - -void -init_xinput(void) -{ - char **extensions; - XDeviceInfo *xdevices; - int num_xdevices; - int num_extensions; - int i; - - extensions = XListExtensions(dpy, &num_extensions); - for (i = 0; i < num_extensions && - (strcmp(extensions[i], "XInputExtension") != 0); i++); - XFreeExtensionList(extensions); - if (i == num_extensions) /* XInput extension not found */ - { - fprintf(stderr,"XInput extension not found\n"); - exit(1); - } - - xdevices = XListInputDevices(dpy, &num_xdevices); - devices = (GxidDevice **)malloc(num_xdevices * sizeof(GxidDevice *)); - - num_devices = 0; - for(i=0; i<num_xdevices; i++) - { - GxidDevice *dev = init_device(&xdevices[i]); - if (dev) - devices[num_devices++] = dev; - } - XFreeDeviceList(xdevices); -} - -/* If this routine needs fixing, the corresponding routine - in gdkinputgxi.h will need it too. */ - -Window -gxi_find_root_child(Display *dpy, Window w) -{ - Window root,parent; - Window *children; - int nchildren; - - parent = w; - do - { - w = parent; - XQueryTree (dpy, w, &root, &parent, &children, &nchildren); - if (children) - XFree (children); - } - while (parent != root); - - return w; -} - -int -handle_claim_device(GxidClaimDevice *msg) -{ - int i,j; - XID devid; - XID winid; - int exclusive; - GxidDevice *device = NULL; - GxidWindow *window = NULL; - - if (msg->length != sizeof(GxidClaimDevice)) - { - fprintf(stderr,"Bad length for ClaimDevice message\n"); - return GXID_RETURN_ERROR; - } - - devid = ntohl(msg->device); - winid = ntohl(msg->window); - exclusive = ntohl(msg->exclusive); - -#ifdef DEBUG_CLIENTS - fprintf(stderr,"device %ld claimed (window 0x%lx)\n",devid,winid); -#endif - - for (i=0;i<num_devices;i++) - { - if (devices[i]->id == devid) - { - device = devices[i]; - break; - } - } - if (!device) - { - fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid); - return GXID_RETURN_ERROR; - } - - if (device->exclusive) - { - /* already in use */ - fprintf(stderr, - "%s: Device %ld already claimed in exclusive mode\n", - program_name,devid); - return GXID_RETURN_ERROR; - } - - if (exclusive) - { - for (i=0;i<num_windows;i++) - { - for (j=0;j<windows[i]->num_devices;j++) - if (windows[i]->devices[j]->id == devid) - { - /* already in use */ - fprintf(stderr, - "%s: Can't establish exclusive use of device %ld\n", - program_name,devid); - return GXID_RETURN_ERROR; - } - } - if (device->ispointer) - if (!switch_core_pointer()) - { - fprintf(stderr, - "%s: Can't free up core pointer %ld\n", - program_name,devid); - return GXID_RETURN_ERROR; - } - - device->exclusive = 1; - disable_device(device); - XSelectInput(dpy,winid,StructureNotifyMask); - } - else /* !exclusive */ - { - /* FIXME: this is a bit improper. We probably should do this only - when a window is first claimed. But we might be fooled if - an old client died without releasing it's windows. So until - we look for client-window closings, do it here - - (We do look for closings now...) - */ - - XSelectInput(dpy,winid,EnterWindowMask|StructureNotifyMask); - } - - for (i=0;i<num_windows;i++) - { - if (windows[i]->xwindow == winid) - { - window = windows[i]; - break; - } - } - - /* Create window structure if no devices have been previously - claimed on it */ - if (!window) - { - num_windows++; - windows = (GxidWindow **)realloc(windows, - sizeof(GxidWindow*)*num_windows); - window = (GxidWindow *)malloc(sizeof(GxidWindow)); - windows[num_windows-1] = window; - - window->xwindow = winid; - window->root_child = gxi_find_root_child(dpy,winid); - window->num_devices = 0; - window->devices = 0; - } - - - for (i=0;i<window->num_devices;i++) - { - if (window->devices[i] == device) - return GXID_RETURN_OK; - } - - window->num_devices++; - window->devices = (GxidDevice **)realloc(window->devices, - sizeof(GxidDevice*)*num_devices); - /* we need add the device to the window */ - window->devices[i] = device; - - return GXID_RETURN_OK; -} - -int -handle_release_device(GxidReleaseDevice *msg) -{ - int i,j; - XID devid; - XID winid; - - GxidDevice *device = NULL; - - if (msg->length != sizeof(GxidReleaseDevice)) - { - fprintf(stderr,"Bad length for ReleaseDevice message\n"); - return GXID_RETURN_ERROR; - } - - devid = ntohl(msg->device); - winid = ntohl(msg->window); - -#ifdef DEBUG_CLIENTS - fprintf(stderr,"device %ld released (window 0x%lx)\n",devid,winid); -#endif - - for (i=0;i<num_devices;i++) - { - if (devices[i]->id == devid) - { - device = devices[i]; - break; - } - } - if (!device) - { - fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid); - return GXID_RETURN_ERROR; - } - - for (i=0;i<num_windows;i++) - { - GxidWindow *w = windows[i]; - - if (w->xwindow == winid) - for (j=0;j<w->num_devices;j++) - if (w->devices[j]->id == devid) - { - if (j<w->num_devices-1) - w->devices[j] = w->devices[w->num_devices-1]; - w->num_devices--; - - if (w->num_devices == 0) - { - if (i<num_windows-1) - windows[i] = windows[num_windows-1]; - num_windows--; - - free((void *)w); - /* FIXME: should we deselect input? But what - what if window is already destroyed */ - } - - if (device->exclusive) - { - device->exclusive = 0; - enable_device(device); - } - return GXID_RETURN_OK; - } - } - - /* device/window combination not found */ - fprintf(stderr, - "%s: Device %ld not claimed for window 0x%lx\n", - program_name,devid,winid); - return GXID_RETURN_ERROR; -} - -void -handle_connection (void) -{ - GxidMessage msg; - GxidU32 type; - GxidU32 length; - GxidI32 retval; - - int conn_fd; - struct sockaddr_in sin; - int sin_length; - int count; - - sin_length = sizeof(struct sockaddr_in); - conn_fd = accept(socket_fd,(struct sockaddr *)&sin,&sin_length); - if (conn_fd < 0) - { - fprintf(stderr,"%s: Error accepting connection\n", - program_name); - exit(1); - } - - /* read type and length of message */ - - count = read(conn_fd,(char *)&msg,2*sizeof(GxidU32)); - if (count != 2*sizeof(GxidU32)) - { - fprintf(stderr,"%s: Error reading message header\n", - program_name); - close(conn_fd); - return; - } - type = ntohl(msg.any.type); - length = ntohl(msg.any.length); - - /* read rest of message */ - - if ((length > sizeof(GxidMessage)) || (length < 2*sizeof(GxidU32))) - { - fprintf(stderr,"%s: Bad message length\n", - program_name); - close(conn_fd); - return; - } - - count = read(conn_fd,2*sizeof(GxidU32) + (char *)&msg, - length - 2*sizeof(GxidU32)); - if (count != length - 2*sizeof(GxidU32)) - { - fprintf(stderr,"%s: Error reading message body\n", - program_name); - close(conn_fd); - return; - } - - switch (type) - { - case GXID_CLAIM_DEVICE: - retval = handle_claim_device((GxidClaimDevice *)&msg); - break; - case GXID_RELEASE_DEVICE: - retval = handle_release_device((GxidReleaseDevice *)&msg); - break; - default: - fprintf(stderr,"%s: Unknown message type: %ld (ignoring)\n", - program_name,type); - close(conn_fd); - return; - } - - count = write(conn_fd,&retval,sizeof(GxidI32)); - if (count != sizeof(GxidI32)) - { - fprintf(stderr,"%s: Error writing return code\n", - program_name); - } - - close(conn_fd); -} - -void -handle_motion_notify(XDeviceMotionEvent *event) -{ - int i,j; - GxidDevice *old_device = NULL; - GxidDevice *new_device = NULL; - Window w, root, child; - int root_x, root_y, x, y, mask; - - for (j=0;j<num_devices;j++) - { - if (devices[j]->ispointer) - old_device = devices[j]; - if (devices[j]->id == event->deviceid) - new_device = devices[j]; - } - - if (new_device && !new_device->exclusive && !new_device->ispointer) - { - /* make sure we aren't stealing the pointer back from a slow - client */ - child = root_window; - do - { - w = child; - /* FIXME: this fails disasterously if child vanishes between - calls. (Which is prone to happening since we get events - on root just as the client exits) */ - - XQueryPointer(dpy,w,&root,&child,&root_x,&root_y, - &x,&y,&mask); - } - while (child != None); - - for (i=0;i<num_windows;i++) - if (windows[i]->xwindow == w) - for (j=0;j<windows[i]->num_devices;j++) - if (windows[i]->devices[j] == new_device) - return; - - /* FIXME: do something smarter with axes */ - XChangePointerDevice(dpy,new_device->xdevice, 0, 1); - new_device->ispointer = 1; - - old_device->ispointer = 0; - if (!old_device->xdevice) - enable_device(old_device); - } -} - -void -handle_change_notify(XChangeDeviceNotifyEvent *event) -{ - int j; - GxidDevice *old_device = NULL; - GxidDevice *new_device = NULL; - - - for (j=0;j<num_devices;j++) - { - if (devices[j]->ispointer) - old_device = devices[j]; - if (devices[j]->id == event->deviceid) - new_device = devices[j]; - } - -#ifdef DEBUG_EVENTS - fprintf(stderr,"gxid: ChangeNotify event; old = %ld; new = %ld\n", - old_device->id, new_device->id); -#endif - - if (old_device != new_device) - { - new_device->ispointer = 1; - - old_device->ispointer = 0; - if (!old_device->xdevice) - enable_device(old_device); - } -} - -void -handle_enter_notify(XEnterWindowEvent *event, GxidWindow *window) -{ - int i; - GxidDevice *old_pointer = NULL; - for (i=0;i<num_devices;i++) - { - if (devices[i]->ispointer) - { - old_pointer = devices[i]; - break; - } - } - -#ifdef DEBUG_EVENTS - fprintf(stderr,"gxid: Enter event; oldpointer = %ld\n", - old_pointer->id); -#endif - - if (old_pointer) - for (i=0;i<window->num_devices;i++) - { - if (window->devices[i] == old_pointer) - { - switch_core_pointer(); - break; - } - } -} - -void -handle_destroy_notify(XDestroyWindowEvent *event) -{ - int i,j; - - for (i=0;i<num_windows;i++) - if (windows[i]->xwindow == event->window) - { - GxidWindow *w = windows[i]; - - for (j=0;j<w->num_devices;j++) - { -#ifdef DEBUG_CLIENTS - fprintf(stderr,"device %ld released on destruction of window 0x%lx.\n", - w->devices[j]->id,w->xwindow); -#endif - - if (w->devices[j]->exclusive) - { - w->devices[j]->exclusive = 0; - enable_device(devices[j]); - } - } - - if (i<num_windows-1) - windows[i] = windows[num_windows-1]; - num_windows--; - - if (w->devices) - free((void *)w->devices); - free((void *)w); - /* FIXME: should we deselect input? But what - what if window is already destroyed */ - - return; - } -} - -void -handle_xevent(void) -{ - int i; - XEvent event; - - XNextEvent (dpy, &event); - -#ifdef DEBUG_EVENTS - fprintf(stderr,"Event - type = %d; window = 0x%lx\n", - event.type,event.xany.window); -#endif - - if (event.type == ConfigureNotify) - { -#ifdef DEBUG_EVENTS - XConfigureEvent *xce = (XConfigureEvent *)&event; - fprintf(stderr," configureNotify: window = 0x%lx\n",xce->window); -#endif - } - else if (event.type == EnterNotify) - { - /* pointer entered a claimed window */ - for (i=0;i<num_windows;i++) - { - if (event.xany.window == windows[i]->xwindow) - handle_enter_notify((XEnterWindowEvent *)&event,windows[i]); - } - } - else if (event.type == DestroyNotify) - { - /* A claimed window was destroyed */ - for (i=0;i<num_windows;i++) - { - if (event.xany.window == windows[i]->xwindow) - handle_destroy_notify((XDestroyWindowEvent *)&event); - } - } - else - for (i=0;i<num_devices;i++) - { - if (event.type == devices[i]->motionnotify_type) - { - handle_motion_notify((XDeviceMotionEvent *)&event); - break; - } - else if (event.type == devices[i]->changenotify_type) - { - handle_change_notify((XChangeDeviceNotifyEvent *)&event); - break; - } - } -} - -void -usage(void) -{ - fprintf(stderr,"Usage: %s [-d display] [-p --gxid-port port]\n", - program_name); - exit(1); -} - -int -main(int argc, char **argv) -{ - int i; - char *display_name = NULL; - fd_set readfds; - - program_name = argv[0]; - - for (i=1;i<argc;i++) - { - if (!strcmp(argv[i],"-d")) - { - if (++i >= argc) usage(); - display_name = argv[i]; - } - else if (!strcmp(argv[i],"--gxid-port") || - !strcmp(argv[i],"-p")) - { - if (++i >= argc) usage(); - port = atoi(argv[i]); - break; - } - else - usage(); - } - - if (!port) - { - char *t = getenv("GXID_PORT"); - if (t) - port = atoi(t); - else - port = 6951; - } - /* set up a signal handler so we can clean up if killed */ - - signal(SIGTERM,handler); - signal(SIGINT,handler); - - /* initialize the X connection */ - - dpy = XOpenDisplay (display_name); - if (!dpy) - { - fprintf (stderr, "%s: unable to open display '%s'\n", - program_name, XDisplayName (display_name)); - exit (1); - } - - root_window = DefaultRootWindow(dpy); - - /* We'll want to do this in the future if we are to support - gxid monitoring visibility information for clients */ -#if 0 - XSelectInput(dpy,root_window,SubstructureNotifyMask); -#endif - init_xinput(); - - /* set up our server connection */ - - init_socket(); - - /* main loop */ - - if (XPending(dpy)) /* this seems necessary to get things - in sync */ - handle_xevent(); - while (1) - { - - FD_ZERO(&readfds); - FD_SET(ConnectionNumber(dpy),&readfds); - FD_SET(socket_fd,&readfds); - - if (select(8*sizeof(readfds),&readfds, - (fd_set *)0,(fd_set *)0, (struct timeval *)0) < 0) - { - fprintf(stderr,"Error in select\n"); - exit(1); - } - - if (FD_ISSET(socket_fd,&readfds)) - handle_connection(); - - while (XPending(dpy)) - handle_xevent(); - } - - XCloseDisplay (dpy); - exit (0); -} diff --git a/gdk/x11/gxid_lib.c b/gdk/x11/gxid_lib.c deleted file mode 100644 index ca07c835e..000000000 --- a/gdk/x11/gxid_lib.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * gxid version 0.3 - * - * Copyright 1997 Owen Taylor <owt1@cornell.edu> -*/ - -#include "config.h" -#include "gxid_lib.h" - -#include <stdio.h> -#include <unistd.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> - -/* handles mechanics of communicating with a client */ -static int -gxid_send_message(char *host, int port, GxidMessage *msg) -{ - int socket_fd; - struct sockaddr_in sin; - int count; - GxidI32 retval; - struct hostent *he; - - if (!port) port = 6951; - - if (!host || strcmp(host,"localhost") ) - { - /* looking it up as localhost can be _SLOW_ on ppp systems */ - /* FIXME: Could localhost be anything other than loopback? */ - host = "127.0.0.1"; - } - - he = gethostbyname(host); - if (!he) - { - fprintf(stderr,"gxid_lib: error looking up %s\n",host); - return GXID_RETURN_ERROR; - } - - sin.sin_family = he->h_addrtype; - sin.sin_port = htons(port); - memcpy(&sin.sin_addr,he->h_addr_list[0],he->h_length); - - socket_fd = socket(AF_INET,SOCK_STREAM,0); - if (socket_fd < 0) - { - fprintf(stderr,"gxid_lib: can't get socket"); - return GXID_RETURN_ERROR; - } - - if (connect(socket_fd, (struct sockaddr *)&sin, - sizeof sin) < 0) - { - fprintf(stderr,"gxid_lib: can't connect to %s:%d\n",host,port); - close(socket_fd); - return GXID_RETURN_ERROR; - } - - count = write(socket_fd,(char *)msg,ntohl(msg->any.length)); - if (count != ntohl(msg->any.length)) - { - fprintf(stderr,"gxid_lib: error writing"); - close(socket_fd); - return GXID_RETURN_ERROR; - } - - /* now read the return code */ - count = read(socket_fd,(char *)&retval,sizeof(GxidI32)); - if (count != sizeof(GxidI32)) - { - fprintf(stderr,"gxid_lib: error reading return code"); - close(socket_fd); - return GXID_RETURN_ERROR; - } - - close (socket_fd); - return ntohl(retval); -} - -/* claim a device. If exclusive, device is claimed exclusively */ -int -_gxid_claim_device(char *host, int port, GxidU32 device, GxidU32 window, - int exclusive) -{ - GxidClaimDevice msg; - msg.type = htonl(GXID_CLAIM_DEVICE); - msg.length = htonl(sizeof(GxidClaimDevice)); - msg.device = htonl(device); - msg.window = htonl(window); - msg.exclusive = htonl(exclusive); - - return gxid_send_message(host,port,(GxidMessage *)&msg); -} - -/* release a device/window pair */ -int -_gxid_release_device(char *host, int port, GxidU32 device, GxidU32 window) -{ - GxidReleaseDevice msg; - msg.type = htonl(GXID_RELEASE_DEVICE); - msg.length = htonl(sizeof(GxidReleaseDevice)); - msg.device = htonl(device); - msg.window = htonl(window); - - return gxid_send_message(host,port,(GxidMessage *)&msg); -} diff --git a/gdk/x11/gxid_lib.h b/gdk/x11/gxid_lib.h deleted file mode 100644 index 0f0d141a5..000000000 --- a/gdk/x11/gxid_lib.h +++ /dev/null @@ -1,6 +0,0 @@ -#include "gxid_proto.h" - -int _gxid_claim_device(char *host, int port, - GxidU32 device, GxidU32 window, int exclusive); -int _gxid_release_device(char *host, int port, GxidU32 device, - GxidU32 window); |