]> Pileus Git - ~andy/gtk/blob - gdk/wayland/gdkscreen-wayland.c
e7dbaba0acc9853824b4a4c763884fe11447c5e2
[~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, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "config.h"
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include <glib.h>
26 #include "gdkscreenprivate.h"
27 #include "gdkvisualprivate.h"
28 #include "gdkdisplay.h"
29 #include "gdkdisplay-wayland.h"
30 #include "gdkwayland.h"
31 #include "gdkprivate-wayland.h"
32
33 typedef struct _GdkScreenWayland      GdkScreenWayland;
34 typedef struct _GdkScreenWaylandClass GdkScreenWaylandClass;
35
36 #define GDK_TYPE_SCREEN_WAYLAND              (_gdk_screen_wayland_get_type ())
37 #define GDK_SCREEN_WAYLAND(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SCREEN_WAYLAND, GdkScreenWayland))
38 #define GDK_SCREEN_WAYLAND_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SCREEN_WAYLAND, GdkScreenWaylandClass))
39 #define GDK_IS_SCREEN_WAYLAND(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SCREEN_WAYLAND))
40 #define GDK_IS_SCREEN_WAYLAND_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SCREEN_WAYLAND))
41 #define GDK_SCREEN_WAYLAND_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SCREEN_WAYLAND, GdkScreenWaylandClass))
42
43 typedef struct _GdkWaylandMonitor GdkWaylandMonitor;
44
45 struct _GdkScreenWayland
46 {
47   GdkScreen parent_instance;
48
49   GdkDisplay *display;
50   GdkWindow *root_window;
51
52   int width, height;
53   int width_mm, height_mm;
54
55   /* Window manager */
56   char *window_manager_name;
57   /* TRUE if wmspec_check_window has changed since last
58    * fetch of _NET_SUPPORTED
59    */
60   guint need_refetch_net_supported : 1;
61   /* TRUE if wmspec_check_window has changed since last
62    * fetch of window manager name
63    */
64   guint need_refetch_wm_name : 1;
65
66   /* Visual Part */
67   GdkVisual *argb_visual;
68   GdkVisual *premultiplied_argb_visual;
69   GdkVisual *rgb_visual;
70
71   /* Xinerama/RandR 1.2 */
72   gint               n_monitors;
73   GdkWaylandMonitor *monitors;
74   gint               primary_monitor;
75
76   /* Xft resources for the display, used for default values for
77    * the Xft/ XSETTINGS
78    */
79   gboolean xft_init;            /* Whether we've intialized these values yet */
80   gboolean xft_antialias;
81   gboolean xft_hinting;
82   gint xft_hintstyle;
83   gint xft_rgba;
84   gint xft_dpi;
85
86   GdkAtom cm_selection_atom;
87   gboolean is_composited;
88 };
89   
90 struct _GdkScreenWaylandClass
91 {
92   GdkScreenClass parent_class;
93
94   void (* window_manager_changed) (GdkScreenWayland *screen_wayland);
95 };
96
97 struct _GdkWaylandMonitor
98 {
99   GdkRectangle  geometry;
100   int           width_mm;
101   int           height_mm;
102   char *        output_name;
103   char *        manufacturer;
104 };
105
106 G_DEFINE_TYPE (GdkScreenWayland, _gdk_screen_wayland, GDK_TYPE_SCREEN)
107
108 static void
109 init_monitor_geometry (GdkWaylandMonitor *monitor,
110                        int x, int y, int width, int height)
111 {
112   monitor->geometry.x = x;
113   monitor->geometry.y = y;
114   monitor->geometry.width = width;
115   monitor->geometry.height = height;
116
117   monitor->width_mm = -1;
118   monitor->height_mm = -1;
119   monitor->output_name = NULL;
120   monitor->manufacturer = NULL;
121 }
122
123 static void
124 free_monitors (GdkWaylandMonitor *monitors,
125                gint           n_monitors)
126 {
127   int i;
128
129   for (i = 0; i < n_monitors; ++i)
130     {
131       g_free (monitors[i].output_name);
132       g_free (monitors[i].manufacturer);
133     }
134
135   g_free (monitors);
136 }
137
138 static void
139 deinit_multihead (GdkScreen *screen)
140 {
141   GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen);
142
143   free_monitors (screen_wayland->monitors, screen_wayland->n_monitors);
144
145   screen_wayland->n_monitors = 0;
146   screen_wayland->monitors = NULL;
147 }
148
149 static void
150 init_multihead (GdkScreen *screen)
151 {
152   GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen);
153
154   /* No multihead support of any kind for this screen */
155   screen_wayland->n_monitors = 1;
156   screen_wayland->monitors = g_new0 (GdkWaylandMonitor, 1);
157   screen_wayland->primary_monitor = 0;
158
159   init_monitor_geometry (screen_wayland->monitors, 0, 0,
160                          screen_wayland->width, screen_wayland->height);
161 }
162
163 static void
164 gdk_wayland_screen_dispose (GObject *object)
165 {
166   GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (object);
167
168   if (screen_wayland->root_window)
169     _gdk_window_destroy (screen_wayland->root_window, TRUE);
170
171   G_OBJECT_CLASS (_gdk_screen_wayland_parent_class)->dispose (object);
172 }
173
174 static void
175 gdk_wayland_screen_finalize (GObject *object)
176 {
177   GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (object);
178
179   if (screen_wayland->root_window)
180     g_object_unref (screen_wayland->root_window);
181
182   /* Visual Part */
183   g_object_unref (screen_wayland->argb_visual);
184   g_object_unref (screen_wayland->premultiplied_argb_visual);
185   g_object_unref (screen_wayland->rgb_visual);
186
187   g_free (screen_wayland->window_manager_name);
188
189   deinit_multihead (GDK_SCREEN (object));
190
191   G_OBJECT_CLASS (_gdk_screen_wayland_parent_class)->finalize (object);
192 }
193
194 static GdkDisplay *
195 gdk_wayland_screen_get_display (GdkScreen *screen)
196 {
197   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
198
199   return GDK_SCREEN_WAYLAND (screen)->display;
200 }
201
202 static gint
203 gdk_wayland_screen_get_width (GdkScreen *screen)
204 {
205   g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
206
207   return GDK_SCREEN_WAYLAND (screen)->width;
208 }
209
210 static gint
211 gdk_wayland_screen_get_height (GdkScreen *screen)
212 {
213   g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
214
215   return GDK_SCREEN_WAYLAND (screen)->height;
216 }
217
218 static gint
219 gdk_wayland_screen_get_width_mm (GdkScreen *screen)
220 {
221   g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
222
223   return GDK_SCREEN_WAYLAND (screen)->width_mm;
224 }
225
226 static gint
227 gdk_wayland_screen_get_height_mm (GdkScreen *screen)
228 {
229   g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
230
231   return GDK_SCREEN_WAYLAND (screen)->height_mm;
232 }
233
234 static gint
235 gdk_wayland_screen_get_number (GdkScreen *screen)
236 {
237   g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
238
239   return 0;
240 }
241
242 static GdkWindow *
243 gdk_wayland_screen_get_root_window (GdkScreen *screen)
244 {
245   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
246
247   return GDK_SCREEN_WAYLAND (screen)->root_window;
248 }
249
250 static gint
251 gdk_wayland_screen_get_n_monitors (GdkScreen *screen)
252 {
253   g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
254
255   return GDK_SCREEN_WAYLAND (screen)->n_monitors;
256 }
257
258 static gint
259 gdk_wayland_screen_get_primary_monitor (GdkScreen *screen)
260 {
261   g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
262
263   return GDK_SCREEN_WAYLAND (screen)->primary_monitor;
264 }
265
266 static gint
267 gdk_wayland_screen_get_monitor_width_mm (GdkScreen *screen,
268                                          gint       monitor_num)
269 {
270   GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen);
271
272   g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
273   g_return_val_if_fail (monitor_num >= 0, -1);
274   g_return_val_if_fail (monitor_num < screen_wayland->n_monitors, -1);
275
276   return screen_wayland->monitors[monitor_num].width_mm;
277 }
278
279 static gint
280 gdk_wayland_screen_get_monitor_height_mm (GdkScreen *screen,
281                                           gint       monitor_num)
282 {
283   GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen);
284
285   g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
286   g_return_val_if_fail (monitor_num >= 0, -1);
287   g_return_val_if_fail (monitor_num < screen_wayland->n_monitors, -1);
288
289   return screen_wayland->monitors[monitor_num].height_mm;
290 }
291
292 static gchar *
293 gdk_wayland_screen_get_monitor_plug_name (GdkScreen *screen,
294                                           gint       monitor_num)
295 {
296   GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen);
297
298   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
299   g_return_val_if_fail (monitor_num >= 0, NULL);
300   g_return_val_if_fail (monitor_num < screen_wayland->n_monitors, NULL);
301
302   return g_strdup (screen_wayland->monitors[monitor_num].output_name);
303 }
304
305 static void
306 gdk_wayland_screen_get_monitor_geometry (GdkScreen    *screen,
307                                          gint          monitor_num,
308                                          GdkRectangle *dest)
309 {
310   GdkScreenWayland *screen_wayland = GDK_SCREEN_WAYLAND (screen);
311
312   g_return_if_fail (GDK_IS_SCREEN (screen));
313   g_return_if_fail (monitor_num >= 0);
314   g_return_if_fail (monitor_num < screen_wayland->n_monitors);
315
316   if (dest)
317     *dest = screen_wayland->monitors[monitor_num].geometry;
318 }
319
320 static GdkVisual *
321 gdk_wayland_screen_get_system_visual (GdkScreen * screen)
322 {
323   return (GdkVisual *) GDK_SCREEN_WAYLAND (screen)->argb_visual;
324 }
325
326 static GdkVisual *
327 gdk_wayland_screen_get_rgba_visual (GdkScreen *screen)
328 {
329   return (GdkVisual *) GDK_SCREEN_WAYLAND (screen)->argb_visual;
330 }
331
332 static gboolean
333 gdk_wayland_screen_is_composited (GdkScreen *screen)
334 {
335   return TRUE;
336 }
337
338 static gchar *
339 gdk_wayland_screen_make_display_name (GdkScreen *screen)
340 {
341   return NULL;
342 }
343
344 static GdkWindow *
345 gdk_wayland_screen_get_active_window (GdkScreen *screen)
346 {
347   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
348
349   return NULL;
350 }
351
352 static GList *
353 gdk_wayland_screen_get_window_stack (GdkScreen *screen)
354 {
355   return NULL;
356 }
357
358 static void
359 gdk_wayland_screen_broadcast_client_message (GdkScreen *screen,
360                                              GdkEvent  *event)
361 {
362 }
363
364 static gboolean
365 gdk_wayland_screen_get_setting (GdkScreen   *screen,
366                                 const gchar *name,
367                                 GValue      *value)
368 {
369   return FALSE;
370 }
371
372 typedef struct _GdkWaylandVisual        GdkWaylandVisual;
373 typedef struct _GdkWaylandVisualClass   GdkWaylandVisualClass;
374
375 struct _GdkWaylandVisual
376 {
377   GdkVisual visual;
378   struct wl_visual *wl_visual;
379 };
380
381 struct _GdkWaylandVisualClass
382 {
383   GdkVisualClass parent_class;
384 };
385
386 G_DEFINE_TYPE (GdkWaylandVisual, _gdk_wayland_visual, GDK_TYPE_VISUAL)
387
388 static void
389 _gdk_wayland_visual_class_init (GdkWaylandVisualClass *klass)
390 {
391 }
392
393 static void
394 _gdk_wayland_visual_init (GdkWaylandVisual *visual)
395 {
396 }
397
398 static gint
399 gdk_wayland_screen_visual_get_best_depth (GdkScreen *screen)
400 {
401   return 32;
402 }
403
404 static GdkVisualType
405 gdk_wayland_screen_visual_get_best_type (GdkScreen *screen)
406 {
407   return GDK_VISUAL_TRUE_COLOR;
408 }
409
410 static GdkVisual*
411 gdk_wayland_screen_visual_get_best (GdkScreen *screen)
412 {
413   return GDK_SCREEN_WAYLAND (screen)->argb_visual;
414 }
415
416 static GdkVisual*
417 gdk_wayland_screen_visual_get_best_with_depth (GdkScreen *screen,
418                                                gint       depth)
419 {
420   return GDK_SCREEN_WAYLAND (screen)->argb_visual;
421 }
422
423 static GdkVisual*
424 gdk_wayland_screen_visual_get_best_with_type (GdkScreen     *screen,
425                                               GdkVisualType  visual_type)
426 {
427   return GDK_SCREEN_WAYLAND (screen)->argb_visual;
428 }
429
430 static GdkVisual*
431 gdk_wayland_screen_visual_get_best_with_both (GdkScreen     *screen,
432                                               gint           depth,
433                                               GdkVisualType  visual_type)
434 {
435   return GDK_SCREEN_WAYLAND (screen)->argb_visual;
436 }
437
438 static void
439 gdk_wayland_screen_query_depths  (GdkScreen  *screen,
440                                   gint      **depths,
441                                   gint       *count)
442 {
443   static gint static_depths[] = { 32 };
444
445   *count = G_N_ELEMENTS(static_depths);
446   *depths = static_depths;
447 }
448
449 static void
450 gdk_wayland_screen_query_visual_types (GdkScreen      *screen,
451                                        GdkVisualType **visual_types,
452                                        gint           *count)
453 {
454   static GdkVisualType static_visual_types[] = { GDK_VISUAL_TRUE_COLOR };
455
456   *count = G_N_ELEMENTS(static_visual_types);
457   *visual_types = static_visual_types;
458 }
459
460 static GList *
461 gdk_wayland_screen_list_visuals (GdkScreen *screen)
462 {
463   GList *list;
464   GdkScreenWayland *screen_wayland;
465
466   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
467   screen_wayland = GDK_SCREEN_WAYLAND (screen);
468
469   list = g_list_append (NULL, screen_wayland->argb_visual);
470   list = g_list_append (NULL, screen_wayland->premultiplied_argb_visual);
471   list = g_list_append (NULL, screen_wayland->rgb_visual);
472
473   return list;
474 }
475
476 #define GDK_TYPE_WAYLAND_VISUAL              (_gdk_wayland_visual_get_type ())
477 #define GDK_WAYLAND_VISUAL(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_VISUAL, GdkWaylandVisual))
478
479 static GdkVisual *
480 gdk_wayland_visual_new (GdkScreen *screen, struct wl_visual *wl_visual)
481 {
482   GdkVisual *visual;
483
484   visual = g_object_new (GDK_TYPE_WAYLAND_VISUAL, NULL);
485   visual->screen = GDK_SCREEN (screen);
486   visual->type = GDK_VISUAL_TRUE_COLOR;
487   visual->depth = 32;
488
489   GDK_WAYLAND_VISUAL (visual)->wl_visual = wl_visual;
490
491   return visual;
492 }
493
494 GdkScreen *
495 _gdk_wayland_screen_new (GdkDisplay *display)
496 {
497   GdkScreen *screen;
498   GdkScreenWayland *screen_wayland;
499   GdkDisplayWayland *display_wayland;
500   struct wl_visual *visual;
501
502   display_wayland = GDK_DISPLAY_WAYLAND (display);
503
504   screen = g_object_new (GDK_TYPE_SCREEN_WAYLAND, NULL);
505
506   screen_wayland = GDK_SCREEN_WAYLAND (screen);
507   screen_wayland->display = display;
508   /* we want this to be always non-null */
509   screen_wayland->window_manager_name = g_strdup ("unknown");
510
511   screen_wayland->width = 8192;
512   screen_wayland->height = 8192;
513
514   visual = wl_display_get_argb_visual(display_wayland->wl_display);
515   screen_wayland->argb_visual = gdk_wayland_visual_new (screen, visual);
516
517   visual =
518     wl_display_get_premultiplied_argb_visual(display_wayland->wl_display);
519   screen_wayland->premultiplied_argb_visual =
520     gdk_wayland_visual_new (screen, visual);
521
522   visual = wl_display_get_rgb_visual(display_wayland->wl_display);
523   screen_wayland->rgb_visual = gdk_wayland_visual_new (screen, visual);
524
525   screen_wayland->root_window =
526     _gdk_wayland_screen_create_root_window (screen,
527                                             screen_wayland->width,
528                                             screen_wayland->height);
529
530   init_multihead (screen);
531
532   return screen;
533 }
534
535 static void
536 _gdk_screen_wayland_class_init (GdkScreenWaylandClass *klass)
537 {
538   GObjectClass *object_class = G_OBJECT_CLASS (klass);
539   GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass);
540
541   object_class->dispose = gdk_wayland_screen_dispose;
542   object_class->finalize = gdk_wayland_screen_finalize;
543
544   screen_class->get_display = gdk_wayland_screen_get_display;
545   screen_class->get_width = gdk_wayland_screen_get_width;
546   screen_class->get_height = gdk_wayland_screen_get_height;
547   screen_class->get_width_mm = gdk_wayland_screen_get_width_mm;
548   screen_class->get_height_mm = gdk_wayland_screen_get_height_mm;
549   screen_class->get_number = gdk_wayland_screen_get_number;
550   screen_class->get_root_window = gdk_wayland_screen_get_root_window;
551   screen_class->get_n_monitors = gdk_wayland_screen_get_n_monitors;
552   screen_class->get_primary_monitor = gdk_wayland_screen_get_primary_monitor;
553   screen_class->get_monitor_width_mm = gdk_wayland_screen_get_monitor_width_mm;
554   screen_class->get_monitor_height_mm = gdk_wayland_screen_get_monitor_height_mm;
555   screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name;
556   screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
557   screen_class->get_system_visual = gdk_wayland_screen_get_system_visual;
558   screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
559   screen_class->is_composited = gdk_wayland_screen_is_composited;
560   screen_class->make_display_name = gdk_wayland_screen_make_display_name;
561   screen_class->get_active_window = gdk_wayland_screen_get_active_window;
562   screen_class->get_window_stack = gdk_wayland_screen_get_window_stack;
563   screen_class->broadcast_client_message = gdk_wayland_screen_broadcast_client_message;
564   screen_class->get_setting = gdk_wayland_screen_get_setting;
565   screen_class->visual_get_best_depth = gdk_wayland_screen_visual_get_best_depth;
566   screen_class->visual_get_best_type = gdk_wayland_screen_visual_get_best_type;
567   screen_class->visual_get_best = gdk_wayland_screen_visual_get_best;
568   screen_class->visual_get_best_with_depth = gdk_wayland_screen_visual_get_best_with_depth;
569   screen_class->visual_get_best_with_type = gdk_wayland_screen_visual_get_best_with_type;
570   screen_class->visual_get_best_with_both = gdk_wayland_screen_visual_get_best_with_both;
571   screen_class->query_depths = gdk_wayland_screen_query_depths;
572   screen_class->query_visual_types = gdk_wayland_screen_query_visual_types;
573   screen_class->list_visuals = gdk_wayland_screen_list_visuals;
574 }
575
576 static void
577 _gdk_screen_wayland_init (GdkScreenWayland *screen_wayland)
578 {
579 }