aca3fcc9215c96b81f3ad28671d7b1eae6871d57
[mesa.git] / src / glut / directfb / cursor.c
1 /*
2 * Copyright (C) 2006 Claudio Ciccani <klan@users.sf.net>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "internal.h"
25
26 #include "cursors.h"
27
28
29 void GLUTAPIENTRY
30 glutSetCursor( int type )
31 {
32 const unsigned char *cursor;
33 DFBSurfaceDescription dsc;
34 IDirectFBSurface *shape;
35
36 if (!g_current || !g_current->window)
37 return;
38
39 if (g_current->cursor == type)
40 return;
41
42 switch (type) {
43 case GLUT_CURSOR_RIGHT_ARROW:
44 cursor = &cur_right_arrow[0];
45 break;
46 case GLUT_CURSOR_LEFT_ARROW:
47 cursor = &cur_left_arrow[0];
48 break;
49 case GLUT_CURSOR_INFO:
50 cursor = &cur_info[0];
51 break;
52 case GLUT_CURSOR_DESTROY:
53 cursor = &cur_destroy[0];
54 break;
55 case GLUT_CURSOR_HELP:
56 cursor = &cur_help[0];
57 break;
58 case GLUT_CURSOR_CYCLE:
59 cursor = &cur_cycle[0];
60 break;
61 case GLUT_CURSOR_SPRAY:
62 cursor = &cur_spray[0];
63 break;
64 case GLUT_CURSOR_WAIT:
65 cursor = &cur_wait[0];
66 break;
67 case GLUT_CURSOR_TEXT:
68 cursor = &cur_text[0];
69 break;
70 case GLUT_CURSOR_CROSSHAIR:
71 cursor = &cur_crosshair[0];
72 break;
73 case GLUT_CURSOR_UP_DOWN:
74 cursor = &cur_up_down[0];
75 break;
76 case GLUT_CURSOR_LEFT_RIGHT:
77 cursor = &cur_left_right[0];
78 break;
79 case GLUT_CURSOR_TOP_SIDE:
80 cursor = &cur_top_side[0];
81 break;
82 case GLUT_CURSOR_BOTTOM_SIDE:
83 cursor = &cur_bottom_side[0];
84 break;
85 case GLUT_CURSOR_LEFT_SIDE:
86 cursor = &cur_left_side[0];
87 break;
88 case GLUT_CURSOR_RIGHT_SIDE:
89 cursor = &cur_right_side[0];
90 break;
91 case GLUT_CURSOR_TOP_LEFT_CORNER:
92 cursor = &cur_top_left[0];
93 break;
94 case GLUT_CURSOR_TOP_RIGHT_CORNER:
95 cursor = &cur_top_right[0];
96 break;
97 case GLUT_CURSOR_BOTTOM_RIGHT_CORNER:
98 cursor = &cur_bottom_right[0];
99 break;
100 case GLUT_CURSOR_BOTTOM_LEFT_CORNER:
101 cursor = &cur_bottom_left[0];
102 break;
103 case GLUT_CURSOR_NONE:
104 cursor = NULL;
105 break;
106 default:
107 cursor = &cur_right_arrow[0];
108 break;
109 }
110
111 dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
112 dsc.width =
113 dsc.height = cursor ? cursor[0] : 8;
114 dsc.pixelformat = DSPF_ARGB;
115
116 if (dfb->CreateSurface( dfb, &dsc, &shape ))
117 return;
118
119 if (cursor) {
120 __u8 *src = (__u8*) &cursor[3];
121 __u8 *msk = src + cursor[0]*cursor[0]/8;
122 void *dst;
123 int pitch;
124 int x, y;
125
126 if (shape->Lock( shape, DSLF_WRITE, &dst, &pitch )) {
127 shape->Release( shape );
128 return;
129 }
130
131 for (y = 0; y < cursor[0]; y++) {
132 for (x = 0; x < cursor[0]; x++) {
133 ((__u32*)dst)[x] =
134 ((src[x>>3] & (0x80 >> (x&7))) ? 0 : 0x00ffffff) |
135 ((msk[x>>3] & (0x80 >> (x&7))) ? 0xff000000 : 0);
136 }
137
138 dst += pitch;
139 src += cursor[0]/8;
140 msk += cursor[0]/8;
141 }
142
143 shape->Unlock( shape );
144 }
145 else {
146 /* Invisible cursor */
147 shape->Clear( shape, 0, 0, 0, 0 );
148 }
149
150 g_current->window->SetCursorShape( g_current->window, shape,
151 cursor ? cursor[1] : 0,
152 cursor ? cursor[2] : 0 );
153 g_current->cursor = type;
154
155 shape->Release( shape );
156 }
157
158
159 void GLUTAPIENTRY
160 glutWarpPointer( int x, int y )
161 {
162 if (g_current) {
163 if (!g_game) {
164 int wx, wy;
165 g_current->window->GetPosition( g_current->window, &wx, &wy );
166 primary->WarpCursor( primary, wx+x, wy+y );
167 }
168 else {
169 g_current->cx = x;
170 g_current->cy = y;
171 }
172 }
173 }
174
175