Added DirectFB GLUT implementation.
[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 __u8 *src, *msk;
36 void *dst;
37 int pitch;
38 int x, y;
39
40 if (!g_current || !g_current->window)
41 return;
42
43 if (g_current->cursor == type)
44 return;
45
46 switch (type) {
47 case GLUT_CURSOR_RIGHT_ARROW:
48 cursor = &cur_right_arrow[0];
49 break;
50 case GLUT_CURSOR_LEFT_ARROW:
51 cursor = &cur_left_arrow[0];
52 break;
53 case GLUT_CURSOR_INFO:
54 cursor = &cur_info[0];
55 break;
56 case GLUT_CURSOR_DESTROY:
57 cursor = &cur_destroy[0];
58 break;
59 case GLUT_CURSOR_HELP:
60 cursor = &cur_help[0];
61 break;
62 case GLUT_CURSOR_CYCLE:
63 cursor = &cur_cycle[0];
64 break;
65 case GLUT_CURSOR_SPRAY:
66 cursor = &cur_spray[0];
67 break;
68 case GLUT_CURSOR_WAIT:
69 cursor = &cur_wait[0];
70 break;
71 case GLUT_CURSOR_TEXT:
72 cursor = &cur_text[0];
73 break;
74 case GLUT_CURSOR_CROSSHAIR:
75 cursor = &cur_crosshair[0];
76 break;
77 case GLUT_CURSOR_UP_DOWN:
78 cursor = &cur_up_down[0];
79 break;
80 case GLUT_CURSOR_LEFT_RIGHT:
81 cursor = &cur_left_right[0];
82 break;
83 case GLUT_CURSOR_TOP_SIDE:
84 cursor = &cur_top_side[0];
85 break;
86 case GLUT_CURSOR_BOTTOM_SIDE:
87 cursor = &cur_bottom_side[0];
88 break;
89 case GLUT_CURSOR_LEFT_SIDE:
90 cursor = &cur_left_side[0];
91 break;
92 case GLUT_CURSOR_RIGHT_SIDE:
93 cursor = &cur_right_side[0];
94 break;
95 case GLUT_CURSOR_TOP_LEFT_CORNER:
96 cursor = &cur_top_left[0];
97 break;
98 case GLUT_CURSOR_TOP_RIGHT_CORNER:
99 cursor = &cur_top_right[0];
100 break;
101 case GLUT_CURSOR_BOTTOM_RIGHT_CORNER:
102 cursor = &cur_bottom_right[0];
103 break;
104 case GLUT_CURSOR_BOTTOM_LEFT_CORNER:
105 cursor = &cur_bottom_left[0];
106 break;
107 default:
108 cursor = &cur_right_arrow[0];
109 break;
110 }
111
112 dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
113 dsc.width = cursor[0];
114 dsc.height = cursor[0];
115 dsc.pixelformat = DSPF_ARGB;
116
117 if (dfb->CreateSurface( dfb, &dsc, &shape ))
118 return;
119
120 if (shape->Lock( shape, DSLF_WRITE, &dst, &pitch )) {
121 shape->Release( shape );
122 return;
123 }
124
125 src = (__u8*) &cursor[3];
126 msk = src + cursor[0]*cursor[0]/8;
127
128 for (y = 0; y < cursor[0]; y++) {
129 for (x = 0; x < cursor[0]; x++) {
130 int p = x & 7;
131
132 ((__u32*)dst)[x] = ((src[x>>3] & (0x80 >> p)) ? 0 : 0x00ffffff) |
133 ((msk[x>>3] & (0x80 >> p)) ? 0xff000000 : 0);
134 }
135
136 dst += pitch;
137 src += 2;
138 msk += 2;
139 }
140
141 shape->Unlock( shape );
142
143 g_current->window->SetCursorShape( g_current->window,
144 shape, cursor[1], cursor[2] );
145 g_current->cursor = type;
146
147 shape->Release( shape );
148 }
149
150
151 void GLUTAPIENTRY
152 glutWarpPointer( int x, int y )
153 {
154 if (g_current) {
155 if (!g_game) {
156 int wx, wy;
157 g_current->window->GetPosition( g_current->window, &wx, &wy );
158 primary->WarpCursor( primary, wx+x, wy+y );
159 }
160 else {
161 g_current->cx = x;
162 g_current->cy = y;
163 }
164 }
165 }
166
167