mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-02 21:50:34 +01: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
309 lines
7.1 KiB
C
309 lines
7.1 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
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <linux/fb.h>
|
|
|
|
#include <GL/glut.h>
|
|
|
|
#include "internal.h"
|
|
|
|
#define MENU_FONT_WIDTH 9
|
|
#define MENU_FONT_HEIGHT 15
|
|
#define MENU_FONT GLUT_BITMAP_9_BY_15
|
|
#define SUBMENU_OFFSET 20
|
|
|
|
struct GlutMenu *Menus;
|
|
int ActiveMenu;
|
|
int CurrentMenu;
|
|
|
|
static double MenuProjection[16];
|
|
|
|
static int AttachedMenus[3];
|
|
static int NumMenus = 1;
|
|
static int SelectedMenu;
|
|
|
|
void InitializeMenus(void)
|
|
{
|
|
glPushAttrib(GL_TRANSFORM_BIT);
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
gluOrtho2D(0.0, VarInfo.xres, VarInfo.yres, 0.0);
|
|
glGetDoublev(GL_PROJECTION_MATRIX, MenuProjection);
|
|
|
|
glPopMatrix();
|
|
glPopAttrib();
|
|
}
|
|
|
|
void FreeMenus(void)
|
|
{
|
|
int i, j;
|
|
|
|
for(i = 1; i<NumMenus; i++) {
|
|
for(j = 0; j<Menus[i].NumItems; j++)
|
|
free(Menus[i].Items[j].name);
|
|
free(Menus[i].Items);
|
|
}
|
|
|
|
free(Menus);
|
|
}
|
|
|
|
int TryMenu(int button, int pressed)
|
|
{
|
|
if(ActiveMenu && !pressed) {
|
|
ActiveMenu = 0;
|
|
CloseMenu();
|
|
Redisplay = 1;
|
|
return 1;
|
|
}
|
|
|
|
if(AttachedMenus[button] && pressed) {
|
|
ActiveMenu = AttachedMenus[button];
|
|
OpenMenu();
|
|
Redisplay = 1;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int DrawMenu(int menu, int x, int *y)
|
|
{
|
|
int i;
|
|
int ret = 1;
|
|
|
|
for(i=0; i < Menus[menu].NumItems; i++) {
|
|
char *s = Menus[menu].Items[i].name;
|
|
int a = 0;
|
|
if(MouseY >= *y && MouseY < *y + MENU_FONT_HEIGHT &&
|
|
MouseX >= x && MouseX < x + Menus[menu].width) {
|
|
a = 1;
|
|
SelectedMenu = menu;
|
|
ret = 0;
|
|
Menus[menu].selected = i;
|
|
glColor3f(1,0,0);
|
|
} else
|
|
glColor3f(1,1,1);
|
|
|
|
*y += MENU_FONT_HEIGHT;
|
|
glRasterPos2i(x, *y);
|
|
for(; *s; s++)
|
|
glutBitmapCharacter(MENU_FONT, *s);
|
|
|
|
if(Menus[menu].selected == i)
|
|
if(Menus[menu].Items[i].submenu)
|
|
if(DrawMenu(Menus[menu].Items[i].submenu, x
|
|
+ SUBMENU_OFFSET, y)) {
|
|
if(!a)
|
|
Menus[menu].selected = -1;
|
|
} else
|
|
ret = 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void DrawMenus(void)
|
|
{
|
|
int x, y;
|
|
|
|
if(GameMode)
|
|
return;
|
|
|
|
x = Menus[ActiveMenu].x;
|
|
y = Menus[ActiveMenu].y;
|
|
|
|
/* save old settings */
|
|
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT
|
|
| GL_ENABLE_BIT | GL_VIEWPORT_BIT);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadMatrixd(MenuProjection);
|
|
glViewport(0, 0, VarInfo.xres, VarInfo.yres);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_ALPHA_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_FOG);
|
|
glDisable(GL_TEXTURE_2D);
|
|
glEnable(GL_COLOR_LOGIC_OP);
|
|
glLogicOp(GL_AND_REVERSE);
|
|
|
|
if(DrawMenu(ActiveMenu, x, &y))
|
|
Menus[ActiveMenu].selected = -1;
|
|
|
|
/* restore settings */
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPopMatrix();
|
|
|
|
glPopAttrib();
|
|
}
|
|
|
|
void OpenMenu(void)
|
|
{
|
|
if(MenuStatusFunc)
|
|
MenuStatusFunc(GLUT_MENU_IN_USE, MouseX, MouseY);
|
|
if(MenuStateFunc)
|
|
MenuStateFunc(GLUT_MENU_IN_USE);
|
|
Menus[ActiveMenu].x = MouseX-Menus[ActiveMenu].width/2;
|
|
|
|
if(Menus[ActiveMenu].x < 0)
|
|
Menus[ActiveMenu].x = 0;
|
|
if(Menus[ActiveMenu].x + Menus[ActiveMenu].width >= VarInfo.xres)
|
|
Menus[ActiveMenu].x = VarInfo.xres - Menus[ActiveMenu].width - 1;
|
|
|
|
Menus[ActiveMenu].y = MouseY-Menus[ActiveMenu].NumItems*MENU_FONT_HEIGHT/2;
|
|
Menus[ActiveMenu].selected = -1;
|
|
}
|
|
|
|
void CloseMenu(void)
|
|
{
|
|
if(MenuStatusFunc)
|
|
MenuStatusFunc(GLUT_MENU_NOT_IN_USE, MouseX, MouseY);
|
|
if(MenuStateFunc)
|
|
MenuStateFunc(GLUT_MENU_NOT_IN_USE);
|
|
if(SelectedMenu > 0) {
|
|
int selected = Menus[SelectedMenu].selected;
|
|
if(selected >= 0)
|
|
if(Menus[SelectedMenu].Items[selected].submenu == 0)
|
|
Menus[SelectedMenu].func(Menus[SelectedMenu].Items
|
|
[selected].value);
|
|
}
|
|
|
|
}
|
|
|
|
/* glut menu functions */
|
|
|
|
int glutCreateMenu(void (*func)(int value))
|
|
{
|
|
CurrentMenu = NumMenus;
|
|
NumMenus++;
|
|
Menus = realloc(Menus, sizeof(*Menus) * NumMenus);
|
|
Menus[CurrentMenu].NumItems = 0;
|
|
Menus[CurrentMenu].Items = NULL;
|
|
Menus[CurrentMenu].func = func;
|
|
Menus[CurrentMenu].width = 0;
|
|
return CurrentMenu;
|
|
}
|
|
|
|
void glutSetMenu(int menu)
|
|
{
|
|
CurrentMenu = menu;
|
|
}
|
|
|
|
int glutGetMenu(void)
|
|
{
|
|
return CurrentMenu;
|
|
}
|
|
|
|
void glutDestroyMenu(int menu)
|
|
{
|
|
if(menu == CurrentMenu)
|
|
CurrentMenu = 0;
|
|
}
|
|
|
|
static void NameMenuEntry(int entry, const char *name)
|
|
{
|
|
int cm = CurrentMenu;
|
|
if(!(Menus[cm].Items[entry-1].name = realloc(Menus[cm].Items[entry-1].name,
|
|
strlen(name) + 1))) {
|
|
sprintf(exiterror, "realloc failed in NameMenuEntry\n");
|
|
exit(0);
|
|
}
|
|
strcpy(Menus[cm].Items[entry-1].name, name);
|
|
if(strlen(name) * MENU_FONT_WIDTH > Menus[cm].width)
|
|
Menus[cm].width = strlen(name) * MENU_FONT_WIDTH;
|
|
}
|
|
|
|
static int AddMenuItem(const char *name)
|
|
{
|
|
int cm = CurrentMenu;
|
|
int item = Menus[cm].NumItems++;
|
|
if(!(Menus[cm].Items = realloc(Menus[cm].Items,
|
|
Menus[cm].NumItems * sizeof(*Menus[0].Items)))) {
|
|
sprintf(exiterror, "realloc failed in AddMenuItem\n");
|
|
exit(0);
|
|
}
|
|
Menus[cm].Items[item].name = NULL;
|
|
NameMenuEntry(item+1, name);
|
|
return item;
|
|
}
|
|
|
|
void glutAddMenuEntry(const char *name, int value)
|
|
{
|
|
int item = AddMenuItem(name);
|
|
Menus[CurrentMenu].Items[item].value = value;
|
|
Menus[CurrentMenu].Items[item].submenu = 0;
|
|
}
|
|
|
|
void glutAddSubMenu(const char *name, int menu)
|
|
{
|
|
int item = AddMenuItem(name);
|
|
if(menu == CurrentMenu) {
|
|
sprintf(exiterror, "Recursive menus not supported\n");
|
|
exit(0);
|
|
}
|
|
Menus[CurrentMenu].Items[item].submenu = menu;
|
|
}
|
|
|
|
void glutChangeToMenuEntry(int entry, const char *name, int value)
|
|
{
|
|
NameMenuEntry(entry, name);
|
|
Menus[CurrentMenu].Items[entry-1].value = value;
|
|
Menus[CurrentMenu].Items[entry-1].submenu = 0;
|
|
}
|
|
|
|
void glutChangeToSubMenu(int entry, const char *name, int menu)
|
|
{
|
|
NameMenuEntry(entry, name);
|
|
Menus[CurrentMenu].Items[entry-1].submenu = menu;
|
|
}
|
|
|
|
void glutRemoveMenuItem(int entry)
|
|
{
|
|
memmove(Menus[CurrentMenu].Items + entry - 1,
|
|
Menus[CurrentMenu].Items + entry,
|
|
sizeof(*Menus[0].Items) * (Menus[CurrentMenu].NumItems - entry));
|
|
Menus[CurrentMenu].NumItems--;
|
|
}
|
|
|
|
void glutAttachMenu(int button)
|
|
{
|
|
AttachedMenus[button] = CurrentMenu;
|
|
}
|
|
|
|
void glutDetachMenu(int button)
|
|
{
|
|
AttachedMenus[button] = 0;
|
|
}
|