1/*
2    SDL - Simple DirectMedia Layer
3    Copyright (C) 1997-2012 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
29extern "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 */
37struct WMcursor {
38	char *bits;
39};
40
41/* Can this be done in the BeOS? */
42WMcursor *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
107int 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
122void 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> */
129void 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 */
142void 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 */
154