cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_DirectFB_mouse.c (11707B)


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