diff options
Diffstat (limited to 'xorg-server/hw/xwayland/xwayland-cursor.c')
-rw-r--r-- | xorg-server/hw/xwayland/xwayland-cursor.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/xorg-server/hw/xwayland/xwayland-cursor.c b/xorg-server/hw/xwayland/xwayland-cursor.c new file mode 100644 index 000000000..5a9d1fe70 --- /dev/null +++ b/xorg-server/hw/xwayland/xwayland-cursor.c @@ -0,0 +1,193 @@ +/* + * Copyright © 2014 Intel Corporation + * 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. + */ + +#include "xwayland.h" + +#include <mipointer.h> + +static DevPrivateKeyRec xwl_cursor_private_key; + +static void +expand_source_and_mask(CursorPtr cursor, CARD32 *data) +{ + CARD32 *p, d, fg, bg; + CursorBitsPtr bits = cursor->bits; + int x, y, stride, i, bit; + + p = data; + 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->source[i] & bit) + d = fg; + else + d = bg; + if (bits->mask[i] & bit) + d |= 0xff000000; + else + d = 0x00000000; + + *p++ = d; + } +} + +static Bool +xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) +{ + PixmapPtr pixmap; + + pixmap = xwl_shm_create_pixmap(screen, cursor->bits->width, + cursor->bits->height, 32, 0); + dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, pixmap); + + return TRUE; +} + +static Bool +xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) +{ + PixmapPtr pixmap; + + pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); + + return xwl_shm_destroy_pixmap(pixmap); +} + +void +xwl_seat_set_cursor(struct xwl_seat *xwl_seat) +{ + PixmapPtr pixmap; + CursorPtr cursor; + int stride; + + if (!xwl_seat->wl_pointer) + return; + + if (!xwl_seat->x_cursor) { + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, NULL, 0, 0); + return; + } + + cursor = xwl_seat->x_cursor; + pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); + stride = cursor->bits->width * 4; + if (cursor->bits->argb) + memcpy(pixmap->devPrivate.ptr, + cursor->bits->argb, cursor->bits->height * stride); + else + expand_source_and_mask(cursor, pixmap->devPrivate.ptr); + + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, + xwl_seat->cursor, + xwl_seat->x_cursor->bits->xhot, + xwl_seat->x_cursor->bits->yhot); + wl_surface_attach(xwl_seat->cursor, + xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0); + wl_surface_damage(xwl_seat->cursor, 0, 0, + xwl_seat->x_cursor->bits->width, + xwl_seat->x_cursor->bits->height); + wl_surface_commit(xwl_seat->cursor); +} + +static void +xwl_set_cursor(DeviceIntPtr device, + ScreenPtr screen, CursorPtr cursor, int x, int y) +{ + struct xwl_seat *xwl_seat; + + xwl_seat = device->public.devicePrivate; + if (xwl_seat == NULL) + return; + + xwl_seat->x_cursor = cursor; + xwl_seat_set_cursor(xwl_seat); +} + +static void +xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y) +{ +} + +static Bool +xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen) +{ + return TRUE; +} + +static void +xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr 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 Bool +xwl_cursor_off_screen(ScreenPtr *ppScreen, int *x, int *y) +{ + return FALSE; +} + +static void +xwl_cross_screen(ScreenPtr pScreen, Bool entering) +{ +} + +static void +xwl_pointer_warp_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ +} + +static miPointerScreenFuncRec xwl_pointer_screen_funcs = { + xwl_cursor_off_screen, + xwl_cross_screen, + xwl_pointer_warp_cursor +}; + +Bool +xwl_screen_init_cursor(struct xwl_screen *xwl_screen) +{ + if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR_BITS, 0)) + return FALSE; + + return miPointerInitialize(xwl_screen->screen, + &xwl_pointer_sprite_funcs, + &xwl_pointer_screen_funcs, TRUE); +} |