diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2011-07-15 14:11:13 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-03-27 09:31:58 -0400 |
commit | 2d74bea5b1ec1128ac6c7539684ead2a6cb856d4 (patch) | |
tree | 72b166a79d25cbc93b881db779beee5c78321d37 | |
parent | 95bc2a26b7938cb940649e115fec004d90cd67ed (diff) |
xwayland: Split out output and window code
-rw-r--r-- | hw/xfree86/xwayland/Makefile.am | 2 | ||||
-rw-r--r-- | hw/xfree86/xwayland/xwayland-output.c | 290 | ||||
-rw-r--r-- | hw/xfree86/xwayland/xwayland-private.h | 3 | ||||
-rw-r--r-- | hw/xfree86/xwayland/xwayland-window.c | 306 | ||||
-rw-r--r-- | hw/xfree86/xwayland/xwayland.c | 512 |
5 files changed, 604 insertions, 509 deletions
diff --git a/hw/xfree86/xwayland/Makefile.am b/hw/xfree86/xwayland/Makefile.am index 7fda1f8a2..fa6d84eb2 100644 --- a/hw/xfree86/xwayland/Makefile.am +++ b/hw/xfree86/xwayland/Makefile.am @@ -19,7 +19,9 @@ libxwayland_ladir = $(moduledir)/extensions libxwayland_la_SOURCES = \ xwayland.c \ xwayland-input.c \ + xwayland-output.c \ xwayland-cursor.c \ + xwayland-window.c \ xwayland-private.h \ drm-client-protocol.h \ drm-protocol.c \ diff --git a/hw/xfree86/xwayland/xwayland-output.c b/hw/xfree86/xwayland/xwayland-output.c new file mode 100644 index 000000000..ed2039103 --- /dev/null +++ b/hw/xfree86/xwayland/xwayland-output.c @@ -0,0 +1,290 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include "xorg-config.h" +#endif + +#include <unistd.h> +#include <errno.h> +#include <sys/mman.h> +#include <wayland-client.h> + +#include <xorg-server.h> +#include <cursorstr.h> +#include <xf86Crtc.h> +#include <mipointrst.h> + +#include "xwayland.h" +#include "xwayland-private.h" +#include "xserver-client-protocol.h" + +static void +crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode) +{ +} + +static Bool +crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, + Rotation rotation, int x, int y) +{ + return TRUE; +} + +static void +crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) +{ +} + +static void +crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) +{ +} + +static void +crtc_show_cursor (xf86CrtcPtr crtc) +{ +} + +static void +crtc_hide_cursor (xf86CrtcPtr crtc) +{ +} + +static void +crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) +{ +} + +static PixmapPtr +crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + return NULL; +} + +static void * +crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ + return NULL; +} + +static void +crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ +} + +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, + .set_mode_major = crtc_set_mode_major, + .set_cursor_colors = crtc_set_cursor_colors, + .set_cursor_position = crtc_set_cursor_position, + .show_cursor = crtc_show_cursor, + .hide_cursor = crtc_hide_cursor, + .load_cursor_argb = crtc_load_cursor_argb, + .shadow_create = crtc_shadow_create, + .shadow_allocate = crtc_shadow_allocate, + .shadow_destroy = crtc_shadow_destroy, + .destroy = NULL, /* XXX */ +}; + +static void +output_dpms(xf86OutputPtr output, int mode) +{ + return; +} + +static xf86OutputStatus +output_detect(xf86OutputPtr output) +{ + return XF86OutputStatusConnected; +} + +static Bool +output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) +{ + return MODE_OK; +} + +static DisplayModePtr +output_get_modes(xf86OutputPtr xf86output) +{ + struct xwl_output *output = xf86output->driver_private; + struct monitor_ranges *ranges; + DisplayModePtr modes; + + modes = xf86CVTMode(output->width, output->height, 60, TRUE, FALSE); + output->xf86monitor.det_mon[0].type = DS_RANGES; + ranges = &output->xf86monitor.det_mon[0].section.ranges; + ranges->min_h = modes->HSync - 10; + ranges->max_h = modes->HSync + 10; + ranges->min_v = modes->VRefresh - 10; + ranges->max_v = modes->VRefresh + 10; + ranges->max_clock = modes->Clock + 100; + output->xf86monitor.det_mon[1].type = DT; + output->xf86monitor.det_mon[2].type = DT; + output->xf86monitor.det_mon[3].type = DT; + output->xf86monitor.no_sections = 0; + + xf86output->MonInfo = &output->xf86monitor; + + return modes; +} + +static void +output_destroy(xf86OutputPtr xf86output) +{ + struct xwl_output *output = xf86output->driver_private; + + free(output); +} + +static const xf86OutputFuncsRec output_funcs = { + .dpms = output_dpms, + .detect = output_detect, + .mode_valid = output_mode_valid, + .get_modes = output_get_modes, + .destroy = output_destroy +}; + +struct xwl_output * +xwl_output_create(struct xwl_screen *xwl_screen) +{ + struct xwl_output *xwl_output; + xf86OutputPtr xf86output; + xf86CrtcPtr xf86crtc; + + xwl_output = calloc(sizeof *xwl_output, 1); + if (xwl_output == NULL) { + ErrorF("create_output ENOMEM"); + return NULL; + } + + xwl_output->xwl_screen = xwl_screen; + xwl_output->width = xwl_screen->width = 800; + xwl_output->height = xwl_screen->height = 600; + + xf86output = xf86OutputCreate(xwl_screen->scrninfo, + &output_funcs, "XWAYLAND-1"); + xf86output->driver_private = xwl_output; + xf86output->mm_width = 300; + xf86output->mm_height = 240; + xf86output->subpixel_order = SubPixelHorizontalRGB; + xf86output->possible_crtcs = 1; + xf86output->possible_clones = 1; + + xf86crtc = xf86CrtcCreate(xwl_screen->scrninfo, &crtc_funcs); + xf86crtc->driver_private = xwl_output; + + xwl_output->xf86output = xf86output; + xwl_output->xf86crtc = xf86crtc; + + xwl_screen->xwl_output = xwl_output; + + return xwl_output; +} + +static Bool +resize(ScrnInfoPtr scrn, int width, int height) +{ + if (scrn->virtualX == width && scrn->virtualY == height) + return TRUE; + /* We don't handle resize at all, we must match the compositor size */ + return FALSE; +} + +static const xf86CrtcConfigFuncsRec config_funcs = { + resize +}; + +static void +display_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) +{ + struct xwl_output *xwl_output = data; + + xwl_output->x = x; + xwl_output->y = y; +} + +static void +display_handle_mode(void *data, + struct wl_output *wl_output, + uint32_t flags, + int width, + int height, + int refresh) +{ + struct xwl_output *xwl_output = data; + + xwl_output->width = width; + xwl_output->height = height; + + xwl_output->xwl_screen->width = width; + xwl_output->xwl_screen->height = height; +} + +static const struct wl_output_listener output_listener = { + display_handle_geometry, + display_handle_mode +}; + +static void +global_handler(struct wl_display *display, + uint32_t id, + const char *interface, + uint32_t version, + void *data) +{ + struct xwl_screen *xwl_screen = data; + struct xwl_output *xwl_output; + + if (strcmp (interface, "wl_output") == 0) { + xwl_output = xwl_output_create(xwl_screen); + + xwl_output->output = wl_output_create (xwl_screen->display, id, 1); + wl_output_add_listener(xwl_output->output, + &output_listener, xwl_output); + } +} + +void +xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo) +{ + xf86CrtcConfigInit(scrninfo, &config_funcs); + + xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192); + + xf86InitialConfiguration(scrninfo, TRUE); + + xwl_screen->global_listener = + wl_display_add_global_listener(xwl_screen->display, + global_handler, xwl_screen); +} diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h index 9bda6a617..f80d66780 100644 --- a/hw/xfree86/xwayland/xwayland-private.h +++ b/hw/xfree86/xwayland/xwayland-private.h @@ -105,7 +105,10 @@ struct xwl_input_device { struct xwl_screen *xwl_screen_get(ScreenPtr screen); +void xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo); + int xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen); +int xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen); struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen); diff --git a/hw/xfree86/xwayland/xwayland-window.c b/hw/xfree86/xwayland/xwayland-window.c new file mode 100644 index 000000000..8649bdcc2 --- /dev/null +++ b/hw/xfree86/xwayland/xwayland-window.c @@ -0,0 +1,306 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include "xorg-config.h" +#endif + +#include <unistd.h> +#include <errno.h> +#include <sys/mman.h> +#include <wayland-client.h> +#include <X11/extensions/compositeproto.h> + +#include <xorg-server.h> +#include <xf86Crtc.h> +#include <selection.h> +#include <compositeext.h> +#include <exevents.h> + +#include "xwayland.h" +#include "xwayland-private.h" +#include "xserver-client-protocol.h" + +static DevPrivateKeyRec xwl_window_private_key; + +static void free_pixmap(void *data) +{ + PixmapPtr pixmap = data; + ScreenPtr screen = pixmap->drawable.pScreen; + + (*screen->DestroyPixmap)(pixmap); +} + +static void +xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap) +{ + struct xwl_screen *xwl_screen = xwl_window->xwl_screen; + + /* We can safely destroy the buffer because we only use one buffer + * per surface in xwayland model */ + if (xwl_window->buffer) + wl_buffer_destroy(xwl_window->buffer); + + xwl_screen->driver->create_window_buffer(xwl_window, pixmap); + + if (!xwl_window->buffer) { + ErrorF("failed to create buffer\n"); + return; + } + + wl_surface_attach(xwl_window->surface, xwl_window->buffer, 0, 0); + wl_surface_damage(xwl_window->surface, 0, 0, + pixmap->drawable.width, + pixmap->drawable.height); + + wl_display_sync_callback(xwl_screen->display, free_pixmap, pixmap); + pixmap->refcnt++; +} + +static Bool +xwl_create_window(WindowPtr window) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + Selection *selection; + char buffer[32]; + int len, rc; + Atom name; + Bool ret; + + xwl_screen = xwl_screen_get(screen); + + screen->CreateWindow = xwl_screen->CreateWindow; + ret = (*screen->CreateWindow)(window); + xwl_screen->CreateWindow = screen->CreateWindow; + screen->CreateWindow = xwl_create_window; + + if (!(xwl_screen->flags & XWL_FLAGS_ROOTLESS) || + window->parent != NULL) + return ret; + + len = snprintf(buffer, sizeof buffer, "_NET_WM_CM_S%d", screen->myNum); + name = MakeAtom(buffer, len, TRUE); + rc = AddSelection(&selection, name, serverClient); + if (rc != Success) + return ret; + + selection->lastTimeChanged = currentTime; + selection->window = window->drawable.id; + selection->pWin = window; + selection->client = serverClient; + + CompositeRedirectSubwindows(window, CompositeRedirectManual); + + return ret; +} + +static void +damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) +{ + struct xwl_window *xwl_window = data; + struct xwl_screen *xwl_screen = xwl_window->xwl_screen; + + list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list); +} + +static void +damage_destroy(DamagePtr pDamage, void *data) +{ +} + +static Bool +xwl_realize_window(WindowPtr window) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + VisualID visual; + Bool ret; + int i; + + xwl_screen = xwl_screen_get(screen); + + screen->RealizeWindow = xwl_screen->RealizeWindow; + ret = (*screen->RealizeWindow)(window); + xwl_screen->RealizeWindow = xwl_screen->RealizeWindow; + screen->RealizeWindow = xwl_realize_window; + + if (xwl_screen->flags & XWL_FLAGS_ROOTLESS) { + if (window->redirectDraw != RedirectDrawManual) + return ret; + } else { + if (window->parent) + return ret; + } + + xwl_window = calloc(sizeof *xwl_window, 1); + xwl_window->xwl_screen = xwl_screen; + xwl_window->window = window; + xwl_window->surface = + wl_compositor_create_surface(xwl_screen->compositor); + if (xwl_window->surface == NULL) { + ErrorF("wl_display_create_surface failed\n"); + return FALSE; + } + + xserver_set_window_id(xwl_screen->xorg_server, + xwl_window->surface, window->drawable.id); + + visual = wVisual(window); + for (i = 0; i < screen->numVisuals; i++) + if (screen->visuals[i].vid == visual) + break; + + if (screen->visuals[i].nplanes == 32) + xwl_window->visual = xwl_screen->premultiplied_argb_visual; + else + xwl_window->visual = xwl_screen->rgb_visual; + + wl_surface_set_user_data(xwl_window->surface, xwl_window); + xwl_window_attach(xwl_window, (*screen->GetWindowPixmap)(window)); + + dixSetPrivate(&window->devPrivates, + &xwl_window_private_key, xwl_window); + + xwl_window->damage = + DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty, + FALSE, screen, xwl_window); + DamageRegister(&window->drawable, xwl_window->damage); + + list_add(&xwl_window->link, &xwl_screen->window_list); + list_init(&xwl_window->link_damage); + + return ret; +} + +static Bool +xwl_unrealize_window(WindowPtr window) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + struct xwl_input_device *xwl_input_device; + Bool ret; + + xwl_screen = xwl_screen_get(screen); + + list_for_each_entry(xwl_input_device, + &xwl_screen->input_device_list, link) { + if (!xwl_input_device->focus_window) + continue ; + if (xwl_input_device->focus_window->window == window) { + xwl_input_device->focus_window = NULL; + SetDeviceRedirectWindow(xwl_input_device->pointer, PointerRootWin); + } + } + + screen->UnrealizeWindow = xwl_screen->UnrealizeWindow; + ret = (*screen->UnrealizeWindow)(window); + xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; + screen->UnrealizeWindow = xwl_unrealize_window; + + xwl_window = + dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); + if (!xwl_window) + return ret; + + if (xwl_window->buffer) + wl_buffer_destroy(xwl_window->buffer); + wl_surface_destroy(xwl_window->surface); + list_del(&xwl_window->link); + list_del(&xwl_window->link_damage); + DamageUnregister(&window->drawable, xwl_window->damage); + DamageDestroy(xwl_window->damage); + free(xwl_window); + dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); + + return ret; +} + +static void +xwl_set_window_pixmap(WindowPtr window, PixmapPtr pixmap) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + + xwl_screen = xwl_screen_get(screen); + + screen->SetWindowPixmap = xwl_screen->SetWindowPixmap; + (*screen->SetWindowPixmap)(window, pixmap); + xwl_screen->SetWindowPixmap = screen->SetWindowPixmap; + screen->SetWindowPixmap = xwl_set_window_pixmap; + + xwl_window = + dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); + if (xwl_window) + xwl_window_attach(xwl_window, pixmap); +} + +static void +xwl_move_window(WindowPtr window, int x, int y, + WindowPtr sibling, VTKind kind) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + + xwl_screen = xwl_screen_get(screen); + + screen->MoveWindow = xwl_screen->MoveWindow; + (*screen->MoveWindow)(window, x, y, sibling, kind); + xwl_screen->MoveWindow = screen->MoveWindow; + screen->MoveWindow = xwl_move_window; + + xwl_window = + dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); + if (xwl_window == NULL) + return; +} + +int +xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen) +{ + if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0)) + return BadAlloc; + + xwl_screen->CreateWindow = screen->CreateWindow; + screen->CreateWindow = xwl_create_window; + + xwl_screen->RealizeWindow = screen->RealizeWindow; + screen->RealizeWindow = xwl_realize_window; + + xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; + screen->UnrealizeWindow = xwl_unrealize_window; + + xwl_screen->SetWindowPixmap = screen->SetWindowPixmap; + screen->SetWindowPixmap = xwl_set_window_pixmap; + + xwl_screen->MoveWindow = screen->MoveWindow; + screen->MoveWindow = xwl_move_window; + + return Success; +} diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c index 1e3089062..370cdd23a 100644 --- a/hw/xfree86/xwayland/xwayland.c +++ b/hw/xfree86/xwayland/xwayland.c @@ -33,13 +33,9 @@ #include <errno.h> #include <wayland-util.h> #include <wayland-client.h> -#include <X11/extensions/compositeproto.h> #include <xorg-server.h> -#include <compositeext.h> -#include <selection.h> #include <extinit.h> -#include <exevents.h> #include <xf86Xinput.h> #include <xf86Crtc.h> #include <xf86Priv.h> @@ -55,438 +51,9 @@ * - active grabs, grab owner crack */ -static DevPrivateKeyRec xwl_window_private_key; static DevPrivateKeyRec xwl_screen_private_key; static void -crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode) -{ -} - -static Bool -crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, - Rotation rotation, int x, int y) -{ - return TRUE; -} - -static void -crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) -{ -} - -static void -crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) -{ -} - -static void -crtc_show_cursor (xf86CrtcPtr crtc) -{ -} - -static void -crtc_hide_cursor (xf86CrtcPtr crtc) -{ -} - -static void -crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) -{ -} - -static PixmapPtr -crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) -{ - return NULL; -} - -static void * -crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) -{ - return NULL; -} - -static void -crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) -{ -} - -static const xf86CrtcFuncsRec crtc_funcs = { - .dpms = crtc_dpms, - .set_mode_major = crtc_set_mode_major, - .set_cursor_colors = crtc_set_cursor_colors, - .set_cursor_position = crtc_set_cursor_position, - .show_cursor = crtc_show_cursor, - .hide_cursor = crtc_hide_cursor, - .load_cursor_argb = crtc_load_cursor_argb, - .shadow_create = crtc_shadow_create, - .shadow_allocate = crtc_shadow_allocate, - .shadow_destroy = crtc_shadow_destroy, - .destroy = NULL, /* XXX */ -}; - -static void -output_dpms(xf86OutputPtr output, int mode) -{ - return; -} - -static xf86OutputStatus -output_detect(xf86OutputPtr output) -{ - return XF86OutputStatusConnected; -} - -static Bool -output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) -{ - return MODE_OK; -} - -static DisplayModePtr -output_get_modes(xf86OutputPtr xf86output) -{ - struct xwl_output *output = xf86output->driver_private; - struct monitor_ranges *ranges; - DisplayModePtr modes; - - modes = xf86CVTMode(output->width, output->height, 60, TRUE, FALSE); - output->xf86monitor.det_mon[0].type = DS_RANGES; - ranges = &output->xf86monitor.det_mon[0].section.ranges; - ranges->min_h = modes->HSync - 10; - ranges->max_h = modes->HSync + 10; - ranges->min_v = modes->VRefresh - 10; - ranges->max_v = modes->VRefresh + 10; - ranges->max_clock = modes->Clock + 100; - output->xf86monitor.det_mon[1].type = DT; - output->xf86monitor.det_mon[2].type = DT; - output->xf86monitor.det_mon[3].type = DT; - output->xf86monitor.no_sections = 0; - - xf86output->MonInfo = &output->xf86monitor; - - return modes; -} - -static void -output_destroy(xf86OutputPtr xf86output) -{ - struct xwl_output *output = xf86output->driver_private; - - free(output); -} - -static const xf86OutputFuncsRec output_funcs = { - .dpms = output_dpms, - .detect = output_detect, - .mode_valid = output_mode_valid, - .get_modes = output_get_modes, - .destroy = output_destroy -}; - -struct xwl_output * -xwl_output_create(struct xwl_screen *xwl_screen) -{ - struct xwl_output *xwl_output; - xf86OutputPtr xf86output; - xf86CrtcPtr xf86crtc; - - xwl_output = calloc(sizeof *xwl_output, 1); - if (xwl_output == NULL) { - ErrorF("create_output ENOMEM"); - return NULL; - } - - xwl_output->xwl_screen = xwl_screen; - xwl_output->width = xwl_screen->width = 800; - xwl_output->height = xwl_screen->height = 600; - - xf86output = xf86OutputCreate(xwl_screen->scrninfo, - &output_funcs, "XWAYLAND-1"); - xf86output->driver_private = xwl_output; - xf86output->mm_width = 300; - xf86output->mm_height = 240; - xf86output->subpixel_order = SubPixelHorizontalRGB; - xf86output->possible_crtcs = 1; - xf86output->possible_clones = 1; - - xf86crtc = xf86CrtcCreate(xwl_screen->scrninfo, &crtc_funcs); - xf86crtc->driver_private = xwl_output; - - xwl_output->xf86output = xf86output; - xwl_output->xf86crtc = xf86crtc; - - xwl_screen->xwl_output = xwl_output; - - return xwl_output; -} - -static Bool -resize(ScrnInfoPtr scrn, int width, int height) -{ - if (scrn->virtualX == width && scrn->virtualY == height) - return TRUE; - /* We don't handle resize at all, we must match the compositor size */ - return FALSE; -} - -static const xf86CrtcConfigFuncsRec config_funcs = { - resize -}; - -static void free_pixmap(void *data) -{ - PixmapPtr pixmap = data; - ScreenPtr screen = pixmap->drawable.pScreen; - - (*screen->DestroyPixmap)(pixmap); -} - -static void -xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap) -{ - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - - /* We can safely destroy the buffer because we only use one buffer - * per surface in xwayland model */ - if (xwl_window->buffer) - wl_buffer_destroy(xwl_window->buffer); - - xwl_screen->driver->create_window_buffer(xwl_window, pixmap); - - if (!xwl_window->buffer) { - ErrorF("failed to create buffer\n"); - return; - } - - wl_surface_attach(xwl_window->surface, xwl_window->buffer, 0, 0); - wl_surface_damage(xwl_window->surface, 0, 0, - pixmap->drawable.width, - pixmap->drawable.height); - - wl_display_sync_callback(xwl_screen->display, free_pixmap, pixmap); - pixmap->refcnt++; - - /* - * DRI2 attach: - * - * Pixmap DRI2NameBuffer(DRI2BufferPtr *buffer); - * - * Not clear how we can render into the back buffer of a - * compositing Xorg host. We'd need a XCompositeSetPixmap or - * something. - */ -} - -static Bool -xwl_create_window(WindowPtr window) -{ - ScreenPtr screen = window->drawable.pScreen; - struct xwl_screen *xwl_screen; - Selection *selection; - char buffer[32]; - int len, rc; - Atom name; - Bool ret; - - xwl_screen = dixLookupPrivate(&screen->devPrivates, - &xwl_screen_private_key); - - screen->CreateWindow = xwl_screen->CreateWindow; - ret = (*screen->CreateWindow)(window); - xwl_screen->CreateWindow = screen->CreateWindow; - screen->CreateWindow = xwl_create_window; - - if (!(xwl_screen->flags & XWL_FLAGS_ROOTLESS) || - window->parent != NULL) - return ret; - - len = snprintf(buffer, sizeof buffer, "_NET_WM_CM_S%d", screen->myNum); - name = MakeAtom(buffer, len, TRUE); - rc = AddSelection(&selection, name, serverClient); - if (rc != Success) - return ret; - - selection->lastTimeChanged = currentTime; - selection->window = window->drawable.id; - selection->pWin = window; - selection->client = serverClient; - - CompositeRedirectSubwindows(window, CompositeRedirectManual); - - return ret; -} - -static void -damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) -{ - struct xwl_window *xwl_window = data; - struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - - list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list); -} - -static void -damage_destroy(DamagePtr pDamage, void *data) -{ -} - -static Bool -xwl_realize_window(WindowPtr window) -{ - ScreenPtr screen = window->drawable.pScreen; - struct xwl_screen *xwl_screen; - struct xwl_window *xwl_window; - VisualID visual; - Bool ret; - int i; - - xwl_screen = dixLookupPrivate(&screen->devPrivates, - &xwl_screen_private_key); - - screen->RealizeWindow = xwl_screen->RealizeWindow; - ret = (*screen->RealizeWindow)(window); - xwl_screen->RealizeWindow = xwl_screen->RealizeWindow; - screen->RealizeWindow = xwl_realize_window; - - if (xwl_screen->flags & XWL_FLAGS_ROOTLESS) { - if (window->redirectDraw != RedirectDrawManual) - return ret; - } else { - if (window->parent) - return ret; - } - - xwl_window = calloc(sizeof *xwl_window, 1); - xwl_window->xwl_screen = xwl_screen; - xwl_window->window = window; - xwl_window->surface = - wl_compositor_create_surface(xwl_screen->compositor); - if (xwl_window->surface == NULL) { - ErrorF("wl_display_create_surface failed\n"); - return FALSE; - } - - xserver_set_window_id(xwl_screen->xorg_server, - xwl_window->surface, window->drawable.id); - - visual = wVisual(window); - for (i = 0; i < screen->numVisuals; i++) - if (screen->visuals[i].vid == visual) - break; - - if (screen->visuals[i].nplanes == 32) - xwl_window->visual = xwl_screen->premultiplied_argb_visual; - else - xwl_window->visual = xwl_screen->rgb_visual; - - wl_surface_set_user_data(xwl_window->surface, xwl_window); - xwl_window_attach(xwl_window, (*screen->GetWindowPixmap)(window)); - - dixSetPrivate(&window->devPrivates, - &xwl_window_private_key, xwl_window); - - xwl_window->damage = - DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty, - FALSE, screen, xwl_window); - DamageRegister(&window->drawable, xwl_window->damage); - - list_add(&xwl_window->link, &xwl_screen->window_list); - list_init(&xwl_window->link_damage); - - return ret; -} - -static Bool -xwl_unrealize_window(WindowPtr window) -{ - ScreenPtr screen = window->drawable.pScreen; - struct xwl_screen *xwl_screen; - struct xwl_window *xwl_window; - struct xwl_input_device *xwl_input_device; - Bool ret; - - xwl_screen = dixLookupPrivate(&screen->devPrivates, - &xwl_screen_private_key); - - list_for_each_entry(xwl_input_device, - &xwl_screen->input_device_list, link) { - if (!xwl_input_device->focus_window) - continue ; - if (xwl_input_device->focus_window->window == window) { - xwl_input_device->focus_window = NULL; - SetDeviceRedirectWindow(xwl_input_device->pointer, PointerRootWin); - } - } - - screen->UnrealizeWindow = xwl_screen->UnrealizeWindow; - ret = (*screen->UnrealizeWindow)(window); - xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; - screen->UnrealizeWindow = xwl_unrealize_window; - - xwl_window = - dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); - if (!xwl_window) - return ret; - - if (xwl_window->buffer) - wl_buffer_destroy(xwl_window->buffer); - wl_surface_destroy(xwl_window->surface); - list_del(&xwl_window->link); - list_del(&xwl_window->link_damage); - DamageUnregister(&window->drawable, xwl_window->damage); - DamageDestroy(xwl_window->damage); - free(xwl_window); - dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); - - return ret; -} - -static void -xwl_set_window_pixmap(WindowPtr window, PixmapPtr pixmap) -{ - ScreenPtr screen = window->drawable.pScreen; - struct xwl_screen *xwl_screen; - struct xwl_window *xwl_window; - - xwl_screen = dixLookupPrivate(&screen->devPrivates, - &xwl_screen_private_key); - - screen->SetWindowPixmap = xwl_screen->SetWindowPixmap; - (*screen->SetWindowPixmap)(window, pixmap); - xwl_screen->SetWindowPixmap = screen->SetWindowPixmap; - screen->SetWindowPixmap = xwl_set_window_pixmap; - - xwl_window = - dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); - if (xwl_window) - xwl_window_attach(xwl_window, pixmap); -} - -static void -xwl_move_window(WindowPtr window, int x, int y, - WindowPtr sibling, VTKind kind) -{ - ScreenPtr screen = window->drawable.pScreen; - struct xwl_screen *xwl_screen; - struct xwl_window *xwl_window; - - xwl_screen = dixLookupPrivate(&screen->devPrivates, - &xwl_screen_private_key); - - screen->MoveWindow = xwl_screen->MoveWindow; - (*screen->MoveWindow)(window, x, y, sibling, kind); - xwl_screen->MoveWindow = screen->MoveWindow; - screen->MoveWindow = xwl_move_window; - - xwl_window = - dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); - if (xwl_window == NULL) - return; -} - -static void xserver_client(void *data, struct xserver *xserver, int fd) { AddClientOnOpenFD(fd); @@ -553,57 +120,6 @@ static const struct wl_compositor_listener compositor_listener = { }; static void -display_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) -{ - struct xwl_output *xwl_output = data; - - xwl_output->x = x; - xwl_output->y = y; -} - -static void -display_handle_mode(void *data, - struct wl_output *wl_output, - uint32_t flags, - int width, - int height, - int refresh) -{ - struct xwl_output *xwl_output = data; - - xwl_output->width = width; - xwl_output->height = height; - - xwl_output->xwl_screen->width = width; - xwl_output->xwl_screen->height = height; -} - -static const struct wl_output_listener output_listener = { - display_handle_geometry, - display_handle_mode -}; - -static void -create_output(struct xwl_screen *xwl_screen, uint32_t id, - uint32_t version) -{ - struct xwl_output *xwl_output; - - xwl_output = xwl_output_create(xwl_screen); - - xwl_output->output = wl_output_create (xwl_screen->display, id, 1); - wl_output_add_listener(xwl_output->output, - &output_listener, xwl_output); -} - -static void global_handler(struct wl_display *display, uint32_t id, const char *interface, @@ -619,8 +135,6 @@ global_handler(struct wl_display *display, &compositor_listener, xwl_screen); } else if (strcmp (interface, "wl_shm") == 0) { xwl_screen->shm = wl_shm_create (xwl_screen->display, id, 1); - } else if (strcmp (interface, "wl_output") == 0) { - create_output(xwl_screen, id, 1); } } @@ -682,26 +196,10 @@ xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen) if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0)) return BadAlloc; - if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0)) - return BadAlloc; - dixSetPrivate(&screen->devPrivates, &xwl_screen_private_key, xwl_screen); - xwl_screen->CreateWindow = screen->CreateWindow; - screen->CreateWindow = xwl_create_window; - - xwl_screen->RealizeWindow = screen->RealizeWindow; - screen->RealizeWindow = xwl_realize_window; - - xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; - screen->UnrealizeWindow = xwl_unrealize_window; - - xwl_screen->SetWindowPixmap = screen->SetWindowPixmap; - screen->SetWindowPixmap = xwl_set_window_pixmap; - - xwl_screen->MoveWindow = screen->MoveWindow; - screen->MoveWindow = xwl_move_window; + xwl_screen_init_window(xwl_screen, screen); xwl_screen_init_cursor(xwl_screen, screen); @@ -742,18 +240,14 @@ xwl_screen_pre_init(ScrnInfoPtr scrninfo, if (xorgRootless) xwl_screen->flags |= XWL_FLAGS_ROOTLESS; - xf86CrtcConfigInit(scrninfo, &config_funcs); - - xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192); - - xf86InitialConfiguration(scrninfo, TRUE); - xwl_screen->display = wl_display_connect(NULL); if (xwl_screen->display == NULL) { ErrorF("wl_display_create failed\n"); return NULL; } + xwayland_screen_preinit_output(xwl_screen, scrninfo); + /* Set up listener so we'll catch all events. */ xwl_screen->global_listener = wl_display_add_global_listener(xwl_screen->display, |