GHOST: add GHOST_HasWindowCursorShape() to test if standard cursor exists
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 26 Sep 2019 12:31:43 +0000 (14:31 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 26 Sep 2019 12:31:43 +0000 (14:31 +0200)
Ref D5197

intern/ghost/GHOST_C-api.h
intern/ghost/GHOST_IWindow.h
intern/ghost/intern/GHOST_C-api.cpp
intern/ghost/intern/GHOST_WindowCocoa.h
intern/ghost/intern/GHOST_WindowCocoa.mm
intern/ghost/intern/GHOST_WindowSDL.cpp
intern/ghost/intern/GHOST_WindowSDL.h
intern/ghost/intern/GHOST_WindowWin32.cpp
intern/ghost/intern/GHOST_WindowWin32.h
intern/ghost/intern/GHOST_WindowX11.cpp
intern/ghost/intern/GHOST_WindowX11.h

index 9c6a0861280f12c70a24e8d303800416dbf45ad1..20bb144a9245b6691b1cf055b93b8ec40e38c06c 100644 (file)
@@ -316,7 +316,8 @@ extern GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle);
 extern GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle);
 
 /**
- * Set the shape of the cursor.
+ * Set the shape of the cursor. If the shape is not supported by the platform,
+ * it will use the default cursor instead.
  * \param windowhandle The handle to the window
  * \param cursorshape The new cursor shape type id.
  * \return Indication of success.
@@ -324,6 +325,13 @@ extern GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandl
 extern GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle,
                                            GHOST_TStandardCursor cursorshape);
 
+/**
+ * Test if the standard cursor shape is supported by current platform.
+ * \return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_HasCursorShape(GHOST_WindowHandle windowhandle,
+                                           GHOST_TStandardCursor cursorshape);
+
 /**
  * Set the shape of the cursor to a custom cursor of specified size.
  * \param windowhandle The handle to the window
index 1a1844bfe41fcae6b73e492656c0eaaa02ec8019..03a0db9abbea53d6dfc9476a231a77f569dd50ac 100644 (file)
@@ -279,6 +279,12 @@ class GHOST_IWindow {
    */
   virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape) = 0;
 
+  /**
+   * Test if the standard cursor shape is supported by current platform.
+   * \return Indication of success.
+   */
+  virtual GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor cursorShape) = 0;
+
   /**
    * Set the shape of the cursor to a custom cursor.
    * \param   bitmap  The bitmap data for the cursor.
index 78f171af7d1caa5173c50ff9b59aafdbe42f1283..a1a209af77af170efa21eabb0a258bf20a9fd406 100644 (file)
@@ -264,6 +264,14 @@ GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle,
   return window->setCursorShape(cursorshape);
 }
 
+GHOST_TSuccess GHOST_HasCursorShape(GHOST_WindowHandle windowhandle,
+                                    GHOST_TStandardCursor cursorshape)
+{
+  GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+
+  return window->hasCursorShape(cursorshape);
+}
+
 GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle,
                                           GHOST_TUns8 *bitmap,
                                           GHOST_TUns8 *mask,
index 5e857c05a09e6b47789581a27df684009c5cf315..66de8bcf7cc4792b3519dd5b5c1f157d58000996 100644 (file)
@@ -215,6 +215,7 @@ class GHOST_WindowCocoa : public GHOST_Window {
    */
   GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
 
+  NSCursor *getStandardCursor(GHOST_TStandardCursor cursor) const;
   void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
 
   const GHOST_TabletData *GetTabletData()
