SDL-1.2.14
[sdl_omap.git] / src / video / bwindow / SDL_sysmouse.cc
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 Sam Lantinga
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #include <AppKit.h>
25 #include <GameKit.h>
26
27 #include "SDL_BWin.h"
28
29 extern "C" {
30 #include "../SDL_cursor_c.h"
31 #include "SDL_sysmouse_c.h"
32
33 /* Convert bits to padded bytes */
34 #define PADDED_BITS(bits)  ((bits+7)/8)
35
36 /* The implementation dependent data for the window manager cursor */
37 struct WMcursor {
38         char *bits;
39 };
40
41 /* Can this be done in the BeOS? */
42 WMcursor *BE_CreateWMCursor(_THIS,
43                 Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
44 {
45         WMcursor *cursor;
46         int allowed_x;
47         int allowed_y;
48         int run, pad, i;
49         char *cptr;
50
51         allowed_x = 16; /* BeOS limitation */
52         allowed_y = 16; /* BeOS limitation */
53         if ( (w > allowed_x) || (h > allowed_y) ) {
54                 SDL_SetError("Only cursors of dimension (%dx%d) are allowed",
55                                                         allowed_x, allowed_y);
56                 return(NULL);
57         }
58
59         /* Allocate the cursor */
60         cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor));
61         if ( cursor == NULL ) {
62                 SDL_OutOfMemory();
63                 return(NULL);
64         }
65         cursor->bits = (char *)SDL_malloc(4+2*((allowed_x/8)*allowed_y));
66         if ( cursor->bits == NULL ) {
67                 SDL_free(cursor);
68                 SDL_OutOfMemory();
69                 return(NULL);
70         }
71         cursor->bits[0] = allowed_y;            /* Size of the cursor */
72         cursor->bits[1] = 1;                    /* Bit depth of cursor */
73         cursor->bits[2] = hot_y;
74         cursor->bits[3] = hot_x;
75         cptr = &cursor->bits[4];
76
77         /* Pad out to the normal cursor size */
78         run = PADDED_BITS(w);
79         pad = PADDED_BITS(allowed_x)-run;
80         for ( i=0; i<h; ++i ) {
81                 SDL_memcpy(cptr, data, run);
82                 SDL_memset(cptr+run, 0, pad);
83                 data += run;
84                 cptr += (run+pad);
85         }
86         for ( ; i<allowed_y; ++i ) {
87                 SDL_memset(cptr, 0, run+pad);
88                 cptr += (run+pad);
89         }
90         for ( i=0; i<h; ++i ) {
91                 /* FIXME: The mask should be OR'd with the data to turn 
92                    inverted color pixels black, since inverted color pixels
93                    aren't supported under BeOS.
94                  */
95                 SDL_memcpy(cptr, mask, run);
96                 SDL_memset(cptr+run, 0, pad);
97                 mask += run;
98                 cptr += (run+pad);
99         }
100         for ( ; i<allowed_y; ++i ) {
101                 SDL_memset(cptr, 0, run+pad);
102                 cptr += (run+pad);
103         }
104         return(cursor);
105 }
106
107 int BE_ShowWMCursor(_THIS, WMcursor *cursor)
108 {
109         if ( be_app->Lock() ) {
110                 if ( cursor == NULL ) {
111                         if ( SDL_BlankCursor != NULL ) {
112                                 be_app->SetCursor(SDL_BlankCursor->bits);
113                         }
114                 } else {
115                         be_app->SetCursor(cursor->bits);
116                 }
117                 be_app->Unlock();
118         }
119         return(1);
120 }
121
122 void BE_FreeWMCursor(_THIS, WMcursor *cursor)
123 {
124         SDL_free(cursor->bits);
125         SDL_free(cursor);
126 }
127
128 /* Implementation by Christian Bauer <cbauer@student.physik.uni-mainz.de> */
129 void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
130 {
131         BPoint pt;
132         SDL_Win->GetXYOffset(pt.x, pt.y);
133         pt.x += x;
134         pt.y += y;
135         SDL_Win->Lock();
136         SDL_Win->ConvertToScreen(&pt);
137         SDL_Win->Unlock();
138         set_mouse_position((int32)pt.x, (int32)pt.y);
139 }
140
141 /* Check to see if we need to enter or leave mouse relative mode */
142 void BE_CheckMouseMode(_THIS)
143 {
144         /* If the mouse is hidden and input is grabbed, we use relative mode */
145         if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
146              (_this->input_grab != SDL_GRAB_OFF) ) {
147                 mouse_relative = 1;
148         } else {
149                 mouse_relative = 0;
150         }
151 }
152
153 }; /* Extern C */