Ticket #748: hwcursor.2.diff

File hwcursor.2.diff, 4.7 KB (added by zsol, 14 months 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