2 * Mesa 3-D graphics library
4 * Copyright (C) 1995-2006 Brian Paul
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Library for glut using mesa fbdev driver
24 * Written by Sean D'Epagnier (c) 2006
27 /* these routines are written to access graphics memory directly, not using mesa
28 to render the cursor, this is faster, it would be good to use a hardware
29 cursor if it exists instead */
43 int CurrentCursor
= GLUT_CURSOR_LEFT_ARROW
;
45 static int LastMouseX
, LastMouseY
;
46 static unsigned char *MouseBuffer
;
48 void InitializeCursor(void)
50 if(!MouseBuffer
&& (MouseBuffer
= malloc(CURSOR_WIDTH
* CURSOR_HEIGHT
51 * VarInfo
.bits_per_pixel
/ 8)) == NULL
) {
52 sprintf(exiterror
, "malloc failure\n");
56 MouseX
= VarInfo
.xres
/ 2;
57 MouseY
= VarInfo
.yres
/ 2;
60 void EraseCursor(void)
62 int off
= LastMouseY
* FixedInfo
.line_length
63 + LastMouseX
* VarInfo
.bits_per_pixel
/ 8;
64 int stride
= CURSOR_WIDTH
* VarInfo
.bits_per_pixel
/ 8;
67 unsigned char *src
= MouseBuffer
;
69 if(!MouseVisible
|| CurrentCursor
< 0 || CurrentCursor
>= NUM_CURSORS
)
72 for(i
= 0; i
<CURSOR_HEIGHT
; i
++) {
73 memcpy(BackBuffer
+ off
, src
, stride
);
75 off
+= FixedInfo
.line_length
;
79 static void SaveCursor(int x
, int y
)
81 int bypp
, off
, stride
, i
;
82 unsigned char *src
= MouseBuffer
;
87 if(x
> (int)VarInfo
.xres
- CURSOR_WIDTH
)
88 LastMouseX
= VarInfo
.xres
- CURSOR_WIDTH
;
95 if(y
> (int)VarInfo
.yres
- CURSOR_HEIGHT
)
96 LastMouseY
= VarInfo
.yres
- CURSOR_HEIGHT
;
100 bypp
= VarInfo
.bits_per_pixel
/ 8;
101 off
= LastMouseY
* FixedInfo
.line_length
+ LastMouseX
* bypp
;
102 stride
= CURSOR_WIDTH
* bypp
;
103 for(i
= 0; i
<CURSOR_HEIGHT
; i
++) {
104 memcpy(src
, BackBuffer
+ off
, stride
);
106 off
+= FixedInfo
.line_length
;
110 void DrawCursor(void)
112 int i
, j
, px
, py
, xoff
, xlen
, yoff
, ylen
, bypp
, cstride
, dstride
;
114 const unsigned char *d
;
116 if(!MouseVisible
|| CurrentCursor
< 0 || CurrentCursor
>= NUM_CURSORS
)
119 px
= MouseX
- CursorsXOffset
[CurrentCursor
];
120 py
= MouseY
- CursorsYOffset
[CurrentCursor
];
129 if(px
+ CURSOR_WIDTH
> VarInfo
.xres
)
130 xlen
= VarInfo
.xres
- px
;
136 ylen
= CURSOR_HEIGHT
;
137 if(py
+ CURSOR_HEIGHT
> VarInfo
.yres
)
138 ylen
= VarInfo
.yres
- py
;
140 bypp
= VarInfo
.bits_per_pixel
/ 8;
142 c
= BackBuffer
+ FixedInfo
.line_length
* (py
+ yoff
) + (px
+ xoff
) * bypp
;
143 cstride
= FixedInfo
.line_length
- bypp
* (xlen
- xoff
);
145 d
= Cursors
[CurrentCursor
] + (CURSOR_WIDTH
* yoff
+ xoff
)*4;
146 dstride
= (CURSOR_WIDTH
- xlen
+ xoff
) * 4;
151 const int shift
= 8 - REVERSECMAPSIZELOG
;
152 for(i
= yoff
; i
< ylen
; i
++) {
153 for(j
= xoff
; j
< xlen
; j
++) {
156 [(d
[0]+(((int)(RedColorMap
[c
[0]]>>8)*d
[3])>>8))>>shift
]
157 [(d
[1]+(((int)(GreenColorMap
[c
[0]]>>8)*d
[3])>>8))>>shift
]
158 [(d
[2]+(((int)(BlueColorMap
[c
[0]]>>8)*d
[3])>>8))>>shift
];
168 uint16_t *e
= (void*)c
;
170 for(i
= yoff
; i
< ylen
; i
++) {
171 for(j
= xoff
; j
< xlen
; j
++) {
173 e
[0] = ((((d
[0] + (((int)(((e
[0] >> 8) & 0xf8)
174 | ((c
[0] >> 11) & 0x7)) * d
[3]) >> 8)) & 0xf8) << 8)
175 | (((d
[1] + (((int)(((e
[0] >> 3) & 0xfc)
176 | ((e
[0] >> 5) & 0x3)) * d
[3]) >> 8)) & 0xfc) << 3)
177 | ((d
[2] + (((int)(((e
[0] << 3) & 0xf8)
178 | (e
[0] & 0x7)) * d
[3]) >> 8)) >> 3));
189 for(i
= yoff
; i
< ylen
; i
++) {
190 for(j
= xoff
; j
< xlen
; j
++) {
192 c
[0] = d
[0] + (((int)c
[0] * d
[3]) >> 8);
193 c
[1] = d
[1] + (((int)c
[1] * d
[3]) >> 8);
194 c
[2] = d
[2] + (((int)c
[2] * d
[3]) >> 8);
206 #define MIN(x, y) x < y ? x : y
207 void SwapCursor(void)
209 int px
= MouseX
- CursorsXOffset
[CurrentCursor
];
210 int py
= MouseY
- CursorsYOffset
[CurrentCursor
];
212 int minx
= MIN(px
, LastMouseX
);
213 int sizex
= abs(px
- LastMouseX
);
215 int miny
= MIN(py
, LastMouseY
);
216 int sizey
= abs(py
- LastMouseY
);
221 /* now update the portion of the screen that has changed, this is also
222 used to hide the mouse if MouseVisible is 0 */
223 if(DisplayMode
& GLUT_DOUBLE
&& ((sizex
|| sizey
) || !MouseVisible
)) {
230 if(minx
+ sizex
> VarInfo
.xres
- CURSOR_WIDTH
)
231 sizex
= VarInfo
.xres
- CURSOR_WIDTH
- minx
;
232 if(miny
+ sizey
> VarInfo
.yres
- CURSOR_HEIGHT
)
233 sizey
= VarInfo
.yres
- CURSOR_HEIGHT
- miny
;
234 off
= FixedInfo
.line_length
* miny
235 + minx
* VarInfo
.bits_per_pixel
/ 8;
236 stride
= (sizex
+ CURSOR_WIDTH
) * VarInfo
.bits_per_pixel
/ 8;
238 for(i
= 0; i
< sizey
+ CURSOR_HEIGHT
; i
++) {
239 memcpy(FrameBuffer
+off
, BackBuffer
+off
, stride
);
240 off
+= FixedInfo
.line_length
;
245 void glutWarpPointer(int x
, int y
)
249 if(x
>= VarInfo
.xres
)
250 x
= VarInfo
.xres
- 1;
255 if(y
>= VarInfo
.yres
)
256 y
= VarInfo
.yres
- 1;
263 void glutSetCursor(int cursor
)
265 if(cursor
== GLUT_CURSOR_FULL_CROSSHAIR
)
266 cursor
= GLUT_CURSOR_CROSSHAIR
;
270 CurrentCursor
= cursor
;