Atlas - SDL_DirectFB_mouse.c
Home / ext / SDL2 / src / video / directfb Lines: 1 | Size: 11616 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "../../SDL_internal.h" 22 23#if SDL_VIDEO_DRIVER_DIRECTFB 24 25#include "SDL_assert.h" 26 27#include "SDL_DirectFB_video.h" 28#include "SDL_DirectFB_mouse.h" 29#include "SDL_DirectFB_modes.h" 30#include "SDL_DirectFB_window.h" 31 32#include "../SDL_sysvideo.h" 33#include "../../events/SDL_mouse_c.h" 34 35static SDL_Cursor *DirectFB_CreateDefaultCursor(void); 36static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface, 37 int hot_x, int hot_y); 38static int DirectFB_ShowCursor(SDL_Cursor * cursor); 39static void DirectFB_FreeCursor(SDL_Cursor * cursor); 40static void DirectFB_WarpMouse(SDL_Window * window, int x, int y); 41 42static const char *arrow[] = { 43 /* pixels */ 44 "X ", 45 "XX ", 46 "X.X ", 47 "X..X ", 48 "X...X ", 49 "X....X ", 50 "X.....X ", 51 "X......X ", 52 "X.......X ", 53 "X........X ", 54 "X.....XXXXX ", 55 "X..X..X ", 56 "X.X X..X ", 57 "XX X..X ", 58 "X X..X ", 59 " X..X ", 60 " X..X ", 61 " X..X ", 62 " XX ", 63 " ", 64 " ", 65 " ", 66 " ", 67 " ", 68 " ", 69 " ", 70 " ", 71 " ", 72 " ", 73 " ", 74 " ", 75 " ", 76}; 77 78static SDL_Cursor * 79DirectFB_CreateDefaultCursor(void) 80{ 81 SDL_VideoDevice *dev = SDL_GetVideoDevice(); 82 83 SDL_DFB_DEVICEDATA(dev); 84 DFB_CursorData *curdata; 85 DFBSurfaceDescription dsc; 86 SDL_Cursor *cursor; 87 Uint32 *dest; 88 int pitch, i, j; 89 90 SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor)); 91 SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata)); 92 93 dsc.flags = 94 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; 95 dsc.caps = DSCAPS_VIDEOONLY; 96 dsc.width = 32; 97 dsc.height = 32; 98 dsc.pixelformat = DSPF_ARGB; 99 100 SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, 101 &curdata->surf)); 102 curdata->hotx = 0; 103 curdata->hoty = 0; 104 cursor->driverdata = curdata; 105 106 SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE, 107 (void *) &dest, &pitch)); 108 109 /* Relies on the fact that this is only called with ARGB surface. */ 110 for (i = 0; i < 32; i++) 111 { 112 for (j = 0; j < 32; j++) 113 { 114 switch (arrow[i][j]) 115 { 116 case ' ': dest[j] = 0x00000000; break; 117 case '.': dest[j] = 0xffffffff; break; 118 case 'X': dest[j] = 0xff000000; break; 119 } 120 } 121 dest += (pitch >> 2); 122 } 123 124 curdata->surf->Unlock(curdata->surf); 125 return cursor; 126 error: 127 return NULL; 128} 129 130/* Create a cursor from a surface */ 131static SDL_Cursor * 132DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) 133{ 134 SDL_VideoDevice *dev = SDL_GetVideoDevice(); 135 136 SDL_DFB_DEVICEDATA(dev); 137 DFB_CursorData *curdata; 138 DFBSurfaceDescription dsc; 139 SDL_Cursor *cursor; 140 Uint32 *dest; 141 Uint32 *p; 142 int pitch, i; 143 144 SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); 145 SDL_assert(surface->pitch == surface->w * 4); 146 147 SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor)); 148 SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata)); 149 150 dsc.flags = 151 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; 152 dsc.caps = DSCAPS_VIDEOONLY; 153 dsc.width = surface->w; 154 dsc.height = surface->h; 155 dsc.pixelformat = DSPF_ARGB; 156 157 SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, 158 &curdata->surf)); 159 curdata->hotx = hot_x; 160 curdata->hoty = hot_y; 161 cursor->driverdata = curdata; 162 163 SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE, 164 (void *) &dest, &pitch)); 165 166 p = surface->pixels; 167 for (i = 0; i < surface->h; i++) 168 memcpy((char *) dest + i * pitch, 169 (char *) p + i * surface->pitch, 4 * surface->w); 170 171 curdata->surf->Unlock(curdata->surf); 172 return cursor; 173 error: 174 return NULL; 175} 176 177/* Show the specified cursor, or hide if cursor is NULL */ 178static int 179DirectFB_ShowCursor(SDL_Cursor * cursor) 180{ 181 SDL_DFB_CURSORDATA(cursor); 182 SDL_Window *window; 183 184 window = SDL_GetFocusWindow(); 185 if (!window) 186 return -1; 187 else { 188 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); 189 190 if (display) { 191 DFB_DisplayData *dispdata = 192 (DFB_DisplayData *) display->driverdata; 193 DFB_WindowData *windata = (DFB_WindowData *) window->driverdata; 194 195 if (cursor) 196 SDL_DFB_CHECKERR(windata->dfbwin-> 197 SetCursorShape(windata->dfbwin, 198 curdata->surf, curdata->hotx, 199 curdata->hoty)); 200 201 SDL_DFB_CHECKERR(dispdata->layer-> 202 SetCooperativeLevel(dispdata->layer, 203 DLSCL_ADMINISTRATIVE)); 204 SDL_DFB_CHECKERR(dispdata->layer-> 205 SetCursorOpacity(dispdata->layer, 206 cursor ? 0xC0 : 0x00)); 207 SDL_DFB_CHECKERR(dispdata->layer-> 208 SetCooperativeLevel(dispdata->layer, 209 DLSCL_SHARED)); 210 } 211 } 212 213 return 0; 214 error: 215 return -1; 216} 217 218/* Free a window manager cursor */ 219static void 220DirectFB_FreeCursor(SDL_Cursor * cursor) 221{ 222 SDL_DFB_CURSORDATA(cursor); 223 224 SDL_DFB_RELEASE(curdata->surf); 225 SDL_DFB_FREE(cursor->driverdata); 226 SDL_DFB_FREE(cursor); 227} 228 229/* Warp the mouse to (x,y) */ 230static void 231DirectFB_WarpMouse(SDL_Window * window, int x, int y) 232{ 233 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); 234 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; 235 DFB_WindowData *windata = (DFB_WindowData *) window->driverdata; 236 int cx, cy; 237 238 SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy)); 239 SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer, 240 cx + x + windata->client.x, 241 cy + y + windata->client.y)); 242 243 error: 244 return; 245} 246 247#if USE_MULTI_API 248 249static void DirectFB_MoveCursor(SDL_Cursor * cursor); 250static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, 251 int x, int y); 252static void DirectFB_FreeMouse(SDL_Mouse * mouse); 253 254static int id_mask; 255 256static DFBEnumerationResult 257EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, 258 void *callbackdata) 259{ 260 DFB_DeviceData *devdata = callbackdata; 261 262 if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) { 263 SDL_Mouse mouse; 264 265 SDL_zero(mouse); 266 mouse.id = device_id; 267 mouse.CreateCursor = DirectFB_CreateCursor; 268 mouse.ShowCursor = DirectFB_ShowCursor; 269 mouse.MoveCursor = DirectFB_MoveCursor; 270 mouse.FreeCursor = DirectFB_FreeCursor; 271 mouse.WarpMouse = DirectFB_WarpMouse; 272 mouse.FreeMouse = DirectFB_FreeMouse; 273 mouse.cursor_shown = 1; 274 275 SDL_AddMouse(&mouse, desc.name, 0, 0, 1); 276 devdata->mouse_id[devdata->num_mice++] = device_id; 277 } 278 return DFENUM_OK; 279} 280 281void 282DirectFB_InitMouse(_THIS) 283{ 284 SDL_DFB_DEVICEDATA(_this); 285 286 devdata->num_mice = 0; 287 if (devdata->use_linux_input) { 288 /* try non-core devices first */ 289 id_mask = 0xF0; 290 devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata); 291 if (devdata->num_mice == 0) { 292 /* try core devices */ 293 id_mask = 0x0F; 294 devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata); 295 } 296 } 297 if (devdata->num_mice == 0) { 298 SDL_Mouse mouse; 299 300 SDL_zero(mouse); 301 mouse.CreateCursor = DirectFB_CreateCursor; 302 mouse.ShowCursor = DirectFB_ShowCursor; 303 mouse.MoveCursor = DirectFB_MoveCursor; 304 mouse.FreeCursor = DirectFB_FreeCursor; 305 mouse.WarpMouse = DirectFB_WarpMouse; 306 mouse.FreeMouse = DirectFB_FreeMouse; 307 mouse.cursor_shown = 1; 308 309 SDL_AddMouse(&mouse, "Mouse", 0, 0, 1); 310 devdata->num_mice = 1; 311 } 312} 313 314void 315DirectFB_QuitMouse(_THIS) 316{ 317 SDL_DFB_DEVICEDATA(_this); 318 319 if (devdata->use_linux_input) { 320 SDL_MouseQuit(); 321 } else { 322 SDL_DelMouse(0); 323 } 324} 325 326 327/* This is called when a mouse motion event occurs */ 328static void 329DirectFB_MoveCursor(SDL_Cursor * cursor) 330{ 331 332} 333 334/* Warp the mouse to (x,y) */ 335static void 336DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y) 337{ 338 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); 339 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; 340 DFB_WindowData *windata = (DFB_WindowData *) window->driverdata; 341 DFBResult ret; 342 int cx, cy; 343 344 SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy)); 345 SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer, 346 cx + x + windata->client.x, 347 cy + y + windata->client.y)); 348 349 error: 350 return; 351} 352 353/* Free the mouse when it's time */ 354static void 355DirectFB_FreeMouse(SDL_Mouse * mouse) 356{ 357 /* nothing yet */ 358} 359 360#else /* USE_MULTI_API */ 361 362void 363DirectFB_InitMouse(_THIS) 364{ 365 SDL_DFB_DEVICEDATA(_this); 366 367 SDL_Mouse *mouse = SDL_GetMouse(); 368 369 mouse->CreateCursor = DirectFB_CreateCursor; 370 mouse->ShowCursor = DirectFB_ShowCursor; 371 mouse->WarpMouse = DirectFB_WarpMouse; 372 mouse->FreeCursor = DirectFB_FreeCursor; 373 374 SDL_SetDefaultCursor(DirectFB_CreateDefaultCursor()); 375 376 devdata->num_mice = 1; 377} 378 379void 380DirectFB_QuitMouse(_THIS) 381{ 382} 383 384 385#endif 386 387#endif /* SDL_VIDEO_DRIVER_DIRECTFB */ 388 389/* vi: set ts=4 sw=4 expandtab: */ 390[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.