mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-21 11:08:24 +02:00
1. updated makefiles to build libOSMesa as well as libGL these are improvements to fbdev-glut 1. mouse cursor will timeout and be invisible if not being used 2. do not restore colormaps to truecolor targets, this causes problems at exit on my g450 3. fixed a crash when cleaning up from failure by munmaping what had not yet been mmaped 4. Resize event handling is improved, the resize function is not invoked from a signal handler now. 5. The main loop can detect if it is running very fast (greater than 2khz) 6. keyboard up and special up events are generated from stdin input mode and if it is also not redrawing, it sleeps 7. corrections in escape sequences for function keys for stdin input
272 lines
6.6 KiB
C
272 lines
6.6 KiB
C
/*
|
|
* Mesa 3-D graphics library
|
|
* Version: 6.5
|
|
* Copyright (C) 1995-2006 Brian Paul
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the Free
|
|
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
/*
|
|
* Library for glut using mesa fbdev driver
|
|
*
|
|
* Written by Sean D'Epagnier (c) 2006
|
|
*/
|
|
|
|
/* these routines are written to access graphics memory directly, not using mesa
|
|
to render the cursor, this is faster, it would be good to use a hardware
|
|
cursor if it exists instead */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <inttypes.h>
|
|
#include <string.h>
|
|
|
|
#include <linux/fb.h>
|
|
|
|
#include <GL/glut.h>
|
|
|
|
#include "internal.h"
|
|
#include "cursors.h"
|
|
|
|
int CurrentCursor = GLUT_CURSOR_LEFT_ARROW;
|
|
|
|
static int LastMouseX, LastMouseY;
|
|
static unsigned char *MouseBuffer;
|
|
|
|
void InitializeCursor(void)
|
|
{
|
|
if(!MouseBuffer && (MouseBuffer = malloc(CURSOR_WIDTH * CURSOR_HEIGHT
|
|
* VarInfo.bits_per_pixel / 8)) == NULL) {
|
|
sprintf(exiterror, "malloc failure\n");
|
|
exit(0);
|
|
}
|
|
|
|
MouseX = VarInfo.xres / 2;
|
|
MouseY = VarInfo.yres / 2;
|
|
}
|
|
|
|
void EraseCursor(void)
|
|
{
|
|
int off = LastMouseY * FixedInfo.line_length
|
|
+ LastMouseX * VarInfo.bits_per_pixel / 8;
|
|
int stride = CURSOR_WIDTH * VarInfo.bits_per_pixel / 8;
|
|
int i;
|
|
|
|
unsigned char *src = MouseBuffer;
|
|
|
|
if(!MouseVisible || CurrentCursor < 0 || CurrentCursor >= NUM_CURSORS)
|
|
return;
|
|
|
|
for(i = 0; i<CURSOR_HEIGHT; i++) {
|
|
memcpy(BackBuffer + off, src, stride);
|
|
src += stride;
|
|
off += FixedInfo.line_length;
|
|
}
|
|
}
|
|
|
|
static void SaveCursor(int x, int y)
|
|
{
|
|
int bypp, off, stride, i;
|
|
unsigned char *src = MouseBuffer;
|
|
|
|
if(x < 0)
|
|
LastMouseX = 0;
|
|
else
|
|
if(x > (int)VarInfo.xres - CURSOR_WIDTH)
|
|
LastMouseX = VarInfo.xres - CURSOR_WIDTH;
|
|
else
|
|
LastMouseX = x;
|
|
|
|
if(y < 0)
|
|
LastMouseY = 0;
|
|
else
|
|
if(y > (int)VarInfo.yres - CURSOR_HEIGHT)
|
|
LastMouseY = VarInfo.yres - CURSOR_HEIGHT;
|
|
else
|
|
LastMouseY = y;
|
|
|
|
bypp = VarInfo.bits_per_pixel / 8;
|
|
off = LastMouseY * FixedInfo.line_length + LastMouseX * bypp;
|
|
stride = CURSOR_WIDTH * bypp;
|
|
for(i = 0; i<CURSOR_HEIGHT; i++) {
|
|
memcpy(src, BackBuffer + off, stride);
|
|
src += stride;
|
|
off += FixedInfo.line_length;
|
|
}
|
|
}
|
|
|
|
void DrawCursor(void)
|
|
{
|
|
int i, j, px, py, xoff, xlen, yoff, ylen, bypp, cstride, dstride;
|
|
unsigned char *c;
|
|
const unsigned char *d;
|
|
|
|
if(!MouseVisible || CurrentCursor < 0 || CurrentCursor >= NUM_CURSORS)
|
|
return;
|
|
|
|
px = MouseX - CursorsXOffset[CurrentCursor];
|
|
py = MouseY - CursorsYOffset[CurrentCursor];
|
|
|
|
SaveCursor(px, py);
|
|
|
|
xoff = 0;
|
|
if(px < 0)
|
|
xoff = -px;
|
|
|
|
xlen = CURSOR_WIDTH;
|
|
if(px + CURSOR_WIDTH > VarInfo.xres)
|
|
xlen = VarInfo.xres - px;
|
|
|
|
yoff = 0;
|
|
if(py < 0)
|
|
yoff = -py;
|
|
|
|
ylen = CURSOR_HEIGHT;
|
|
if(py + CURSOR_HEIGHT > VarInfo.yres)
|
|
ylen = VarInfo.yres - py;
|
|
|
|
bypp = VarInfo.bits_per_pixel / 8;
|
|
|
|
c = BackBuffer + FixedInfo.line_length * (py + yoff) + (px + xoff) * bypp;
|
|
cstride = FixedInfo.line_length - bypp * (xlen - xoff);
|
|
|
|
d = Cursors[CurrentCursor] + (CURSOR_WIDTH * yoff + xoff)*4;
|
|
dstride = (CURSOR_WIDTH - xlen + xoff) * 4;
|
|
|
|
switch(bypp) {
|
|
case 1:
|
|
{
|
|
const int shift = 8 - REVERSECMAPSIZELOG;
|
|
for(i = yoff; i < ylen; i++) {
|
|
for(j = xoff; j < xlen; j++) {
|
|
if(d[3] < 220)
|
|
*c = ReverseColorMap
|
|
[(d[0]+(((int)(RedColorMap[c[0]]>>8)*d[3])>>8))>>shift]
|
|
[(d[1]+(((int)(GreenColorMap[c[0]]>>8)*d[3])>>8))>>shift]
|
|
[(d[2]+(((int)(BlueColorMap[c[0]]>>8)*d[3])>>8))>>shift];
|
|
c++;
|
|
d+=4;
|
|
}
|
|
d += dstride;
|
|
c += cstride;
|
|
}
|
|
} break;
|
|
case 2:
|
|
{
|
|
uint16_t *e = (void*)c;
|
|
cstride /= 2;
|
|
for(i = yoff; i < ylen; i++) {
|
|
for(j = xoff; j < xlen; j++) {
|
|
if(d[3] < 220)
|
|
e[0] = ((((d[0] + (((int)(((e[0] >> 8) & 0xf8)
|
|
| ((c[0] >> 11) & 0x7)) * d[3]) >> 8)) & 0xf8) << 8)
|
|
| (((d[1] + (((int)(((e[0] >> 3) & 0xfc)
|
|
| ((e[0] >> 5) & 0x3)) * d[3]) >> 8)) & 0xfc) << 3)
|
|
| ((d[2] + (((int)(((e[0] << 3) & 0xf8)
|
|
| (e[0] & 0x7)) * d[3]) >> 8)) >> 3));
|
|
|
|
e++;
|
|
d+=4;
|
|
}
|
|
d += dstride;
|
|
e += cstride;
|
|
}
|
|
} break;
|
|
case 3:
|
|
case 4:
|
|
for(i = yoff; i < ylen; i++) {
|
|
for(j = xoff; j < xlen; j++) {
|
|
if(d[3] < 220) {
|
|
c[0] = d[0] + (((int)c[0] * d[3]) >> 8);
|
|
c[1] = d[1] + (((int)c[1] * d[3]) >> 8);
|
|
c[2] = d[2] + (((int)c[2] * d[3]) >> 8);
|
|
}
|
|
|
|
c+=bypp;
|
|
d+=4;
|
|
}
|
|
d += dstride;
|
|
c += cstride;
|
|
} break;
|
|
}
|
|
}
|
|
|
|
#define MIN(x, y) x < y ? x : y
|
|
void SwapCursor(void)
|
|
{
|
|
int px = MouseX - CursorsXOffset[CurrentCursor];
|
|
int py = MouseY - CursorsYOffset[CurrentCursor];
|
|
|
|
int minx = MIN(px, LastMouseX);
|
|
int sizex = abs(px - LastMouseX);
|
|
|
|
int miny = MIN(py, LastMouseY);
|
|
int sizey = abs(py - LastMouseY);
|
|
|
|
if(MouseVisible)
|
|
DrawCursor();
|
|
|
|
/* now update the portion of the screen that has changed, this is also
|
|
used to hide the mouse if MouseVisible is 0 */
|
|
if(DisplayMode & GLUT_DOUBLE && ((sizex || sizey) || !MouseVisible)) {
|
|
int off, stride, i;
|
|
if(minx < 0)
|
|
minx = 0;
|
|
if(miny < 0)
|
|
miny = 0;
|
|
|
|
if(minx + sizex > VarInfo.xres - CURSOR_WIDTH)
|
|
sizex = VarInfo.xres - CURSOR_WIDTH - minx;
|
|
if(miny + sizey > VarInfo.yres - CURSOR_HEIGHT)
|
|
sizey = VarInfo.yres - CURSOR_HEIGHT - miny;
|
|
off = FixedInfo.line_length * miny
|
|
+ minx * VarInfo.bits_per_pixel / 8;
|
|
stride = (sizex + CURSOR_WIDTH) * VarInfo.bits_per_pixel / 8;
|
|
|
|
for(i = 0; i < sizey + CURSOR_HEIGHT; i++) {
|
|
memcpy(FrameBuffer+off, BackBuffer+off, stride);
|
|
off += FixedInfo.line_length;
|
|
}
|
|
}
|
|
}
|
|
|
|
void glutWarpPointer(int x, int y)
|
|
{
|
|
if(x < 0)
|
|
x = 0;
|
|
if(x >= VarInfo.xres)
|
|
x = VarInfo.xres - 1;
|
|
MouseX = x;
|
|
|
|
if(y < 0)
|
|
y = 0;
|
|
if(y >= VarInfo.yres)
|
|
y = VarInfo.yres - 1;
|
|
MouseY = y;
|
|
|
|
EraseCursor();
|
|
SwapCursor();
|
|
}
|
|
|
|
void glutSetCursor(int cursor)
|
|
{
|
|
if(cursor == GLUT_CURSOR_FULL_CROSSHAIR)
|
|
cursor = GLUT_CURSOR_CROSSHAIR;
|
|
|
|
EraseCursor();
|
|
MouseVisible = 1;
|
|
CurrentCursor = cursor;
|
|
SwapCursor();
|
|
}
|