1 /*
2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
4 * Copyright (C) 2008 Christian Dywan <christian@imendio.com>
5 * Copyright (C) 2008 Collabora Ltd.
6 * Copyright (C) 2009 Holger Hans Peter Freyther
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "PlatformScreen.h"
33
34 #include "HostWindow.h"
35 #include "ScrollView.h"
36 #include "Widget.h"
37
38 #include <gtk/gtk.h>
39
40 #if PLATFORM(X11)
41 #include <gdk/gdkx.h>
42 #include <X11/Xatom.h>
43 #endif
44
45 namespace WebCore {
46
getVisual(Widget * widget)47 static GdkVisual* getVisual(Widget* widget)
48 {
49 if (!widget)
50 return 0;
51
52 GtkWidget* container = GTK_WIDGET(widget->root()->hostWindow()->platformWindow());
53
54 if (!container)
55 return 0;
56
57 if (!GTK_WIDGET_REALIZED(container)) {
58 GtkWidget* toplevel = gtk_widget_get_toplevel(container);
59 if (GTK_WIDGET_TOPLEVEL(toplevel))
60 container = toplevel;
61 else
62 return 0;
63 }
64
65
66 return gdk_drawable_get_visual(GDK_DRAWABLE(container->window));
67 }
68
screenDepth(Widget * widget)69 int screenDepth(Widget* widget)
70 {
71 GdkVisual* visual = getVisual(widget);
72 if (!visual)
73 return 24;
74 return visual->depth;
75 }
76
screenDepthPerComponent(Widget * widget)77 int screenDepthPerComponent(Widget* widget)
78 {
79 GdkVisual* visual = getVisual(widget);
80 if (!visual)
81 return 8;
82
83 return visual->bits_per_rgb;
84 }
85
screenIsMonochrome(Widget * widget)86 bool screenIsMonochrome(Widget* widget)
87 {
88 return screenDepth(widget) < 2;
89 }
90
screenRect(Widget * widget)91 FloatRect screenRect(Widget* widget)
92 {
93 if (!widget)
94 return FloatRect();
95
96 GtkWidget* container = gtk_widget_get_toplevel(GTK_WIDGET(widget->root()->hostWindow()->platformWindow()));
97 if (!GTK_WIDGET_TOPLEVEL(container))
98 return FloatRect();
99
100 GdkScreen* screen = gtk_widget_has_screen(container) ? gtk_widget_get_screen(container) : gdk_screen_get_default();
101 if (!screen)
102 return FloatRect();
103
104 gint monitor = gdk_screen_get_monitor_at_window(screen, GTK_WIDGET(container)->window);
105 GdkRectangle geometry;
106 gdk_screen_get_monitor_geometry(screen, monitor, &geometry);
107
108 return FloatRect(geometry.x, geometry.y, geometry.width, geometry.height);
109 }
110
screenAvailableRect(Widget * widget)111 FloatRect screenAvailableRect(Widget* widget)
112 {
113 if (!widget)
114 return FloatRect();
115
116 #if PLATFORM(X11)
117 GtkWidget* container = GTK_WIDGET(widget->root()->hostWindow()->platformWindow());
118 if (!container)
119 return FloatRect();
120
121 if (!GTK_WIDGET_REALIZED(container))
122 return screenRect(widget);
123
124 GdkDrawable* rootWindow = GDK_DRAWABLE(gtk_widget_get_root_window(container));
125 GdkDisplay* display = gdk_drawable_get_display(rootWindow);
126 Atom xproperty = gdk_x11_get_xatom_by_name_for_display(display, "_NET_WORKAREA");
127
128 Atom retType;
129 int retFormat;
130 long *workAreaPos = NULL;
131 unsigned long retNItems;
132 unsigned long retAfter;
133 int xRes = XGetWindowProperty(GDK_DISPLAY_XDISPLAY(display), GDK_WINDOW_XWINDOW(rootWindow), xproperty,
134 0, 4, FALSE, XA_CARDINAL, &retType, &retFormat, &retNItems, &retAfter, (guchar**)&workAreaPos);
135
136 FloatRect rect;
137 if (xRes == Success && workAreaPos != NULL && retType == XA_CARDINAL && retNItems == 4 && retFormat == 32) {
138 rect = FloatRect(workAreaPos[0], workAreaPos[1], workAreaPos[2], workAreaPos[3]);
139 // rect contains the available space in the whole screen not just in the monitor
140 // containing the widget, so we intersect it with the monitor rectangle.
141 rect.intersect(screenRect(widget));
142 } else
143 rect = screenRect(widget);
144
145 if (workAreaPos)
146 XFree(workAreaPos);
147
148 return rect;
149 #else
150 return screenRect(widget);
151 #endif
152 }
153
154 } // namespace WebCore
155