@@ -296,6 +297,7 @@ class GHOST_WindowCocoa : public GHOST_Window {
    * native window system calls.
    */
   GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+  GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor shape);
 
   /**
    * Sets the cursor shape on the window using
index 0b8e808b84e31569afb2ca0341c7a3694cff29e5..dcf6d5da487bcd17e8c439353f0c5e210125c7c8 100644 (file)
@@ -925,12 +925,56 @@ GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
 
 #pragma mark Cursor handling
 
-void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
+NSCursor *GHOST_WindowCocoa::getStandardCursor(GHOST_TStandardCursor shape) const
 {
-  static bool systemCursorVisible = true;
-
-  NSCursor *tmpCursor = nil;
+  switch (shape) {
+    case GHOST_kStandardCursorCustom:
+      if (m_customCursor) {
+        return m_customCursor;
+      }
+      else {
+        return NULL;
+      }
+    case GHOST_kStandardCursorDestroy:
+      return [NSCursor disappearingItemCursor];
+    case GHOST_kStandardCursorText:
+      return [NSCursor IBeamCursor];
+    case GHOST_kStandardCursorCrosshair:
+      return [NSCursor crosshairCursor];
+    case GHOST_kStandardCursorUpDown:
+      return [NSCursor resizeUpDownCursor];
+    case GHOST_kStandardCursorLeftRight:
+      return [NSCursor resizeLeftRightCursor];
+    case GHOST_kStandardCursorTopSide:
+      return [NSCursor resizeUpCursor];
+    case GHOST_kStandardCursorBottomSide:
+      return [NSCursor resizeDownCursor];
+    case GHOST_kStandardCursorLeftSide:
+      return [NSCursor resizeLeftCursor];
+    case GHOST_kStandardCursorRightSide:
+      return [NSCursor resizeRightCursor];
+    case GHOST_kStandardCursorRightArrow:
+    case GHOST_kStandardCursorInfo:
+    case GHOST_kStandardCursorLeftArrow:
+    case GHOST_kStandardCursorHelp:
+    case GHOST_kStandardCursorCycle:
+    case GHOST_kStandardCursorSpray:
+    case GHOST_kStandardCursorWait:
+    case GHOST_kStandardCursorTopLeftCorner:
+    case GHOST_kStandardCursorTopRightCorner:
+    case GHOST_kStandardCursorBottomRightCorner:
+    case GHOST_kStandardCursorBottomLeftCorner:
+    case GHOST_kStandardCursorCopy:
+    case GHOST_kStandardCursorDefault:
+      return [NSCursor arrowCursor];
+    default:
+      return NULL;
+  }
+}
 
+void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor shape) const
+{
+  static bool systemCursorVisible = true;
   if (visible != systemCursorVisible) {
     if (visible) {
       [NSCursor unhide];
@@ -942,57 +986,12 @@ void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) c
     }
   }
 
-  if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
-    tmpCursor = m_customCursor;
-  }
-  else {
-    switch (cursor) {
-      case GHOST_kStandardCursorDestroy:
-        tmpCursor = [NSCursor disappearingItemCursor];
-        break;
-      case GHOST_kStandardCursorText:
-        tmpCursor = [NSCursor IBeamCursor];
-        break;
-      case GHOST_kStandardCursorCrosshair:
-        tmpCursor = [NSCursor crosshairCursor];
-        break;
-      case GHOST_kStandardCursorUpDown:
-        tmpCursor = [NSCursor resizeUpDownCursor];
-        break;
-      case GHOST_kStandardCursorLeftRight:
-        tmpCursor = [NSCursor resizeLeftRightCursor];
-        break;
-      case GHOST_kStandardCursorTopSide:
-        tmpCursor = [NSCursor resizeUpCursor];
-        break;
-      case GHOST_kStandardCursorBottomSide:
-        tmpCursor = [NSCursor resizeDownCursor];
-        break;
-      case GHOST_kStandardCursorLeftSide:
-        tmpCursor = [NSCursor resizeLeftCursor];
-        break;
-      case GHOST_kStandardCursorRightSide:
-        tmpCursor = [NSCursor resizeRightCursor];
-        break;
-      case GHOST_kStandardCursorRightArrow:
-      case GHOST_kStandardCursorInfo:
-      case GHOST_kStandardCursorLeftArrow:
-      case GHOST_kStandardCursorHelp:
-      case GHOST_kStandardCursorCycle:
-      case GHOST_kStandardCursorSpray:
-      case GHOST_kStandardCursorWait:
-      case GHOST_kStandardCursorTopLeftCorner:
-      case GHOST_kStandardCursorTopRightCorner:
-      case GHOST_kStandardCursorBottomRightCorner:
-      case GHOST_kStandardCursorBottomLeftCorner:
-      case GHOST_kStandardCursorCopy:
-      case GHOST_kStandardCursorDefault:
-      default:
-        tmpCursor = [NSCursor arrowCursor];
-        break;
-    };
+  NSCursor *cursor = getStandardCursor(shape);
+  if (cursor == NULL) {
+    cursor = getStandardCursor(GHOST_kStandardCursorDefault);
   }
-  [tmpCursor set];
+
+  [cursor set];
 }
 
 GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
@@ -1047,11 +1046,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor sha
 {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
-  if (m_customCursor) {
-    [m_customCursor release];
-    m_customCursor = nil;
-  }
-
   if ([m_window isVisible]) {
     loadCursor(getCursorVisibility(), shape);
   }
@@ -1060,6 +1054,14 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor sha
   return GHOST_kSuccess;
 }
 
+GHOST_TSuccess GHOST_WindowCocoa::hasCursorShape(GHOST_TStandardCursor shape)
+{
+  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+  GHOST_TSuccess success = (getStandardCursor(shape)) ? GHOST_kSuccess : GHOST_kFailure;
+  [pool drain];
+  return success;
+}
+
 /** Reverse the bits in a GHOST_TUns8
 static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
 {
index cd9863d7e724ed4080961f652e8be5ddd30df6f8..38c6f51dea484fcf8c96428c01fe0f2ec25f39a0 100644 (file)
@@ -583,9 +583,9 @@ static SDL_Cursor *sdl_ghost_CreateCursor(
 }
 
 /* TODO, this is currently never freed but it wont leak either. */
