This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_DirectFB_mouse.c
390 lines (324 loc) · 11.3 KB
1
/*
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
20
*/
21
22
#include "SDL_config.h"
23
#include "SDL_assert.h"
24
25
#include "SDL_DirectFB_video.h"
26
27
28
#include "SDL_DirectFB_mouse.h"
#include "SDL_DirectFB_modes.h"
#include "SDL_DirectFB_window.h"
29
30
31
32
#include "../SDL_sysvideo.h"
#include "../../events/SDL_mouse_c.h"
33
static SDL_Cursor *DirectFB_CreateDefaultCursor(void);
34
35
static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface,
int hot_x, int hot_y);
36
37
38
static int DirectFB_ShowCursor(SDL_Cursor * cursor);
static void DirectFB_MoveCursor(SDL_Cursor * cursor);
static void DirectFB_FreeCursor(SDL_Cursor * cursor);
39
static void DirectFB_WarpMouse(SDL_Window * window, int x, int y);
40
41
static void DirectFB_FreeMouse(SDL_Mouse * mouse);
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
static const char *arrow[] = {
/* pixels */
"X ",
"XX ",
"X.X ",
"X..X ",
"X...X ",
"X....X ",
"X.....X ",
"X......X ",
"X.......X ",
"X........X ",
"X.....XXXXX ",
"X..X..X ",
"X.X X..X ",
"XX X..X ",
"X X..X ",
" X..X ",
" X..X ",
" X..X ",
" XX ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
};
77
78
79
static SDL_Cursor *
DirectFB_CreateDefaultCursor(void)
80
{
81
SDL_VideoDevice *dev = SDL_GetVideoDevice();
82
83
84
85
86
87
88
89
90
SDL_DFB_DEVICEDATA(dev);
DFB_CursorData *curdata;
DFBResult ret;
DFBSurfaceDescription dsc;
SDL_Cursor *cursor;
Uint32 *dest;
Uint32 *p;
int pitch, i, j;
91
92
93
SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
94
95
96
97
98
99
100
dsc.flags =
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
dsc.caps = DSCAPS_VIDEOONLY;
dsc.width = 32;
dsc.height = 32;
dsc.pixelformat = DSPF_ARGB;
101
102
103
104
105
106
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
&curdata->surf));
curdata->hotx = 0;
curdata->hoty = 0;
cursor->driverdata = curdata;
107
108
109
SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
(void *) &dest, &pitch));
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* Relies on the fact that this is only called with ARGB surface. */
for (i = 0; i < 32; i++)
{
for (j = 0; j < 32; j++)
{
switch (arrow[i][j])
{
case ' ': dest[j] = 0x00000000; break;
case '.': dest[j] = 0xffffffff; break;
case 'X': dest[j] = 0xff000000; break;
}
}
dest += (pitch >> 2);
124
}
125
126
127
128
129
curdata->surf->Unlock(curdata->surf);
return cursor;
error:
return NULL;
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
}
/* Create a cursor from a surface */
static SDL_Cursor *
DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_DFB_DEVICEDATA(dev);
DFB_CursorData *curdata;
DFBResult ret;
DFBSurfaceDescription dsc;
SDL_Cursor *cursor;
Uint32 *dest;
Uint32 *p;
int pitch, i;
147
148
149
150
151
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
SDL_assert(surface->pitch == surface->w * 4);
SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
152
153
154
dsc.flags =
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
155
dsc.caps = DSCAPS_VIDEOONLY;
156
157
158
159
dsc.width = surface->w;
dsc.height = surface->h;
dsc.pixelformat = DSPF_ARGB;
160
161
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
&curdata->surf));
162
163
164
165
curdata->hotx = hot_x;
curdata->hoty = hot_y;
cursor->driverdata = curdata;
166
167
SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
(void *) &dest, &pitch));
168
169
p = surface->pixels;
170
for (i = 0; i < surface->h; i++)
171
172
memcpy((char *) dest + i * pitch,
(char *) p + i * surface->pitch, 4 * surface->w);
173
174
175
176
177
178
179
180
181
182
183
184
185
curdata->surf->Unlock(curdata->surf);
return cursor;
error:
return NULL;
}
/* Show the specified cursor, or hide if cursor is NULL */
static int
DirectFB_ShowCursor(SDL_Cursor * cursor)
{
SDL_DFB_CURSORDATA(cursor);
DFBResult ret;
186
SDL_Window *window;
187
188
189
window = SDL_GetFocusWindow();
if (!window)
190
191
return -1;
else {
192
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
193
194
195
196
197
198
199
if (display) {
DFB_DisplayData *dispdata =
(DFB_DisplayData *) display->driverdata;
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
if (cursor)
200
SDL_DFB_CHECKERR(windata->dfbwin->
201
SetCursorShape(windata->dfbwin,
202
203
curdata->surf, curdata->hotx,
curdata->hoty));
204
205
206
207
208
209
210
211
212
213
SDL_DFB_CHECKERR(dispdata->layer->
SetCooperativeLevel(dispdata->layer,
DLSCL_ADMINISTRATIVE));
SDL_DFB_CHECKERR(dispdata->layer->
SetCursorOpacity(dispdata->layer,
cursor ? 0xC0 : 0x00));
SDL_DFB_CHECKERR(dispdata->layer->
SetCooperativeLevel(dispdata->layer,
DLSCL_SHARED));
214
}
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
}
return 0;
error:
return -1;
}
/* Free a window manager cursor */
static void
DirectFB_FreeCursor(SDL_Cursor * cursor)
{
SDL_DFB_CURSORDATA(cursor);
SDL_DFB_RELEASE(curdata->surf);
SDL_DFB_FREE(cursor->driverdata);
SDL_DFB_FREE(cursor);
}
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/* Warp the mouse to (x,y) */
static void
DirectFB_WarpMouse(SDL_Window * window, int x, int y)
{
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
DFBResult ret;
int cx, cy;
SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
cx + x + windata->client.x,
cy + y + windata->client.y));
error:
return;
}
#if USE_MULTI_API
static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window,
int x, int y);
static int id_mask;
static DFBEnumerationResult
EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc,
void *callbackdata)
{
DFB_DeviceData *devdata = callbackdata;
if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) {
SDL_Mouse mouse;
SDL_zero(mouse);
mouse.id = device_id;
mouse.CreateCursor = DirectFB_CreateCursor;
mouse.ShowCursor = DirectFB_ShowCursor;
mouse.MoveCursor = DirectFB_MoveCursor;
mouse.FreeCursor = DirectFB_FreeCursor;
mouse.WarpMouse = DirectFB_WarpMouse;
mouse.FreeMouse = DirectFB_FreeMouse;
mouse.cursor_shown = 1;
SDL_AddMouse(&mouse, desc.name, 0, 0, 1);
devdata->mouse_id[devdata->num_mice++] = device_id;
}
return DFENUM_OK;
}
void
DirectFB_InitMouse(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
devdata->num_mice = 0;
if (devdata->use_linux_input) {
/* try non-core devices first */
id_mask = 0xF0;
devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
if (devdata->num_mice == 0) {
/* try core devices */
id_mask = 0x0F;
devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
}
}
if (devdata->num_mice == 0) {
SDL_Mouse mouse;
SDL_zero(mouse);
mouse.CreateCursor = DirectFB_CreateCursor;
mouse.ShowCursor = DirectFB_ShowCursor;
mouse.MoveCursor = DirectFB_MoveCursor;
mouse.FreeCursor = DirectFB_FreeCursor;
mouse.WarpMouse = DirectFB_WarpMouse;
mouse.FreeMouse = DirectFB_FreeMouse;
mouse.cursor_shown = 1;
SDL_AddMouse(&mouse, "Mouse", 0, 0, 1);
devdata->num_mice = 1;
}
}
void
DirectFB_QuitMouse(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
if (devdata->use_linux_input) {
SDL_MouseQuit();
} else {
SDL_DelMouse(0);
}
}
/* This is called when a mouse motion event occurs */
static void
DirectFB_MoveCursor(SDL_Cursor * cursor)
{
}
337
338
/* Warp the mouse to (x,y) */
static void
339
DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y)
340
{
341
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
342
343
344
345
346
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
DFBResult ret;
int cx, cy;
347
SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
348
349
350
SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
cx + x + windata->client.x,
cy + y + windata->client.y));
351
352
353
354
355
356
357
358
359
error:
return;
}
/* Free the mouse when it's time */
static void
DirectFB_FreeMouse(SDL_Mouse * mouse)
{
360
/* nothing yet */
361
362
}
363
364
365
366
367
368
369
#else /* USE_MULTI_API */
void
DirectFB_InitMouse(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
370
371
372
373
374
375
376
SDL_Mouse *mouse = SDL_GetMouse();
mouse->CreateCursor = DirectFB_CreateCursor;
mouse->ShowCursor = DirectFB_ShowCursor;
mouse->WarpMouse = DirectFB_WarpMouse;
mouse->FreeCursor = DirectFB_FreeCursor;
377
SDL_SetDefaultCursor(DirectFB_CreateDefaultCursor());
378
379
380
381
382
383
384
385
386
387
388
389
devdata->num_mice = 1;
}
void
DirectFB_QuitMouse(_THIS)
{
}
#endif
390
/* vi: set ts=4 sw=4 expandtab: */