Commit ec9c9775 authored by Matthias Clasen's avatar Matthias Clasen

Work toward turning GdkDisplayManager into a backend singleton

This commit hides the GdkDisplayManager instance and class structs,
adds vfuncs for listing displays, opening displays, and getting and
setting the default display. The X11 backend has a derived
GdkDisplayManagerX11.

The gdk_display_manager_get() function is responsible for deciding on
which of the compiled in backends to use. Currently, it consults the
GDK_BACKEND environment variable and falls back to x11.
parent fa4b54b6
......@@ -228,9 +228,8 @@ gdk_pre_parse_libgtk_only (void)
g_type_init ();
/* Do any setup particular to the windowing system
*/
_gdk_windowing_init ();
/* Do any setup particular to the windowing system */
gdk_display_manager_get ();
}
......@@ -262,13 +261,13 @@ gdk_parse_args (int *argc,
return;
gdk_pre_parse_libgtk_only ();
option_context = g_option_context_new (NULL);
g_option_context_set_ignore_unknown_options (option_context, TRUE);
g_option_context_set_help_enabled (option_context, FALSE);
option_group = g_option_group_new (NULL, NULL, NULL, NULL, NULL);
g_option_context_set_main_group (option_context, option_group);
g_option_group_add_entries (option_group, gdk_args);
g_option_group_add_entries (option_group, _gdk_windowing_args);
......@@ -282,7 +281,7 @@ gdk_parse_args (int *argc,
GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
}
/**
/**
* gdk_get_display_arg_name:
*
* Gets the display name specified in the command line arguments passed
......@@ -309,13 +308,13 @@ gdk_get_display_arg_name (void)
/**
* gdk_display_open_default_libgtk_only:
*
*
* Opens the default display specified by command line arguments or
* environment variables, sets it as the default display, and returns
* it. gdk_parse_args must have been called first. If the default
* display has previously been set, simply returns that. An internal
* function that should not be used by applications.
*
*
* Return value: (transfer none): the default display, if it could be
* opened, otherwise %NULL.
**/
......@@ -325,7 +324,7 @@ gdk_display_open_default_libgtk_only (void)
GdkDisplay *display;
g_return_val_if_fail (gdk_initialized, NULL);
display = gdk_display_get_default ();
if (display)
return display;
......@@ -336,14 +335,10 @@ gdk_display_open_default_libgtk_only (void)
{
g_free (_gdk_display_arg_name);
_gdk_display_arg_name = g_strdup (_gdk_display_name);
display = gdk_display_open (_gdk_display_name);
}
if (display)
gdk_display_manager_set_default_display (gdk_display_manager_get (),
display);
return display;
}
......@@ -365,7 +360,7 @@ gdk_display_open_default_libgtk_only (void)
*/
gboolean
gdk_init_check (int *argc,
char ***argv)
char ***argv)
{
gdk_parse_args (argc, argv);
......
......@@ -272,8 +272,6 @@ gdk_display_opened (GdkDisplay *display)
static void
gdk_display_init (GdkDisplay *display)
{
_gdk_displays = g_slist_prepend (_gdk_displays, display);
display->double_click_time = 250;
display->double_click_distance = 5;
......@@ -306,18 +304,6 @@ gdk_display_dispose (GObject *object)
display->queued_events = NULL;
display->queued_tail = NULL;
_gdk_displays = g_slist_remove (_gdk_displays, object);
if (gdk_display_get_default () == display)
{
if (_gdk_displays)
gdk_display_manager_set_default_display (gdk_display_manager_get(),
_gdk_displays->data);
else
gdk_display_manager_set_default_display (gdk_display_manager_get(),
NULL);
}
if (device_manager)
{
/* this is to make it drop devices which may require using the X
......@@ -609,6 +595,29 @@ gdk_beep (void)
gdk_display_beep (gdk_display_get_default ());
}
/**
* gdk_flush:
*
* Flushes the output buffers of all display connections and waits
* until all requests have been processed.
* This is rarely needed by applications.
*/
void
gdk_flush (void)
{
GSList *list, *l;
list = gdk_display_manager_list_displays (gdk_display_manager_get ());
for (l = list; l; l = l->next)
{
GdkDisplay *display = l->data;
GDK_DISPLAY_GET_CLASS (display)->sync (display);
}
g_slist_free (list);
}
/**
* gdk_event_send_client_message:
* @event: the #GdkEvent to send, which should be a #GdkEventClient.
......@@ -2264,3 +2273,26 @@ gdk_drag_get_protocol_for_display (GdkDisplay *display,
{
return GDK_DISPLAY_GET_CLASS (display)->get_drag_protocol (display, xid, protocol, NULL);
}
/**
* gdk_display_open:
* @display_name: the name of the display to open
*
* Opens a display.
*
* Return value: (transfer none): a #GdkDisplay, or %NULL if the display
* could not be opened.
*
* Since: 2.2
*/
GdkDisplay *
gdk_display_open (const gchar *display_name)
{
return gdk_display_manager_open_display (gdk_display_manager_get (), display_name);
}
gboolean
gdk_display_has_pending (GdkDisplay *display)
{
return GDK_DISPLAY_GET_CLASS (display)->has_pending (display);
}
......@@ -227,7 +227,8 @@ 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,
const GdkEvent *event);
const GdkEvent *event);
gboolean gdk_display_has_pending (GdkDisplay *display);
void gdk_display_add_client_message_filter (GdkDisplay *display,
GdkAtom message_type,
......
......@@ -21,11 +21,12 @@
* 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/.
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gdkconfig.h"
#include "gdkdisplaymanager.h"
#include "gdkscreen.h"
......@@ -58,18 +59,16 @@ enum {
static void gdk_display_manager_class_init (GdkDisplayManagerClass *klass);
static void gdk_display_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gdk_display_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
guint prop_id,
GValue *value,
GParamSpec *pspec);
static guint signals[LAST_SIGNAL] = { 0 };
static GdkDisplay *default_display = NULL;
G_DEFINE_TYPE (GdkDisplayManager, gdk_display_manager, G_TYPE_OBJECT)
static void
......@@ -82,32 +81,32 @@ gdk_display_manager_class_init (GdkDisplayManagerClass *klass)
/**
* GdkDisplayManager::display-opened:
* @display_manager: the object on which the signal is emitted
* @manager: the object on which the signal is emitted
* @display: the opened display
*
* The ::display_opened signal is emitted when a display is opened.
* The ::display-opened signal is emitted when a display is opened.
*
* Since: 2.2
*/
signals[DISPLAY_OPENED] =
g_signal_new (g_intern_static_string ("display-opened"),
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkDisplayManagerClass, display_opened),
NULL, NULL,
_gdk_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
GDK_TYPE_DISPLAY);
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkDisplayManagerClass, display_opened),
NULL, NULL,
_gdk_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
GDK_TYPE_DISPLAY);
g_object_class_install_property (object_class,
PROP_DEFAULT_DISPLAY,
g_param_spec_object ("default-display",
P_("Default Display"),
P_("The default display for GDK"),
GDK_TYPE_DISPLAY,
G_PARAM_READWRITE|G_PARAM_STATIC_NAME|
G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
PROP_DEFAULT_DISPLAY,
g_param_spec_object ("default-display",
P_("Default Display"),
P_("The default display for GDK"),
GDK_TYPE_DISPLAY,
G_PARAM_READWRITE|G_PARAM_STATIC_NAME|
G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
}
static void
......@@ -117,15 +116,15 @@ gdk_display_manager_init (GdkDisplayManager *manager)
static void
gdk_display_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
case PROP_DEFAULT_DISPLAY:
gdk_display_manager_set_default_display (GDK_DISPLAY_MANAGER (object),
g_value_get_object (value));
g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -135,14 +134,15 @@ gdk_display_manager_set_property (GObject *object,
static void
gdk_display_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
case PROP_DEFAULT_DISPLAY:
g_value_set_object (value, default_display);
g_value_set_object (value,
gdk_display_manager_get_default_display (GDK_DISPLAY_MANAGER (object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -150,42 +150,60 @@ gdk_display_manager_get_property (GObject *object,
}
}
#ifdef GDK_WINDOWING_X11
extern GType gdk_display_manager_x11_get_type (void);
#endif
/**
* gdk_display_manager_get:
*
* Gets the singleton #GdkDisplayManager object.
*
* Returns: (transfer none): The global #GdkDisplayManager singleton; gdk_parse_pargs(),
* gdk_init(), or gdk_init_check() must have been called first.
* Returns: (transfer none): The global #GdkDisplayManager singleton;
* gdk_parse_pargs(), gdk_init(), or gdk_init_check() must have
* been called first.
*
* Since: 2.2
**/
GdkDisplayManager*
gdk_display_manager_get (void)
{
static GdkDisplayManager *display_manager = NULL;
static GdkDisplayManager *manager = NULL;
if (!manager)
{
const gchar *backend;
if (!display_manager)
display_manager = g_object_new (GDK_TYPE_DISPLAY_MANAGER, NULL);
backend = g_getenv ("GDK_BACKEND");
#ifdef GDK_WINDOWING_X11
if (backend == NULL || strcmp (backend, "x11") == 0)
manager = g_object_new (gdk_display_manager_x11_get_type (), NULL);
else
#endif
if (backend != NULL)
g_error ("Unsupported GDK backend: %s", backend);
else
g_error ("No GDK backend found");
}
return display_manager;
return manager;
}
/**
* gdk_display_manager_get_default_display:
* @display_manager: a #GdkDisplayManager
* @manager: a #GdkDisplayManager
*
* Gets the default #GdkDisplay.
*
* Returns: (transfer none): a #GdkDisplay, or %NULL if there is no default
* display.
* Returns: (transfer none): a #GdkDisplay, or %NULL
* if there is no default display.
*
* Since: 2.2
*/
GdkDisplay *
gdk_display_manager_get_default_display (GdkDisplayManager *display_manager)
gdk_display_manager_get_default_display (GdkDisplayManager *manager)
{
return default_display;
return GDK_DISPLAY_MANAGER_GET_CLASS (manager)->get_default_display (manager);
}
/**
......@@ -203,7 +221,7 @@ gdk_display_manager_get_default_display (GdkDisplayManager *display_manager)
GdkDisplay *
gdk_display_get_default (void)
{
return default_display;
return gdk_display_manager_get_default_display (gdk_display_manager_get ());
}
/**
......@@ -219,6 +237,10 @@ gdk_display_get_default (void)
GdkScreen *
gdk_screen_get_default (void)
{
GdkDisplay *default_display;
default_display = gdk_display_get_default ();
if (default_display)
return gdk_display_get_default_screen (default_display);
else
......@@ -227,7 +249,7 @@ gdk_screen_get_default (void)
/**
* gdk_display_manager_set_default_display:
* @display_manager: a #GdkDisplayManager
* @manager: a #GdkDisplayManager
* @display: a #GdkDisplay
*
* Sets @display as the default display.
......@@ -235,30 +257,35 @@ gdk_screen_get_default (void)
* Since: 2.2
**/
void
gdk_display_manager_set_default_display (GdkDisplayManager *display_manager,
GdkDisplay *display)
gdk_display_manager_set_default_display (GdkDisplayManager *manager,
GdkDisplay *display)
{
default_display = display;
_gdk_windowing_set_default_display (display);
GDK_DISPLAY_MANAGER_GET_CLASS (manager)->set_default_display (manager, display);
g_object_notify (G_OBJECT (display_manager), "default-display");
g_object_notify (G_OBJECT (manager), "default-display");
}
/**
* gdk_display_manager_list_displays:
* @display_manager: a #GdkDisplayManager
* @manager: a #GdkDisplayManager
*
* List all currently open displays.
*
* Return value: (transfer container) (element-type GdkDisplay): a newly allocated
* #GSList of #GdkDisplay objects. Free this list with g_slist_free() when you
* are done with it.
*
* Return value: (transfer container) (element-type GdkDisplay): a newly
* allocated #GSList of #GdkDisplay objects. Free with g_slist_free()
* when you are done with it.
*
* Since: 2.2
**/
GSList *
gdk_display_manager_list_displays (GdkDisplayManager *display_manager)
gdk_display_manager_list_displays (GdkDisplayManager *manager)
{
return GDK_DISPLAY_MANAGER_GET_CLASS (manager)->list_displays (manager);
}
GdkDisplay *
gdk_display_manager_open_display (GdkDisplayManager *manager,
const gchar *name)
{
return g_slist_copy (_gdk_displays);
return GDK_DISPLAY_MANAGER_GET_CLASS (manager)->open_display (manager, name);
}
......@@ -8,7 +8,7 @@
*
* 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
* 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
......@@ -44,29 +44,17 @@ G_BEGIN_DECLS
#define GDK_IS_DISPLAY_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DISPLAY_MANAGER))
#define GDK_DISPLAY_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DISPLAY_MANAGER, GdkDisplayManagerClass))
typedef struct _GdkDisplayManager GdkDisplayManager;
typedef struct _GdkDisplayManagerClass GdkDisplayManagerClass;
struct _GdkDisplayManager
{
GObject parent_instance;
};
struct _GdkDisplayManagerClass
{
GObjectClass parent_class;
void (*display_opened) (GdkDisplayManager *display_manager,
GdkDisplay *display);
};
GType gdk_display_manager_get_type (void) G_GNUC_CONST;
GdkDisplayManager *gdk_display_manager_get (void);
GdkDisplay * gdk_display_manager_get_default_display (GdkDisplayManager *display_manager);
void gdk_display_manager_set_default_display (GdkDisplayManager *display_manager,
GdkDisplay *display);
GSList * gdk_display_manager_list_displays (GdkDisplayManager *display_manager);
GdkDisplay * gdk_display_manager_get_default_display (GdkDisplayManager *manager);
void gdk_display_manager_set_default_display (GdkDisplayManager *manager,
GdkDisplay *display);
GSList * gdk_display_manager_list_displays (GdkDisplayManager *manager);
GdkDisplay * gdk_display_manager_open_display (GdkDisplayManager *manager,
const gchar *name);
G_END_DECLS
......
......@@ -276,6 +276,45 @@ gdk_event_handler_set (GdkEventFunc func,
_gdk_event_notify = notify;
}
/**
* 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)
{
GSList *list, *l;
gboolean pending;
pending = FALSE;
list = gdk_display_manager_list_displays (gdk_display_manager_get ());
for (l = list; l; l = l->next)
{
if (_gdk_event_queue_find_first (l->data))
{
pending = TRUE;
goto out;
}
}
for (l = list; l; l = l->next)
{
if (gdk_display_has_pending (l->data))
{
pending = TRUE;
goto out;
}
}
out:
g_slist_free (list);
return pending;
}
/**
* gdk_event_get:
*
......@@ -289,16 +328,21 @@ gdk_event_handler_set (GdkEventFunc func,
GdkEvent*
gdk_event_get (void)
{
GSList *tmp_list;
GSList *list, *l;
GdkEvent *event;
for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
event = NULL;
list = gdk_display_manager_list_displays (gdk_display_manager_get ());
for (l = list; l; l = l->next)
{
GdkEvent *event = gdk_display_get_event (tmp_list->data);
event = gdk_display_get_event (l->data);
if (event)
return event;
break;
}
return NULL;
g_slist_free (list);
return event;
}
/**
......@@ -314,16 +358,21 @@ gdk_event_get (void)
GdkEvent*
gdk_event_peek (void)
{
GSList *tmp_list;
GSList *list, *l;
GdkEvent *event;
for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
event = NULL;
list = gdk_display_manager_list_displays (gdk_display_manager_get ());
for (l = list; l; l = l->next)
{
GdkEvent *event = gdk_display_peek_event (tmp_list->data);
event = gdk_display_peek_event (l->data);
if (event)
return event;
break;
}
return NULL;
g_slist_free (list);
return event;
}
/**
......
......@@ -40,4 +40,3 @@ gchar *_gdk_display_arg_name = NULL;
gboolean _gdk_native_windows = FALSE;
gboolean _gdk_disable_multidevice = FALSE;
GSList *_gdk_displays = NULL;
......@@ -269,6 +269,27 @@ struct _GdkWindow
#define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
#define GDK_WINDOW_DESTROYED(d) (GDK_WINDOW (d)->destroyed)
struct _GdkDisplayManager
{
GObject parent_instance;
};
struct _GdkDisplayManagerClass
{
GObjectClass parent_class;
GSList * (*list_displays) (GdkDisplayManager *manager);
GdkDisplay * (*get_default_display) (GdkDisplayManager *manager);
void (*set_default_display) (GdkDisplayManager *manager,
GdkDisplay *display);
GdkDisplay * (*open_display) (GdkDisplayManager *manager,
const gchar *name);
/* signals */
void (*display_opened) (GdkDisplayManager *manager,
GdkDisplay *display);
};
struct _GdkDisplayClass
{
GObjectClass parent_class;
......@@ -281,6 +302,7 @@ struct _GdkDisplayClass
void (*beep) (GdkDisplay *display);
void (*sync) (GdkDisplay *display);
void (*flush) (GdkDisplay *display);
gboolean (*has_pending) (GdkDisplay *display);
GdkWindow * (*get_default_group) (GdkDisplay *display);
gboolean (*supports_selection_notification) (GdkDisplay *display);
gboolean (*request_selection_notification) (GdkDisplay *display,
......@@ -530,7 +552,6 @@ struct _GdkDeviceManagerClass
GdkDevice * (* get_client_pointer) (GdkDeviceManager *device_manager);
};
extern GSList *_gdk_displays;
extern gchar *_gdk_display_name;
extern gint _gdk_screen_number;
extern gchar *_gdk_display_arg_name;
......
......@@ -132,13 +132,6 @@ void gdk_beep (void);
#endif /* GDK_MULTIHEAD_SAFE */
/**
* gdk_flush:
*
* Flushes the X output buffer and waits until all requests have been processed
* by the server. This is rarely needed by applications. It's main use is for
* trapping X errors with gdk_error_trap_push() and gdk_error_trap_pop().
*/
void gdk_flush (void);
G_END_DECLS
......
......@@ -139,14 +139,10 @@ typedef struct _GdkRGBA GdkRGBA;
typedef struct _GdkCursor GdkCursor;
typedef struct _GdkVisual GdkVisual;
/**
* GdkWindow:
*
* An opaque structure representing an onscreen drawable.
*/
typedef struct _GdkWindow GdkWindow;
typedef struct _GdkDisplayManager GdkDisplayManager;
typedef struct _GdkDisplay GdkDisplay;
typedef struct _GdkScreen GdkScreen;
typedef struct _GdkWindow GdkWindow;
typedef struct GdkAppLaunchContext GdkAppLaunchContext;
/**
......
......@@ -188,15 +188,6 @@ gdk_display_beep (GdkDisplay *display)
Beep(1000, 50);
}
void
_gdk_windowing_exit (void)
{
_gdk_win32_dnd_exit ();
CoUninitialize ();
DeleteDC (_gdk_display_hdc);
_gdk_display_hdc = NULL;
}
void
gdk_error_trap_push (void)
{
......
......@@ -27,6 +27,7 @@ libgdk_x11_la_SOURCES = \
gdkdevicemanager-core.h \
gdkdevicemanager-core.c \
gdkdevicemanager-x11.c \
gdkdisplaymanager-x11.c \
gdkdisplay-x11.c \
gdkdisplay-x11.h \
gdkdnd-x11.c \
......
......@@ -165,6 +165,8 @@ G_DEFINE_TYPE_WITH_CODE (GdkDisplayX11, _gdk_display_x11, GDK_TYPE_DISPLAY,
static void
_gdk_display_x11_init (GdkDisplayX11 *display)
{
_gdk_x11_display_manager_add_display (gdk_display_manager_get (),
GDK_DISPLAY_OBJECT (display));
}
static void
......@@ -1090,7 +1092,7 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
}
static void
_gdk_event_init (GdkDisplay *display)
gdk_event_init (GdkDisplay *display)
{
GdkDisplayX11 *display_x11;
GdkDeviceManager *device_manager;
......@@ -1112,7 +1114,7 @@ _gdk_event_init (GdkDisplay *display)
}
static void
_gdk_input_init (GdkDisplay *display)
gdk_input_init (GdkDisplay *display)
{
GdkDisplayX11 *display_x11;
GdkDeviceManager *device_manager;
......@@ -1175,7 +1177,7 @@ _gdk_input_init (GdkDisplay *display)
* Since: 2.2
*/
GdkDisplay *
gdk_display_open (const gchar *display_name)
_gdk_x11_display_open (const gchar *display_name)
{
Display *xdisplay;
GdkDisplay *display;
......@@ -1214,7 +1216,7 @@ gdk_display_open (const gchar *display_name)
&display_x11->xrandr_event_base, &ignore))
{
int major, minor;
XRRQueryVersion (display_x11->xdisplay, &major, &minor);
if ((major == 1 && minor >= 3) || major > 1)
......@@ -1223,7 +1225,7 @@ gdk_display_open (const gchar *display_name)
gdk_x11_register_standard_event_type (display, display_x11->xrandr_event_base, RRNumberEvents);
}
#endif
/* initialize the display's screens */
display_x11->screens = g_new (GdkScreen *, ScreenCount (display_x11->xdisplay));
for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
......@@ -1240,7 +1242,7 @@ gdk_display_open (const gchar *display_name)