-static void sdl_cursor_init(void)
+static void getStandardCursorShape(GHOST_TStandardCursor shape)
 {
-
+  if (sdl_std_cursor_array[0] == NULL) {
 #define DEF_CURSOR(name, ind) \
   { \
     sdl_std_cursor_array[(int)ind] = sdl_ghost_CreateCursor( \
@@ -599,32 +599,34 @@ static void sdl_cursor_init(void)
   } \
   (void)0
 
-  DEF_CURSOR(left_ptr, GHOST_kStandardCursorDefault);
-  DEF_CURSOR(right_ptr, GHOST_kStandardCursorRightArrow);
-  DEF_CURSOR(left_ptr, GHOST_kStandardCursorLeftArrow);
-  DEF_CURSOR(umbrella, GHOST_kStandardCursorInfo);  // TODO, replace this one.
-  DEF_CURSOR(pirate, GHOST_kStandardCursorDestroy);
-  DEF_CURSOR(question_arrow, GHOST_kStandardCursorHelp);
-  DEF_CURSOR(exchange, GHOST_kStandardCursorCycle);
-  DEF_CURSOR(spraycan, GHOST_kStandardCursorSpray);
-  DEF_CURSOR(watch, GHOST_kStandardCursorWait);
-  DEF_CURSOR(xterm, GHOST_kStandardCursorText);
-  DEF_CURSOR(crosshair, GHOST_kStandardCursorCrosshair);
-  DEF_CURSOR(sb_v_double_arrow, GHOST_kStandardCursorUpDown);
-  DEF_CURSOR(sb_h_double_arrow, GHOST_kStandardCursorLeftRight);
-  DEF_CURSOR(top_side, GHOST_kStandardCursorTopSide);
-  DEF_CURSOR(bottom_side, GHOST_kStandardCursorBottomSide);
-  DEF_CURSOR(left_side, GHOST_kStandardCursorLeftSide);
-  DEF_CURSOR(right_side, GHOST_kStandardCursorRightSide);
-  DEF_CURSOR(top_left_corner, GHOST_kStandardCursorTopLeftCorner);
-  DEF_CURSOR(top_right_corner, GHOST_kStandardCursorTopRightCorner);
-  DEF_CURSOR(bottom_right_corner, GHOST_kStandardCursorBottomRightCorner);
-  DEF_CURSOR(bottom_left_corner, GHOST_kStandardCursorBottomLeftCorner);
-  DEF_CURSOR(arrow, GHOST_kStandardCursorCopy);
-  // DEF_CURSOR(arrow, GHOST_kStandardCursorCustom);
-  DEF_CURSOR(arrow, GHOST_kStandardCursorPencil);
-
+    DEF_CURSOR(left_ptr, GHOST_kStandardCursorDefault);
+    DEF_CURSOR(right_ptr, GHOST_kStandardCursorRightArrow);
+    DEF_CURSOR(left_ptr, GHOST_kStandardCursorLeftArrow);
+    DEF_CURSOR(umbrella, GHOST_kStandardCursorInfo);  // TODO, replace this one.
+    DEF_CURSOR(pirate, GHOST_kStandardCursorDestroy);
+    DEF_CURSOR(question_arrow, GHOST_kStandardCursorHelp);
+    DEF_CURSOR(exchange, GHOST_kStandardCursorCycle);
+    DEF_CURSOR(spraycan, GHOST_kStandardCursorSpray);
+    DEF_CURSOR(watch, GHOST_kStandardCursorWait);
+    DEF_CURSOR(xterm, GHOST_kStandardCursorText);
+    DEF_CURSOR(crosshair, GHOST_kStandardCursorCrosshair);
+    DEF_CURSOR(sb_v_double_arrow, GHOST_kStandardCursorUpDown);
+    DEF_CURSOR(sb_h_double_arrow, GHOST_kStandardCursorLeftRight);
+    DEF_CURSOR(top_side, GHOST_kStandardCursorTopSide);
+    DEF_CURSOR(bottom_side, GHOST_kStandardCursorBottomSide);
+    DEF_CURSOR(left_side, GHOST_kStandardCursorLeftSide);
+    DEF_CURSOR(right_side, GHOST_kStandardCursorRightSide);
+    DEF_CURSOR(top_left_corner, GHOST_kStandardCursorTopLeftCorner);
+    DEF_CURSOR(top_right_corner, GHOST_kStandardCursorTopRightCorner);
+    DEF_CURSOR(bottom_right_corner, GHOST_kStandardCursorBottomRightCorner);
+    DEF_CURSOR(bottom_left_corner, GHOST_kStandardCursorBottomLeftCorner);
+    DEF_CURSOR(arrow, GHOST_kStandardCursorCopy);
+    // DEF_CURSOR(arrow, GHOST_kStandardCursorCustom);
+    DEF_CURSOR(arrow, GHOST_kStandardCursorPencil);
 #undef DEF_CURSOR
+  }
+
+  return sdl_std_cursor_array[(int)shape];
 }
 
 GHOST_TSuccess GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
@@ -634,14 +636,20 @@ GHOST_TSuccess GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
 
 GHOST_TSuccess GHOST_WindowSDL::setWindowCursorShape(GHOST_TStandardCursor shape)
 {
-  if (sdl_std_cursor_array[0] == NULL) {
-    sdl_cursor_init();
+  SDL_Cursor *cursor = getStandardCursorShape(shape);
+  if (cursor == NULL) {
+    cursor = getStandardCursorShape(GHOST_kStandardCursorDefault);
   }
 
-  SDL_SetCursor(sdl_std_cursor_array[(int)shape]);
+  SDL_SetCursor(cursor);
   return GHOST_kSuccess;
 }
 
+GHOST_TSuccess GHOST_WindowSDL::hasCursorShape(GHOST_TStandardCursor shape)
+{
+  return (getStandardCursorShape(shape)) ? GHOST_kSuccess : GHOST_kFailure;
+}
+
 GHOST_TSuccess GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
                                                            GHOST_TUns8 *mask,
                                                            int sizex,
index bb19b62e06d27a5891c1fea0e656df89f6bfe226..a5c2fa9b18570f2c626ad4355969f1863e6dd26a 100644 (file)
@@ -100,6 +100,7 @@ class GHOST_WindowSDL : public GHOST_Window {
   GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
 
   GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+  GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor shape);
 
   GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
                                             GHOST_TUns8 *mask,
index e8b36c5936608ca492ff23a00f4b289e876992d9..679431e8597099defccb6af49cfd36355e82e287 100644 (file)
@@ -766,7 +766,78 @@ void GHOST_WindowWin32::registerMouseClickEvent(int press)
   }
 }
 
