1 /* vi:set sw=2 sts=2 ts=2 et ai tw=100: */
2 /*-
3 * Copyright (c) 2017 Viktor Odintsev <zakhams@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21 #include <string.h>
22 #include <gdk/gdkx.h>
23
24 #include "xfwm-common.h"
25 #define DEFAULT_REFRESH_RATE 30
26
27
28 void
xfwm_widget_reparent(GtkWidget * widget,GtkWidget * new_parent)29 xfwm_widget_reparent (GtkWidget *widget,
30 GtkWidget *new_parent)
31 {
32 GtkWidget *old_parent;
33
34 g_return_if_fail (GTK_IS_WIDGET (widget));
35 g_return_if_fail (GTK_IS_CONTAINER (new_parent));
36
37 old_parent = gtk_widget_get_parent (widget);
38
39 g_return_if_fail (old_parent != NULL);
40
41 if (old_parent != new_parent)
42 {
43 g_object_ref (widget);
44 gtk_container_remove (GTK_CONTAINER (old_parent), widget);
45 gtk_container_add (GTK_CONTAINER (new_parent), widget);
46 g_object_unref (widget);
47 }
48 }
49
50
51
52 void
xfwm_get_screen_dimensions(gint * width,gint * height)53 xfwm_get_screen_dimensions (gint *width, gint *height)
54 {
55 GdkDisplay *display;
56 GdkMonitor *monitor;
57 GdkRectangle geometry;
58
59 display = gdk_display_get_default ();
60 monitor = gdk_display_get_primary_monitor (display);
61 gdk_monitor_get_geometry (monitor, &geometry);
62
63 if (width != NULL)
64 *width = geometry.width;
65 if (height != NULL)
66 *height = geometry.height;
67 }
68
69
70
71 static void
xfwm_geometry_convert_to_device_pixels(GdkRectangle * geometry,gint scale)72 xfwm_geometry_convert_to_device_pixels (GdkRectangle *geometry,
73 gint scale)
74 {
75 if (geometry != NULL)
76 {
77 geometry->x *= scale;
78 geometry->y *= scale;
79 geometry->width *= scale;
80 geometry->height *= scale;
81 }
82 }
83
84
85
86 void
xfwm_get_monitor_geometry(GdkScreen * screen,gint monitor_num,GdkRectangle * geometry,gboolean scaled)87 xfwm_get_monitor_geometry (GdkScreen *screen,
88 gint monitor_num,
89 GdkRectangle *geometry,
90 gboolean scaled)
91 {
92 gint scale;
93 GdkDisplay *display;
94 GdkMonitor *monitor;
95
96 display = gdk_screen_get_display (screen);
97 monitor = gdk_display_get_monitor (display, monitor_num);
98 scale = gdk_monitor_get_scale_factor (monitor);
99 gdk_monitor_get_geometry (monitor, geometry);
100
101 if (scaled && scale != 1)
102 xfwm_geometry_convert_to_device_pixels (geometry, scale);
103 }
104
105
106
107 gboolean
xfwm_get_primary_monitor_geometry(GdkScreen * screen,GdkRectangle * geometry,gboolean scaled)108 xfwm_get_primary_monitor_geometry (GdkScreen *screen,
109 GdkRectangle *geometry,
110 gboolean scaled)
111 {
112 gint scale;
113 GdkDisplay *display;
114 GdkMonitor *monitor;
115
116 display = gdk_screen_get_display (screen);
117 monitor = gdk_display_get_primary_monitor (display);
118
119 if (!monitor)
120 {
121 geometry->width = 0;
122 geometry->height = 0;
123
124 return FALSE;
125 }
126
127 scale = gdk_monitor_get_scale_factor (monitor);
128 gdk_monitor_get_geometry (monitor, geometry);
129
130 if (scaled && scale != 1)
131 xfwm_geometry_convert_to_device_pixels (geometry, scale);
132
133 return TRUE;
134 }
135
136
137
138 gint
xfwm_get_primary_refresh_rate(GdkScreen * screen)139 xfwm_get_primary_refresh_rate (GdkScreen *screen)
140 {
141 GdkDisplay *display;
142 GdkMonitor *monitor;
143 int refresh_rate;
144
145 display = gdk_screen_get_display (screen);
146 monitor = gdk_display_get_primary_monitor (display);
147 refresh_rate = 0;
148
149 if (monitor)
150 refresh_rate = gdk_monitor_get_refresh_rate (monitor) / 1000;
151
152 if (refresh_rate)
153 return refresh_rate;
154
155 return DEFAULT_REFRESH_RATE;
156 }
157
158
159
160 gboolean
xfwm_monitor_is_primary(GdkScreen * screen,gint monitor_num)161 xfwm_monitor_is_primary (GdkScreen *screen,
162 gint monitor_num)
163 {
164 GdkDisplay *display;
165 GdkMonitor *monitor;
166
167 display = gdk_screen_get_display (screen);
168 monitor = gdk_display_get_monitor (display, monitor_num);
169
170 return gdk_monitor_is_primary (monitor);
171 }
172
173
174
175 gint
xfwm_get_n_monitors(GdkScreen * screen)176 xfwm_get_n_monitors (GdkScreen *screen)
177 {
178 return gdk_display_get_n_monitors (gdk_screen_get_display (screen));
179 }
180
181
182
183 static gchar *
substitute_screen_number(const gchar * display_name,gint screen_number)184 substitute_screen_number (const gchar *display_name,
185 gint screen_number)
186 {
187 GString *str;
188 gchar *p;
189
190 str = g_string_new (display_name);
191
192 p = strrchr (str->str, '.');
193 if (p != NULL && p > strchr (str->str, ':'))
194 {
195 /* remove screen number from string */
196 g_string_truncate (str, p - str->str);
197 }
198
199 g_string_append_printf (str, ".%d", screen_number);
200
201 return g_string_free (str, FALSE);
202 }
203
204
205
206 gchar *
xfwm_make_display_name(GdkScreen * screen)207 xfwm_make_display_name (GdkScreen *screen)
208 {
209 const gchar *name;
210 gint number;
211
212 name = gdk_display_get_name (gdk_screen_get_display (screen));
213 number = gdk_x11_screen_get_screen_number (screen);
214
215 return substitute_screen_number (name, number);
216 }
217