gtk2/gdk/wayland/gdkscreen-wayland.c

617 lines
17 KiB
C
Raw Normal View History

2010-12-18 20:38:49 +00:00
/*
* 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
2012-02-27 13:01:10 +00:00
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
2010-12-18 20:38:49 +00:00
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <glib.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;
2010-12-18 20:38:49 +00:00
#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))
2010-12-18 20:38:49 +00:00
typedef struct _GdkWaylandMonitor GdkWaylandMonitor;
struct _GdkWaylandScreen
2010-12-18 20:38:49 +00:00
{
GdkScreen parent_instance;
GdkDisplay *display;
GdkWindow *root_window;
int width, height;
int width_mm, height_mm;
/* Visual Part */
2011-11-30 15:21:27 +00:00
GdkVisual *visual;
2010-12-18 20:38:49 +00:00
/* Xinerama/RandR 1.2 */
GPtrArray *monitors;
gint primary_monitor;
2010-12-18 20:38:49 +00:00
};
struct _GdkWaylandScreenClass
2010-12-18 20:38:49 +00:00
{
GdkScreenClass parent_class;
void (* window_manager_changed) (GdkWaylandScreen *screen_wayland);
2010-12-18 20:38:49 +00:00
};
struct _GdkWaylandMonitor
{
struct wl_output *output;
2010-12-18 20:38:49 +00:00
GdkRectangle geometry;
int width_mm;
int height_mm;
char * output_name;
char * manufacturer;
};
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
2010-12-18 20:38:49 +00:00
static void
free_monitor (gpointer data)
2010-12-18 20:38:49 +00:00
{
GdkWaylandMonitor *monitor = data;
2010-12-18 20:38:49 +00:00
if (monitor == NULL)
return;
2010-12-18 20:38:49 +00:00
g_free (monitor->output_name);
g_free (monitor->manufacturer);
2010-12-18 20:38:49 +00:00
g_free (monitor);
2010-12-18 20:38:49 +00:00
}
static void
deinit_multihead (GdkScreen *screen)
{
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
2010-12-18 20:38:49 +00:00
g_ptr_array_free (screen_wayland->monitors, TRUE);
2010-12-18 20:38:49 +00:00
screen_wayland->monitors = NULL;
}
static void
init_multihead (GdkScreen *screen)
{
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
2010-12-18 20:38:49 +00:00
screen_wayland->monitors = g_ptr_array_new_with_free_func (free_monitor);
2010-12-18 20:38:49 +00:00
screen_wayland->primary_monitor = 0;
}
static void
gdk_wayland_screen_dispose (GObject *object)
{
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
2010-12-18 20:38:49 +00:00
if (screen_wayland->root_window)
_gdk_window_destroy (screen_wayland->root_window, TRUE);
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->dispose (object);
2010-12-18 20:38:49 +00:00
}
static void
gdk_wayland_screen_finalize (GObject *object)
{
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
2010-12-18 20:38:49 +00:00
if (screen_wayland->root_window)
g_object_unref (screen_wayland->root_window);
2011-11-30 15:21:27 +00:00
g_object_unref (screen_wayland->visual);
2010-12-18 20:38:49 +00:00
deinit_multihead (GDK_SCREEN (object));
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->finalize (object);
2010-12-18 20:38:49 +00:00
}
static GdkDisplay *
gdk_wayland_screen_get_display (GdkScreen *screen)
{
return GDK_WAYLAND_SCREEN (screen)->display;
2010-12-18 20:38:49 +00:00
}
static gint
gdk_wayland_screen_get_width (GdkScreen *screen)
{
return GDK_WAYLAND_SCREEN (screen)->width;
2010-12-18 20:38:49 +00:00
}
static gint
gdk_wayland_screen_get_height (GdkScreen *screen)
{
return GDK_WAYLAND_SCREEN (screen)->height;
2010-12-18 20:38:49 +00:00
}
static gint
gdk_wayland_screen_get_width_mm (GdkScreen *screen)
{
return GDK_WAYLAND_SCREEN (screen)->width_mm;
2010-12-18 20:38:49 +00:00
}
static gint
gdk_wayland_screen_get_height_mm (GdkScreen *screen)
{
return GDK_WAYLAND_SCREEN (screen)->height_mm;
2010-12-18 20:38:49 +00:00
}
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;
2010-12-18 20:38:49 +00:00
}
static gint
gdk_wayland_screen_get_n_monitors (GdkScreen *screen)
{
return GDK_WAYLAND_SCREEN (screen)->monitors->len;
2010-12-18 20:38:49 +00:00
}
static gint
gdk_wayland_screen_get_primary_monitor (GdkScreen *screen)
{
return GDK_WAYLAND_SCREEN (screen)->primary_monitor;
2010-12-18 20:38:49 +00:00
}
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);
2010-12-18 20:38:49 +00:00
return monitor->width_mm;
2010-12-18 20:38:49 +00:00
}
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);
2010-12-18 20:38:49 +00:00
return monitor->height_mm;
2010-12-18 20:38:49 +00:00
}
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);
2010-12-18 20:38:49 +00:00
return g_strdup (monitor->output_name);
2010-12-18 20:38:49 +00:00
}
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);
2010-12-18 20:38:49 +00:00
if (dest)
*dest = monitor->geometry;
2010-12-18 20:38:49 +00:00
}
static GdkVisual *
gdk_wayland_screen_get_system_visual (GdkScreen * screen)
{
return (GdkVisual *) GDK_WAYLAND_SCREEN (screen)->visual;
2010-12-18 20:38:49 +00:00
}
static GdkVisual *
gdk_wayland_screen_get_rgba_visual (GdkScreen *screen)
{
return (GdkVisual *) GDK_WAYLAND_SCREEN (screen)->visual;
2010-12-18 20:38:49 +00:00
}
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)
{
}
static gboolean
gdk_wayland_screen_get_setting (GdkScreen *screen,
const gchar *name,
GValue *value)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
if (strcmp ("gtk-theme-name", name) == 0)
{
const gchar *s = "Adwaita";
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
g_value_set_static_string (value, s);
return TRUE;
}
if (strcmp ("gtk-cursor-theme-name", name) == 0)
{
const gchar *s = "Adwaita";
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
g_value_set_static_string (value, s);
return TRUE;
}
else if (strcmp ("gtk-icon-theme-name", name) == 0)
{
const gchar *s = "gnome";
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
g_value_set_static_string (value, s);
return TRUE;
}
else 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, TRUE);
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, TRUE);
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;
}
2010-12-18 20:38:49 +00:00
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;
2010-12-18 20:38:49 +00:00
}
static GdkVisual*
gdk_wayland_screen_visual_get_best_with_depth (GdkScreen *screen,
gint depth)
{
return GDK_WAYLAND_SCREEN (screen)->visual;
2010-12-18 20:38:49 +00:00
}
static GdkVisual*
gdk_wayland_screen_visual_get_best_with_type (GdkScreen *screen,
GdkVisualType visual_type)
{
return GDK_WAYLAND_SCREEN (screen)->visual;
2010-12-18 20:38:49 +00:00
}
static GdkVisual*
gdk_wayland_screen_visual_get_best_with_both (GdkScreen *screen,
gint depth,
GdkVisualType visual_type)
{
return GDK_WAYLAND_SCREEN (screen)->visual;
2010-12-18 20:38:49 +00:00
}
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;
2010-12-18 20:38:49 +00:00
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
screen_wayland = GDK_WAYLAND_SCREEN (screen);
2010-12-18 20:38:49 +00:00
2011-11-30 15:21:27 +00:00
list = g_list_append (NULL, screen_wayland->visual);
2010-12-18 20:38:49 +00:00
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 *
2011-11-30 15:21:27 +00:00
gdk_wayland_visual_new (GdkScreen *screen)
2010-12-18 20:38:49 +00:00
{
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;
2010-12-18 20:38:49 +00:00
screen = g_object_new (GDK_TYPE_WAYLAND_SCREEN, NULL);
2010-12-18 20:38:49 +00:00
screen_wayland = GDK_WAYLAND_SCREEN (screen);
2010-12-18 20:38:49 +00:00
screen_wayland->display = display;
screen_wayland->width = 8192;
screen_wayland->height = 8192;
2011-11-30 15:21:27 +00:00
screen_wayland->visual = gdk_wayland_visual_new (screen);
2010-12-18 20:38:49 +00:00
screen_wayland->root_window =
_gdk_wayland_screen_create_root_window (screen,
screen_wayland->width,
screen_wayland->height);
init_multihead (screen);
return screen;
}
static void
_gdk_wayland_screen_class_init (GdkWaylandScreenClass *klass)
2010-12-18 20:38:49 +00:00
{
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;
2010-12-18 20:38:49 +00:00
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)
2010-12-18 20:38:49 +00:00
{
}
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;
}
}
}