]> Pileus Git - ~andy/gtk/blob - gdk/gdkscreen.c
Add hidden aliases for exported symbols which are used internally in order
[~andy/gtk] / gdk / gdkscreen.c
1 /*
2  * gdkscreen.c
3  * 
4  * Copyright 2001 Sun Microsystems Inc. 
5  *
6  * Erwann Chenede <erwann.chenede@sun.com>
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 #include <config.h>
25 #include "gdkalias.h"
26 #include "gdk.h"                /* For gdk_rectangle_intersect() */
27 #include "gdkcolor.h"
28 #include "gdkwindow.h"
29 #include "gdkscreen.h"
30
31 static void gdk_screen_class_init  (GdkScreenClass *klass);
32 static void gdk_screen_dispose     (GObject        *object);
33
34 enum
35 {
36   SIZE_CHANGED,
37   LAST_SIGNAL
38 };
39
40 static guint signals[LAST_SIGNAL] = { 0 };
41
42 static gpointer parent_class = NULL;
43
44 GType
45 gdk_screen_get_type (void)
46 {
47   static GType object_type = 0;
48
49   if (!object_type)
50     {
51       static const GTypeInfo object_info =
52         {
53           sizeof (GdkScreenClass),
54           (GBaseInitFunc) NULL,
55           (GBaseFinalizeFunc) NULL,
56           (GClassInitFunc) gdk_screen_class_init,
57           NULL,                 /* class_finalize */
58           NULL,                 /* class_data */
59           sizeof (GdkScreen),
60           0,                    /* n_preallocs */
61           (GInstanceInitFunc) NULL,
62         };
63       
64       object_type = g_type_register_static (G_TYPE_OBJECT,
65                                             "GdkScreen", &object_info, 0);
66     }
67
68   return object_type;
69 }
70
71 static void
72 gdk_screen_class_init (GdkScreenClass *klass)
73 {
74   GObjectClass *object_class = G_OBJECT_CLASS (klass);
75
76   parent_class = g_type_class_peek_parent (klass);
77   
78   object_class->dispose = gdk_screen_dispose;
79   
80   /**
81    * GdkScreen::size-changed:
82    * @screen: the object on which the signal is emitted
83    * 
84    * The ::size_changed signal is emitted when the pixel width or 
85    * height of a screen changes.
86    *
87    * Since: 2.2
88    */
89   signals[SIZE_CHANGED] =
90     g_signal_new ("size_changed",
91                   G_OBJECT_CLASS_TYPE (klass),
92                   G_SIGNAL_RUN_LAST,
93                   G_STRUCT_OFFSET (GdkScreenClass, size_changed),
94                   NULL, NULL,
95                   g_cclosure_marshal_VOID__VOID,
96                   G_TYPE_NONE,
97                   0);
98 }
99
100 static void
101 gdk_screen_dispose (GObject *object)
102 {
103   GdkScreen *screen = GDK_SCREEN (object);
104   gint i;
105
106   for (i = 0; i < 32; ++i)
107     {
108       if (screen->exposure_gcs[i])
109         g_object_unref (screen->exposure_gcs[i]);
110
111       if (screen->normal_gcs[i])
112         g_object_unref (screen->normal_gcs[i]);
113     }
114
115   G_OBJECT_CLASS (parent_class)->dispose (object);
116 }
117
118 void 
119 _gdk_screen_close (GdkScreen *screen)
120 {
121   g_return_if_fail (GDK_IS_SCREEN (screen));
122
123   if (!screen->closed)
124     {
125       screen->closed = TRUE;
126       g_object_run_dispose (G_OBJECT (screen));
127     }
128 }
129
130 /* Fallback used when the monitor "at" a point or window
131  * doesn't exist.
132  */
133 static gint
134 get_nearest_monitor (GdkScreen *screen,
135                      gint       x,
136                      gint       y)
137 {
138   gint num_monitors, i;
139   gint nearest_dist = G_MAXINT;
140   gint nearest_monitor = 0;
141   
142   g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
143
144   num_monitors = gdk_screen_get_n_monitors (screen);
145   
146   for (i = 0; i < num_monitors; i++)
147     {
148       GdkRectangle monitor;
149       gint dist_x, dist_y;
150       
151       gdk_screen_get_monitor_geometry (screen, i, &monitor);
152
153       if (x < monitor.x)
154         dist_x = monitor.x - x;
155       else if (x >= monitor.x + monitor.width)
156         dist_x = x - (monitor.x + monitor.width) + 1;
157       else
158         dist_x = 0;
159
160       if (y < monitor.y)
161         dist_y = monitor.y - y;
162       else if (y >= monitor.y + monitor.height)
163         dist_y = y - (monitor.y + monitor.height) + 1;
164       else
165         dist_y = 0;
166
167       if (MIN (dist_x, dist_y) < nearest_dist)
168         {
169           nearest_dist = MIN (dist_x, dist_y);
170           nearest_monitor = i;
171         }
172     }
173
174   return nearest_monitor;
175 }
176
177 /**
178  * gdk_screen_get_monitor_at_point:
179  * @screen: a #GdkScreen.
180  * @x: the x coordinate in the virtual screen.
181  * @y: the y coordinate in the virtual screen.
182  *
183  * Returns the monitor number in which the point (@x,@y) is located.
184  *
185  * Returns: the monitor number in which the point (@x,@y) lies, or
186  *   a monitor close to (@x,@y) if the point is not in any monitor.
187  *
188  * Since: 2.2
189  **/
190 gint 
191 gdk_screen_get_monitor_at_point (GdkScreen *screen,
192                                  gint       x,
193                                  gint       y)
194 {
195   gint num_monitors, i;
196   
197   g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
198
199   num_monitors = gdk_screen_get_n_monitors (screen);
200   
201   for (i=0;i<num_monitors;i++)
202     {
203       GdkRectangle monitor;
204       
205       gdk_screen_get_monitor_geometry (screen, i, &monitor);
206
207       if (x >= monitor.x &&
208           x < monitor.x + monitor.width &&
209           y >= monitor.y &&
210           y < (monitor.y + monitor.height))
211         return i;
212     }
213
214   return get_nearest_monitor (screen, x, y);
215 }
216
217 /**
218  * gdk_screen_get_monitor_at_window:
219  * @screen: a #GdkScreen.
220  * @window: a #GdkWindow
221  * @returns: the monitor number in which most of @window is located,
222  *           or if @window does not intersect any monitors, a monitor,
223  *           close to @window.
224  *
225  * Returns the number of the monitor in which the largest area of the 
226  * bounding rectangle of @window resides.
227  *
228  * Since: 2.2
229  **/
230 gint 
231 gdk_screen_get_monitor_at_window (GdkScreen      *screen,
232                                   GdkWindow      *window)
233 {
234   gint num_monitors, i, area = 0, screen_num = -1;
235   GdkRectangle win_rect;
236   g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
237   
238   gdk_window_get_geometry (window, &win_rect.x, &win_rect.y, &win_rect.width,
239                            &win_rect.height, NULL);
240   gdk_window_get_origin (window, &win_rect.x, &win_rect.y);
241   num_monitors = gdk_screen_get_n_monitors (screen);
242   
243   for (i=0;i<num_monitors;i++)
244     {
245       GdkRectangle tmp_monitor, intersect;
246       
247       gdk_screen_get_monitor_geometry (screen, i, &tmp_monitor);
248       gdk_rectangle_intersect (&win_rect, &tmp_monitor, &intersect);
249       
250       if (intersect.width * intersect.height > area)
251         { 
252           area = intersect.width * intersect.height;
253           screen_num = i;
254         }
255     }
256   if (screen_num >= 0)
257     return screen_num;
258   else
259     return get_nearest_monitor (screen,
260                                 win_rect.x + win_rect.width / 2,
261                                 win_rect.y + win_rect.height / 2);
262 }
263
264 /**
265  * gdk_screen_width:
266  * 
267  * Returns the width of the default screen in pixels.
268  * 
269  * Return value: the width of the default screen in pixels.
270  **/
271 gint
272 gdk_screen_width (void)
273 {
274   return gdk_screen_get_width (gdk_screen_get_default());
275 }
276
277 /**
278  * gdk_screen_height:
279  * 
280  * Returns the height of the default screen in pixels.
281  * 
282  * Return value: the height of the default screen in pixels.
283  **/
284 gint
285 gdk_screen_height (void)
286 {
287   return gdk_screen_get_height (gdk_screen_get_default());
288 }
289
290 /**
291  * gdk_screen_width_mm:
292  * 
293  * Returns the width of the default screen in millimeters.
294  * Note that on many X servers this value will not be correct.
295  * 
296  * Return value: the width of the default screen in millimeters,
297  * though it is not always correct.
298  **/
299 gint
300 gdk_screen_width_mm (void)
301 {
302   return gdk_screen_get_width_mm (gdk_screen_get_default());
303 }
304
305 /**
306  * gdk_screen_height_mm:
307  * 
308  * Returns the height of the default screen in millimeters.
309  * Note that on many X servers this value will not be correct.
310  * 
311  * Return value: the height of the default screen in millimeters,
312  * though it is not always correct.
313  **/
314 gint
315 gdk_screen_height_mm (void)
316 {
317   return gdk_screen_get_height_mm (gdk_screen_get_default ());
318 }