From c534a0f2dfda82aed28deb4e3b32860896bb8a9a Mon Sep 17 00:00:00 2001 From: "huiyu.eun" Date: Thu, 7 Jul 2016 11:31:47 +0900 Subject: [PATCH] [SDL_Tizen] Add Tizen Mouse 1. Add Tizen_InitMouse() function and call in VideoInit() 2. Add new function of mouse - Tizen_CreateCursor() - Tizen_ShowCursor() - Tizen_FreeCursor() 3. When create window, set the mouse focus Change-Id: I0580464cc3117a9913c6850d2f1b13c95fa9dd80 Signed-off-by: huiyu.eun --- src/video/tizen/SDL_tizenmouse.c | 213 ++++++++++++++++++++++++++++++++++++++ src/video/tizen/SDL_tizenmouse.h | 2 + src/video/tizen/SDL_tizenvideo.c | 2 + src/video/tizen/SDL_tizenwindow.c | 2 + 4 files changed, 219 insertions(+) diff --git a/src/video/tizen/SDL_tizenmouse.c b/src/video/tizen/SDL_tizenmouse.c index 0544704..ff4cb92 100644 --- a/src/video/tizen/SDL_tizenmouse.c +++ b/src/video/tizen/SDL_tizenmouse.c @@ -21,9 +21,222 @@ */ #include "../../SDL_internal.h" +#include "../../events/SDL_mouse_c.h" + #include "SDL_tizenmouse.h" #include "SDL_log.h" +#include +#include + + +typedef struct { + struct wl_buffer *buffer; + struct wl_surface *surface; + SDL_WindowData *win_data; + + int hot_x, hot_y; + int w, h; + + /* Either a preloaded cursor, or one we created ourselves */ + struct wl_cursor *cursor; + void *shm_data; +} Tizen_CursorData; + +static int +wayland_create_tmp_file(off_t size) +{ + static const char template[] = "/sdl-shared-XXXXXX"; + char *xdg_path; + char tmp_path[PATH_MAX]; + int fd; + + xdg_path = SDL_getenv("XDG_RUNTIME_DIR"); + if (!xdg_path) { + errno = ENOENT; + return -1; + } + + SDL_strlcpy(tmp_path, xdg_path, PATH_MAX); + SDL_strlcat(tmp_path, template, PATH_MAX); + + fd = mkostemp(tmp_path, O_CLOEXEC); + if (fd < 0) + return -1; + + if (ftruncate(fd, size) < 0) { + close(fd); + return -1; + } + + return fd; +} + +static void +mouse_buffer_release(void *data, struct wl_buffer *buffer) +{ +} + +static const struct wl_buffer_listener mouse_buffer_listener = { + mouse_buffer_release +}; + +static int +create_buffer_from_shm(Tizen_CursorData *d, int width, int height, uint32_t format) +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *data = (SDL_VideoData *) vd->driverdata; + struct wl_shm_pool *shm_pool; + + int stride = width * 4; + int size = stride * height; + + int shm_fd; + + shm_fd = wayland_create_tmp_file(size); + if (shm_fd < 0) + { + fprintf(stderr, "creating mouse cursor buffer failed!\n"); + return -1; + } + + d->shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + if (d->shm_data == MAP_FAILED) { + d->shm_data = NULL; + fprintf (stderr, "mmap () failed\n"); + close (shm_fd); + } + + shm_pool = wl_shm_create_pool(ecore_wl_shm_get(), shm_fd, size); + d->buffer = wl_shm_pool_create_buffer(shm_pool, 0, width, height, stride, format); + wl_buffer_add_listener(d->buffer, &mouse_buffer_listener, d); + + wl_shm_pool_destroy (shm_pool); + close (shm_fd); + + return 0; +} + +static SDL_Cursor * +Tizen_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) +{ + SDL_Cursor *cursor; + + cursor = calloc(1, sizeof (*cursor)); + if (cursor) { + SDL_VideoDevice *vd = SDL_GetVideoDevice (); + SDL_Window* window = vd->windows; + + Tizen_CursorData *data = calloc (1, sizeof (Tizen_CursorData)); + data->win_data = window->driverdata; + cursor->driverdata = (void *) data; + + /* Assume ARGB8888 */ + SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); + SDL_assert(surface->pitch == surface->w * 4); + + /* Allocate shared memory buffer for this cursor */ + if (create_buffer_from_shm (data, + surface->w, + surface->h, + WL_SHM_FORMAT_XRGB8888) < 0) + { + free (cursor->driverdata); + free (cursor); + return NULL; + } + + SDL_memcpy(data->shm_data, + surface->pixels, + surface->h * surface->pitch); + + data->surface = wl_compositor_create_surface(ecore_wl_compositor_get()); + + data->hot_x = hot_x; + data->hot_y = hot_y; + data->w = surface->w; + data->h = surface->h; + } + + return cursor; +} + + +static void +Tizen_FreeCursor(SDL_Cursor *cursor) +{ + Tizen_CursorData *d; + + if (!cursor) + return; + + d = cursor->driverdata; + + /* Probably not a cursor we own */ + if (!d) + return; + + if (d->buffer && !d->cursor) + wl_buffer_destroy(d->buffer); + + if (d->surface) + wl_surface_destroy(d->surface); + + /* Not sure what's meant to happen to shm_data */ + free (cursor->driverdata); + SDL_free(cursor); +} + +static int +Tizen_ShowCursor(SDL_Cursor *cursor) +{ + if (cursor) + { + Tizen_CursorData *data = cursor->driverdata; + SDL_WindowData *win_data = data->win_data; + ecore_wl_window_buffer_attach(win_data->window, data->buffer, 0,0); + ecore_wl_input_pointer_set(ecore_wl_input_get(), data->surface, data->hot_x, data->hot_y); + } + else + { + ecore_wl_input_pointer_set(ecore_wl_input_get(), NULL, 0, 0); + } + + return 0; +} + +void +Tizen_InitMouse(void) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + mouse->CreateCursor = Tizen_CreateCursor; + mouse->ShowCursor = Tizen_ShowCursor; + mouse->FreeCursor = Tizen_FreeCursor; +} + +void +Tizen_FiniMouse(void) +{ + /* This effectively assumes that nobody else touches SDL_Mouse which is effectively a singleton */ + SDL_Mouse *mouse = SDL_GetMouse(); + + /* Free the current cursor if not the same pointer as + * the default cursor */ + if (mouse->def_cursor != mouse->cur_cursor) + Tizen_FreeCursor (mouse->cur_cursor); + + Tizen_FreeCursor (mouse->def_cursor); + mouse->def_cursor = NULL; + mouse->cur_cursor = NULL; + + mouse->CreateCursor = NULL; + mouse->CreateSystemCursor = NULL; + mouse->ShowCursor = NULL; + mouse->FreeCursor = NULL; + mouse->WarpMouse = NULL; + mouse->SetRelativeMouseMode = NULL; +} Eina_Bool __tizen_cb_event_mousedown_change(void *data, int type, void *event) diff --git a/src/video/tizen/SDL_tizenmouse.h b/src/video/tizen/SDL_tizenmouse.h index 2c2c0a8..45d20db 100644 --- a/src/video/tizen/SDL_tizenmouse.h +++ b/src/video/tizen/SDL_tizenmouse.h @@ -26,6 +26,8 @@ #include "SDL_tizenwindow.h" #include "SDL_events.h" +#include "SDL_assert.h" + extern Eina_Bool __tizen_cb_event_mouseup_change(void *data, int type, void *event); extern Eina_Bool __tizen_cb_event_mousedown_change(void *data, int type, void *event); extern Eina_Bool __tizen_cb_event_mousemove_change(void *data, int type, void *event); diff --git a/src/video/tizen/SDL_tizenvideo.c b/src/video/tizen/SDL_tizenvideo.c index 341883b..b62dcbb 100644 --- a/src/video/tizen/SDL_tizenvideo.c +++ b/src/video/tizen/SDL_tizenvideo.c @@ -161,6 +161,7 @@ Tizen_VideoInit(_THIS) __tizen_add_display(data, 0); Tizen_InitWindow(_this); + Tizen_InitMouse(); return 0; } @@ -183,6 +184,7 @@ Tizen_VideoQuit(_THIS) Tizen_DeinitWindow(_this); Tizen_FiniKeyboard(); + Tizen_FiniMouse(); SDL_tizen_app_exit(); ecore_wl_shutdown(); free(data); diff --git a/src/video/tizen/SDL_tizenwindow.c b/src/video/tizen/SDL_tizenwindow.c index 8e4debb..c6298ee 100644 --- a/src/video/tizen/SDL_tizenwindow.c +++ b/src/video/tizen/SDL_tizenwindow.c @@ -108,6 +108,8 @@ Tizen_CreateWindow(_THIS, SDL_Window *window) if(keyboard.imf_context == NULL) Tizen_InitKeyboard(_this); + SDL_SetMouseFocus(window); + return 0; } -- 2.7.4