1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
4 
5   This software is provided 'as-is', without any express or implied
6   warranty.  In no event will the authors be held liable for any damages
7   arising from the use of this software.
8 
9   Permission is granted to anyone to use this software for any purpose,
10   including commercial applications, and to alter it and redistribute it
11   freely, subject to the following restrictions:
12 
13   1. The origin of this software must not be misrepresented; you must not
14      claim that you wrote the original software. If you use this software
15      in a product, an acknowledgment in the product documentation would be
16      appreciated but is not required.
17   2. Altered source versions must be plainly marked as such, and must not be
18      misrepresented as being the original software.
19   3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_DRIVER_OS2
24 
25 #include "SDL_os2video.h"
26 #include "../../events/SDL_mouse_c.h"
27 #include "SDL_os2util.h"
28 
29 HPOINTER    hptrCursor = NULLHANDLE;
30 
OS2_CreateCursor(SDL_Surface * surface,int hot_x,int hot_y)31 static SDL_Cursor* OS2_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
32 {
33     ULONG       ulMaxW = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER);
34     ULONG       ulMaxH = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER);
35     HPOINTER    hptr;
36     SDL_Cursor* pSDLCursor;
37 
38     if (surface->w > ulMaxW || surface->h > ulMaxH) {
39         debug_os2("Given image size is %u x %u, maximum allowed size is %u x %u",
40                   surface->w, surface->h, ulMaxW, ulMaxH);
41         return NULL;
42     }
43 
44     hptr = utilCreatePointer(surface, hot_x, ulMaxH - hot_y - 1);
45     if (hptr == NULLHANDLE)
46         return NULL;
47 
48     pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor));
49     if (pSDLCursor == NULL) {
50         WinDestroyPointer(hptr);
51         SDL_OutOfMemory();
52         return NULL;
53     }
54 
55     pSDLCursor->driverdata = (void *)hptr;
56     return pSDLCursor;
57 }
58 
OS2_CreateSystemCursor(SDL_SystemCursor id)59 static SDL_Cursor* OS2_CreateSystemCursor(SDL_SystemCursor id)
60 {
61     SDL_Cursor* pSDLCursor;
62     LONG        lSysId;
63     HPOINTER    hptr;
64 
65     switch (id) {
66     case SDL_SYSTEM_CURSOR_ARROW:     lSysId = SPTR_ARROW;    break;
67     case SDL_SYSTEM_CURSOR_IBEAM:     lSysId = SPTR_TEXT;     break;
68     case SDL_SYSTEM_CURSOR_WAIT:      lSysId = SPTR_WAIT;     break;
69     case SDL_SYSTEM_CURSOR_CROSSHAIR: lSysId = SPTR_MOVE;     break;
70     case SDL_SYSTEM_CURSOR_WAITARROW: lSysId = SPTR_WAIT;     break;
71     case SDL_SYSTEM_CURSOR_SIZENWSE:  lSysId = SPTR_SIZENWSE; break;
72     case SDL_SYSTEM_CURSOR_SIZENESW:  lSysId = SPTR_SIZENESW; break;
73     case SDL_SYSTEM_CURSOR_SIZEWE:    lSysId = SPTR_SIZEWE;   break;
74     case SDL_SYSTEM_CURSOR_SIZENS:    lSysId = SPTR_SIZENS;   break;
75     case SDL_SYSTEM_CURSOR_SIZEALL:   lSysId = SPTR_MOVE;     break;
76     case SDL_SYSTEM_CURSOR_NO:        lSysId = SPTR_ILLEGAL;  break;
77     case SDL_SYSTEM_CURSOR_HAND:      lSysId = SPTR_ARROW;    break;
78     default:
79         debug_os2("Unknown cursor id: %u", id);
80         return NULL;
81     }
82 
83     /* On eCS SPTR_WAIT for last paramether fCopy=TRUE/FALSE gives different
84      * "wait" icons. -=8( ) */
85     hptr = WinQuerySysPointer(HWND_DESKTOP, lSysId,
86                               id == SDL_SYSTEM_CURSOR_WAIT);
87     if (hptr == NULLHANDLE) {
88         debug_os2("Cannot load OS/2 system pointer %u for SDL cursor id %u",
89                   lSysId, id);
90         return NULL;
91     }
92 
93     pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor));
94     if (pSDLCursor == NULL) {
95         WinDestroyPointer(hptr);
96         SDL_OutOfMemory();
97         return NULL;
98     }
99 
100     pSDLCursor->driverdata = (void *)hptr;
101     return pSDLCursor;
102 }
103 
OS2_FreeCursor(SDL_Cursor * cursor)104 static void OS2_FreeCursor(SDL_Cursor *cursor)
105 {
106     HPOINTER    hptr = (HPOINTER)cursor->driverdata;
107 
108     WinDestroyPointer(hptr);
109     SDL_free(cursor);
110 }
111 
OS2_ShowCursor(SDL_Cursor * cursor)112 static int OS2_ShowCursor(SDL_Cursor *cursor)
113 {
114     hptrCursor = (cursor != NULL)? (HPOINTER)cursor->driverdata : NULLHANDLE;
115     return ((SDL_GetMouseFocus() == NULL) ||
116              WinSetPointer(HWND_DESKTOP, hptrCursor))? 0 : -1;
117 }
118 
OS2_WarpMouse(SDL_Window * window,int x,int y)119 static void OS2_WarpMouse(SDL_Window * window, int x, int y)
120 {
121     WINDATA    *pWinData = (WINDATA *)window->driverdata;
122     POINTL      pointl;
123 
124     pointl.x = x;
125     pointl.y = window->h - y;
126     WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1);
127 /*  pWinData->lSkipWMMouseMove++; ???*/
128     WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y);
129 }
130 
OS2_WarpMouseGlobal(int x,int y)131 static int OS2_WarpMouseGlobal(int x, int y)
132 {
133     WinSetPointerPos(HWND_DESKTOP, x,
134                      WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - y);
135     return 0;
136 }
137 
OS2_CaptureMouse(SDL_Window * window)138 static int OS2_CaptureMouse(SDL_Window *window)
139 {
140     return WinSetCapture(HWND_DESKTOP, (window == NULL)? NULLHANDLE :
141                                          ((WINDATA *)window->driverdata)->hwnd)? 0 : -1;
142 }
143 
OS2_GetGlobalMouseState(int * x,int * y)144 static Uint32 OS2_GetGlobalMouseState(int *x, int *y)
145 {
146     POINTL  pointl;
147     ULONG   ulRes;
148 
149     WinQueryPointerPos(HWND_DESKTOP, &pointl);
150     *x = pointl.x;
151     *y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - pointl.y - 1;
152 
153     ulRes = (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)? SDL_BUTTON_LMASK : 0;
154     if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
155         ulRes |= SDL_BUTTON_RMASK;
156     if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
157         ulRes |= SDL_BUTTON_MMASK;
158 
159     return ulRes;
160 }
161 
162 
OS2_InitMouse(_THIS,ULONG hab)163 void OS2_InitMouse(_THIS, ULONG hab)
164 {
165     SDL_Mouse   *pSDLMouse = SDL_GetMouse();
166 
167     pSDLMouse->CreateCursor         = OS2_CreateCursor;
168     pSDLMouse->CreateSystemCursor   = OS2_CreateSystemCursor;
169     pSDLMouse->ShowCursor           = OS2_ShowCursor;
170     pSDLMouse->FreeCursor           = OS2_FreeCursor;
171     pSDLMouse->WarpMouse            = OS2_WarpMouse;
172     pSDLMouse->WarpMouseGlobal      = OS2_WarpMouseGlobal;
173     pSDLMouse->CaptureMouse         = OS2_CaptureMouse;
174     pSDLMouse->GetGlobalMouseState  = OS2_GetGlobalMouseState;
175 
176     SDL_SetDefaultCursor(OS2_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW));
177     if (hptrCursor == NULLHANDLE)
178         hptrCursor = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE);
179 }
180 
OS2_QuitMouse(_THIS)181 void OS2_QuitMouse(_THIS)
182 {
183     SDL_Mouse   *pSDLMouse = SDL_GetMouse();
184 
185     if (pSDLMouse->def_cursor != NULL) {
186         SDL_free(pSDLMouse->def_cursor);
187         pSDLMouse->def_cursor = NULL;
188         pSDLMouse->cur_cursor = NULL;
189     }
190 }
191 
192 #endif /* SDL_VIDEO_DRIVER_OS2 */
193 
194 /* vi: set ts=4 sw=4 expandtab: */
195