* X11 specific implementations of generic functions *
*****************************************************/
-static void
-gdk_x11_surface_finalize (GObject *object)
-{
- GdkX11Surface *impl;
-
- g_return_if_fail (GDK_IS_X11_SURFACE (object));
-
- impl = GDK_X11_SURFACE (object);
-
- if (impl->toplevel->in_frame)
- unhook_surface_changed (GDK_SURFACE (impl));
-
- g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl),
- gdk_x11_toplevel_state_callback,
- NULL);
- g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl),
- gdk_x11_toplevel_event_callback,
- NULL);
-
- _gdk_x11_surface_grab_check_destroy (GDK_SURFACE (impl));
-
- if (!GDK_SURFACE_DESTROYED (impl))
- {
- GdkDisplay *display = GDK_SURFACE_DISPLAY (GDK_SURFACE (impl));
-
- _gdk_x11_display_remove_window (display, impl->xid);
- if (impl->toplevel && impl->toplevel->focus_window)
- _gdk_x11_display_remove_window (display, impl->toplevel->focus_window);
- }
-
- g_clear_pointer (&impl->surface_is_on_monitor, g_list_free);
- g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
- g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
-
- g_free (impl->toplevel);
-
- if (impl->cursor)
- g_object_unref (impl->cursor);
-
- G_OBJECT_CLASS (gdk_x11_surface_parent_class)->finalize (object);
-}
-
-typedef struct {
- GdkDisplay *display;
- Pixmap pixmap;
-} FreePixmapData;
-
-static void
-free_pixmap (gpointer datap)
-{
- FreePixmapData *data = datap;
-
- if (!gdk_display_is_closed (data->display))
- {
- XFreePixmap (GDK_DISPLAY_XDISPLAY (data->display),
- data->pixmap);
- }
-
- g_object_unref (data->display);
- g_free (data);
-}
-
-static void
-attach_free_pixmap_handler (cairo_surface_t *surface,
- GdkDisplay *display,
- Pixmap pixmap)
-{
- static const cairo_user_data_key_t key;
- FreePixmapData *data;
-
- data = g_new (FreePixmapData, 1);
- data->display = g_object_ref (display);
- data->pixmap = pixmap;
-
- cairo_surface_set_user_data (surface, &key, data, free_pixmap);
-}
-
-/* Cairo does not guarantee we get an xlib surface if we call
- * cairo_surface_create_similar(). In some cases however, we must use a
- * pixmap or bitmap in the X11 API.
- * These functions ensure an Xlib surface.
- */
-cairo_surface_t *
-_gdk_x11_display_create_bitmap_surface (GdkDisplay *display,
- int width,
- int height)
-{
- cairo_surface_t *surface;
- Pixmap pixmap;
-
- pixmap = XCreatePixmap (GDK_DISPLAY_XDISPLAY (display),
- GDK_SCREEN_XROOTWIN (GDK_X11_DISPLAY (display)->screen),
- width, height, 1);
- surface = cairo_xlib_surface_create_for_bitmap (GDK_DISPLAY_XDISPLAY (display),
- pixmap,
- GDK_X11_SCREEN (GDK_X11_DISPLAY (display)->screen)->xscreen,
- width, height);
- attach_free_pixmap_handler (surface, display, pixmap);
-
- return surface;
-}
-
-/* Create a surface backed with a pixmap without alpha on the same screen as surface */
-static cairo_surface_t *
-gdk_x11_surface_create_pixmap_surface (GdkSurface *surface,
- int width,
- int height)
+static const char *
+get_default_title (void)
{
- GdkDisplay *display;
- Display *dpy;
- cairo_surface_t *cairo_surface;
- Pixmap pixmap;
-
- display = gdk_surface_get_display (surface);
- dpy = GDK_DISPLAY_XDISPLAY (display);
+ const char *title;
- pixmap = XCreatePixmap (dpy,
- GDK_SURFACE_XID (surface),
- width, height,
- DefaultDepth (dpy, DefaultScreen (dpy)));
- cairo_surface = cairo_xlib_surface_create (dpy,
- pixmap,
- DefaultVisual (dpy, DefaultScreen (dpy)),
- width, height);
- attach_free_pixmap_handler (cairo_surface, display, pixmap);
+ title = g_get_application_name ();
+ if (!title)
+ title = g_get_prgname ();
+ if (!title)
+ title = "";
- return cairo_surface;
+ return title;
}
static void
XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_SURFACE_XID (surface), protocols, n);
}
-static const char *
-get_default_title (void)
-{
- const char *title;
-
- title = g_get_application_name ();
- if (!title)
- title = g_get_prgname ();
- if (!title)
- title = "";
-
- return title;
-}
-
static void
check_leader_window_title (GdkDisplay *display)
{
}
static void
-setup_toplevel_window (GdkSurface *surface,
- GdkX11Screen *x11_screen)
+setup_toplevel_window (GdkSurface *surface)
{
GdkToplevelX11 *toplevel = _gdk_x11_surface_get_toplevel (surface);
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
* press events so they don't get sent to child surfaces.
*/
toplevel->focus_window = create_focus_window (display, xid);
- _gdk_x11_display_add_window (x11_screen->display,
+ _gdk_x11_display_add_window (display,
&toplevel->focus_window,
surface);
- check_leader_window_title (x11_screen->display);
+ check_leader_window_title (display);
/* FIXME: Is there any point in doing this? Do any WM's pay
* attention to PSize, and even if they do, is this the
/* if sandboxed, we're likely in a pid namespace and would only confuse the wm with this */
long pid = getpid ();
XChangeProperty (xdisplay, xid,
- gdk_x11_get_xatom_by_name_for_display (x11_screen->display, "_NET_WM_PID"),
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
XA_CARDINAL, 32,
PropModeReplace,
(guchar *)&pid, 1);
}
- leader_window = GDK_X11_DISPLAY (x11_screen->display)->leader_window;
+ leader_window = GDK_X11_DISPLAY (display)->leader_window;
if (!leader_window)
leader_window = xid;
XChangeProperty (xdisplay, xid,
- gdk_x11_get_xatom_by_name_for_display (x11_screen->display, "WM_CLIENT_LEADER"),
+ gdk_x11_get_xatom_by_name_for_display (display, "WM_CLIENT_LEADER"),
XA_WINDOW, 32, PropModeReplace,
(guchar *) &leader_window, 1);
if (toplevel->focus_window != None)
XChangeProperty (xdisplay, xid,
- gdk_x11_get_xatom_by_name_for_display (x11_screen->display, "_NET_WM_USER_TIME_WINDOW"),
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME_WINDOW"),
XA_WINDOW, 32, PropModeReplace,
(guchar *) &toplevel->focus_window, 1);
- if (GDK_X11_DISPLAY (x11_screen->display)->user_time != 0)
- gdk_x11_surface_set_user_time (surface, GDK_X11_DISPLAY (x11_screen->display)->user_time);
+ if (GDK_X11_DISPLAY (display)->user_time != 0)
+ gdk_x11_surface_set_user_time (surface, GDK_X11_DISPLAY (display)->user_time);
ensure_sync_counter (surface);
static void gdk_x11_surface_set_title (GdkSurface *surface,
const char *title);
+static void
+gdk_x11_surface_constructed (GObject *object)
+{
+ GdkX11Surface *self = GDK_X11_SURFACE (object);
+ GdkSurface *surface = GDK_SURFACE (self);
+ GdkDisplay *display = gdk_surface_get_display (surface);
+ GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+ XClassHint *class_hint;
+
+ g_assert (self->xid);
+
+ g_object_ref (surface);
+ _gdk_x11_display_add_window (display, &self->xid, surface);
+
+ self->surface_scale = display_x11->screen->surface_scale;
+
+ gdk_surface_set_egl_native_window (surface, (void *) self->xid);
+
+ gdk_x11_surface_set_title (surface, get_default_title ());
+
+ class_hint = XAllocClassHint ();
+ class_hint->res_name = (char *) g_get_prgname ();
+ if (display_x11->program_class)
+ class_hint->res_class = (char *) display_x11->program_class;
+ else
+ class_hint->res_class = class_hint->res_name;
+ XSetClassHint (GDK_DISPLAY_XDISPLAY (display), self->xid, class_hint);
+ XFree (class_hint);
+
+ setup_toplevel_window (surface);
+
+ gdk_x11_event_source_select_events ((GdkEventSource *) display_x11->event_source,
+ GDK_SURFACE_XID (surface), GDK_ALL_EVENTS_MASK,
+ StructureNotifyMask | PropertyChangeMask);
+
+ _gdk_x11_surface_register_dnd (surface);
+
+ connect_frame_clock (surface);
+
+ gdk_surface_freeze_updates (surface);
+
+ G_OBJECT_CLASS (gdk_x11_surface_parent_class)->constructed (object);
+}
+
+static void
+gdk_x11_surface_finalize (GObject *object)
+{
+ GdkX11Surface *impl;
+
+ g_return_if_fail (GDK_IS_X11_SURFACE (object));
+
+ impl = GDK_X11_SURFACE (object);
+
+ if (impl->toplevel->in_frame)
+ unhook_surface_changed (GDK_SURFACE (impl));
+
+ g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl),
+ gdk_x11_toplevel_state_callback,
+ NULL);
+ g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl),
+ gdk_x11_toplevel_event_callback,
+ NULL);
+
+ _gdk_x11_surface_grab_check_destroy (GDK_SURFACE (impl));
+
+ if (!GDK_SURFACE_DESTROYED (impl))
+ {
+ GdkDisplay *display = GDK_SURFACE_DISPLAY (GDK_SURFACE (impl));
+
+ _gdk_x11_display_remove_window (display, impl->xid);
+ if (impl->toplevel && impl->toplevel->focus_window)
+ _gdk_x11_display_remove_window (display, impl->toplevel->focus_window);
+ }
+
+ g_clear_pointer (&impl->surface_is_on_monitor, g_list_free);
+ g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
+ g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
+
+ g_free (impl->toplevel);
+
+ if (impl->cursor)
+ g_object_unref (impl->cursor);
+
+ G_OBJECT_CLASS (gdk_x11_surface_parent_class)->finalize (object);
+}
+
+typedef struct {
+ GdkDisplay *display;
+ Pixmap pixmap;
+} FreePixmapData;
+
+static void
+free_pixmap (gpointer datap)
+{
+ FreePixmapData *data = datap;
+
+ if (!gdk_display_is_closed (data->display))
+ {
+ XFreePixmap (GDK_DISPLAY_XDISPLAY (data->display),
+ data->pixmap);
+ }
+
+ g_object_unref (data->display);
+ g_free (data);
+}
+
+static void
+attach_free_pixmap_handler (cairo_surface_t *surface,
+ GdkDisplay *display,
+ Pixmap pixmap)
+{
+ static const cairo_user_data_key_t key;
+ FreePixmapData *data;
+
+ data = g_new (FreePixmapData, 1);
+ data->display = g_object_ref (display);
+ data->pixmap = pixmap;
+
+ cairo_surface_set_user_data (surface, &key, data, free_pixmap);
+}
+
+/* Cairo does not guarantee we get an xlib surface if we call
+ * cairo_surface_create_similar(). In some cases however, we must use a
+ * pixmap or bitmap in the X11 API.
+ * These functions ensure an Xlib surface.
+ */
+cairo_surface_t *
+_gdk_x11_display_create_bitmap_surface (GdkDisplay *display,
+ int width,
+ int height)
+{
+ cairo_surface_t *surface;
+ Pixmap pixmap;
+
+ pixmap = XCreatePixmap (GDK_DISPLAY_XDISPLAY (display),
+ GDK_SCREEN_XROOTWIN (GDK_X11_DISPLAY (display)->screen),
+ width, height, 1);
+ surface = cairo_xlib_surface_create_for_bitmap (GDK_DISPLAY_XDISPLAY (display),
+ pixmap,
+ GDK_X11_SCREEN (GDK_X11_DISPLAY (display)->screen)->xscreen,
+ width, height);
+ attach_free_pixmap_handler (surface, display, pixmap);
+
+ return surface;
+}
+
+/* Create a surface backed with a pixmap without alpha on the same screen as surface */
+static cairo_surface_t *
+gdk_x11_surface_create_pixmap_surface (GdkSurface *surface,
+ int width,
+ int height)
+{
+ GdkDisplay *display;
+ Display *dpy;
+ cairo_surface_t *cairo_surface;
+ Pixmap pixmap;
+
+ display = gdk_surface_get_display (surface);
+ dpy = GDK_DISPLAY_XDISPLAY (display);
+
+ pixmap = XCreatePixmap (dpy,
+ GDK_SURFACE_XID (surface),
+ width, height,
+ DefaultDepth (dpy, DefaultScreen (dpy)));
+ cairo_surface = cairo_xlib_surface_create (dpy,
+ pixmap,
+ DefaultVisual (dpy, DefaultScreen (dpy)),
+ width, height);
+ attach_free_pixmap_handler (cairo_surface, display, pixmap);
+
+ return cairo_surface;
+}
+
static void gdk_x11_surface_set_type_hint (GdkSurface *surface,
GdkSurfaceTypeHint hint);
{
GdkSurface *surface;
GdkFrameClock *frame_clock;
- GdkX11Surface *impl;
- GdkX11Screen *x11_screen;
- GdkX11Display *display_x11;
-
- Window xparent;
- Display *xdisplay;
-
- XSetWindowAttributes xattributes;
- long xattributes_mask;
- XClassHint *class_hint;
-
- display_x11 = GDK_X11_DISPLAY (display);
- x11_screen = GDK_X11_SCREEN (display_x11->screen);
- xparent = GDK_SCREEN_XROOTWIN (x11_screen);
if (parent)
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
g_object_unref (frame_clock);
- impl = GDK_X11_SURFACE (surface);
- impl->surface_scale = x11_screen->surface_scale;
-
- xdisplay = x11_screen->xdisplay;
-
- xattributes_mask = 0;
-
- impl->override_redirect = FALSE;
-
- xattributes.background_pixmap = None;
- xattributes_mask |= CWBackPixmap;
-
- xattributes.border_pixel = BlackPixel (xdisplay, x11_screen->screen_num);
- xattributes_mask |= CWBorderPixel;
-
- xattributes.bit_gravity = NorthWestGravity;
- xattributes_mask |= CWBitGravity;
-
- xattributes.colormap = gdk_x11_display_get_window_colormap (display_x11);
- xattributes_mask |= CWColormap;
-
- if (surface_type == GDK_SURFACE_DRAG ||
- surface_type == GDK_SURFACE_POPUP)
- {
- xattributes.save_under = True;
- xattributes.override_redirect = True;
- xattributes.cursor = None;
- xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
-
- impl->override_redirect = TRUE;
- }
-
- impl->xid = XCreateWindow (xdisplay, xparent,
- 0, 0, 1, 1,
- 0,
- gdk_x11_display_get_window_depth (display_x11),
- InputOutput,
- gdk_x11_display_get_window_visual (display_x11),
- xattributes_mask, &xattributes);
-
- g_object_ref (surface);
- _gdk_x11_display_add_window (x11_screen->display, &impl->xid, surface);
-
- gdk_surface_set_egl_native_window (surface, (void *) impl->xid);
-
- gdk_x11_surface_set_title (surface, get_default_title ());
- if (surface_type == GDK_SURFACE_TOPLEVEL)
- gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_NORMAL);
- else if (surface_type == GDK_SURFACE_POPUP)
- gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_MENU);
-
- class_hint = XAllocClassHint ();
- class_hint->res_name = (char *) g_get_prgname ();
- if (display_x11->program_class)
- class_hint->res_class = (char *) display_x11->program_class;
- else
- class_hint->res_class = class_hint->res_name;
- XSetClassHint (xdisplay, impl->xid, class_hint);
- XFree (class_hint);
-
- setup_toplevel_window (surface, x11_screen);
-
- gdk_x11_event_source_select_events ((GdkEventSource *) display_x11->event_source,
- GDK_SURFACE_XID (surface), GDK_ALL_EVENTS_MASK,
- StructureNotifyMask | PropertyChangeMask);
-
- _gdk_x11_surface_register_dnd (surface);
-
- connect_frame_clock (surface);
-
- gdk_surface_freeze_updates (surface);
-
return surface;
}
static void
gdk_x11_surface_set_type_hint (GdkSurface *surface,
- GdkSurfaceTypeHint hint)
+ GdkSurfaceTypeHint hint)
{
GdkDisplay *display;
Atom atom;
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
+ object_class->constructed = gdk_x11_surface_constructed;
object_class->finalize = gdk_x11_surface_finalize;
impl_class->hide = gdk_x11_surface_hide;
impl_class->compute_size = gdk_x11_surface_compute_size;
}
+static void
+gdk_x11_surface_create_window (GdkX11Surface *self,
+ XSetWindowAttributes *xattributes,
+ long xattributes_mask)
+{
+ GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (self));
+ GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+
+ g_assert (self->xid == 0);
+
+ xattributes->background_pixmap = None;
+ xattributes_mask |= CWBackPixmap;
+
+ xattributes->border_pixel = BlackPixel (GDK_DISPLAY_XDISPLAY (display),
+ display_x11->screen->screen_num);
+ xattributes_mask |= CWBorderPixel;
+
+ xattributes->bit_gravity = NorthWestGravity;
+ xattributes_mask |= CWBitGravity;
+
+ xattributes->colormap = gdk_x11_display_get_window_colormap (display_x11);
+ xattributes_mask |= CWColormap;
+
+ self->xid = XCreateWindow (GDK_DISPLAY_XDISPLAY (display),
+ display_x11->screen->xroot_window,
+ 0, 0, 1, 1,
+ 0,
+ gdk_x11_display_get_window_depth (display_x11),
+ InputOutput,
+ gdk_x11_display_get_window_visual (display_x11),
+ xattributes_mask, xattributes);
+}
+
#define LAST_PROP 1
typedef struct {
{
}
+static void
+gdk_x11_popup_constructed (GObject *object)
+{
+ GdkX11Surface *x11_surface = GDK_X11_SURFACE (object);
+ GdkSurface *surface = GDK_SURFACE (x11_surface);
+ XSetWindowAttributes xattributes;
+ long xattributes_mask;
+
+ xattributes.save_under = True;
+ xattributes.override_redirect = True;
+ xattributes_mask = CWSaveUnder | CWOverrideRedirect;
+
+ gdk_x11_surface_create_window (x11_surface, &xattributes, xattributes_mask);
+
+ x11_surface->override_redirect = TRUE;
+
+ G_OBJECT_CLASS (gdk_x11_popup_parent_class)->constructed (object);
+
+ gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_MENU);
+}
+
static void
gdk_x11_popup_get_property (GObject *object,
guint prop_id,
}
}
-
static void
gdk_x11_popup_class_init (GdkX11PopupClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = gdk_x11_popup_constructed;
object_class->get_property = gdk_x11_popup_get_property;
object_class->set_property = gdk_x11_popup_set_property;
gdk_x11_toplevel_init (GdkX11Toplevel *toplevel)
{
}
+
+static void
+gdk_x11_toplevel_constructed (GObject *object)
+{
+ GdkX11Surface *x11_surface = GDK_X11_SURFACE (object);
+ GdkSurface *surface = GDK_SURFACE (x11_surface);
+ XSetWindowAttributes xattributes;
+ long xattributes_mask;
+
+ xattributes_mask = 0;
+
+ gdk_x11_surface_create_window (x11_surface, &xattributes, xattributes_mask);
+
+ G_OBJECT_CLASS (gdk_x11_toplevel_parent_class)->constructed (object);
+
+ gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_NORMAL);
+}
+
static void
gdk_x11_toplevel_set_property (GObject *object,
guint prop_id,
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = gdk_x11_toplevel_constructed;
object_class->get_property = gdk_x11_toplevel_get_property;
object_class->set_property = gdk_x11_toplevel_set_property;
G_IMPLEMENT_INTERFACE (GDK_TYPE_DRAG_SURFACE,
gdk_x11_drag_surface_iface_init))
+static void
+gdk_x11_drag_surface_constructed (GObject *object)
+{
+ GdkX11Surface *x11_surface = GDK_X11_SURFACE (object);
+ XSetWindowAttributes xattributes;
+ long xattributes_mask;
+
+ xattributes.save_under = True;
+ xattributes.override_redirect = True;
+ xattributes_mask = CWSaveUnder | CWOverrideRedirect;
+
+ gdk_x11_surface_create_window (x11_surface, &xattributes, xattributes_mask);
+
+ x11_surface->override_redirect = TRUE;
+
+ G_OBJECT_CLASS (gdk_x11_drag_surface_parent_class)->constructed (object);
+}
+
static void
gdk_x11_drag_surface_init (GdkX11DragSurface *surface)
{
static void
gdk_x11_drag_surface_class_init (GdkX11DragSurfaceClass *class)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->constructed = gdk_x11_drag_surface_constructed;
}
static gboolean