]> Pileus Git - ~andy/gtk/blob - gdk/wayland/gdkscreen-wayland.c
wayland: Use g_value_set_static to avoid string copies
[~andy/gtk] / gdk / wayland / gdkscreen-wayland.c
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "config.h"
19
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <glib.h>
24 #include "gdkscreenprivate.h"
25 #include "gdkvisualprivate.h"
26 #include "gdkdisplay.h"
27 #include "gdkdisplay-wayland.h"
28 #include "gdkwayland.h"
29 #include "gdkprivate-wayland.h"
30
31 typedef struct _GdkWaylandScreen      GdkWaylandScreen;
32 typedef struct _GdkWaylandScreenClass GdkWaylandScreenClass;
33
34 #define GDK_TYPE_WAYLAND_SCREEN              (_gdk_wayland_screen_get_type ())
35 #define GDK_WAYLAND_SCREEN(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_SCREEN, GdkWaylandScreen))
36 #define GDK_WAYLAND_SCREEN_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_SCREEN, GdkWaylandScreenClass))
37 #define GDK_IS_WAYLAND_SCREEN(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_SCREEN))
38 #define GDK_IS_WAYLAND_SCREEN_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_SCREEN))
39 #define GDK_WAYLAND_SCREEN_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_SCREEN, GdkWaylandScreenClass))
40
41 typedef struct _GdkWaylandMonitor GdkWaylandMonitor;
42
43 struct _GdkWaylandScreen
44 {
45   GdkScreen parent_instance;
46
47   GdkDisplay *display;
48   GdkWindow *root_window;
49
50   int width, height;
51   int width_mm, height_mm;
52
53   /* Visual Part */
54   GdkVisual *visual;
55
56   /* Xinerama/RandR 1.2 */
57   gint               n_monitors;
58   GdkWaylandMonitor *monitors;
59   gint               primary_monitor;
60 };
61
62 struct _GdkWaylandScreenClass
63 {
64   GdkScreenClass parent_class;
65
66   void (* window_manager_changed) (GdkWaylandScreen *screen_wayland);
67 };
68
69 struct _GdkWaylandMonitor
70 {
71   GdkRectangle  geometry;
72   int           width_mm;
73   int           height_mm;
74   char *        output_name;
75   char *        manufacturer;
76 };
77
78 G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
79
80 #define MM_PER_INCH 25
81 #define DEFAULT_DPI 96
82
83 static void
84 init_monitor_geometry (GdkWaylandMonitor *monitor,
85                        int x, int y, int width, int height)
86 {
87   monitor->geometry.x = x;
88   monitor->geometry.y = y;
89   monitor->geometry.width = width;
90   monitor->geometry.height = height;
91
92   monitor->width_mm = width/DEFAULT_DPI*MM_PER_INCH;
93   monitor->height_mm = height/DEFAULT_DPI*MM_PER_INCH;
94   monitor->output_name = NULL;
95   monitor->manufacturer = NULL;
96 }
97
98 static void
99 free_monitors (GdkWaylandMonitor *monitors,
100                gint           n_monitors)
101 {
102   int i;
103
104   for (i = 0; i < n_monitors; ++i)
105     {
106       g_free (monitors[i].output_name);
107       g_free (monitors[i].manufacturer);
108     }
109
110   g_free (monitors);
111 }
112
113 static void
114 deinit_multihead (GdkScreen *screen)
115 {
116   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
117
118   free_monitors (screen_wayland->monitors, screen_wayland->n_monitors);
119
120   screen_wayland->n_monitors = 0;
121   screen_wayland->monitors = NULL;
122 }
123
124 static void
125 init_multihead (GdkScreen *screen)
126 {
127   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
128
129   /* No multihead support of any kind for this screen */
130   screen_wayland->n_monitors = 1;
131   screen_wayland->monitors = g_new0 (GdkWaylandMonitor, 1);
132   screen_wayland->primary_monitor = 0;
133
134   init_monitor_geometry (screen_wayland->monitors, 0, 0,
135                          screen_wayland->width, screen_wayland->height);
136 }
137
138 static void
139 gdk_wayland_screen_dispose (GObject *object)
140 {
141   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
142
143   if (screen_wayland->root_window)
144     _gdk_window_destroy (screen_wayland->root_window, TRUE);
145
146   G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->dispose (object);
147 }
148
149 static void
150 gdk_wayland_screen_finalize (GObject *object)
151 {
152   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
153
154   if (screen_wayland->root_window)
155     g_object_unref (screen_wayland->root_window);
156
157   g_object_unref (screen_wayland->visual);
158
159   deinit_multihead (GDK_SCREEN (object));
160
161   G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->finalize (object);
162 }
163
164 static GdkDisplay *
165 gdk_wayland_screen_get_display (GdkScreen *screen)
166 {
167   return GDK_WAYLAND_SCREEN (screen)->display;
168 }
169
170 static gint
171 gdk_wayland_screen_get_width (GdkScreen *screen)
172 {
173   return GDK_WAYLAND_SCREEN (screen)->width;
174 }
175
176 static gint
177 gdk_wayland_screen_get_height (GdkScreen *screen)
178 {
179   return GDK_WAYLAND_SCREEN (screen)->height;
180 }
181
182 static gint
183 gdk_wayland_screen_get_width_mm (GdkScreen *screen)
184 {
185   return GDK_WAYLAND_SCREEN (screen)->width_mm;
186 }
187
188 static gint
189 gdk_wayland_screen_get_height_mm (GdkScreen *screen)
190 {
191   return GDK_WAYLAND_SCREEN (screen)->height_mm;
192 }
193
194 static gint
195 gdk_wayland_screen_get_number (GdkScreen *screen)
196 {
197   return 0;
198 }
199
200 static GdkWindow *
201 gdk_wayland_screen_get_root_window (GdkScreen *screen)
202 {
203   return GDK_WAYLAND_SCREEN (screen)->root_window;
204 }
205
206 static gint
207 gdk_wayland_screen_get_n_monitors (GdkScreen *screen)
208 {
209   return GDK_WAYLAND_SCREEN (screen)->n_monitors;
210 }
211
212 static gint
213 gdk_wayland_screen_get_primary_monitor (GdkScreen *screen)
214 {
215   return GDK_WAYLAND_SCREEN (screen)->primary_monitor;
216 }
217
218 static gint
219 gdk_wayland_screen_get_monitor_width_mm (GdkScreen *screen,
220                                          gint       monitor_num)
221 {
222   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
223
224   return screen_wayland->monitors[monitor_num].width_mm;
225 }
226
227 static gint
228 gdk_wayland_screen_get_monitor_height_mm (GdkScreen *screen,
229                                           gint       monitor_num)
230 {
231   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
232
233   return screen_wayland->monitors[monitor_num].height_mm;
234 }
235
236 static gchar *
237 gdk_wayland_screen_get_monitor_plug_name (GdkScreen *screen,
238                                           gint       monitor_num)
239 {
240   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
241
242   return g_strdup (screen_wayland->monitors[monitor_num].output_name);
243 }
244
245 static void
246 gdk_wayland_screen_get_monitor_geometry (GdkScreen    *screen,
247                                          gint          monitor_num,
248                                          GdkRectangle *dest)
249 {
250   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
251
252   if (dest)
253     *dest = screen_wayland->monitors[monitor_num].geometry;
254 }
255
256 static GdkVisual *
257 gdk_wayland_screen_get_system_visual (GdkScreen * screen)
258 {
259   return (GdkVisual *) GDK_WAYLAND_SCREEN (screen)->visual;
260 }
261
262 static GdkVisual *
263 gdk_wayland_screen_get_rgba_visual (GdkScreen *screen)
264 {
265   return (GdkVisual *) GDK_WAYLAND_SCREEN (screen)->visual;
266 }
267
268 static gboolean
269 gdk_wayland_screen_is_composited (GdkScreen *screen)
270 {
271   return TRUE;
272 }
273
274 static gchar *
275 gdk_wayland_screen_make_display_name (GdkScreen *screen)
276 {
277   return NULL;
278 }
279
280 static GdkWindow *
281 gdk_wayland_screen_get_active_window (GdkScreen *screen)
282 {
283   return NULL;
284 }
285
286 static GList *
287 gdk_wayland_screen_get_window_stack (GdkScreen *screen)
288 {
289   return NULL;
290 }
291
292 static void
293 gdk_wayland_screen_broadcast_client_message (GdkScreen *screen,
294                                              GdkEvent  *event)
295 {
296 }
297
298 static gboolean
299 gdk_wayland_screen_get_setting (GdkScreen   *screen,
300                                 const gchar *name,
301                                 GValue      *value)
302 {
303   g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
304
305   if (strcmp ("gtk-theme-name", name) == 0)
306     {
307       const gchar *s = "Adwaita";
308       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
309       g_value_set_static_string (value, s);
310       return TRUE;
311     }
312   if (strcmp ("gtk-cursor-theme-name", name) == 0)
313     {
314       const gchar *s = "Adwaita";
315       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
316       g_value_set_static_string (value, s);
317       return TRUE;
318     }
319   else if (strcmp ("gtk-icon-theme-name", name) == 0)
320     {
321       const gchar *s = "gnome";
322       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
323       g_value_set_static_string (value, s);
324       return TRUE;
325     }
326   else if (strcmp ("gtk-double-click-time", name) == 0)
327     {
328       gint i = 250;
329       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
330       g_value_set_int (value, i);
331       return TRUE;
332     }
333   else if (strcmp ("gtk-double-click-distance", name) == 0)
334     {
335       gint i = 5;
336       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
337       g_value_set_int (value, i);
338       return TRUE;
339     }
340   else if (strcmp ("gtk-dnd-drag-threshold", name) == 0)
341     {
342       gint i = 8;
343       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
344       g_value_set_int (value, i);
345       return TRUE;
346     }
347   else if (strcmp ("gtk-split-cursor", name) == 0)
348     {
349       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : FALSE\n", name));
350       g_value_set_boolean (value, FALSE);
351       return TRUE;
352     }
353   else if (strcmp ("gtk-alternative-button-order", name) == 0)
354     {
355       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
356       g_value_set_boolean (value, TRUE);
357       return TRUE;
358     }
359   else if (strcmp ("gtk-alternative-sort-arrows", name) == 0)
360     {
361       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
362       g_value_set_boolean (value, TRUE);
363       return TRUE;
364     }
365   else if (strcmp ("gtk-xft-dpi", name) == 0)
366     {
367       gint i = 96*1024;
368       GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
369       g_value_set_int (value, i);
370       return TRUE;
371     }
372
373   return FALSE;
374 }
375
376 typedef struct _GdkWaylandVisual        GdkWaylandVisual;
377 typedef struct _GdkWaylandVisualClass   GdkWaylandVisualClass;
378
379 struct _GdkWaylandVisual
380 {
381   GdkVisual visual;
382 };
383
384 struct _GdkWaylandVisualClass
385 {
386   GdkVisualClass parent_class;
387 };
388
389 G_DEFINE_TYPE (GdkWaylandVisual, _gdk_wayland_visual, GDK_TYPE_VISUAL)
390
391 static void
392 _gdk_wayland_visual_class_init (GdkWaylandVisualClass *klass)
393 {
394 }
395
396 static void
397 _gdk_wayland_visual_init (GdkWaylandVisual *visual)
398 {
399 }
400
401 static gint
402 gdk_wayland_screen_visual_get_best_depth (GdkScreen *screen)
403 {
404   return 32;
405 }
406
407 static GdkVisualType
408 gdk_wayland_screen_visual_get_best_type (GdkScreen *screen)
409 {
410   return GDK_VISUAL_TRUE_COLOR;
411 }
412
413 static GdkVisual*
414 gdk_wayland_screen_visual_get_best (GdkScreen *screen)
415 {
416   return GDK_WAYLAND_SCREEN (screen)->visual;
417 }
418
419 static GdkVisual*
420 gdk_wayland_screen_visual_get_best_with_depth (GdkScreen *screen,
421                                                gint       depth)
422 {
423   return GDK_WAYLAND_SCREEN (screen)->visual;
424 }
425
426 static GdkVisual*
427 gdk_wayland_screen_visual_get_best_with_type (GdkScreen     *screen,
428                                               GdkVisualType  visual_type)
429 {
430   return GDK_WAYLAND_SCREEN (screen)->visual;
431 }
432
433 static GdkVisual*
434 gdk_wayland_screen_visual_get_best_with_both (GdkScreen     *screen,
435                                               gint           depth,
436                                               GdkVisualType  visual_type)
437 {
438   return GDK_WAYLAND_SCREEN (screen)->visual;
439 }
440
441 static void
442 gdk_wayland_screen_query_depths  (GdkScreen  *screen,
443                                   gint      **depths,
444                                   gint       *count)
445 {
446   static gint static_depths[] = { 32 };
447
448   *count = G_N_ELEMENTS(static_depths);
449   *depths = static_depths;
450 }
451
452 static void
453 gdk_wayland_screen_query_visual_types (GdkScreen      *screen,
454                                        GdkVisualType **visual_types,
455                                        gint           *count)
456 {
457   static GdkVisualType static_visual_types[] = { GDK_VISUAL_TRUE_COLOR };
458
459   *count = G_N_ELEMENTS(static_visual_types);
460   *visual_types = static_visual_types;
461 }
462
463 static GList *
464 gdk_wayland_screen_list_visuals (GdkScreen *screen)
465 {
466   GList *list;
467   GdkWaylandScreen *screen_wayland;
468
469   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
470   screen_wayland = GDK_WAYLAND_SCREEN (screen);
471
472   list = g_list_append (NULL, screen_wayland->visual);
473
474   return list;
475 }
476
477 #define GDK_TYPE_WAYLAND_VISUAL              (_gdk_wayland_visual_get_type ())
478 #define GDK_WAYLAND_VISUAL(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_VISUAL, GdkWaylandVisual))
479
480 static GdkVisual *
481 gdk_wayland_visual_new (GdkScreen *screen)
482 {
483   GdkVisual *visual;
484
485   visual = g_object_new (GDK_TYPE_WAYLAND_VISUAL, NULL);
486   visual->screen = GDK_SCREEN (screen);
487   visual->type = GDK_VISUAL_TRUE_COLOR;
488   visual->depth = 32;
489
490   return visual;
491 }
492
493 GdkScreen *
494 _gdk_wayland_screen_new (GdkDisplay *display)
495 {
496   GdkScreen *screen;
497   GdkWaylandScreen *screen_wayland;
498
499   screen = g_object_new (GDK_TYPE_WAYLAND_SCREEN, NULL);
500
501   screen_wayland = GDK_WAYLAND_SCREEN (screen);
502   screen_wayland->display = display;
503   screen_wayland->width = 8192;
504   screen_wayland->height = 8192;
505
506   screen_wayland->visual = gdk_wayland_visual_new (screen);
507
508   screen_wayland->root_window =
509     _gdk_wayland_screen_create_root_window (screen,
510                                             screen_wayland->width,
511                                             screen_wayland->height);
512
513   init_multihead (screen);
514
515   return screen;
516 }
517
518 static void
519 _gdk_wayland_screen_class_init (GdkWaylandScreenClass *klass)
520 {
521   GObjectClass *object_class = G_OBJECT_CLASS (klass);
522   GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass);
523
524   object_class->dispose = gdk_wayland_screen_dispose;
525   object_class->finalize = gdk_wayland_screen_finalize;
526
527   screen_class->get_display = gdk_wayland_screen_get_display;
528   screen_class->get_width = gdk_wayland_screen_get_width;
529   screen_class->get_height = gdk_wayland_screen_get_height;
530   screen_class->get_width_mm = gdk_wayland_screen_get_width_mm;
531   screen_class->get_height_mm = gdk_wayland_screen_get_height_mm;
532   screen_class->get_number = gdk_wayland_screen_get_number;
533   screen_class->get_root_window = gdk_wayland_screen_get_root_window;
534   screen_class->get_n_monitors = gdk_wayland_screen_get_n_monitors;
535   screen_class->get_primary_monitor = gdk_wayland_screen_get_primary_monitor;
536   screen_class->get_monitor_width_mm = gdk_wayland_screen_get_monitor_width_mm;
537   screen_class->get_monitor_height_mm = gdk_wayland_screen_get_monitor_height_mm;
538   screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name;
539   screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
540   screen_class->get_monitor_workarea = gdk_wayland_screen_get_monitor_geometry;
541   screen_class->get_system_visual = gdk_wayland_screen_get_system_visual;
542   screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
543   screen_class->is_composited = gdk_wayland_screen_is_composited;
544   screen_class->make_display_name = gdk_wayland_screen_make_display_name;
545   screen_class->get_active_window = gdk_wayland_screen_get_active_window;
546   screen_class->get_window_stack = gdk_wayland_screen_get_window_stack;
547   screen_class->broadcast_client_message = gdk_wayland_screen_broadcast_client_message;
548   screen_class->get_setting = gdk_wayland_screen_get_setting;
549   screen_class->visual_get_best_depth = gdk_wayland_screen_visual_get_best_depth;
550   screen_class->visual_get_best_type = gdk_wayland_screen_visual_get_best_type;
551   screen_class->visual_get_best = gdk_wayland_screen_visual_get_best;
552   screen_class->visual_get_best_with_depth = gdk_wayland_screen_visual_get_best_with_depth;
553   screen_class->visual_get_best_with_type = gdk_wayland_screen_visual_get_best_with_type;
554   screen_class->visual_get_best_with_both = gdk_wayland_screen_visual_get_best_with_both;
555   screen_class->query_depths = gdk_wayland_screen_query_depths;
556   screen_class->query_visual_types = gdk_wayland_screen_query_visual_types;
557   screen_class->list_visuals = gdk_wayland_screen_list_visuals;
558 }
559
560 static void
561 _gdk_wayland_screen_init (GdkWaylandScreen *screen_wayland)
562 {
563 }