sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_DirectFB_mouse.c (11592B)


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