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 void gdk_screen_x11_dispose (GObject *object);
40 static void gdk_screen_x11_finalize (GObject *object);
41 static void init_xinerama_support (GdkScreen *screen);
44 static gpointer parent_class = NULL;
47 _gdk_screen_x11_get_type ()
49 static GType object_type = 0;
53 static const GTypeInfo object_info =
55 sizeof (GdkScreenX11Class),
57 (GBaseFinalizeFunc) gdk_screen_x11_finalize,
58 (GClassInitFunc) gdk_screen_x11_class_init,
59 NULL, /* class_finalize */
60 NULL, /* class_data */
61 sizeof (GdkScreenX11),
63 (GInstanceInitFunc) NULL,
65 object_type = g_type_register_static (GDK_TYPE_SCREEN,
73 gdk_screen_x11_class_init (GdkScreenX11Class *klass)
75 GObjectClass *object_class = G_OBJECT_CLASS (klass);
77 object_class->dispose = gdk_screen_x11_dispose;
78 object_class->finalize = gdk_screen_x11_finalize;
80 parent_class = g_type_class_peek_parent (klass);
84 * gdk_screen_get_display:
85 * @screen: a #GdkScreen
87 * Gets the display to which the @screen belongs.
89 * Returns: the display to which @screen belongs
92 gdk_screen_get_display (GdkScreen *screen)
94 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
96 return GDK_SCREEN_X11 (screen)->display;
99 * gdk_screen_get_width:
100 * @screen: a #GdkScreen
102 * Gets the width of @screen in pixels
104 * Returns: the width of @screen in pixels.
107 gdk_screen_get_width (GdkScreen *screen)
109 g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
111 return WidthOfScreen (GDK_SCREEN_X11 (screen)->xscreen);
115 * gdk_screen_get_height:
116 * @screen: a #GdkScreen
118 * Gets the height of @screen in pixels
120 * Returns: the height of @screen in pixels.
123 gdk_screen_get_height (GdkScreen *screen)
125 g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
127 return HeightOfScreen (GDK_SCREEN_X11 (screen)->xscreen);
131 * gdk_screen_get_width_mm:
132 * @screen: a #GdkScreen
134 * Gets the width of @screen in millimeters.
135 * Note that on some X servers this value will not be correct.
137 * Returns: the width of @screen in pixels.
140 gdk_screen_get_width_mm (GdkScreen *screen)
142 g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
144 return WidthMMOfScreen (GDK_SCREEN_X11 (screen)->xscreen);
148 * gdk_screen_get_height_mm:
149 * @screen: a #GdkScreen
151 * Returns the height of @screen in millimeters.
152 * Note that on some X servers this value will not be correct.
154 * Returns: the heigth of @screen in pixels.
157 gdk_screen_get_height_mm (GdkScreen *screen)
159 g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
161 return HeightMMOfScreen (GDK_SCREEN_X11 (screen)->xscreen);
165 * gdk_screen_get_number:
166 * @screen: a #GdkScreen
168 * Gets the index of @screen among the screens in the display
169 * to which it belongs. (See gdk_screen_get_display())
174 gdk_screen_get_number (GdkScreen *screen)
176 g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
178 return GDK_SCREEN_X11 (screen)->screen_num;
182 * gdk_screen_get_root_window:
183 * @screen: a #GdkScreen
185 * Gets the root window of @screen.
187 * Returns: the root window
190 gdk_screen_get_root_window (GdkScreen *screen)
192 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
194 return GDK_SCREEN_X11 (screen)->root_window;
198 * gdk_screen_get_default_colormap:
199 * @screen: a #GdkScreen
201 * Gets the default colormap for @screen.
203 * Returns: the default #GdkColormap.
206 gdk_screen_get_default_colormap (GdkScreen *screen)
208 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
210 return GDK_SCREEN_X11 (screen)->default_colormap;
214 * gdk_screen_set_default_colormap:
215 * @screen: a #GdkScreen
216 * @colormap: a #GdkColormap
218 * Sets the default @colormap for @screen.
221 gdk_screen_set_default_colormap (GdkScreen *screen,
222 GdkColormap *colormap)
224 g_return_if_fail (GDK_IS_SCREEN (screen));
225 g_return_if_fail (GDK_IS_COLORMAP (colormap));
227 GDK_SCREEN_X11 (screen)->default_colormap = colormap;
231 gdk_screen_x11_dispose (GObject *object)
233 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (object);
235 screen_x11->root_window = NULL;
237 screen_x11->xdisplay = NULL;
238 screen_x11->xscreen = NULL;
239 screen_x11->screen_num = -1;
240 screen_x11->xroot_window = None;
241 screen_x11->wmspec_check_window = None;
243 G_OBJECT_CLASS (parent_class)->dispose (object);
247 gdk_screen_x11_finalize (GObject *object)
249 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (object);
251 g_object_unref (G_OBJECT (screen_x11->root_window));
253 /* Visual Part (Need to implement finalize for Visuals for a clean
255 /* for (i=0;i<screen_x11->nvisuals;i++)
256 g_object_unref (G_OBJECT (screen_x11->visuals[i]));*/
257 g_free (screen_x11->visuals);
258 g_hash_table_destroy (screen_x11->visual_hash);
260 g_free (screen_x11->xsettings_client);
262 g_free (screen_x11->monitors);
264 G_OBJECT_CLASS (parent_class)->finalize (object);
268 * gdk_screen_get_n_monitors:
269 * @screen : a #GdkScreen.
271 * Returns the number of monitors being part of the virtual screen
273 * Returns: number of monitors part of the virtual screen or
274 * 0 if @screen is not in virtual screen mode.
277 gdk_screen_get_n_monitors (GdkScreen *screen)
279 g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
281 return GDK_SCREEN_X11 (screen)->num_monitors;
285 * gdk_screen_get_monitor_geometry:
286 * @screen : a #GdkScreen.
287 * @monitor_num: the monitor number.
288 * @dest : a #GdkRectangle to be filled with the monitor geometry
290 * Retrieves the #GdkRectangle representing the size and start
291 * coordinates of the individual monitor within the the entire virtual
294 * Note that the virtual screen coordinates can be retrieved via
295 * gdk_screen_get_width() and gdk_screen_get_height().
299 gdk_screen_get_monitor_geometry (GdkScreen *screen,
303 g_return_if_fail (GDK_IS_SCREEN (screen));
304 g_return_if_fail (monitor_num < GDK_SCREEN_X11 (screen)->num_monitors);
306 *dest = GDK_SCREEN_X11 (screen)->monitors[monitor_num];
310 * gdk_x11_screen_get_xscreen:
311 * @screen: a #GdkScreen.
312 * @returns: an Xlib <type>Screen*</type>
314 * Returns the screen of a #GdkScreen.
317 gdk_x11_screen_get_xscreen (GdkScreen *screen)
319 return GDK_SCREEN_X11 (screen)->xscreen;
324 * gdk_x11_screen_get_screen_number:
325 * @screen: a #GdkScreen.
326 * @returns: the position of @screen among the screens of
329 * Returns the index of a #GdkScreen.
332 gdk_x11_screen_get_screen_number (GdkScreen *screen)
334 return GDK_SCREEN_X11 (screen)->screen_num;
338 _gdk_x11_screen_new (GdkDisplay *display,
342 GdkScreenX11 *screen_x11;
343 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
345 screen = g_object_new (GDK_TYPE_SCREEN_X11, NULL);
347 screen_x11 = GDK_SCREEN_X11 (screen);
348 screen_x11->display = display;
349 screen_x11->xdisplay = display_x11->xdisplay;
350 screen_x11->xscreen = ScreenOfDisplay (display_x11->xdisplay, screen_number);
351 screen_x11->screen_num = screen_number;
352 screen_x11->xroot_window = RootWindow (display_x11->xdisplay,screen_number);
353 screen_x11->wmspec_check_window = None;
355 init_xinerama_support (screen);
357 _gdk_visual_init (screen);
358 _gdk_windowing_window_init (screen);
359 _gdk_x11_events_init_screen (screen);
366 check_solaris_xinerama (GdkScreen *screen)
368 #ifdef HAVE_SOLARIS_XINERAMA
370 if (XineramaGetState (GDK_SCREEN_XDISPLAY (screen),
371 gdk_screen_get_number (screen)))
373 XRectangle monitors[MAXFRAMEBUFFERS];
374 unsigned char hints[16];
376 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
378 result = XineramaGetInfo (GDK_SCREEN_XDISPLAY (screen),
379 gdk_screen_get_number (screen),
381 &screen_x11->num_monitors);
382 /* Yes I know it should be Success but the current implementation
383 returns the num of monitor*/
386 /* FIXME: We need to trap errors, since XINERAMA isn't always XINERAMA.
388 g_error ("error while retrieving Xinerama information");
393 screen_x11->monitors = g_new0 (GdkRectangle, screen_x11->num_monitors);
395 for (i = 0; i < screen_x11->num_monitors; i++)
397 screen_x11->monitors[i].x = monitors[i].x;
398 screen_x11->monitors[i].y = monitors[i].y;
399 screen_x11->monitors[i].width = monitors[i].width;
400 screen_x11->monitors[i].height = monitors[i].height;
406 #endif /* HAVE_SOLARIS_XINERAMA */
412 check_xfree_xinerama (GdkScreen *screen)
414 #ifdef HAVE_XFREE_XINERAMA
415 if (XineramaIsActive (GDK_SCREEN_XDISPLAY (screen)))
417 XineramaScreenInfo *monitors = XineramaQueryScreens (GDK_SCREEN_XDISPLAY (screen),
418 &screen_x11->num_monitors);
419 if (screen_x11->num_monitors <= 0)
421 /* FIXME: We need to trap errors, since XINERAMA isn't always XINERAMA.
422 * I don't think the num_monitors <= 0 check has any validity.
424 g_error ("error while retrieving Xinerama information");
429 screen_x11->monitors = g_new0 (GdkRectangle, screen_x11->num_monitors);
431 for (i = 0; i < screen_x11->num_monitors; i++)
433 screen_x11->monitors[i].x = monitors[i].x_org;
434 screen_x11->monitors[i].y = monitors[i].y_org;
435 screen_x11->monitors[i].width = monitors[i].width;
436 screen_x11->monitors[i].height = monitors[i].height;
444 #endif /* HAVE_XFREE_XINERAMA */
448 #endif /* HAVE_XINERAMA */
451 init_xinerama_support (GdkScreen * screen)
453 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
456 int opcode, firstevent, firsterror;
459 if (XQueryExtension (GDK_SCREEN_XDISPLAY (screen), "XINERAMA",
460 &opcode, &firstevent, &firsterror))
462 if (check_solaris_xinerama (screen) ||
463 check_xfree_xinerama (screen))
466 #endif /* HAVE_XINERAMA */
470 screen_x11->num_monitors = 1;
471 screen_x11->monitors = g_new0 (GdkRectangle, 1);
472 screen_x11->monitors[0].x = 0;
473 screen_x11->monitors[0].y = 0;
474 screen_x11->monitors[0].width = WidthOfScreen (screen_x11->xscreen);
475 screen_x11->monitors[0].height = HeightOfScreen (screen_x11->xscreen);