1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "WidgetUtilsGtk.h"
7 
8 #include "mozilla/UniquePtr.h"
9 #include "nsReadableUtils.h"
10 #include "nsWindow.h"
11 
12 #include <gtk/gtk.h>
13 #include <dlfcn.h>
14 #include <glib.h>
15 
16 namespace mozilla::widget {
17 
IsTouchDeviceSupportPresent()18 int32_t WidgetUtilsGTK::IsTouchDeviceSupportPresent() {
19   int32_t result = 0;
20   GdkDisplay* display = gdk_display_get_default();
21   if (!display) {
22     return 0;
23   }
24 
25   GdkDeviceManager* manager = gdk_display_get_device_manager(display);
26   if (!manager) {
27     return 0;
28   }
29 
30   GList* devices =
31       gdk_device_manager_list_devices(manager, GDK_DEVICE_TYPE_SLAVE);
32   GList* list = devices;
33 
34   while (devices) {
35     GdkDevice* device = static_cast<GdkDevice*>(devices->data);
36     if (gdk_device_get_source(device) == GDK_SOURCE_TOUCHSCREEN) {
37       result = 1;
38       break;
39     }
40     devices = devices->next;
41   }
42 
43   if (list) {
44     g_list_free(list);
45   }
46 
47   return result;
48 }
49 
IsMainWindowTransparent()50 bool IsMainWindowTransparent() {
51   return nsWindow::IsToplevelWindowTransparent();
52 }
53 
54 // We avoid linking gdk_*_display_get_type directly in order to avoid a runtime
55 // dependency on GTK built with both backends. Other X11- and Wayland-specific
56 // functions get stubbed out by libmozgtk and crash when called, but those
57 // should only be called when the matching backend is already in use.
58 
GdkIsWaylandDisplay(GdkDisplay * display)59 bool GdkIsWaylandDisplay(GdkDisplay* display) {
60   static auto sGdkWaylandDisplayGetType =
61       (GType(*)())dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_type");
62   return sGdkWaylandDisplayGetType &&
63          G_TYPE_CHECK_INSTANCE_TYPE(display, sGdkWaylandDisplayGetType());
64 }
65 
GdkIsX11Display(GdkDisplay * display)66 bool GdkIsX11Display(GdkDisplay* display) {
67   static auto sGdkX11DisplayGetType =
68       (GType(*)())dlsym(RTLD_DEFAULT, "gdk_x11_display_get_type");
69   return sGdkX11DisplayGetType &&
70          G_TYPE_CHECK_INSTANCE_TYPE(display, sGdkX11DisplayGetType());
71 }
72 
GdkIsWaylandDisplay()73 bool GdkIsWaylandDisplay() {
74   static bool isWaylandDisplay =
75       gdk_display_get_default() ? GdkIsWaylandDisplay(gdk_display_get_default())
76                                 : false;
77   return isWaylandDisplay;
78 }
79 
GdkIsX11Display()80 bool GdkIsX11Display() {
81   static bool isX11Display = gdk_display_get_default()
82                                  ? GdkIsX11Display(gdk_display_get_default())
83                                  : false;
84   return isX11Display;
85 }
86 
ParseTextURIList(const nsACString & aData)87 nsTArray<nsCString> ParseTextURIList(const nsACString& aData) {
88   UniquePtr<char[]> data(ToNewCString(aData));
89   gchar** uris = g_uri_list_extract_uris(data.get());
90 
91   nsTArray<nsCString> result;
92   for (size_t i = 0; i < g_strv_length(uris); i++) {
93     result.AppendElement(nsCString(uris[i]));
94   }
95 
96   g_strfreev(uris);
97   return result;
98 }
99 
100 }  // namespace mozilla::widget
101