Imported Upstream version 2.0.14
[platform/upstream/SDL.git] / src / video / os2 / SDL_os2mouse.c
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2020 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
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
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
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
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
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
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
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
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
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
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: */