Ticket #748: hwcursor.osx.diff
File hwcursor.osx.diff, 16.7 KB (added by , 12 years ago) |
---|
-
source/lib/sysdep/os/android/android.cpp
23 23 #include "precompiled.h" 24 24 25 25 #include "lib/sysdep/sysdep.h" 26 #include "lib/sysdep/cursor.h" 26 27 28 #include "lib/external_libraries/libsdl.h" 29 27 30 Status sys_clipboard_set(const wchar_t* UNUSED(text)) 28 31 { 29 32 return INFO::OK; … … 61 64 } 62 65 63 66 } 67 68 // stub implementation of sys_cursor* functions 69 70 // note: do not return ERR_NOT_IMPLEMENTED or similar because that 71 // would result in WARN_ERRs. 72 Status sys_cursor_create(int w, int h, void* bgra_img, int hx, int hy, sys_cursor* cursor) 73 { 74 UNUSED2(w); 75 UNUSED2(h); 76 UNUSED2(hx); 77 UNUSED2(hy); 78 UNUSED2(bgra_img); 79 80 *cursor = 0; 81 return INFO::OK; 82 } 83 84 // returns a dummy value representing an empty cursor 85 Status sys_cursor_create_empty(sys_cursor* cursor) 86 { 87 *cursor = (void*)1; // any non-zero value, since the cursor NULL has special meaning 88 return INFO::OK; 89 } 90 91 // replaces the current system cursor with the one indicated. need only be 92 // called once per cursor; pass 0 to restore the default. 93 Status sys_cursor_set(sys_cursor cursor) 94 { 95 if (cursor) // dummy empty cursor 96 SDL_ShowCursor(SDL_DISABLE); 97 else // restore default cursor 98 SDL_ShowCursor(SDL_ENABLE); 99 100 return INFO::OK; 101 } 102 103 // destroys the indicated cursor and frees its resources. if it is 104 // currently the system cursor, the default cursor is restored first. 105 Status sys_cursor_free(sys_cursor cursor) 106 { 107 // bail now to prevent potential confusion below; there's nothing to do. 108 if(!cursor) 109 return INFO::OK; 110 111 SDL_ShowCursor(SDL_ENABLE); 112 113 return INFO::OK; 114 } 115 116 Status sys_cursor_reset() 117 { 118 return INFO::OK; 119 } 120 -
source/lib/sysdep/os/unix/unix.cpp
26 26 #include <stdio.h> 27 27 #include <wchar.h> 28 28 29 #include "lib/external_libraries/libsdl.h"30 29 #include "lib/utf8.h" 31 30 #include "lib/sysdep/sysdep.h" 32 #include "lib/sysdep/cursor.h"33 31 #include "udbg.h" 34 32 35 33 #include <boost/algorithm/string/replace.hpp> … … 45 43 #define URL_OPEN_COMMAND "xdg-open" 46 44 #endif 47 45 48 49 46 bool sys_IsDebuggerPresent() 50 47 { 51 48 return false; … … 283 280 return ERR::FAIL; 284 281 } 285 282 286 // stub for sys_cursor_create - we don't need to implement this (SDL/X11 only287 // has monochrome cursors so we need to use the software cursor anyways)288 289 // note: do not return ERR_NOT_IMPLEMENTED or similar because that290 // 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)292 {293 UNUSED2(w);294 UNUSED2(h);295 UNUSED2(hx);296 UNUSED2(hy);297 UNUSED2(bgra_img);298 299 *cursor = 0;300 return INFO::OK;301 }302 303 // returns a dummy value representing an empty cursor304 Status sys_cursor_create_empty(sys_cursor* cursor)305 {306 *cursor = (void*)1; // any non-zero value, since the cursor NULL has special meaning307 return INFO::OK;308 }309 310 // replaces the current system cursor with the one indicated. need only be311 // called once per cursor; pass 0 to restore the default.312 Status sys_cursor_set(sys_cursor cursor)313 {314 if (cursor) // dummy empty cursor315 SDL_ShowCursor(SDL_DISABLE);316 else // restore default cursor317 SDL_ShowCursor(SDL_ENABLE);318 319 return INFO::OK;320 }321 322 // destroys the indicated cursor and frees its resources. if it is323 // currently the system cursor, the default cursor is restored first.324 Status sys_cursor_free(sys_cursor cursor)325 {326 // bail now to prevent potential confusion below; there's nothing to do.327 if(!cursor)328 return INFO::OK;329 330 SDL_ShowCursor(SDL_ENABLE);331 332 return INFO::OK;333 }334 335 Status sys_cursor_reset()336 {337 return INFO::OK;338 }339 340 283 // note: just use the sector size: Linux aio doesn't really care about 341 284 // the alignment of buffers/lengths/offsets, so we'll just pick a 342 285 // sane value and not bother scanning all drives. -
source/lib/sysdep/os/unix/x/x.cpp
34 34 35 35 #include "lib/debug.h" 36 36 #include "lib/sysdep/gfx.h" 37 #include "lib/sysdep/cursor.h" 37 38 38 39 #include "ps/VideoMode.h" 39 40 … … 42 43 #include <Xlib.h> 43 44 #include <stdlib.h> 44 45 #include <Xatom.h> 46 #include <Xcursor/Xcursor.h> 45 47 46 48 #include "SDL.h" 47 49 #include "SDL_syswm.h" … … 147 149 wchar_t *sys_clipboard_get() 148 150 { 149 151 Display *disp=XOpenDisplay(NULL); 150 if 152 if(!disp) 151 153 return NULL; 152 154 153 155 // We use CLIPBOARD as the default, since the CLIPBOARD semantics are much … … 155 157 Atom selSource=XInternAtom(disp, "CLIPBOARD", False); 156 158 157 159 Window selOwner=XGetSelectionOwner(disp, selSource); 158 if 160 if(selOwner == None) 159 161 { 160 162 // However, since many apps don't use CLIPBOARD, but use PRIMARY instead 161 163 // we use XA_PRIMARY as a fallback clipboard. This is true for xterm, … … 163 165 selSource=XA_PRIMARY; 164 166 selOwner=XGetSelectionOwner(disp, selSource); 165 167 } 166 if 168 if(selOwner != None) { 167 169 Atom pty=XInternAtom(disp, "SelectionPropertyTemp", False); 168 170 XConvertSelection(disp, selSource, XA_STRING, pty, selOwner, CurrentTime); 169 171 XFlush(disp); … … 171 173 Atom type; 172 174 int format=0, result=0; 173 175 unsigned long len=0, bytes_left=0, dummy=0; 174 u nsigned char*data=NULL;176 u8 *data=NULL; 175 177 176 178 // Get the length of the property and some attributes 177 179 // bytes_left will contain the length of the selection … … 183 185 &format, // return format 184 186 &len, &bytes_left, 185 187 &data); 186 if 188 if(result != Success) 187 189 debug_printf(L"clipboard_get: result: %d type:%lu len:%lu format:%d bytes_left:%lu\n", 188 190 result, type, len, format, bytes_left); 189 if 191 if(result == Success && bytes_left > 0) 190 192 { 191 193 result = XGetWindowProperty (disp, selOwner, 192 194 pty, 0, bytes_left, 0, 193 195 AnyPropertyType, &type, &format, 194 196 &len, &dummy, &data); 195 197 196 if 198 if(result == Success) 197 199 { 198 200 debug_printf(L"clipboard_get: XGetWindowProperty succeeded, returning data\n"); 199 201 debug_printf(L"clipboard_get: data was: \"%hs\", type was %lu, XA_STRING atom is %lu\n", data, type, XA_STRING); 200 202 201 if 203 if(type == XA_STRING) //Latin-1: Just copy into low byte of wchar_t 202 204 { 203 205 wchar_t *ret=(wchar_t *)malloc((bytes_left+1)*sizeof(wchar_t)); 204 206 std::copy(data, data+bytes_left, ret); … … 239 241 { 240 242 /* Pass on all non-window manager specific events immediately */ 241 243 /* And do nothing if we don't actually have a clip-out to send out */ 242 if 244 if(event->type != SDL_SYSWMEVENT || !selection_data) 243 245 return 1; 244 246 245 247 /* Handle window-manager specific clipboard events */ … … 250 252 #else 251 253 XEvent* xevent = &event->syswm.msg->event.xevent; 252 254 #endif 253 switch 255 switch(xevent->type) { 254 256 /* Copy the selection from our buffer to the requested property, and 255 257 convert to the requested target format */ 256 258 case SelectionRequest: { … … 267 269 sevent.xselection.time = req->time; 268 270 // Simply strip all non-Latin1 characters and replace with '?' 269 271 // We should support XA_UTF8 270 if 272 if(req->target == XA_STRING) 271 273 { 272 274 size_t size = wcslen(selection_data); 273 275 u8* buf = (u8*)alloca(size); 274 276 275 for 277 for(size_t i = 0; i < size; i++) 276 278 { 277 279 buf[i] = selection_data[i] < 0x100 ? selection_data[i] : '?'; 278 280 } … … 302 304 303 305 SDL_VERSION(&info.version); 304 306 #if SDL_VERSION_ATLEAST(2, 0, 0) 305 if 307 if(SDL_GetWindowWMInfo(g_VideoMode.GetWindow(), &info)) 306 308 #else 307 if 309 if(SDL_GetWMInfo(&info)) 308 310 #endif 309 311 { 310 312 /* Save the information for later use */ 311 if 313 if(info.subsystem == SDL_SYSWM_X11) 312 314 { 313 315 g_SDL_Display = info.info.x11.display; 314 316 g_SDL_Window = info.info.x11.window; … … 352 354 353 355 debug_printf(L"sys_clipboard_set: %ls\n", str); 354 356 355 if 357 if(selection_data) 356 358 { 357 359 free(selection_data); 358 360 selection_data = NULL; … … 383 385 return INFO::OK; 384 386 } 385 387 388 struct sys_cursor_impl 389 { 390 XcursorImage* image; 391 X__Cursor cursor; 392 }; 393 394 static XcursorPixel cursor_pixel_to_x11_format(const XcursorPixel& bgra_pixel) 395 { 396 BOOST_STATIC_ASSERT(sizeof(XcursorPixel) == 4 * sizeof(u8)); 397 XcursorPixel ret; 398 u8* dst = reinterpret_cast<u8*>(&ret); 399 const u8* b = reinterpret_cast<const u8*>(&bgra_pixel); 400 const u8 a = b[3]; 401 402 for(size_t i = 0; i < 3; ++i) 403 *dst++ = (b[i]) * a / 255; 404 *dst = a; 405 return ret; 406 } 407 408 static bool get_wminfo(SDL_SysWMinfo& wminfo) 409 { 410 SDL_VERSION(&wminfo.version); 411 const int ret = SDL_GetWMInfo(&wminfo); 412 if(ret == 1) 413 return true; 414 415 if(ret == -1) 416 { 417 debug_printf(L"SDL_GetWMInfo failed\n"); 418 return false; 419 } 420 if(ret == 0) 421 { 422 debug_printf(L"SDL_GetWMInfo is not implemented on this platform\n"); 423 return false; 424 } 425 426 debug_printf(L"SDL_GetWMInfo returned an unknown value: %d\n", ret); 427 return false; 428 } 429 430 Status sys_cursor_create(int w, int h, void* bgra_img, int hx, int hy, sys_cursor* cursor) 431 { 432 debug_printf(L"Using Xcursor to sys_cursor_create %d x %d cursor\n", w, h); 433 XcursorImage* image = XcursorImageCreate(w, h); 434 if(!image) 435 WARN_RETURN(ERR::FAIL); 436 437 const XcursorPixel* bgra_img_begin = reinterpret_cast<XcursorPixel*>(bgra_img); 438 std::transform(bgra_img_begin, bgra_img_begin + (w*h), image->pixels, 439 cursor_pixel_to_x11_format); 440 image->xhot = hx; 441 image->yhot = hy; 442 443 SDL_SysWMinfo wminfo; 444 if(!get_wminfo(wminfo)) 445 WARN_RETURN(ERR::FAIL); 446 447 sys_cursor_impl* impl = new sys_cursor_impl; 448 impl->image = image; 449 impl->cursor = XcursorImageLoadCursor(wminfo.info.x11.display, image); 450 if(impl->cursor == None) 451 WARN_RETURN(ERR::FAIL); 452 453 *cursor = static_cast<sys_cursor>(impl); 454 return INFO::OK; 455 } 456 457 // returns a dummy value representing an empty cursor 458 Status sys_cursor_create_empty(sys_cursor* cursor) 459 { 460 static u8 transparent_bgra[] = { 0x0, 0x0, 0x0, 0x0 }; 461 462 return sys_cursor_create(1, 1, static_cast<void*>(transparent_bgra), 0, 0, cursor); 463 } 464 465 // replaces the current system cursor with the one indicated. need only be 466 // called once per cursor; pass 0 to restore the default. 467 Status sys_cursor_set(sys_cursor cursor) 468 { 469 if(!cursor) // restore default cursor 470 SDL_ShowCursor(SDL_DISABLE); 471 else 472 { 473 SDL_SysWMinfo wminfo; 474 if(!get_wminfo(wminfo)) 475 WARN_RETURN(ERR::FAIL); 476 477 wminfo.info.x11.lock_func(); 478 SDL_ShowCursor(SDL_ENABLE); 479 // wminfo.info.x11.window is sometimes 0, in which case 480 // it causes a crash; in these cases use fswindow instead 481 Window& window = wminfo.info.x11.window ? wminfo.info.x11.window : wminfo.info.x11.fswindow; 482 XDefineCursor(wminfo.info.x11.display, window, 483 static_cast<sys_cursor_impl*>(cursor)->cursor); 484 wminfo.info.x11.unlock_func(); 485 } 486 487 return INFO::OK; 488 } 489 490 // destroys the indicated cursor and frees its resources. if it is 491 // currently the system cursor, the default cursor is restored first. 492 Status sys_cursor_free(sys_cursor cursor) 493 { 494 // bail now to prevent potential confusion below; there's nothing to do. 495 if(!cursor) 496 return INFO::OK; 497 498 sys_cursor_set(0); // restore default cursor 499 sys_cursor_impl* impl = static_cast<sys_cursor_impl*>(cursor); 500 501 XcursorImageDestroy(impl->image); 502 503 SDL_SysWMinfo wminfo; 504 if(!get_wminfo(wminfo)) 505 return ERR::FAIL; 506 XFreeCursor(wminfo.info.x11.display, impl->cursor); 507 508 delete impl; 509 510 return INFO::OK; 511 } 512 513 Status sys_cursor_reset() 514 { 515 return INFO::OK; 516 } 517 518 386 519 #endif // #if HAVE_X -
source/lib/sysdep/os/osx/osx_sys_cursor.mm
1 /* Copyright (c) 2012 Wildfire Games 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining 4 * a copy of this software and associated documentation files (the 5 * "Software"), to deal in the Software without restriction, including 6 * without limitation the rights to use, copy, modify, merge, publish, 7 * distribute, sublicense, and/or sell copies of the Software, and to 8 * permit persons to whom the Software is furnished to do so, subject to 9 * the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23 #include "precompiled.h" 24 #include "lib/sysdep/cursor.h" 25 26 #import <AppKit/NSCursor.h> 27 #import <AppKit/NSImage.h> 28 #import <ApplicationServices/ApplicationServices.h> 29 30 //TODO: make sure these are threadsafe 31 Status sys_cursor_create(int w, int h, void* bgra_img, int hx, int hy, sys_cursor* cursor) 32 { 33 NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] 34 initWithBitmapDataPlanes:0 pixelsWide:w pixelsHigh:h 35 bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO 36 colorSpaceName:NSCalibratedRGBColorSpace bytesPerRow:w*4 bitsPerPixel:0]; 37 if (!bitmap) 38 { 39 debug_printf(L"sys_cursor_create: Error creating NSBitmapImageRep!\n"); 40 return ERR::FAIL; 41 } 42 u8* planes[5]; 43 [bitmap getBitmapDataPlanes:planes]; 44 const u8* bgra = static_cast<const u8*>(bgra_img); 45 u8* dst = planes[0]; 46 for (int i = 0; i < w*h*4; i += 4) 47 { 48 dst[i] = bgra[i+2]; 49 dst[i+1] = bgra[i+1]; 50 dst[i+2] = bgra[i]; 51 dst[i+3] = bgra[i+3]; 52 } 53 54 NSImage* image = [[NSImage alloc] init]; 55 if (!image) 56 { 57 debug_printf(L"sys_cursor_create: Error creating NSImage!\n"); 58 return ERR::FAIL; 59 } 60 61 [image addRepresentation:bitmap]; 62 NSCursor* impl = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(hx, hy)]; 63 64 if (!impl) 65 { 66 debug_printf(L"sys_cursor_create: Error creating NSCursor!\n"); 67 return ERR::FAIL; 68 } 69 70 [image release]; 71 72 *cursor = static_cast<sys_cursor>(impl); 73 74 return INFO::OK; 75 } 76 77 Status sys_cursor_free(sys_cursor cursor) 78 { 79 NSCursor* impl = static_cast<NSCursor*>(cursor); 80 [impl release]; 81 return INFO::OK; 82 } 83 84 Status sys_cursor_create_empty(sys_cursor* cursor) 85 { 86 static u8 empty_bgra[] = {0, 0, 0, 0}; 87 sys_cursor_create(1, 1, reinterpret_cast<void*>(empty_bgra), 0, 0, cursor); 88 return INFO::OK; 89 } 90 91 Status sys_cursor_set(sys_cursor cursor) 92 { 93 NSCursor* impl = static_cast<NSCursor*>(cursor); 94 [impl set]; 95 return INFO::OK; 96 } 97 98 Status sys_cursor_reset() 99 { 100 return INFO::OK; 101 } 102 -
source/lib/res/graphics/cursor.cpp
39 39 // On Windows, allow runtime choice between system cursors and OpenGL 40 40 // cursors (Windows = more responsive, OpenGL = more consistent with what 41 41 // the game sees) 42 #if OS_WIN 42 #if OS_WIN || OS_UNIX 43 43 # define ALLOW_SYS_CURSOR 1 44 44 #else 45 45 # define ALLOW_SYS_CURSOR 0 -
build/premake/extern_libs4.lua
587 587 }) 588 588 end, 589 589 }, 590 xcursor = { 591 link_settings = function() 592 add_default_links({ 593 unix_names = { "Xcursor" }, 594 }) 595 end, 596 }, 590 597 zlib = { 591 598 compile_settings = function() 592 599 if os.is("windows") then -
build/premake/premake4.lua
707 707 "valgrind", 708 708 } 709 709 710 if not os.is("windows") and not _OPTIONS["android"] then710 if not os.is("windows") and not _OPTIONS["android"] and not os.is("macosx") then 711 711 table.insert(used_extern_libs, "x11") 712 table.insert(used_extern_libs, "xcursor") 712 713 end 713 714 714 715 if not _OPTIONS["without-audio"] then … … 798 799 799 800 elseif os.is("macosx") then 800 801 links { "pthread" } 802 linkoptions { "-framework AppKit" } 801 803 end 802 804 end 803 805