forked from AuroraMiddleware/gtk
5f48934943
Until we figure out where we want to go with settings under Wayland, this makes GTK+ applications a lot easier to deal with under Wayland. Note that we are careful to deal with the absence of schemas, so this does not introduce a dependency on GNOME settings.
779 lines
22 KiB
C
779 lines
22 KiB
C
/*
|
|
* Copyright © 2010 Intel Corporation
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <glib.h>
|
|
#include <gio/gio.h>
|
|
#include "gdkscreenprivate.h"
|
|
#include "gdkvisualprivate.h"
|
|
#include "gdkdisplay.h"
|
|
#include "gdkdisplay-wayland.h"
|
|
#include "gdkwayland.h"
|
|
#include "gdkprivate-wayland.h"
|
|
|
|
typedef struct _GdkWaylandScreen GdkWaylandScreen;
|
|
typedef struct _GdkWaylandScreenClass GdkWaylandScreenClass;
|
|
|
|
#define GDK_TYPE_WAYLAND_SCREEN (_gdk_wayland_screen_get_type ())
|
|
#define GDK_WAYLAND_SCREEN(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_SCREEN, GdkWaylandScreen))
|
|
#define GDK_WAYLAND_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_SCREEN, GdkWaylandScreenClass))
|
|
#define GDK_IS_WAYLAND_SCREEN(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_SCREEN))
|
|
#define GDK_IS_WAYLAND_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_SCREEN))
|
|
#define GDK_WAYLAND_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_SCREEN, GdkWaylandScreenClass))
|
|
|
|
typedef struct _GdkWaylandMonitor GdkWaylandMonitor;
|
|
|
|
struct _GdkWaylandScreen
|
|
{
|
|
GdkScreen parent_instance;
|
|
|
|
GdkDisplay *display;
|
|
GdkWindow *root_window;
|
|
|
|
int width, height;
|
|
int width_mm, height_mm;
|
|
|
|
/* Visual Part */
|
|
GdkVisual *visual;
|
|
|
|
/* Xinerama/RandR 1.2 */
|
|
GPtrArray *monitors;
|
|
gint primary_monitor;
|
|
|
|
GHashTable *settings;
|
|
};
|
|
|
|
struct _GdkWaylandScreenClass
|
|
{
|
|
GdkScreenClass parent_class;
|
|
|
|
void (* window_manager_changed) (GdkWaylandScreen *screen_wayland);
|
|
};
|
|
|
|
struct _GdkWaylandMonitor
|
|
{
|
|
struct wl_output *output;
|
|
GdkRectangle geometry;
|
|
int width_mm;
|
|
int height_mm;
|
|
char * output_name;
|
|
char * manufacturer;
|
|
};
|
|
|
|
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
|
|
|
|
static void
|
|
free_monitor (gpointer data)
|
|
{
|
|
GdkWaylandMonitor *monitor = data;
|
|
|
|
if (monitor == NULL)
|
|
return;
|
|
|
|
g_free (monitor->output_name);
|
|
g_free (monitor->manufacturer);
|
|
|
|
g_free (monitor);
|
|
}
|
|
|
|
static void
|
|
deinit_multihead (GdkScreen *screen)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
|
|
g_ptr_array_free (screen_wayland->monitors, TRUE);
|
|
|
|
screen_wayland->monitors = NULL;
|
|
}
|
|
|
|
static void
|
|
init_multihead (GdkScreen *screen)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
|
|
screen_wayland->monitors = g_ptr_array_new_with_free_func (free_monitor);
|
|
screen_wayland->primary_monitor = 0;
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_screen_dispose (GObject *object)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
|
|
|
|
if (screen_wayland->root_window)
|
|
_gdk_window_destroy (screen_wayland->root_window, TRUE);
|
|
|
|
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_screen_finalize (GObject *object)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
|
|
|
|
if (screen_wayland->root_window)
|
|
g_object_unref (screen_wayland->root_window);
|
|
|
|
g_object_unref (screen_wayland->visual);
|
|
|
|
deinit_multihead (GDK_SCREEN (object));
|
|
|
|
g_hash_table_destroy (screen_wayland->settings);
|
|
|
|
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->finalize (object);
|
|
}
|
|
|
|
static GdkDisplay *
|
|
gdk_wayland_screen_get_display (GdkScreen *screen)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->display;
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_get_width (GdkScreen *screen)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->width;
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_get_height (GdkScreen *screen)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->height;
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_get_width_mm (GdkScreen *screen)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->width_mm;
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_get_height_mm (GdkScreen *screen)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->height_mm;
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_get_number (GdkScreen *screen)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static GdkWindow *
|
|
gdk_wayland_screen_get_root_window (GdkScreen *screen)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->root_window;
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_get_n_monitors (GdkScreen *screen)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->monitors->len;
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_get_primary_monitor (GdkScreen *screen)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->primary_monitor;
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_get_monitor_width_mm (GdkScreen *screen,
|
|
gint monitor_num)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
GdkWaylandMonitor *monitor = g_ptr_array_index(screen_wayland->monitors, monitor_num);
|
|
|
|
return monitor->width_mm;
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_get_monitor_height_mm (GdkScreen *screen,
|
|
gint monitor_num)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
GdkWaylandMonitor *monitor = g_ptr_array_index(screen_wayland->monitors, monitor_num);
|
|
|
|
return monitor->height_mm;
|
|
}
|
|
|
|
static gchar *
|
|
gdk_wayland_screen_get_monitor_plug_name (GdkScreen *screen,
|
|
gint monitor_num)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
GdkWaylandMonitor *monitor = g_ptr_array_index(screen_wayland->monitors, monitor_num);
|
|
|
|
return g_strdup (monitor->output_name);
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_screen_get_monitor_geometry (GdkScreen *screen,
|
|
gint monitor_num,
|
|
GdkRectangle *dest)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
GdkWaylandMonitor *monitor = g_ptr_array_index(screen_wayland->monitors, monitor_num);
|
|
|
|
if (dest)
|
|
*dest = monitor->geometry;
|
|
}
|
|
|
|
static GdkVisual *
|
|
gdk_wayland_screen_get_system_visual (GdkScreen * screen)
|
|
{
|
|
return (GdkVisual *) GDK_WAYLAND_SCREEN (screen)->visual;
|
|
}
|
|
|
|
static GdkVisual *
|
|
gdk_wayland_screen_get_rgba_visual (GdkScreen *screen)
|
|
{
|
|
return (GdkVisual *) GDK_WAYLAND_SCREEN (screen)->visual;
|
|
}
|
|
|
|
static gboolean
|
|
gdk_wayland_screen_is_composited (GdkScreen *screen)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
static gchar *
|
|
gdk_wayland_screen_make_display_name (GdkScreen *screen)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static GdkWindow *
|
|
gdk_wayland_screen_get_active_window (GdkScreen *screen)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static GList *
|
|
gdk_wayland_screen_get_window_stack (GdkScreen *screen)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_screen_broadcast_client_message (GdkScreen *screen,
|
|
GdkEvent *event)
|
|
{
|
|
}
|
|
|
|
typedef struct _TranslationEntry TranslationEntry;
|
|
struct _TranslationEntry {
|
|
const gchar *schema;
|
|
const gchar *key;
|
|
const gchar *setting;
|
|
GType type;
|
|
const gchar *default_string;
|
|
gint default_int;
|
|
};
|
|
|
|
static TranslationEntry translations[] = {
|
|
{ "org.gnome.desktop.interface", "gtk-theme", "gtk-theme-name" , G_TYPE_STRING, "Adwaita", 0 },
|
|
{ "org.gnome.desktop.interface", "icon-theme", "gtk-icon-theme-name", G_TYPE_STRING, "gnome", 0 },
|
|
{ "org.gnome.desktop.interface", "cursor-theme", "gtk-cursor-theme-name", G_TYPE_STRING, "Adwaita", 0 },
|
|
{ "org.gnome.desktop.interface", "font-name", "gtk-font-name", G_TYPE_STRING, "Cantarell 11", 0 },
|
|
{ "org.gnome.desktop.interface", "cursor-blink", "gtk-cursor-blink", G_TYPE_BOOLEAN, NULL, 1 },
|
|
{ "org.gnome.desktop.interface", "cursor-blink-time", "gtk-cursor-blink-time", G_TYPE_INT, NULL, 1200 },
|
|
{ "org.gnome.desktop.interface", "cursor-blink-timeout", "gtk-cursor-blink-timeout", G_TYPE_INT, NULL, 3600 },
|
|
{ "org.gnome.desktop.interface", "menus-have-icons", "gtk-menu-images", G_TYPE_BOOLEAN, NULL, 0 },
|
|
{ "org.gnome.desktop.interface", "buttons-have-icons", "gtk-button-images", G_TYPE_BOOLEAN, NULL, 0 },
|
|
{ "org.gnome.desktop.interface", "gtk-im-module", "gtk-im-module", G_TYPE_STRING, "simple", 0 },
|
|
{ "org.gnome.desktop.interface", "enable-animations", "gtk-enable-animations", G_TYPE_BOOLEAN, NULL, 1 },
|
|
{ "org.gnome.desktop.interface", "show-input-method-menu", "gtk-show-input-method-menu", G_TYPE_BOOLEAN, NULL, 0 },
|
|
{ "org.gnome.desktop.interface", "show-unicode-menu", "gtk-show-unicode-menu", G_TYPE_BOOLEAN, NULL, 0 },
|
|
{ "org.gnome.desktop.interface", "automatic-mnemonics", "gtk-auto-mnemonics", G_TYPE_BOOLEAN, NULL, 1 },
|
|
{ "org.gnome.settings-daemon.peripherals.mouse", "double-click", "gtk-double-click-time", G_TYPE_INT, NULL, 250 },
|
|
{ "org.gnome.settings-daemon.peripherals.mouse", "drag-threshold", "gtk-dnd-drag-threshold", G_TYPE_INT, NULL, 8 },
|
|
{ "org.gnome.desktop.sound", "theme-name", "gtk-sound-theme-name", G_TYPE_STRING, "freedesktop", 0 },
|
|
{ "org.gnome.desktop.sound", "event-sounds", "gtk-enable-event-sounds", G_TYPE_BOOLEAN, NULL, 1 },
|
|
{ "org.gnome.desktop.sound", "input-feedback-sounds", "gtk-enable-input-feedback-sounds", G_TYPE_BOOLEAN, NULL, 0 }
|
|
};
|
|
|
|
static TranslationEntry *
|
|
find_translation_entry_by_key (GSettings *settings, const gchar *key)
|
|
{
|
|
guint i;
|
|
gchar *schema;
|
|
|
|
g_object_get (settings, "schema", &schema, NULL);
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (translations); i++)
|
|
{
|
|
if (g_str_equal (schema, translations[i].schema) &&
|
|
g_str_equal (key, translations[i].key))
|
|
{
|
|
g_free (schema);
|
|
return &translations[i];
|
|
}
|
|
}
|
|
|
|
g_free (schema);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static TranslationEntry *
|
|
find_translation_entry_by_setting (const gchar *setting)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (translations); i++)
|
|
{
|
|
if (g_str_equal (setting, translations[i].setting))
|
|
return &translations[i];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
settings_changed (GSettings *settings,
|
|
const gchar *key,
|
|
GdkScreen *screen)
|
|
{
|
|
TranslationEntry *entry;
|
|
|
|
entry = find_translation_entry_by_key (settings, key);
|
|
|
|
if (entry != NULL)
|
|
{
|
|
GdkEvent event;
|
|
event.type = GDK_SETTING;
|
|
event.setting.window = gdk_screen_get_root_window (screen);
|
|
event.setting.send_event = FALSE;
|
|
event.setting.action = GDK_SETTING_ACTION_CHANGED;
|
|
event.setting.name = (gchar *)entry->setting;
|
|
gdk_event_put (&event);
|
|
}
|
|
}
|
|
|
|
static void
|
|
init_settings (GdkScreen *screen)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
GSettingsSchemaSource *source;
|
|
GSettingsSchema *schema;
|
|
GSettings *settings;
|
|
gint i;
|
|
|
|
screen_wayland->settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
|
|
|
|
source = g_settings_schema_source_get_default ();
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (translations); i++)
|
|
{
|
|
if (g_hash_table_lookup (screen_wayland->settings, (gpointer)translations[i].schema) != NULL)
|
|
continue;
|
|
|
|
schema = g_settings_schema_source_lookup (source, translations[i].schema, FALSE);
|
|
if (schema != NULL)
|
|
{
|
|
settings = g_settings_new_full (schema, NULL, NULL);
|
|
g_signal_connect (settings, "changed",
|
|
G_CALLBACK (settings_changed), screen);
|
|
g_hash_table_insert (screen_wayland->settings, (gpointer)translations[i].schema, settings);
|
|
g_settings_schema_unref (schema);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
set_value_from_entry (GdkScreen *screen,
|
|
TranslationEntry *entry,
|
|
GValue *value)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
GSettings *settings;
|
|
|
|
settings = (GSettings *)g_hash_table_lookup (screen_wayland->settings, entry->schema);
|
|
if (settings != NULL)
|
|
{
|
|
gchar *s;
|
|
switch (entry->type)
|
|
{
|
|
case G_TYPE_STRING:
|
|
s = g_settings_get_string (settings, entry->key);
|
|
g_value_set_string (value, s);
|
|
g_free (s);
|
|
break;
|
|
case G_TYPE_INT:
|
|
g_value_set_int (value, g_settings_get_int (settings, entry->key));
|
|
break;
|
|
case G_TYPE_BOOLEAN:
|
|
g_value_set_boolean (value, g_settings_get_boolean (settings, entry->key));
|
|
break;
|
|
default:
|
|
g_assert_not_reached ();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (entry->type)
|
|
{
|
|
case G_TYPE_STRING:
|
|
g_value_set_static_string (value, entry->default_string);
|
|
break;
|
|
case G_TYPE_INT:
|
|
g_value_set_int (value, entry->default_int);
|
|
break;
|
|
case G_TYPE_BOOLEAN:
|
|
g_value_set_boolean (value, entry->default_int);
|
|
break;
|
|
default:
|
|
g_assert_not_reached ();
|
|
}
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
gdk_wayland_screen_get_setting (GdkScreen *screen,
|
|
const gchar *name,
|
|
GValue *value)
|
|
{
|
|
TranslationEntry *entry;
|
|
|
|
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
|
|
|
|
entry = find_translation_entry_by_setting (name);
|
|
if (entry != NULL)
|
|
{
|
|
set_value_from_entry (screen, entry, value);
|
|
return TRUE;
|
|
}
|
|
|
|
if (strcmp ("gtk-double-click-time", name) == 0)
|
|
{
|
|
gint i = 250;
|
|
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
|
|
g_value_set_int (value, i);
|
|
return TRUE;
|
|
}
|
|
else if (strcmp ("gtk-double-click-distance", name) == 0)
|
|
{
|
|
gint i = 5;
|
|
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
|
|
g_value_set_int (value, i);
|
|
return TRUE;
|
|
}
|
|
else if (strcmp ("gtk-dnd-drag-threshold", name) == 0)
|
|
{
|
|
gint i = 8;
|
|
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
|
|
g_value_set_int (value, i);
|
|
return TRUE;
|
|
}
|
|
else if (strcmp ("gtk-split-cursor", name) == 0)
|
|
{
|
|
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : FALSE\n", name));
|
|
g_value_set_boolean (value, FALSE);
|
|
return TRUE;
|
|
}
|
|
else if (strcmp ("gtk-alternative-button-order", name) == 0)
|
|
{
|
|
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
|
|
g_value_set_boolean (value, FALSE);
|
|
return TRUE;
|
|
}
|
|
else if (strcmp ("gtk-alternative-sort-arrows", name) == 0)
|
|
{
|
|
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
|
|
g_value_set_boolean (value, FALSE);
|
|
return TRUE;
|
|
}
|
|
else if (strcmp ("gtk-xft-dpi", name) == 0)
|
|
{
|
|
gint i = 96*1024;
|
|
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
|
|
g_value_set_int (value, i);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
typedef struct _GdkWaylandVisual GdkWaylandVisual;
|
|
typedef struct _GdkWaylandVisualClass GdkWaylandVisualClass;
|
|
|
|
struct _GdkWaylandVisual
|
|
{
|
|
GdkVisual visual;
|
|
};
|
|
|
|
struct _GdkWaylandVisualClass
|
|
{
|
|
GdkVisualClass parent_class;
|
|
};
|
|
|
|
G_DEFINE_TYPE (GdkWaylandVisual, _gdk_wayland_visual, GDK_TYPE_VISUAL)
|
|
|
|
static void
|
|
_gdk_wayland_visual_class_init (GdkWaylandVisualClass *klass)
|
|
{
|
|
}
|
|
|
|
static void
|
|
_gdk_wayland_visual_init (GdkWaylandVisual *visual)
|
|
{
|
|
}
|
|
|
|
static gint
|
|
gdk_wayland_screen_visual_get_best_depth (GdkScreen *screen)
|
|
{
|
|
return 32;
|
|
}
|
|
|
|
static GdkVisualType
|
|
gdk_wayland_screen_visual_get_best_type (GdkScreen *screen)
|
|
{
|
|
return GDK_VISUAL_TRUE_COLOR;
|
|
}
|
|
|
|
static GdkVisual*
|
|
gdk_wayland_screen_visual_get_best (GdkScreen *screen)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->visual;
|
|
}
|
|
|
|
static GdkVisual*
|
|
gdk_wayland_screen_visual_get_best_with_depth (GdkScreen *screen,
|
|
gint depth)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->visual;
|
|
}
|
|
|
|
static GdkVisual*
|
|
gdk_wayland_screen_visual_get_best_with_type (GdkScreen *screen,
|
|
GdkVisualType visual_type)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->visual;
|
|
}
|
|
|
|
static GdkVisual*
|
|
gdk_wayland_screen_visual_get_best_with_both (GdkScreen *screen,
|
|
gint depth,
|
|
GdkVisualType visual_type)
|
|
{
|
|
return GDK_WAYLAND_SCREEN (screen)->visual;
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_screen_query_depths (GdkScreen *screen,
|
|
gint **depths,
|
|
gint *count)
|
|
{
|
|
static gint static_depths[] = { 32 };
|
|
|
|
*count = G_N_ELEMENTS(static_depths);
|
|
*depths = static_depths;
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_screen_query_visual_types (GdkScreen *screen,
|
|
GdkVisualType **visual_types,
|
|
gint *count)
|
|
{
|
|
static GdkVisualType static_visual_types[] = { GDK_VISUAL_TRUE_COLOR };
|
|
|
|
*count = G_N_ELEMENTS(static_visual_types);
|
|
*visual_types = static_visual_types;
|
|
}
|
|
|
|
static GList *
|
|
gdk_wayland_screen_list_visuals (GdkScreen *screen)
|
|
{
|
|
GList *list;
|
|
GdkWaylandScreen *screen_wayland;
|
|
|
|
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
|
|
screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
|
|
list = g_list_append (NULL, screen_wayland->visual);
|
|
|
|
return list;
|
|
}
|
|
|
|
#define GDK_TYPE_WAYLAND_VISUAL (_gdk_wayland_visual_get_type ())
|
|
#define GDK_WAYLAND_VISUAL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_VISUAL, GdkWaylandVisual))
|
|
|
|
static GdkVisual *
|
|
gdk_wayland_visual_new (GdkScreen *screen)
|
|
{
|
|
GdkVisual *visual;
|
|
|
|
visual = g_object_new (GDK_TYPE_WAYLAND_VISUAL, NULL);
|
|
visual->screen = GDK_SCREEN (screen);
|
|
visual->type = GDK_VISUAL_TRUE_COLOR;
|
|
visual->depth = 32;
|
|
|
|
return visual;
|
|
}
|
|
|
|
GdkScreen *
|
|
_gdk_wayland_screen_new (GdkDisplay *display)
|
|
{
|
|
GdkScreen *screen;
|
|
GdkWaylandScreen *screen_wayland;
|
|
|
|
screen = g_object_new (GDK_TYPE_WAYLAND_SCREEN, NULL);
|
|
|
|
screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
screen_wayland->display = display;
|
|
screen_wayland->width = 8192;
|
|
screen_wayland->height = 8192;
|
|
|
|
screen_wayland->visual = gdk_wayland_visual_new (screen);
|
|
|
|
screen_wayland->root_window =
|
|
_gdk_wayland_screen_create_root_window (screen,
|
|
screen_wayland->width,
|
|
screen_wayland->height);
|
|
|
|
init_multihead (screen);
|
|
init_settings (screen);
|
|
|
|
return screen;
|
|
}
|
|
|
|
static void
|
|
_gdk_wayland_screen_class_init (GdkWaylandScreenClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass);
|
|
|
|
object_class->dispose = gdk_wayland_screen_dispose;
|
|
object_class->finalize = gdk_wayland_screen_finalize;
|
|
|
|
screen_class->get_display = gdk_wayland_screen_get_display;
|
|
screen_class->get_width = gdk_wayland_screen_get_width;
|
|
screen_class->get_height = gdk_wayland_screen_get_height;
|
|
screen_class->get_width_mm = gdk_wayland_screen_get_width_mm;
|
|
screen_class->get_height_mm = gdk_wayland_screen_get_height_mm;
|
|
screen_class->get_number = gdk_wayland_screen_get_number;
|
|
screen_class->get_root_window = gdk_wayland_screen_get_root_window;
|
|
screen_class->get_n_monitors = gdk_wayland_screen_get_n_monitors;
|
|
screen_class->get_primary_monitor = gdk_wayland_screen_get_primary_monitor;
|
|
screen_class->get_monitor_width_mm = gdk_wayland_screen_get_monitor_width_mm;
|
|
screen_class->get_monitor_height_mm = gdk_wayland_screen_get_monitor_height_mm;
|
|
screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name;
|
|
screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
|
|
screen_class->get_monitor_workarea = gdk_wayland_screen_get_monitor_geometry;
|
|
screen_class->get_system_visual = gdk_wayland_screen_get_system_visual;
|
|
screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
|
|
screen_class->is_composited = gdk_wayland_screen_is_composited;
|
|
screen_class->make_display_name = gdk_wayland_screen_make_display_name;
|
|
screen_class->get_active_window = gdk_wayland_screen_get_active_window;
|
|
screen_class->get_window_stack = gdk_wayland_screen_get_window_stack;
|
|
screen_class->broadcast_client_message = gdk_wayland_screen_broadcast_client_message;
|
|
screen_class->get_setting = gdk_wayland_screen_get_setting;
|
|
screen_class->visual_get_best_depth = gdk_wayland_screen_visual_get_best_depth;
|
|
screen_class->visual_get_best_type = gdk_wayland_screen_visual_get_best_type;
|
|
screen_class->visual_get_best = gdk_wayland_screen_visual_get_best;
|
|
screen_class->visual_get_best_with_depth = gdk_wayland_screen_visual_get_best_with_depth;
|
|
screen_class->visual_get_best_with_type = gdk_wayland_screen_visual_get_best_with_type;
|
|
screen_class->visual_get_best_with_both = gdk_wayland_screen_visual_get_best_with_both;
|
|
screen_class->query_depths = gdk_wayland_screen_query_depths;
|
|
screen_class->query_visual_types = gdk_wayland_screen_query_visual_types;
|
|
screen_class->list_visuals = gdk_wayland_screen_list_visuals;
|
|
}
|
|
|
|
static void
|
|
_gdk_wayland_screen_init (GdkWaylandScreen *screen_wayland)
|
|
{
|
|
}
|
|
|
|
static void
|
|
output_handle_geometry(void *data,
|
|
struct wl_output *wl_output,
|
|
int x, int y, int physical_width, int physical_height,
|
|
int subpixel, const char *make, const char *model,
|
|
int32_t transform)
|
|
{
|
|
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
|
|
|
monitor->geometry.x = x;
|
|
monitor->geometry.y = y;
|
|
|
|
monitor->width_mm = physical_width;
|
|
monitor->height_mm = physical_height;
|
|
|
|
monitor->manufacturer = g_strdup (make);
|
|
monitor->output_name = g_strdup (model);
|
|
}
|
|
|
|
static void
|
|
output_handle_mode(void *data,
|
|
struct wl_output *wl_output,
|
|
uint32_t flags,
|
|
int width,
|
|
int height,
|
|
int refresh)
|
|
{
|
|
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
|
|
|
if ((flags & WL_OUTPUT_MODE_CURRENT) == 0)
|
|
return;
|
|
|
|
monitor->geometry.width = width;
|
|
monitor->geometry.height = height;
|
|
}
|
|
|
|
static const struct wl_output_listener output_listener =
|
|
{
|
|
output_handle_geometry,
|
|
output_handle_mode
|
|
};
|
|
|
|
void
|
|
_gdk_wayland_screen_add_output (GdkScreen *screen,
|
|
struct wl_output *output)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
GdkWaylandMonitor *monitor = g_new0(GdkWaylandMonitor, 1);
|
|
|
|
monitor->output = output;
|
|
g_ptr_array_add(screen_wayland->monitors, monitor);
|
|
|
|
wl_output_add_listener(output, &output_listener, monitor);
|
|
}
|
|
|
|
void
|
|
_gdk_wayland_screen_remove_output_by_id (GdkScreen *screen,
|
|
guint32 id)
|
|
{
|
|
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
|
int i;
|
|
|
|
for (i = 0; i < screen_wayland->monitors->len; i++)
|
|
{
|
|
GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
|
|
|
|
if (wl_proxy_get_id ((struct wl_proxy *)monitor->output) == id)
|
|
{
|
|
g_ptr_array_remove (screen_wayland->monitors, monitor);
|
|
break;
|
|
}
|
|
}
|
|
}
|