4 * Copyright 2001 Sun Microsystems Inc.
6 * Erwann Chenede <erwann.chenede@sun.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
25 #include "gdkscreen.h"
26 #include "gdkscreen-x11.h"
27 #include "gdkdisplay.h"
28 #include "gdkdisplay-x11.h"
31 #ifdef HAVE_SOLARIS_XINERAMA
32 #include <X11/extensions/xinerama.h>
34 #ifdef HAVE_XFREE_XINERAMA
35 #include <X11/extensions/Xinerama.h>
38 static void gdk_screen_x11_class_init (GdkScreenX11Class *klass);
39 static GdkDisplay * gdk_screen_x11_get_display (GdkScreen *screen);
40 static gint gdk_screen_x11_get_width (GdkScreen *screen);
41 static gint gdk_screen_x11_get_height (GdkScreen *screen);
42 static gint gdk_screen_x11_get_width_mm (GdkScreen *screen);
43 static gint gdk_screen_x11_get_height_mm (GdkScreen *screen);
44 static gint gdk_screen_x11_get_default_depth (GdkScreen *screen);
45 static GdkWindow * gdk_screen_x11_get_root_window (GdkScreen *screen);
46 static gint gdk_screen_x11_get_screen_num (GdkScreen *screen);
47 static GdkColormap *gdk_screen_x11_get_default_colormap (GdkScreen *screen);
48 static void gdk_screen_x11_set_default_colormap (GdkScreen *screen,
49 GdkColormap *colormap);
50 static GdkWindow * gdk_screen_x11_get_window_at_pointer (GdkScreen *screen,
53 static void gdk_screen_x11_finalize (GObject *object);
55 static gint gdk_screen_x11_get_n_monitors (GdkScreen *screen);
56 static void gdk_screen_x11_get_monitor_geometry (GdkScreen *screen,
59 static void init_xinerama_support (GdkScreen * screen);
62 GType gdk_screen_x11_get_type ();
63 static gpointer parent_class = NULL;
66 gdk_screen_x11_get_type ()
68 static GType object_type = 0;
72 static const GTypeInfo object_info =
74 sizeof (GdkScreenX11Class),
76 (GBaseFinalizeFunc) gdk_screen_x11_finalize,
77 (GClassInitFunc) gdk_screen_x11_class_init,
78 NULL, /* class_finalize */
79 NULL, /* class_data */
80 sizeof (GdkScreenX11),
82 (GInstanceInitFunc) NULL,
84 object_type = g_type_register_static (GDK_TYPE_SCREEN,
92 gdk_screen_x11_class_init (GdkScreenX11Class * klass)
94 GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass);
96 screen_class->get_display = gdk_screen_x11_get_display;
97 screen_class->get_width = gdk_screen_x11_get_width;
98 screen_class->get_height = gdk_screen_x11_get_height;
99 screen_class->get_width_mm = gdk_screen_x11_get_width_mm;
100 screen_class->get_height_mm = gdk_screen_x11_get_height_mm;
101 screen_class->get_root_depth = gdk_screen_x11_get_default_depth;
102 screen_class->get_screen_num = gdk_screen_x11_get_screen_num;
103 screen_class->get_root_window = gdk_screen_x11_get_root_window;
104 screen_class->get_default_colormap = gdk_screen_x11_get_default_colormap;
105 screen_class->set_default_colormap = gdk_screen_x11_set_default_colormap;
106 screen_class->get_window_at_pointer = gdk_screen_x11_get_window_at_pointer;
107 screen_class->get_n_monitors = gdk_screen_x11_get_n_monitors;
108 screen_class->get_monitor_geometry = gdk_screen_x11_get_monitor_geometry;
110 G_OBJECT_CLASS (klass)->finalize = gdk_screen_x11_finalize;
111 parent_class = g_type_class_peek_parent (klass);
115 gdk_screen_x11_get_display (GdkScreen *screen)
117 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
119 return screen_x11->display;
123 gdk_screen_x11_get_width (GdkScreen *screen)
125 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
127 return WidthOfScreen (screen_x11->xscreen);
131 gdk_screen_x11_get_height (GdkScreen *screen)
133 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
135 return HeightOfScreen (screen_x11->xscreen);
139 gdk_screen_x11_get_width_mm (GdkScreen *screen)
141 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
143 return WidthMMOfScreen (screen_x11->xscreen);
147 gdk_screen_x11_get_height_mm (GdkScreen *screen)
149 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
151 return HeightMMOfScreen (screen_x11->xscreen);
155 gdk_screen_x11_get_default_depth (GdkScreen *screen)
157 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
159 return DefaultDepthOfScreen (screen_x11->xscreen);
163 gdk_screen_x11_get_screen_num (GdkScreen *screen)
165 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
167 return screen_x11->screen_num;
171 gdk_screen_x11_get_root_window (GdkScreen *screen)
173 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
175 return screen_x11->root_window;
179 gdk_screen_x11_get_default_colormap (GdkScreen *screen)
181 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
183 return screen_x11->default_colormap;
187 gdk_screen_x11_set_default_colormap (GdkScreen *screen,
188 GdkColormap * colormap)
190 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
192 screen_x11->default_colormap = colormap;
196 gdk_screen_x11_get_window_at_pointer (GdkScreen *screen,
203 Window xwindow_last = 0;
205 int rootx = -1, rooty = -1;
209 xwindow = GDK_SCREEN_XROOTWIN (screen);
210 xdisplay = GDK_SCREEN_XDISPLAY (screen);
212 XGrabServer (xdisplay);
215 xwindow_last = xwindow;
216 XQueryPointer (xdisplay, xwindow,
217 &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
219 XUngrabServer (xdisplay);
221 window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY(screen),
224 *win_x = window ? winx : -1;
226 *win_y = window ? winy : -1;
232 gdk_screen_x11_finalize (GObject *object)
234 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (object);
236 g_object_unref (G_OBJECT (screen_x11->root_window));
238 /* Visual Part (Need to implement finalize for Visuals for a clean
240 /* for (i=0;i<screen_x11->nvisuals;i++)
241 g_object_unref (G_OBJECT (screen_x11->visuals[i]));*/
242 g_free (screen_x11->visuals);
243 g_hash_table_destroy (screen_x11->visual_hash);
245 g_free (screen_x11->xsettings_client);
246 G_OBJECT_CLASS (parent_class)->finalize (object);
250 gdk_screen_x11_get_n_monitors (GdkScreen *screen)
252 g_return_val_if_fail (GDK_IS_SCREEN (screen), 1);
253 return GDK_SCREEN_X11 (screen)->num_monitors;
257 gdk_screen_x11_get_monitor_geometry (GdkScreen *screen,
261 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
262 g_return_if_fail (num_monitor < GDK_SCREEN_X11 (screen)->num_monitors);
264 *dest = screen_x11->monitors[num_monitor];
268 * gdk_x11_screen_get_xscreen:
269 * @screen: a #GdkScreen.
270 * @returns: an Xlib <type>Screen*</type>
272 * Returns the screen of a #GdkScreen.
275 gdk_x11_screen_get_xscreen (GdkScreen *screen)
277 return GDK_SCREEN_X11 (screen)->xscreen;
282 * gdk_x11_screen_get_screen_number:
283 * @screen: a #GdkScreen.
284 * @returns: the position of @screen among the screens of
287 * Returns the index of a #GdkScreen.
290 gdk_x11_screen_get_screen_number (GdkScreen *screen)
292 return GDK_SCREEN_X11 (screen)->screen_num;
296 _gdk_x11_screen_new (GdkDisplay *display,
300 GdkScreenX11 *screen_x11;
301 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
303 screen = g_object_new (GDK_TYPE_SCREEN_X11, NULL);
305 screen_x11 = GDK_SCREEN_X11 (screen);
306 screen_x11->display = display;
307 screen_x11->xdisplay = display_x11->xdisplay;
308 screen_x11->xscreen = ScreenOfDisplay (display_x11->xdisplay, screen_number);
309 screen_x11->screen_num = screen_number;
310 screen_x11->xroot_window = RootWindow (display_x11->xdisplay,screen_number);
311 screen_x11->wmspec_check_window = None;
313 init_xinerama_support (screen);
315 _gdk_visual_init (screen);
316 _gdk_windowing_window_init (screen);
317 _gdk_x11_events_init_screen (screen);
324 check_solaris_xinerama (GdkScreen *screen)
326 #ifdef HAVE_SOLARIS_XINERAMA
328 if (XineramaGetState (GDK_SCREEN_XDISPLAY (screen),
329 gdk_screen_get_number (screen)))
331 XRectangle monitors[MAXFRAMEBUFFERS];
334 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
336 result = XineramaGetInfo (GDK_SCREEN_XDISPLAY (screen),
337 gdk_screen_get_number (screen),
339 &screen_x11->num_monitors);
340 /* Yes I know it should be Success but the current implementation
341 returns the num of monitor*/
344 /* FIXME: We need to trap errors, since XINERAMA isn't always XINERAMA.
346 g_error ("error while retrieving Xinerama information");
351 screen_x11->monitors = g_new0 (GdkRectangle, screen_x11->num_monitors);
353 for (i = 0; i < screen_x11->num_monitors; i++)
355 screen_x11->monitors[i].x = monitors[i].x;
356 screen_x11->monitors[i].y = monitors[i].y;
357 screen_x11->monitors[i].width = monitors[i].width;
358 screen_x11->monitors[i].height = monitors[i].height;
364 #endif /* HAVE_SOLARIS_XINERAMA */
370 check_xfree_xinerama (GdkScreen *screen)
372 #ifdef HAVE_XFREE_XINERAMA
373 if (XineramaIsActive (GDK_SCREEN_XDISPLAY (screen)))
375 XineramaScreenInfo *monitors = XineramaQueryScreens (GDK_SCREEN_XDISPLAY (screen),
376 &screen_x11->num_monitors);
377 if (screen_x11->num_monitors <= 0)
379 /* FIXME: We need to trap errors, since XINERAMA isn't always XINERAMA.
380 * I don't think the num_monitors <= 0 check has any validity.
382 g_error ("error while retrieving Xinerama information");
387 screen_x11->monitors = g_new0 (GdkRectangle, screen_x11->num_monitors);
389 for (i = 0; i < screen_x11->num_monitors; i++)
391 screen_x11->monitors[i].x = monitors[i].x_org;
392 screen_x11->monitors[i].y = monitors[i].y_org;
393 screen_x11->monitors[i].width = monitors[i].width;
394 screen_x11->monitors[i].height = monitors[i].height;
402 #endif /* HAVE_XFREE_XINERAMA */
406 #endif /* HAVE_XINERAMA */
409 init_xinerama_support (GdkScreen * screen)
411 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
414 int opcode, firstevent, firsterror;
417 if (XQueryExtension (GDK_SCREEN_XDISPLAY (screen), "XINERAMA",
418 &opcode, &firstevent, &firsterror))
420 if (check_solaris_xinerama (screen) ||
421 check_xfree_xinerama (screen))
424 #endif /* HAVE_XINERAMA */
428 screen_x11->num_monitors = 1;
429 screen_x11->monitors = g_new0 (GdkRectangle, 1);
430 screen_x11->monitors[0].x = 0;
431 screen_x11->monitors[0].y = 0;
432 screen_x11->monitors[0].width = WidthOfScreen (screen_x11->xscreen);
433 screen_x11->monitors[0].height = HeightOfScreen (screen_x11->xscreen);