From 95bc2a26b7938cb940649e115fec004d90cd67ed Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Wed, 29 Jun 2011 10:01:11 -0400 Subject: xwayland: Split out cursor handling --- hw/xfree86/xwayland/Makefile.am | 1 + hw/xfree86/xwayland/xwayland-cursor.c | 225 +++++++++++++++++++++++++++++++++ hw/xfree86/xwayland/xwayland-private.h | 4 + hw/xfree86/xwayland/xwayland.c | 188 +-------------------------- 4 files changed, 237 insertions(+), 181 deletions(-) create mode 100644 hw/xfree86/xwayland/xwayland-cursor.c diff --git a/hw/xfree86/xwayland/Makefile.am b/hw/xfree86/xwayland/Makefile.am index 9993a7e12..7fda1f8a2 100644 --- a/hw/xfree86/xwayland/Makefile.am +++ b/hw/xfree86/xwayland/Makefile.am @@ -19,6 +19,7 @@ libxwayland_ladir = $(moduledir)/extensions libxwayland_la_SOURCES = \ xwayland.c \ xwayland-input.c \ + xwayland-cursor.c \ xwayland-private.h \ drm-client-protocol.h \ drm-protocol.c \ diff --git a/hw/xfree86/xwayland/xwayland-cursor.c b/hw/xfree86/xwayland/xwayland-cursor.c new file mode 100644 index 000000000..9732197d0 --- /dev/null +++ b/hw/xfree86/xwayland/xwayland-cursor.c @@ -0,0 +1,225 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * + * 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 +#include +#include +#include + +#include +#include +#include +#include + +#include "xwayland.h" +#include "xwayland-private.h" +#include "xserver-client-protocol.h" + +static DevPrivateKeyRec xwl_cursor_private_key; + +static void +expand_source_and_mask(CursorPtr cursor, void *data) +{ + CARD32 *argb, *p, d, fg, bg; + CursorBitsPtr bits = cursor->bits; + int size; + int x, y, stride, i, bit; + + size = bits->width * bits->height * 4; + argb = malloc(size); + if (argb == NULL) + return; + + p = argb; + fg = ((cursor->foreRed & 0xff00) << 8) | + (cursor->foreGreen & 0xff00) | (cursor->foreGreen >> 8); + bg = ((cursor->backRed & 0xff00) << 8) | + (cursor->backGreen & 0xff00) | (cursor->backGreen >> 8); + stride = (bits->width / 8 + 3) & ~3; + for (y = 0; y < bits->height; y++) + for (x = 0; x < bits->width; x++) { + i = y * stride + x / 8; + bit = 1 << (x & 7); + if (bits->mask[i] & bit) + d = 0xff000000; + else + d = 0x00000000; + if (bits->source[i] & bit) + d |= fg; + else + d |= bg; + + *p++ = d; + } + + memcpy(data, argb, size); + free(argb); +} + +static Bool +xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) +{ + struct xwl_screen *xwl_screen; + int size; + char filename[] = "/tmp/wayland-shm-XXXXXX"; + int fd; + struct wl_buffer *buffer; + struct wl_visual *visual; + void *data; + + xwl_screen = xwl_screen_get(screen); + size = cursor->bits->width * cursor->bits->height * 4; + + fd = mkstemp(filename); + if (fd < 0) { + ErrorF("open %s failed: %s", filename, strerror(errno)); + return FALSE; + } + if (ftruncate(fd, size) < 0) { + ErrorF("ftruncate failed: %s", strerror(errno)); + close(fd); + return FALSE; + } + + data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + unlink(filename); + + if (data == MAP_FAILED) { + ErrorF("mmap failed: %s", strerror(errno)); + close(fd); + return FALSE; + } + + if (cursor->bits->argb) + memcpy(data, cursor->bits->argb, size); + else + expand_source_and_mask(cursor, data); + munmap(data, size); + + visual = xwl_screen->argb_visual; + buffer = wl_shm_create_buffer(xwl_screen->shm, fd, + cursor->bits->width, cursor->bits->height, + cursor->bits->width * 4, visual); + close(fd); + + dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, buffer); + + wl_buffer_damage(buffer, 0, 0, cursor->bits->width, cursor->bits->height); + + return TRUE; +} + +static Bool +xwl_unrealize_cursor(DeviceIntPtr device, + ScreenPtr screen, CursorPtr cursor) +{ + struct wl_buffer *buffer; + + buffer = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); + wl_buffer_destroy(buffer); + + return TRUE; +} + +static void +xwl_set_cursor(DeviceIntPtr device, + ScreenPtr screen, CursorPtr cursor, int x, int y) +{ + struct xwl_screen *xwl_screen; + struct xwl_input_device *xwl_input_device; + struct wl_buffer *buffer; + + if (!cursor) + return; + + xwl_screen = xwl_screen_get(screen); + + if (!xwl_screen || list_is_empty(&xwl_screen->input_device_list)) + return ; + + xwl_input_device = list_first_entry(&xwl_screen->input_device_list, + struct xwl_input_device, link); + + buffer = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); + + wl_input_device_attach(xwl_input_device->input_device, + xwl_input_device->time, buffer, + cursor->bits->xhot, cursor->bits->yhot); +} + +static void +xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y) +{ +} + +static Bool +xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen) +{ + struct xwl_screen *xwl_screen; + + xwl_screen = xwl_screen_get(screen); + + return xwl_screen->sprite_funcs->DeviceCursorInitialize(device, + screen); +} + +static void +xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen) +{ + struct xwl_screen *xwl_screen; + + xwl_screen = xwl_screen_get(screen); + + xwl_screen->sprite_funcs->DeviceCursorCleanup(device, screen); +} + +static miPointerSpriteFuncRec xwl_pointer_sprite_funcs = +{ + xwl_realize_cursor, + xwl_unrealize_cursor, + xwl_set_cursor, + xwl_move_cursor, + xwl_device_cursor_initialize, + xwl_device_cursor_cleanup +}; + +int +xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen) +{ + miPointerScreenPtr pointer_priv; + + if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR, 0)) + return BadAlloc; + + pointer_priv = dixLookupPrivate(&screen->devPrivates, miPointerScreenKey); + xwl_screen->sprite_funcs = pointer_priv->spriteFuncs; + pointer_priv->spriteFuncs = &xwl_pointer_sprite_funcs; + + return Success; +} diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h index a08c2dfed..9bda6a617 100644 --- a/hw/xfree86/xwayland/xwayland-private.h +++ b/hw/xfree86/xwayland/xwayland-private.h @@ -103,6 +103,10 @@ struct xwl_input_device { struct list link; }; +struct xwl_screen *xwl_screen_get(ScreenPtr screen); + +int xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen); + struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen); void xwl_input_teardown(pointer p); diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c index d61e11d02..1e3089062 100644 --- a/hw/xfree86/xwayland/xwayland.c +++ b/hw/xfree86/xwayland/xwayland.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -44,7 +43,6 @@ #include #include #include -#include #include #include "xwayland.h" @@ -59,7 +57,6 @@ static DevPrivateKeyRec xwl_window_private_key; static DevPrivateKeyRec xwl_screen_private_key; -static DevPrivateKeyRec xwl_cursor_private_key; static void crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode) @@ -489,176 +486,6 @@ xwl_move_window(WindowPtr window, int x, int y, return; } -static void -expand_source_and_mask(CursorPtr cursor, void *data) -{ - CARD32 *argb, *p, d, fg, bg; - CursorBitsPtr bits = cursor->bits; - int size; - int x, y, stride, i, bit; - - size = bits->width * bits->height * 4; - argb = malloc(size); - if (argb == NULL) - return; - - p = argb; - fg = ((cursor->foreRed & 0xff00) << 8) | - (cursor->foreGreen & 0xff00) | (cursor->foreGreen >> 8); - bg = ((cursor->backRed & 0xff00) << 8) | - (cursor->backGreen & 0xff00) | (cursor->backGreen >> 8); - stride = (bits->width / 8 + 3) & ~3; - for (y = 0; y < bits->height; y++) - for (x = 0; x < bits->width; x++) { - i = y * stride + x / 8; - bit = 1 << (x & 7); - if (bits->mask[i] & bit) - d = 0xff000000; - else - d = 0x00000000; - if (bits->source[i] & bit) - d |= fg; - else - d |= bg; - - *p++ = d; - } - - memcpy(data, argb, size); - free(argb); -} - -static Bool -xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) -{ - struct xwl_screen *xwl_screen; - int size; - char filename[] = "/tmp/wayland-shm-XXXXXX"; - int fd; - struct wl_buffer *buffer; - struct wl_visual *visual; - void *data; - - xwl_screen = dixLookupPrivate(&screen->devPrivates, - &xwl_screen_private_key); - size = cursor->bits->width * cursor->bits->height * 4; - - fd = mkstemp(filename); - if (fd < 0) { - ErrorF("open %s failed: %s", filename, strerror(errno)); - return FALSE; - } - if (ftruncate(fd, size) < 0) { - ErrorF("ftruncate failed: %s", strerror(errno)); - close(fd); - return FALSE; - } - - data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - unlink(filename); - - if (data == MAP_FAILED) { - ErrorF("mmap failed: %s", strerror(errno)); - close(fd); - return FALSE; - } - - if (cursor->bits->argb) - memcpy(data, cursor->bits->argb, size); - else - expand_source_and_mask(cursor, data); - munmap(data, size); - - visual = xwl_screen->argb_visual; - buffer = wl_shm_create_buffer(xwl_screen->shm, fd, - cursor->bits->width, cursor->bits->height, - cursor->bits->width * 4, visual); - close(fd); - - dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, buffer); - - wl_buffer_damage(buffer, 0, 0, cursor->bits->width, cursor->bits->height); - - return TRUE; -} - -static Bool -xwl_unrealize_cursor(DeviceIntPtr device, - ScreenPtr screen, CursorPtr cursor) -{ - struct wl_buffer *buffer; - - buffer = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); - wl_buffer_destroy(buffer); - - return TRUE; -} - -static void -xwl_set_cursor(DeviceIntPtr device, - ScreenPtr screen, CursorPtr cursor, int x, int y) -{ - struct xwl_screen *xwl_screen; - struct xwl_input_device *xwl_input_device; - struct wl_buffer *buffer; - - if (!cursor) - return; - - xwl_screen = dixLookupPrivate(&screen->devPrivates, - &xwl_screen_private_key); - - if (!xwl_screen || list_is_empty(&xwl_screen->input_device_list)) - return ; - - xwl_input_device = list_first_entry(&xwl_screen->input_device_list, - struct xwl_input_device, link); - - buffer = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); - - wl_input_device_attach(xwl_input_device->input_device, - xwl_input_device->time, buffer, - cursor->bits->xhot, cursor->bits->yhot); -} - -static void -xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y) -{ -} - -static Bool -xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen) -{ - struct xwl_screen *xwl_screen; - - xwl_screen = dixLookupPrivate(&screen->devPrivates, - &xwl_screen_private_key); - - return xwl_screen->sprite_funcs->DeviceCursorInitialize(device, - screen); -} - -static void -xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen) -{ - struct xwl_screen *xwl_screen; - - xwl_screen = dixLookupPrivate(&screen->devPrivates, - &xwl_screen_private_key); - - xwl_screen->sprite_funcs->DeviceCursorCleanup(device, screen); -} - -static miPointerSpriteFuncRec xwl_pointer_sprite_funcs = -{ - xwl_realize_cursor, - xwl_unrealize_cursor, - xwl_set_cursor, - xwl_move_cursor, - xwl_device_cursor_initialize, - xwl_device_cursor_cleanup -}; - static void xserver_client(void *data, struct xserver *xserver, int fd) { @@ -850,8 +677,6 @@ xwl_force_roundtrip(struct xwl_screen *xwl_screen) int xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen) { - miPointerScreenPtr pointer_priv; - xwl_screen->screen = screen; if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0)) @@ -860,9 +685,6 @@ xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen) if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0)) return BadAlloc; - if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR, 0)) - return BadAlloc; - dixSetPrivate(&screen->devPrivates, &xwl_screen_private_key, xwl_screen); @@ -881,9 +703,7 @@ xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen) xwl_screen->MoveWindow = screen->MoveWindow; screen->MoveWindow = xwl_move_window; - pointer_priv = dixLookupPrivate(&screen->devPrivates, miPointerScreenKey); - xwl_screen->sprite_funcs = pointer_priv->spriteFuncs; - pointer_priv->spriteFuncs = &xwl_pointer_sprite_funcs; + xwl_screen_init_cursor(xwl_screen, screen); AddGeneralSocket(xwl_screen->wayland_fd); RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen); @@ -893,6 +713,12 @@ xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen) return Success; } +struct xwl_screen * +xwl_screen_get(ScreenPtr screen) +{ + return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key); +} + struct xwl_screen * xwl_screen_pre_init(ScrnInfoPtr scrninfo, uint32_t flags, struct xwl_driver *driver) -- cgit v1.2.3