-void GHOST_WindowWin32::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
+HCURSOR GHOST_WindowWin32::getStandardCursor(GHOST_TStandardCursor shape) const
+{
+  // Convert GHOST cursor to Windows OEM cursor
+  switch (shape) {
+    case GHOST_kStandardCursorCustom:
+      if (m_customCursor) {
+        return m_customCursor;
+      }
+      else {
+        return NULL;
+      }
+    case GHOST_kStandardCursorDefault:
+      return ::LoadCursor(0, IDC_ARROW);
+    case GHOST_kStandardCursorRightArrow:
+      return ::LoadCursor(0, IDC_ARROW);
+    case GHOST_kStandardCursorLeftArrow:
+      return ::LoadCursor(0, IDC_ARROW);
+    case GHOST_kStandardCursorInfo:
+      // Four-pointed arrow pointing north, south, east, and west
+      return ::LoadCursor(0, IDC_SIZEALL);
+    case GHOST_kStandardCursorDestroy:
+      // Slashed circle
+      return ::LoadCursor(0, IDC_NO);
+    case GHOST_kStandardCursorHelp:
+      // Arrow and question mark
+      return ::LoadCursor(0, IDC_HELP);
+    case GHOST_kStandardCursorCycle:
+      // Slashed circle
+      return ::LoadCursor(0, IDC_NO);
+    case GHOST_kStandardCursorSpray:
+      // Four-pointed arrow pointing north, south, east, and west
+      return ::LoadCursor(0, IDC_SIZEALL);
+    case GHOST_kStandardCursorWait:
+      // Hourglass
+      return ::LoadCursor(0, IDC_WAIT);
+    case GHOST_kStandardCursorText:
+      // I-beam
+      return ::LoadCursor(0, IDC_IBEAM);
+    case GHOST_kStandardCursorCrosshair:
+      // Crosshair
+      return ::LoadCursor(0, IDC_CROSS);
+    case GHOST_kStandardCursorUpDown:
+      // Double-pointed arrow pointing north and south
+      return ::LoadCursor(0, IDC_SIZENS);
+    case GHOST_kStandardCursorLeftRight:
+      // Double-pointed arrow pointing west and east
+      return ::LoadCursor(0, IDC_SIZEWE);
+    case GHOST_kStandardCursorTopSide:
+      // Vertical arrow
+      return ::LoadCursor(0, IDC_UPARROW);
+    case GHOST_kStandardCursorBottomSide:
+      return ::LoadCursor(0, IDC_SIZENS);
+    case GHOST_kStandardCursorLeftSide:
+      return ::LoadCursor(0, IDC_SIZEWE);
+    case GHOST_kStandardCursorTopLeftCorner:
+      return ::LoadCursor(0, IDC_SIZENWSE);
+    case GHOST_kStandardCursorTopRightCorner:
+      return ::LoadCursor(0, IDC_SIZENESW);
+    case GHOST_kStandardCursorBottomRightCorner:
+      return ::LoadCursor(0, IDC_SIZENWSE);
+    case GHOST_kStandardCursorBottomLeftCorner:
+      return ::LoadCursor(0, IDC_SIZENESW);
+    case GHOST_kStandardCursorPencil:
+      return ::LoadCursor(0, IDC_ARROW);
+    case GHOST_kStandardCursorCopy:
+      return ::LoadCursor(0, IDC_ARROW);
+    default:
+      return NULL;
+  }
+}
+
+void GHOST_WindowWin32::loadCursor(bool visible, GHOST_TStandardCursor shape) const
 {
   if (!visible) {
     while (::ShowCursor(FALSE) >= 0)
@@ -777,88 +848,11 @@ void GHOST_WindowWin32::loadCursor(bool visible, GHOST_TStandardCursor cursor) c
       ;
   }
 
-  if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
-    ::SetCursor(m_customCursor);
-  }
-  else {
-    // Convert GHOST cursor to Windows OEM cursor
-    bool success = true;
-    LPCSTR id;
-    switch (cursor) {
-      case GHOST_kStandardCursorDefault:
-        id = IDC_ARROW;
-        break;
-      case GHOST_kStandardCursorRightArrow:
-        id = IDC_ARROW;
-        break;
-      case GHOST_kStandardCursorLeftArrow:
-        id = IDC_ARROW;
-        break;
-      case GHOST_kStandardCursorInfo:
-        id = IDC_SIZEALL;
-        break;  // Four-pointed arrow pointing north, south, east, and west
-      case GHOST_kStandardCursorDestroy:
-        id = IDC_NO;
-        break;  // Slashed circle
-      case GHOST_kStandardCursorHelp:
-        id = IDC_HELP;
-        break;  // Arrow and question mark
-      case GHOST_kStandardCursorCycle:
-        id = IDC_NO;
-        break;  // Slashed circle
-      case GHOST_kStandardCursorSpray:
-        id = IDC_SIZEALL;
-        break;  // Four-pointed arrow pointing north, south, east, and west
-      case GHOST_kStandardCursorWait:
-        id = IDC_WAIT;
-        break;  // Hourglass
-      case GHOST_kStandardCursorText:
-        id = IDC_IBEAM;
-        break;  // I-beam
-      case GHOST_kStandardCursorCrosshair:
-        id = IDC_CROSS;
-        break;  // Crosshair
-      case GHOST_kStandardCursorUpDown:
-        id = IDC_SIZENS;
-        break;  // Double-pointed arrow pointing north and south
-      case GHOST_kStandardCursorLeftRight:
-        id = IDC_SIZEWE;
-        break;  // Double-pointed arrow pointing west and east
-      case GHOST_kStandardCursorTopSide:
-        id = IDC_UPARROW;
-        break;  // Vertical arrow
-      case GHOST_kStandardCursorBottomSide:
-        id = IDC_SIZENS;
-        break;
-      case GHOST_kStandardCursorLeftSide:
-        id = IDC_SIZEWE;
-        break;
-      case GHOST_kStandardCursorTopLeftCorner:
-        id = IDC_SIZENWSE;
-        break;
-      case GHOST_kStandardCursorTopRightCorner:
-        id = IDC_SIZENESW;
-        break;
-      case GHOST_kStandardCursorBottomRightCorner:
-        id = IDC_SIZENWSE;
-        break;
-      case GHOST_kStandardCursorBottomLeftCorner:
-        id = IDC_SIZENESW;
-        break;
-      case GHOST_kStandardCursorPencil:
-        id = IDC_ARROW;
-        break;
-      case GHOST_kStandardCursorCopy:
-        id = IDC_ARROW;
-        break;
-      default:
-        success = false;
-    }
-
-    if (success) {
-      ::SetCursor(::LoadCursor(0, id));
-    }
+  HCURSOR cursor = getStandardCursor(shape);
+  if (cursor == NULL) {
+    cursor = getStandardCursor(GHOST_kStandardCursorDefault);
   }
+  ::SetCursor(cursor);
 }
 
 GHOST_TSuccess GHOST_WindowWin32::setWindowCursorVisibility(bool visible)
