1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /*
4 * Copyright (C) 2014 Red Hat
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 *
21 * Written by:
22 * Jasper St. Pierre <jstpierre@mecheye.net>
23 */
24
25 /**
26 * SECTION:meta-backend-native
27 * @title: MetaBackendNative
28 * @short_description: A native (KMS/evdev) MetaBackend
29 *
30 * MetaBackendNative is an implementation of #MetaBackend that uses "native"
31 * technologies like DRM/KMS and libinput/evdev to perform the necessary
32 * functions.
33 */
34
35 #include "config.h"
36
37 #include "backends/native/meta-backend-native.h"
38 #include "backends/native/meta-backend-native-private.h"
39 #include "backends/native/meta-input-thread.h"
40
41 #include <sched.h>
42 #include <stdlib.h>
43
44 #include "backends/meta-cursor-tracker-private.h"
45 #include "backends/meta-idle-manager.h"
46 #include "backends/meta-keymap-utils.h"
47 #include "backends/meta-logical-monitor.h"
48 #include "backends/meta-monitor-manager-private.h"
49 #include "backends/meta-pointer-constraint.h"
50 #include "backends/meta-settings-private.h"
51 #include "backends/meta-stage-private.h"
52 #include "backends/native/meta-clutter-backend-native.h"
53 #include "backends/native/meta-device-pool-private.h"
54 #include "backends/native/meta-kms.h"
55 #include "backends/native/meta-kms-device.h"
56 #include "backends/native/meta-launcher.h"
57 #include "backends/native/meta-monitor-manager-native.h"
58 #include "backends/native/meta-renderer-native.h"
59 #include "backends/native/meta-seat-native.h"
60 #include "backends/native/meta-stage-native.h"
61 #include "cogl/cogl.h"
62 #include "core/meta-border.h"
63 #include "meta/main.h"
64
65 #ifdef HAVE_REMOTE_DESKTOP
66 #include "backends/meta-screen-cast.h"
67 #endif
68
69 enum
70 {
71 PROP_0,
72
73 PROP_HEADLESS,
74
75 N_PROPS
76 };
77
78 static GParamSpec *obj_props[N_PROPS];
79
80 struct _MetaBackendNative
81 {
82 MetaBackend parent;
83
84 MetaLauncher *launcher;
85 MetaDevicePool *device_pool;
86 MetaUdev *udev;
87 MetaKms *kms;
88
89 gboolean is_headless;
90 };
91
92 static GInitableIface *initable_parent_iface;
93
94 static void
95 initable_iface_init (GInitableIface *initable_iface);
96
G_DEFINE_TYPE_WITH_CODE(MetaBackendNative,meta_backend_native,META_TYPE_BACKEND,G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,initable_iface_init))97 G_DEFINE_TYPE_WITH_CODE (MetaBackendNative, meta_backend_native, META_TYPE_BACKEND,
98 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
99 initable_iface_init))
100
101 static void
102 meta_backend_native_dispose (GObject *object)
103 {
104 MetaBackendNative *native = META_BACKEND_NATIVE (object);
105
106 if (native->kms)
107 meta_kms_prepare_shutdown (native->kms);
108
109 G_OBJECT_CLASS (meta_backend_native_parent_class)->dispose (object);
110
111 g_clear_object (&native->kms);
112 g_clear_object (&native->udev);
113 g_clear_object (&native->device_pool);
114 g_clear_pointer (&native->launcher, meta_launcher_free);
115 }
116
117 static ClutterBackend *
meta_backend_native_create_clutter_backend(MetaBackend * backend)118 meta_backend_native_create_clutter_backend (MetaBackend *backend)
119 {
120 return g_object_new (META_TYPE_CLUTTER_BACKEND_NATIVE, NULL);
121 }
122
123 static ClutterSeat *
meta_backend_native_create_default_seat(MetaBackend * backend,GError ** error)124 meta_backend_native_create_default_seat (MetaBackend *backend,
125 GError **error)
126 {
127 MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
128 const char *seat_id;
129 MetaSeatNativeFlag flags;
130
131 seat_id = meta_backend_native_get_seat_id (backend_native);
132
133 if (meta_backend_native_is_headless (backend_native))
134 flags = META_SEAT_NATIVE_FLAG_NO_LIBINPUT;
135 else
136 flags = META_SEAT_NATIVE_FLAG_NONE;
137
138 return CLUTTER_SEAT (g_object_new (META_TYPE_SEAT_NATIVE,
139 "backend", backend,
140 "seat-id", seat_id,
141 "flags", flags,
142 NULL));
143 }
144
145 #ifdef HAVE_REMOTE_DESKTOP
146 static void
maybe_disable_screen_cast_dma_bufs(MetaBackendNative * native)147 maybe_disable_screen_cast_dma_bufs (MetaBackendNative *native)
148 {
149 MetaBackend *backend = META_BACKEND (native);
150 MetaSettings *settings = meta_backend_get_settings (backend);
151 MetaRenderer *renderer = meta_backend_get_renderer (backend);
152 MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
153 MetaScreenCast *screen_cast = meta_backend_get_screen_cast (backend);
154 MetaGpuKms *primary_gpu;
155 MetaKmsDevice *kms_device;
156 const char *driver_name;
157 static const char *enable_dma_buf_drivers[] = {
158 "i915",
159 NULL,
160 };
161
162 primary_gpu = meta_renderer_native_get_primary_gpu (renderer_native);
163 if (!primary_gpu)
164 {
165 g_message ("Disabling DMA buffer screen sharing (surfaceless)");
166 goto disable_dma_bufs;
167 }
168
169 kms_device = meta_gpu_kms_get_kms_device (primary_gpu);
170 driver_name = meta_kms_device_get_driver_name (kms_device);
171
172 if (g_strv_contains (enable_dma_buf_drivers, driver_name))
173 return;
174
175 if (meta_settings_is_experimental_feature_enabled (settings,
176 META_EXPERIMENTAL_FEATURE_DMA_BUF_SCREEN_SHARING))
177 return;
178
179 g_message ("Disabling DMA buffer screen sharing for driver '%s'.",
180 driver_name);
181
182 disable_dma_bufs:
183 meta_screen_cast_disable_dma_bufs (screen_cast);
184 }
185 #endif /* HAVE_REMOTE_DESKTOP */
186
187 static void
update_viewports(MetaBackend * backend)188 update_viewports (MetaBackend *backend)
189 {
190 MetaMonitorManager *monitor_manager =
191 meta_backend_get_monitor_manager (backend);
192 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
193 MetaSeatNative *seat =
194 META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
195 MetaViewportInfo *viewports;
196
197 viewports = meta_monitor_manager_get_viewports (monitor_manager);
198 meta_seat_native_set_viewports (seat, viewports);
199 g_object_unref (viewports);
200 }
201
202 static void
meta_backend_native_post_init(MetaBackend * backend)203 meta_backend_native_post_init (MetaBackend *backend)
204 {
205 MetaSettings *settings = meta_backend_get_settings (backend);
206
207 META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
208
209 if (meta_settings_is_experimental_feature_enabled (settings,
210 META_EXPERIMENTAL_FEATURE_RT_SCHEDULER))
211 {
212 int retval;
213 struct sched_param sp = {
214 .sched_priority = sched_get_priority_min (SCHED_RR)
215 };
216
217 retval = sched_setscheduler (0, SCHED_RR | SCHED_RESET_ON_FORK, &sp);
218
219 if (retval != 0)
220 g_warning ("Failed to set RT scheduler: %m");
221 }
222
223 #ifdef HAVE_REMOTE_DESKTOP
224 maybe_disable_screen_cast_dma_bufs (META_BACKEND_NATIVE (backend));
225 #endif
226
227 update_viewports (backend);
228 }
229
230 static MetaMonitorManager *
meta_backend_native_create_monitor_manager(MetaBackend * backend,GError ** error)231 meta_backend_native_create_monitor_manager (MetaBackend *backend,
232 GError **error)
233 {
234 MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
235 MetaMonitorManager *manager;
236
237 manager = g_initable_new (META_TYPE_MONITOR_MANAGER_NATIVE, NULL, error,
238 "backend", backend,
239 "needs-outputs", !backend_native->is_headless,
240 NULL);
241 if (!manager)
242 return NULL;
243
244 g_signal_connect_swapped (manager, "monitors-changed-internal",
245 G_CALLBACK (update_viewports), backend);
246
247 return manager;
248 }
249
250 static MetaCursorRenderer *
meta_backend_native_get_cursor_renderer(MetaBackend * backend,ClutterInputDevice * device)251 meta_backend_native_get_cursor_renderer (MetaBackend *backend,
252 ClutterInputDevice *device)
253 {
254 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
255 MetaSeatNative *seat_native =
256 META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
257
258 return meta_seat_native_maybe_ensure_cursor_renderer (seat_native, device);
259 }
260
261 static MetaRenderer *
meta_backend_native_create_renderer(MetaBackend * backend,GError ** error)262 meta_backend_native_create_renderer (MetaBackend *backend,
263 GError **error)
264 {
265 MetaBackendNative *native = META_BACKEND_NATIVE (backend);
266 MetaRendererNative *renderer_native;
267
268 renderer_native = meta_renderer_native_new (native, error);
269 if (!renderer_native)
270 return NULL;
271
272 return META_RENDERER (renderer_native);
273 }
274
275 static MetaInputSettings *
meta_backend_native_get_input_settings(MetaBackend * backend)276 meta_backend_native_get_input_settings (MetaBackend *backend)
277 {
278 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
279 MetaSeatNative *seat_native =
280 META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
281
282 return meta_seat_impl_get_input_settings (seat_native->impl);
283 }
284
285 static MetaLogicalMonitor *
meta_backend_native_get_current_logical_monitor(MetaBackend * backend)286 meta_backend_native_get_current_logical_monitor (MetaBackend *backend)
287 {
288 MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
289 MetaMonitorManager *monitor_manager =
290 meta_backend_get_monitor_manager (backend);
291 graphene_point_t point;
292
293 meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
294 return meta_monitor_manager_get_logical_monitor_at (monitor_manager,
295 point.x, point.y);
296 }
297
298 static void
meta_backend_native_set_keymap(MetaBackend * backend,const char * layouts,const char * variants,const char * options)299 meta_backend_native_set_keymap (MetaBackend *backend,
300 const char *layouts,
301 const char *variants,
302 const char *options)
303 {
304 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
305 ClutterSeat *seat;
306
307 seat = clutter_backend_get_default_seat (clutter_backend);
308 meta_seat_native_set_keyboard_map (META_SEAT_NATIVE (seat),
309 layouts, variants, options);
310
311 meta_backend_notify_keymap_changed (backend);
312 }
313
314 static struct xkb_keymap *
meta_backend_native_get_keymap(MetaBackend * backend)315 meta_backend_native_get_keymap (MetaBackend *backend)
316 {
317 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
318 ClutterSeat *seat;
319
320 seat = clutter_backend_get_default_seat (clutter_backend);
321 return meta_seat_native_get_keyboard_map (META_SEAT_NATIVE (seat));
322 }
323
324 static xkb_layout_index_t
meta_backend_native_get_keymap_layout_group(MetaBackend * backend)325 meta_backend_native_get_keymap_layout_group (MetaBackend *backend)
326 {
327 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
328 ClutterSeat *seat;
329
330 seat = clutter_backend_get_default_seat (clutter_backend);
331 return meta_seat_native_get_keyboard_layout_index (META_SEAT_NATIVE (seat));
332 }
333
334 static void
meta_backend_native_lock_layout_group(MetaBackend * backend,guint idx)335 meta_backend_native_lock_layout_group (MetaBackend *backend,
336 guint idx)
337 {
338 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
339 xkb_layout_index_t old_idx;
340 ClutterSeat *seat;
341
342 old_idx = meta_backend_native_get_keymap_layout_group (backend);
343 if (old_idx == idx)
344 return;
345
346 seat = clutter_backend_get_default_seat (clutter_backend);
347 meta_seat_native_set_keyboard_layout_index (META_SEAT_NATIVE (seat), idx);
348 meta_backend_notify_keymap_layout_group_changed (backend, idx);
349 }
350
351 const char *
meta_backend_native_get_seat_id(MetaBackendNative * backend_native)352 meta_backend_native_get_seat_id (MetaBackendNative *backend_native)
353 {
354 if (backend_native->is_headless)
355 return "seat0";
356 else
357 return meta_launcher_get_seat_id (backend_native->launcher);
358 }
359
360 gboolean
meta_backend_native_is_headless(MetaBackendNative * backend_native)361 meta_backend_native_is_headless (MetaBackendNative *backend_native)
362 {
363 return backend_native->is_headless;
364 }
365
366 static void
meta_backend_native_set_pointer_constraint(MetaBackend * backend,MetaPointerConstraint * constraint)367 meta_backend_native_set_pointer_constraint (MetaBackend *backend,
368 MetaPointerConstraint *constraint)
369 {
370 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
371 ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
372 MetaPointerConstraintImpl *constraint_impl = NULL;
373 cairo_region_t *region;
374
375 if (constraint)
376 {
377 region = meta_pointer_constraint_get_region (constraint);
378 constraint_impl = meta_pointer_constraint_impl_native_new (constraint,
379 region);
380 }
381
382 meta_seat_native_set_pointer_constraint (META_SEAT_NATIVE (seat),
383 constraint_impl);
384 }
385
386 static void
meta_backend_native_update_screen_size(MetaBackend * backend,int width,int height)387 meta_backend_native_update_screen_size (MetaBackend *backend,
388 int width, int height)
389 {
390 ClutterActor *stage = meta_backend_get_stage (backend);
391 ClutterStageWindow *stage_window =
392 _clutter_stage_get_window (CLUTTER_STAGE (stage));
393 MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
394
395 meta_stage_native_rebuild_views (stage_native);
396
397 clutter_actor_set_size (stage, width, height);
398 }
399
400 static MetaGpuKms *
create_gpu_from_udev_device(MetaBackendNative * native,GUdevDevice * device,GError ** error)401 create_gpu_from_udev_device (MetaBackendNative *native,
402 GUdevDevice *device,
403 GError **error)
404 {
405 MetaKmsDeviceFlag flags = META_KMS_DEVICE_FLAG_NONE;
406 const char *device_path;
407 MetaKmsDevice *kms_device;
408
409 if (meta_is_udev_device_platform_device (device))
410 flags |= META_KMS_DEVICE_FLAG_PLATFORM_DEVICE;
411
412 if (meta_is_udev_device_boot_vga (device))
413 flags |= META_KMS_DEVICE_FLAG_BOOT_VGA;
414
415 if (meta_is_udev_device_disable_modifiers (device))
416 flags |= META_KMS_DEVICE_FLAG_DISABLE_MODIFIERS;
417
418 if (meta_is_udev_device_preferred_primary (device))
419 flags |= META_KMS_DEVICE_FLAG_PREFERRED_PRIMARY;
420
421 device_path = g_udev_device_get_device_file (device);
422
423 kms_device = meta_kms_create_device (native->kms, device_path, flags,
424 error);
425 if (!kms_device)
426 return NULL;
427
428 return meta_gpu_kms_new (native, kms_device, error);
429 }
430
431 static void
on_udev_device_added(MetaUdev * udev,GUdevDevice * device,MetaBackendNative * native)432 on_udev_device_added (MetaUdev *udev,
433 GUdevDevice *device,
434 MetaBackendNative *native)
435 {
436 MetaBackend *backend = META_BACKEND (native);
437 g_autoptr (GError) error = NULL;
438 const char *device_path;
439 MetaGpuKms *new_gpu_kms;
440 GList *gpus, *l;
441
442 if (!meta_udev_is_drm_device (udev, device))
443 return;
444
445 device_path = g_udev_device_get_device_file (device);
446
447 gpus = meta_backend_get_gpus (backend);
448 for (l = gpus; l; l = l->next)
449 {
450 MetaGpuKms *gpu_kms = l->data;
451
452 if (!g_strcmp0 (device_path, meta_gpu_kms_get_file_path (gpu_kms)))
453 {
454 g_warning ("Failed to hotplug secondary gpu '%s': %s",
455 device_path, "device already present");
456 return;
457 }
458 }
459
460 if (meta_is_udev_device_ignore (device))
461 {
462 g_message ("Ignoring DRM device '%s' (from udev rule)", device_path);
463 return;
464 }
465
466 new_gpu_kms = create_gpu_from_udev_device (native, device, &error);
467 if (!new_gpu_kms)
468 {
469 g_warning ("Failed to hotplug secondary gpu '%s': %s",
470 device_path, error->message);
471 return;
472 }
473
474 meta_backend_add_gpu (backend, META_GPU (new_gpu_kms));
475 }
476
477 static gboolean
init_gpus(MetaBackendNative * native,GError ** error)478 init_gpus (MetaBackendNative *native,
479 GError **error)
480 {
481 MetaBackend *backend = META_BACKEND (native);
482 MetaUdev *udev = meta_backend_native_get_udev (native);
483 GList *devices;
484 GList *l;
485
486 devices = meta_udev_list_drm_devices (udev, error);
487 if (*error)
488 return FALSE;
489
490 for (l = devices; l; l = l->next)
491 {
492 GUdevDevice *device = l->data;
493 MetaGpuKms *gpu_kms;
494 GError *local_error = NULL;
495
496 if (meta_is_udev_device_ignore (device))
497 {
498 g_message ("Ignoring DRM device '%s' (from udev rule)",
499 g_udev_device_get_device_file (device));
500 continue;
501 }
502
503 gpu_kms = create_gpu_from_udev_device (native, device, &local_error);
504
505 if (!gpu_kms)
506 {
507 g_warning ("Failed to open gpu '%s': %s",
508 g_udev_device_get_device_file (device),
509 local_error->message);
510 g_clear_error (&local_error);
511 continue;
512 }
513
514 meta_backend_add_gpu (backend, META_GPU (gpu_kms));
515 }
516
517 g_list_free_full (devices, g_object_unref);
518
519 if (!native->is_headless &&
520 g_list_length (meta_backend_get_gpus (backend)) == 0)
521 {
522 g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
523 "No GPUs found");
524 return FALSE;
525 }
526
527 g_signal_connect_object (native->udev, "device-added",
528 G_CALLBACK (on_udev_device_added), native,
529 0);
530
531 return TRUE;
532 }
533
534 static gboolean
meta_backend_native_initable_init(GInitable * initable,GCancellable * cancellable,GError ** error)535 meta_backend_native_initable_init (GInitable *initable,
536 GCancellable *cancellable,
537 GError **error)
538 {
539 MetaBackendNative *native = META_BACKEND_NATIVE (initable);
540 MetaKmsFlags kms_flags;
541
542 if (!meta_is_stage_views_enabled ())
543 {
544 g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
545 "The native backend requires stage views");
546 return FALSE;
547 }
548
549 if (!native->is_headless)
550 {
551 native->launcher = meta_launcher_new (error);
552 if (!native->launcher)
553 return FALSE;
554 }
555
556 native->device_pool = meta_device_pool_new (native->launcher);
557 native->udev = meta_udev_new (native);
558
559 kms_flags = META_KMS_FLAG_NONE;
560 if (native->is_headless)
561 kms_flags |= META_KMS_FLAG_NO_MODE_SETTING;
562
563 native->kms = meta_kms_new (META_BACKEND (native), kms_flags, error);
564 if (!native->kms)
565 return FALSE;
566
567 if (!init_gpus (native, error))
568 return FALSE;
569
570 return initable_parent_iface->init (initable, cancellable, error);
571 }
572
573 static void
meta_backend_native_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)574 meta_backend_native_set_property (GObject *object,
575 guint prop_id,
576 const GValue *value,
577 GParamSpec *pspec)
578 {
579 MetaBackendNative *backend_native = META_BACKEND_NATIVE (object);
580
581 switch (prop_id)
582 {
583 case PROP_HEADLESS:
584 backend_native->is_headless = g_value_get_boolean (value);
585 break;
586 default:
587 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
588 break;
589 }
590 }
591
592 static void
initable_iface_init(GInitableIface * initable_iface)593 initable_iface_init (GInitableIface *initable_iface)
594 {
595 initable_parent_iface = g_type_interface_peek_parent (initable_iface);
596
597 initable_iface->init = meta_backend_native_initable_init;
598 }
599
600 static void
meta_backend_native_class_init(MetaBackendNativeClass * klass)601 meta_backend_native_class_init (MetaBackendNativeClass *klass)
602 {
603 MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
604 GObjectClass *object_class = G_OBJECT_CLASS (klass);
605
606 object_class->set_property = meta_backend_native_set_property;
607 object_class->dispose = meta_backend_native_dispose;
608
609 backend_class->create_clutter_backend = meta_backend_native_create_clutter_backend;
610 backend_class->create_default_seat = meta_backend_native_create_default_seat;
611
612 backend_class->post_init = meta_backend_native_post_init;
613
614 backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
615 backend_class->get_cursor_renderer = meta_backend_native_get_cursor_renderer;
616 backend_class->create_renderer = meta_backend_native_create_renderer;
617 backend_class->get_input_settings = meta_backend_native_get_input_settings;
618
619 backend_class->get_current_logical_monitor = meta_backend_native_get_current_logical_monitor;
620
621 backend_class->set_keymap = meta_backend_native_set_keymap;
622 backend_class->get_keymap = meta_backend_native_get_keymap;
623 backend_class->get_keymap_layout_group = meta_backend_native_get_keymap_layout_group;
624 backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
625 backend_class->update_screen_size = meta_backend_native_update_screen_size;
626
627 backend_class->set_pointer_constraint = meta_backend_native_set_pointer_constraint;
628
629 obj_props[PROP_HEADLESS] =
630 g_param_spec_boolean ("headless",
631 "headless",
632 "Headless",
633 FALSE,
634 G_PARAM_WRITABLE |
635 G_PARAM_CONSTRUCT_ONLY |
636 G_PARAM_STATIC_STRINGS);
637 g_object_class_install_properties (object_class, N_PROPS, obj_props);
638 }
639
640 static void
meta_backend_native_init(MetaBackendNative * native)641 meta_backend_native_init (MetaBackendNative *native)
642 {
643 }
644
645 MetaLauncher *
meta_backend_native_get_launcher(MetaBackendNative * native)646 meta_backend_native_get_launcher (MetaBackendNative *native)
647 {
648 return native->launcher;
649 }
650
651 MetaDevicePool *
meta_backend_native_get_device_pool(MetaBackendNative * native)652 meta_backend_native_get_device_pool (MetaBackendNative *native)
653 {
654 return native->device_pool;
655 }
656
657 MetaUdev *
meta_backend_native_get_udev(MetaBackendNative * native)658 meta_backend_native_get_udev (MetaBackendNative *native)
659 {
660 return native->udev;
661 }
662
663 MetaKms *
meta_backend_native_get_kms(MetaBackendNative * native)664 meta_backend_native_get_kms (MetaBackendNative *native)
665 {
666 return native->kms;
667 }
668
669 gboolean
meta_activate_vt(int vt,GError ** error)670 meta_activate_vt (int vt, GError **error)
671 {
672 MetaBackend *backend = meta_get_backend ();
673 MetaBackendNative *native = META_BACKEND_NATIVE (backend);
674 MetaLauncher *launcher = meta_backend_native_get_launcher (native);
675
676 if (native->is_headless)
677 {
678 g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
679 "Can't switch VT while headless");
680 return FALSE;
681 }
682
683 return meta_launcher_activate_vt (launcher, vt, error);
684 }
685
686 void
meta_backend_native_pause(MetaBackendNative * native)687 meta_backend_native_pause (MetaBackendNative *native)
688 {
689 MetaBackend *backend = META_BACKEND (native);
690 MetaMonitorManager *monitor_manager =
691 meta_backend_get_monitor_manager (backend);
692 MetaMonitorManagerNative *monitor_manager_native =
693 META_MONITOR_MANAGER_NATIVE (monitor_manager);
694 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
695 MetaSeatNative *seat =
696 META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
697 MetaRenderer *renderer = meta_backend_get_renderer (backend);
698
699 COGL_TRACE_BEGIN_SCOPED (MetaBackendNativePause,
700 "Backend (pause)");
701
702 meta_seat_native_release_devices (seat);
703 meta_renderer_pause (renderer);
704 meta_udev_pause (native->udev);
705
706 meta_monitor_manager_native_pause (monitor_manager_native);
707 }
708
meta_backend_native_resume(MetaBackendNative * native)709 void meta_backend_native_resume (MetaBackendNative *native)
710 {
711 MetaBackend *backend = META_BACKEND (native);
712 ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
713 MetaMonitorManager *monitor_manager =
714 meta_backend_get_monitor_manager (backend);
715 MetaMonitorManagerNative *monitor_manager_native =
716 META_MONITOR_MANAGER_NATIVE (monitor_manager);
717 ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
718 MetaSeatNative *seat =
719 META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
720 MetaRenderer *renderer = meta_backend_get_renderer (backend);
721 MetaIdleManager *idle_manager;
722 MetaInputSettings *input_settings;
723
724 COGL_TRACE_BEGIN_SCOPED (MetaBackendNativeResume,
725 "Backend (resume)");
726
727 meta_monitor_manager_native_resume (monitor_manager_native);
728 meta_udev_resume (native->udev);
729 meta_kms_resume (native->kms);
730
731 meta_seat_native_reclaim_devices (seat);
732 meta_renderer_resume (renderer);
733
734 clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
735
736 idle_manager = meta_backend_get_idle_manager (backend);
737 meta_idle_manager_reset_idle_time (idle_manager);
738
739 input_settings = meta_backend_get_input_settings (backend);
740 meta_input_settings_maybe_restore_numlock_state (input_settings);
741
742 clutter_seat_ensure_a11y_state (CLUTTER_SEAT (seat));
743 }
744