Ticket #748: hwcursor.copyless.diff

File hwcursor.copyless.diff, 4.6 KB (added by Zsolt Dollenstein, 12 years ago)

Faster and potentially unsafe version

  • build/premake/extern_libs4.lua

     
    587587            })
    588588        end,
    589589    },
     590    Xcursor = {
     591         link_settings = function()
     592                add_default_links({
     593                    unix_names = { "Xcursor" },
     594                })
     595         end,
     596    },
    590597    zlib = {
    591598        compile_settings = function()
    592599            if os.is("windows") then
  • build/premake/premake4.lua

     
    643643            table.insert(source_dirs, "lib/sysdep/os/android")
    644644        else
    645645            table.insert(source_dirs, "lib/sysdep/os/unix/x")
     646            table.insert(extern_libs, "Xcursor")
    646647        end
    647648    end
    648649
     
    709710
    710711if not os.is("windows") and not _OPTIONS["android"] then
    711712    table.insert(used_extern_libs, "x11")
     713    table.insert(used_extern_libs, "Xcursor")
    712714end
    713715
    714716if not _OPTIONS["without-audio"] then
     
    796798            linkoptions { "-rdynamic" }
    797799        configuration { }
    798800
     801        links { "Xcursor" }
     802
    799803    elseif os.is("macosx") then
    800804        links { "pthread" }
    801805    end
  • source/lib/sysdep/os/unix/unix.cpp

     
    4545#define URL_OPEN_COMMAND "xdg-open"
    4646#endif
    4747
     48#include <X11/Xcursor/Xcursor.h>
     49#undef Status
     50#include <SDL_syswm.h>
    4851
    4952bool sys_IsDebuggerPresent()
    5053{
     
    283286    return ERR::FAIL;
    284287}
    285288
    286 // stub for sys_cursor_create - we don't need to implement this (SDL/X11 only
    287 // has monochrome cursors so we need to use the software cursor anyways)
     289struct sys_cursor_impl
     290{
     291    XcursorImage* image;
     292    Cursor cursor;
     293};
    288294
    289 // note: do not return ERR_NOT_IMPLEMENTED or similar because that
    290 // would result in WARN_ERRs.
    291 Status sys_cursor_create(size_t w, size_t h, void* bgra_img, size_t hx, size_t hy, sys_cursor* cursor)
     295Status sys_cursor_create(int w, int h, void* bgra_img, int hx, int hy, sys_cursor* cursor)
    292296{
    293     UNUSED2(w);
    294     UNUSED2(h);
    295     UNUSED2(hx);
    296     UNUSED2(hy);
    297     UNUSED2(bgra_img);
     297    XcursorImage* image = XcursorImageCreate(w, h);
    298298
    299     *cursor = 0;
     299    image->pixels = reinterpret_cast<XcursorPixel*>(bgra_img);
     300    image->xhot = hx;
     301    image->yhot = hy;
     302
     303    SDL_SysWMinfo wminfo;
     304    SDL_VERSION(&wminfo.version);
     305    if (not SDL_GetWMInfo(&wminfo))
     306        WARN_RETURN(ERR::FAIL);
     307    sys_cursor_impl* impl = new sys_cursor_impl;
     308    impl->image = image;
     309    impl->cursor = XcursorImageLoadCursor(wminfo.info.x11.display, image);
     310    *cursor = static_cast<sys_cursor>(impl);
    300311    return INFO::OK;
    301312}
    302313
    303314// returns a dummy value representing an empty cursor
    304315Status sys_cursor_create_empty(sys_cursor* cursor)
    305316{
    306     *cursor = (void*)1; // any non-zero value, since the cursor NULL has special meaning
    307     return INFO::OK;
     317    static char transparent_bgra[] = { 0x0, 0x0, 0x0, 0xFF };
     318
     319    return sys_cursor_create(1, 1, static_cast<void*>(transparent_bgra), 0, 0, cursor);
    308320}
    309321
    310322// replaces the current system cursor with the one indicated. need only be
    311323// called once per cursor; pass 0 to restore the default.
    312324Status sys_cursor_set(sys_cursor cursor)
    313325{
    314     if (cursor) // dummy empty cursor
     326    if (not cursor) // restore default cursor
    315327        SDL_ShowCursor(SDL_DISABLE);
    316     else // restore default cursor
     328    else
     329    {
     330        SDL_SysWMinfo wminfo;
     331        SDL_VERSION(&wminfo.version);
     332        if (not SDL_GetWMInfo(&wminfo))
     333            WARN_RETURN(ERR::FAIL);
     334       
     335        wminfo.info.x11.lock_func();
    317336        SDL_ShowCursor(SDL_ENABLE);
     337        XDefineCursor(wminfo.info.x11.display, wminfo.info.x11.window,
     338                      static_cast<sys_cursor_impl*>(cursor)->cursor);
     339        wminfo.info.x11.unlock_func();
     340    }
    318341
    319342    return INFO::OK;
    320343}
     
    327350    if(!cursor)
    328351        return INFO::OK;
    329352
    330     SDL_ShowCursor(SDL_ENABLE);
     353    sys_cursor_set(0); // restore default cursor
     354    sys_cursor_impl* impl = static_cast<sys_cursor_impl*>(cursor);
    331355
     356    XcursorImageDestroy(impl->image);
     357   
     358    SDL_SysWMinfo wminfo;
     359    SDL_VERSION(&wminfo.version);
     360    if (not SDL_GetWMInfo(&wminfo))
     361        return ERR::FAIL;
     362    XFreeCursor(wminfo.info.x11.display, impl->cursor);
     363
    332364    return INFO::OK;
    333365}
    334366
  • source/lib/res/graphics/cursor.cpp

     
    3939// On Windows, allow runtime choice between system cursors and OpenGL
    4040// cursors (Windows = more responsive, OpenGL = more consistent with what
    4141// the game sees)
    42 #if OS_WIN
     42#if OS_WIN || OS_UNIX
    4343# define ALLOW_SYS_CURSOR 1
    4444#else
    4545# define ALLOW_SYS_CURSOR 0