@@ -908,11 +902,6 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode
 
 GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cursorShape)
 {
-  if (m_customCursor) {
-    DestroyCursor(m_customCursor);
-    m_customCursor = NULL;
-  }
-
   if (::GetForegroundWindow() == m_hWnd) {
     loadCursor(getCursorVisibility(), cursorShape);
   }
@@ -920,6 +909,11 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cur
   return GHOST_kSuccess;
 }
 
+GHOST_TSuccess GHOST_WindowWin32::hasCursorShape(GHOST_TStandardCursor cursorShape)
+{
+  return (getStandardCursor(cursorShape)) ? GHOST_kSuccess : GHOST_kFailure;
+}
+
 GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(GHOST_PointerInfoWin32 *pointerInfo,
                                                  WPARAM wParam,
                                                  LPARAM lParam)
index cf7177b00621833a4166dcdade3be5cd45a2093d..8dac142d6f439e70a3d1b510c568bcde33416a9e 100644 (file)
@@ -386,6 +386,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
    * \param visible       Flag for cursor visibility.
    * \param cursorShape   The cursor shape.
    */
+  HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const;
   void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
 
   const GHOST_TabletData *GetTabletData()
@@ -456,6 +457,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
    * native window system calls.
    */
   GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+  GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor shape);
 
   /**
    * Sets the cursor shape on the window using
index 166fea8a84b23dcb6ef034b6ba332adde02bc112..402c48bc0fc0edd52dd4f1aa3f88d39eded3c701 100644 (file)
@@ -1284,77 +1284,94 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
   return NULL;
 }
 
-Cursor GHOST_WindowX11::getStandardCursor(GHOST_TStandardCursor g_cursor)
+GHOST_TSuccess GHOST_WindowX11::getStandardCursor(GHOST_TStandardCursor g_cursor, Cursor &xcursor)
 {
   unsigned int xcursor_id;
 
-#define GtoX(gcurs, xcurs) \
-  case gcurs: \
-    xcursor_id = xcurs
   switch (g_cursor) {
-    GtoX(GHOST_kStandardCursorRightArrow, XC_arrow);
-    break;
-    GtoX(GHOST_kStandardCursorLeftArrow, XC_top_left_arrow);
-    break;
-    GtoX(GHOST_kStandardCursorInfo, XC_hand1);
-    break;
-    GtoX(GHOST_kStandardCursorDestroy, XC_pirate);
-    break;
-    GtoX(GHOST_kStandardCursorHelp, XC_question_arrow);
-    break;
-    GtoX(GHOST_kStandardCursorCycle, XC_exchange);
-    break;
-    GtoX(GHOST_kStandardCursorSpray, XC_spraycan);
-    break;
-    GtoX(GHOST_kStandardCursorWait, XC_watch);
-    break;
-    GtoX(GHOST_kStandardCursorText, XC_xterm);
-    break;
-    GtoX(GHOST_kStandardCursorCrosshair, XC_crosshair);
-    break;
-    GtoX(GHOST_kStandardCursorUpDown, XC_sb_v_double_arrow);
-    break;
-    GtoX(GHOST_kStandardCursorLeftRight, XC_sb_h_double_arrow);
-    break;
-    GtoX(GHOST_kStandardCursorTopSide, XC_top_side);
-    break;
-    GtoX(GHOST_kStandardCursorBottomSide, XC_bottom_side);
-    break;
-    GtoX(GHOST_kStandardCursorLeftSide, XC_left_side);
-    break;
-    GtoX(GHOST_kStandardCursorRightSide, XC_right_side);
-    break;
-    GtoX(GHOST_kStandardCursorTopLeftCorner, XC_top_left_corner);
-    break;
-    GtoX(GHOST_kStandardCursorTopRightCorner, XC_top_right_corner);
-    break;
-    GtoX(GHOST_kStandardCursorBottomRightCorner, XC_bottom_right_corner);
-    break;
-    GtoX(GHOST_kStandardCursorBottomLeftCorner, XC_bottom_left_corner);
-    break;
-    GtoX(GHOST_kStandardCursorPencil, XC_pencil);
-    break;
-    GtoX(GHOST_kStandardCursorCopy, XC_arrow);
-    break;
+    case GHOST_kStandardCursorRightArrow:
+      xcursor_id = XC_arrow;
+      break;
+    case GHOST_kStandardCursorLeftArrow:
+      xcursor_id = XC_top_left_arrow;
+      break;
+    case GHOST_kStandardCursorInfo:
+      xcursor_id = XC_hand1;
+      break;
+    case GHOST_kStandardCursorDestroy:
+      xcursor_id = XC_pirate;
+      break;
+    case GHOST_kStandardCursorHelp:
+      xcursor_id = XC_question_arrow;
+      break;
+    case GHOST_kStandardCursorCycle:
+      xcursor_id = XC_exchange;
+      break;
+    case GHOST_kStandardCursorSpray:
+      xcursor_id = XC_spraycan;
+      break;
+    case GHOST_kStandardCursorWait:
+      xcursor_id = XC_watch;
+      break;
+    case GHOST_kStandardCursorText:
+      xcursor_id = XC_xterm;
+      break;
+    case GHOST_kStandardCursorCrosshair:
+      xcursor_id = XC_crosshair;
+      break;
+    case GHOST_kStandardCursorUpDown:
+      xcursor_id = XC_sb_v_double_arrow;
+      break;
+    case GHOST_kStandardCursorLeftRight:
+      xcursor_id = XC_sb_h_double_arrow;
+      break;
+    case GHOST_kStandardCursorTopSide:
+      xcursor_id = XC_top_side;
+      break;
+    case GHOST_kStandardCursorBottomSide:
+      xcursor_id = XC_bottom_side;
+      break;
+    case GHOST_kStandardCursorLeftSide:
+      xcursor_id = XC_left_side;
+      break;
+    case GHOST_kStandardCursorRightSide:
+      xcursor_id = XC_right_side;
+      break;
+    case GHOST_kStandardCursorTopLeftCorner:
+      xcursor_id = XC_top_left_corner;
+      break;
+    case GHOST_kStandardCursorTopRightCorner:
+      xcursor_id = XC_top_right_corner;
+      break;
+    case GHOST_kStandardCursorBottomRightCorner:
+      xcursor_id = XC_bottom_right_corner;
+      break;
+    case GHOST_kStandardCursorBottomLeftCorner:
+      xcursor_id = XC_bottom_left_corner;
+      break;
+    case GHOST_kStandardCursorPencil:
+      xcursor_id = XC_pencil;
+      break;
+    case GHOST_kStandardCursorCopy:
+      xcursor_id = XC_arrow;
+      break;
+    case GHOST_kStandardCursorDefault:
+      xcursor = None;
+      return GHOST_kSuccess;
     default:
-      xcursor_id = 0;
+      xcursor = None;
+      return GHOST_kFailure;
   }
-#undef GtoX
 
-  if (xcursor_id) {
-    Cursor xcursor = m_standard_cursors[xcursor_id];
+  xcursor = m_standard_cursors[xcursor_id];
 
-    if (!xcursor) {
-      xcursor = XCreateFontCursor(m_display, xcursor_id);
+  if (!xcursor) {
+    xcursor = XCreateFontCursor(m_display, xcursor_id);
 
-      m_standard_cursors[xcursor_id] = xcursor;
-    }
-
-    return xcursor;
-  }
-  else {
-    return None;
+    m_standard_cursors[xcursor_id] = xcursor;
   }
+
+  return GHOST_kSuccess;
 }
 
 Cursor GHOST_WindowX11::getEmptyCursor()
@@ -1380,10 +1397,12 @@ GHOST_TSuccess GHOST_WindowX11::setWindowCursorVisibility(bool visible)
   Cursor xcursor;
 
   if (visible) {
-    if (m_visible_cursor)
+    if (m_visible_cursor) {
       xcursor = m_visible_cursor;
-    else
-      xcursor = getStandardCursor(getCursorShape());
+    }
+    else if (getStandardCursor(getCursorShape(), xcursor) == GHOST_kFailure) {
+      getStandardCursor(getCursorShape(), xcursor);
+    }
   }
   else {
     xcursor = getEmptyCursor();
@@ -1463,7 +1482,10 @@ GHOST_TSuccess GHOST_WindowX11::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
 
 GHOST_TSuccess GHOST_WindowX11::setWindowCursorShape(GHOST_TStandardCursor shape)
 {
-  Cursor xcursor = getStandardCursor(shape);
+  Cursor xcursor;
+  if (getStandardCursor(shape, xcursor) == GHOST_kFailure) {
+    getStandardCursor(GHOST_kStandardCursorDefault, xcursor);
+  }
 
   m_visible_cursor = xcursor;
 
@@ -1473,6 +1495,12 @@ GHOST_TSuccess GHOST_WindowX11::setWindowCursorShape(GHOST_TStandardCursor shape
   return GHOST_kSuccess;
 }
 
+GHOST_TSuccess GHOST_WindowX11::hasCursorShape(GHOST_TStandardCursor shape)
+{
+  Cursor xcursor;
+  return getStandardCursor(shape, xcursor);
+}
+
 GHOST_TSuccess GHOST_WindowX11::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
                                                            GHOST_TUns8 *mask,
                                                            int sizex,
index 83e0a2b59db0b74426376f6507d6f33ad9827fec..0b8fe3a3a418428164c17b20368aaa49e47ee82c 100644 (file)
@@ -213,6 +213,7 @@ class GHOST_WindowX11 : public GHOST_Window {
    * native window system calls.
    */
   GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+  GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor shape);
 
   /**
    * Sets the cursor shape on the window using
@@ -233,7 +234,7 @@ class GHOST_WindowX11 : public GHOST_Window {
 
   GHOST_WindowX11(const GHOST_WindowX11 &);
 
-  Cursor getStandardCursor(GHOST_TStandardCursor g_cursor);
+  GHOST_TSuccess getStandardCursor(GHOST_TStandardCursor g_cursor, Cursor &xcursor);
 
   Cursor getEmptyCursor();