Ticket #748: hwcursor.2.diff

File hwcursor.2.diff, 4.7 KB (added by Zsolt Dollenstein, 12 years ago)

work in progress - should work on unix (for real)

  • 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    std::copy(static_cast<char*>(bgra_img), static_cast<char*>(bgra_img) + 4 * w * h,
     300              reinterpret_cast<char*>(image->pixels));
     301    image->xhot = hx;
     302    image->yhot = hy;
     303
     304    SDL_SysWMinfo wminfo;
     305    SDL_VERSION(&wminfo.version);
     306    if (not SDL_GetWMInfo(&wminfo))
     307        WARN_RETURN(ERR::FAIL);
     308    sys_cursor_impl* impl = new sys_cursor_impl;
     309    impl->image = image;
     310    impl->cursor = XcursorImageLoadCursor(wminfo.info.x11.display, image);
     311    *cursor = static_cast<sys_cursor>(impl);
    300312    return INFO::OK;
    301313}
    302314
    303315// returns a dummy value representing an empty cursor
    304316Status sys_cursor_create_empty(sys_cursor* cursor)
    305317{
    306     *cursor = (void*)1; // any non-zero value, since the cursor NULL has special meaning
    307     return INFO::OK;
     318    static char transparent_bgra[] = { 0x0, 0x0, 0x0, 0xFF };
     319
     320    return sys_cursor_create(1, 1, static_cast<void*>(transparent_bgra), 0, 0, cursor);
    308321}
    309322
    310323// replaces the current system cursor with the one indicated. need only be
    311324// called once per cursor; pass 0 to restore the default.
    312325Status sys_cursor_set(sys_cursor cursor)
    313326{
    314     if (cursor) // dummy empty cursor
     327    if (not cursor) // restore default cursor
    315328        SDL_ShowCursor(SDL_DISABLE);
    316     else // restore default cursor
     329    else
     330    {
     331        SDL_SysWMinfo wminfo;
     332        SDL_VERSION(&wminfo.version);
     333        if (not SDL_GetWMInfo(&wminfo))
     334            WARN_RETURN(ERR::FAIL);
     335       
     336        wminfo.info.x11.lock_func();
    317337        SDL_ShowCursor(SDL_ENABLE);
     338        XDefineCursor(wminfo.info.x11.display, wminfo.info.x11.window,
     339                      static_cast<sys_cursor_impl*>(cursor)->cursor);
     340        wminfo.info.x11.unlock_func();
     341    }
    318342
    319343    return INFO::OK;
    320344}
     
    327351    if(!cursor)
    328352        return INFO::OK;
    329353
    330     SDL_ShowCursor(SDL_ENABLE);
     354    sys_cursor_set(0); // restore default cursor
     355    sys_cursor_impl* impl = static_cast<sys_cursor_impl*>(cursor);
    331356
     357    XcursorImageDestroy(impl->image);
     358   
     359    SDL_SysWMinfo wminfo;
     360    SDL_VERSION(&wminfo.version);
     361    if (not SDL_GetWMInfo(&wminfo))
     362        return ERR::FAIL;
     363    XFreeCursor(wminfo.info.x11.display, impl->cursor);
     364
    332365    return INFO::OK;
    333366}
    334367
  • 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