diff options
Diffstat (limited to 'src/glut/fbdev/input.c')
-rw-r--r-- | src/glut/fbdev/input.c | 828 |
1 files changed, 0 insertions, 828 deletions
diff --git a/src/glut/fbdev/input.c b/src/glut/fbdev/input.c deleted file mode 100644 index 1445682c76..0000000000 --- a/src/glut/fbdev/input.c +++ /dev/null @@ -1,828 +0,0 @@ -/* - * 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 <errno.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <termios.h> -#include <inttypes.h> - -#include <sys/ioctl.h> -#include <sys/poll.h> -#include <sys/kd.h> - -#include <linux/keyboard.h> -#include <linux/fb.h> -#include <linux/vt.h> - -#include <GL/glut.h> - -#include "internal.h" - -#define MOUSEDEV "/dev/gpmdata" - -#ifdef HAVE_GPM -#include <gpm.h> -int GpmMouse; -#endif - -int CurrentVT = 0; -int ConsoleFD = -1; - -int KeyboardModifiers; - -int MouseX, MouseY; -int NumMouseButtons; - -double MouseSpeed = 0; - -int KeyRepeatMode = GLUT_KEY_REPEAT_DEFAULT; - -int MouseVisible = 0; -int LastMouseTime = 0; - -static int OldKDMode = -1; -static int OldMode = KD_TEXT; -static struct vt_mode OldVTMode; -static struct termios OldTermios; - -static int KeyboardLedState; - -static int MouseFD; - -static int kbdpipe[2]; - -static int LastStdinKeyTime, LastStdinSpecialKey = -1, LastStdinCode = -1; - -#define MODIFIER(mod) \ - KeyboardModifiers = release ? KeyboardModifiers & ~mod \ - : KeyboardModifiers | mod; - -/* signal handler attached to SIGIO on keyboard input, vt - switching and modifiers is handled in the signal handler - other keypresses read from a pipe that leaves the handler - if a program locks up the glut loop, you can still switch - vts and kill it without Alt-SysRq hack */ -static void KeyboardHandler(int sig) -{ - unsigned char code; - - while(read(ConsoleFD, &code, 1) == 1) { - int release, labelval; - struct kbentry entry; - static int lalt; /* only left alt does vt switch */ - - release = code & 0x80; - - entry.kb_index = code & 0x7F; - entry.kb_table = 0; - - if (ioctl(ConsoleFD, KDGKBENT, &entry) < 0) { - sprintf(exiterror, "ioctl(KDGKBENT) failed.\n"); - exit(0); - } - - labelval = entry.kb_value; - - switch(labelval) { - case K_SHIFT: - case K_SHIFTL: - MODIFIER(GLUT_ACTIVE_SHIFT); - continue; - case K_CTRL: - MODIFIER(GLUT_ACTIVE_CTRL); - continue; - case K_ALT: - lalt = !release; - case K_ALTGR: - MODIFIER(GLUT_ACTIVE_ALT); - continue; - } - - if(lalt && !release) { - /* VT switch, we must do it */ - int vt = -1; - struct vt_stat st; - if(labelval >= K_F1 && labelval <= K_F12) - vt = labelval - K_F1 + 1; - - if(labelval == K_LEFT) - if(ioctl(ConsoleFD, VT_GETSTATE, &st) >= 0) - vt = st.v_active - 1; - - if(labelval == K_RIGHT) - if(ioctl(ConsoleFD, VT_GETSTATE, &st) >= 0) - vt = st.v_active + 1; - - if(vt != -1) { - if(Swapping) - VTSwitch = vt; - else - if(ioctl(ConsoleFD, VT_ACTIVATE, vt) < 0) - sprintf(exiterror, "Error switching console\n"); - continue; - } - } - write(kbdpipe[1], &code, 1); - } -} - -static void LedModifier(int led, int release) -{ - static int releaseflag = K_CAPS | K_NUM | K_HOLD; - if(release) - releaseflag |= led; - else - if(releaseflag & led) { - KeyboardLedState ^= led; - releaseflag &= ~led; - } - - ioctl(ConsoleFD, KDSKBLED, KeyboardLedState); - ioctl(ConsoleFD, KDSETLED, 0x80); -} - -static void HandleKeyPress(unsigned char key, int up) -{ - if(up) { - if(KeyboardUpFunc) - KeyboardUpFunc(key, MouseX, MouseY); - } else - if(KeyboardFunc) - KeyboardFunc(key, MouseX, MouseY); - else - if(key == 27) - exit(0); /* no handler, to provide a way to exit */ -} - -static void HandleSpecialPress(int key, int up) -{ - if(up) { - if(SpecialUpFunc) - SpecialUpFunc(key, MouseX, MouseY); - } else - if(SpecialFunc) - SpecialFunc(key, MouseX, MouseY); -} - -static void ReleaseStdinKey(void) -{ - if(LastStdinSpecialKey != -1) { - HandleSpecialPress(LastStdinSpecialKey, 1); - LastStdinSpecialKey = -1; - } - if(LastStdinCode != -1) { - HandleKeyPress(LastStdinCode, 1); - LastStdinCode = -1; - } -} - -#define READKEY read(kbdpipe[0], &code, 1) -static int ReadKey(void) -{ - int release, labelval, labelvalnoshift; - unsigned char code; - int specialkey = 0; - struct kbentry entry; - - if(READKEY != 1) { - /* if we are reading from stdin, we detect key releases when the key - does not repeat after a given timeout */ - if(ConsoleFD == 0 && LastStdinKeyTime + 100 < glutGet(GLUT_ELAPSED_TIME)) - ReleaseStdinKey(); - return 0; - } - - if(code == 0) - return 0; - - /* stdin input escape code based */ - if(ConsoleFD == 0) { - KeyboardModifiers = 0; - altset: - if(code == 27 && READKEY == 1) { - if(code != 91) { - KeyboardModifiers |= GLUT_ACTIVE_ALT; - goto altset; - } - READKEY; - switch(code) { - case 68: - specialkey = GLUT_KEY_LEFT; break; - case 65: - specialkey = GLUT_KEY_UP; break; - case 67: - specialkey = GLUT_KEY_RIGHT; break; - case 66: - specialkey = GLUT_KEY_DOWN; break; - case 52: - specialkey = GLUT_KEY_END; READKEY; break; - case 53: - specialkey = GLUT_KEY_PAGE_UP; READKEY; break; - case 54: - specialkey = GLUT_KEY_PAGE_DOWN; READKEY; break; - case 49: - READKEY; - if(code == 126) - specialkey = GLUT_KEY_HOME; - else { - specialkey = GLUT_KEY_F1 + code - 50; - READKEY; - } - break; - case 50: - READKEY; - if(code == 126) - specialkey = GLUT_KEY_INSERT; - else { - if(code > '1') - code--; - if(code > '6') - code--; - if(code > '3') { - KeyboardModifiers |= GLUT_ACTIVE_SHIFT; - code -= 12; - } - specialkey = GLUT_KEY_F1 + code - 40; - READKEY; - } - break; - case 51: - READKEY; - if(code == 126) { - code = '\b'; - goto stdkey; - } - KeyboardModifiers |= GLUT_ACTIVE_SHIFT; - specialkey = GLUT_KEY_F1 + code - 45; - READKEY; - break; - case 91: - READKEY; - specialkey = GLUT_KEY_F1 + code - 65; - break; - default: - return 0; - } - } - - if(specialkey) { - LastStdinKeyTime = glutGet(GLUT_ELAPSED_TIME); - - if(LastStdinSpecialKey != specialkey) { - ReleaseStdinKey(); - HandleSpecialPress(specialkey, 0); - LastStdinSpecialKey = specialkey; - LastStdinKeyTime += 200; /* initial repeat */ - } else - if(KeyRepeatMode != GLUT_KEY_REPEAT_OFF) - HandleSpecialPress(specialkey, 0); - } else { - if(code >= 1 && code <= 26 && code != '\r') { - KeyboardModifiers |= GLUT_ACTIVE_CTRL; - code += 'a' - 1; - } - if((code >= 43 && code <= 34) || (code == 60) - || (code >= 62 && code <= 90) || (code == 94) - || (code == 95) || (code >= 123 && code <= 126)) - KeyboardModifiers |= GLUT_ACTIVE_SHIFT; - - stdkey: - LastStdinKeyTime = glutGet(GLUT_ELAPSED_TIME); - if(LastStdinCode != code) { - ReleaseStdinKey(); - HandleKeyPress(code, 0); - LastStdinCode = code; - LastStdinKeyTime += 200; /* initial repeat */ - } else - if(KeyRepeatMode != GLUT_KEY_REPEAT_OFF) - HandleSpecialPress(code, 0); - } - return 1; - } - - /* linux kbd reading */ - release = code & 0x80; - code &= 0x7F; - - if(KeyRepeatMode == GLUT_KEY_REPEAT_OFF) { - static char keystates[128]; - if(release) - keystates[code] = 0; - else { - if(keystates[code]) - return 1; - keystates[code] = 1; - } - } - - entry.kb_index = code; - entry.kb_table = 0; - - if (ioctl(ConsoleFD, KDGKBENT, &entry) < 0) { - sprintf(exiterror, "ioctl(KDGKBENT) failed.\n"); - exit(0); - } - - labelvalnoshift = entry.kb_value; - - if(KeyboardModifiers & GLUT_ACTIVE_SHIFT) - entry.kb_table |= K_SHIFTTAB; - - if (ioctl(ConsoleFD, KDGKBENT, &entry) < 0) { - sprintf(exiterror, "ioctl(KDGKBENT) failed.\n"); - exit(0); - } - - labelval = entry.kb_value; - - switch(labelvalnoshift) { - case K_CAPS: - LedModifier(LED_CAP, release); - return 0; - case K_NUM: - LedModifier(LED_NUM, release); - return 0; - case K_HOLD: /* scroll lock suspends glut */ - LedModifier(LED_SCR, release); - while(KeyboardLedState & LED_SCR) { - usleep(10000); - ReadKey(); - } - return 0; - } - - /* we could queue keypresses here */ - if(KeyboardLedState & LED_SCR) - return 0; - - if(labelvalnoshift >= K_F1 && labelvalnoshift <= K_F12) - specialkey = GLUT_KEY_F1 + labelvalnoshift - K_F1; - else - switch(labelvalnoshift) { - case K_LEFT: - specialkey = GLUT_KEY_LEFT; break; - case K_UP: - specialkey = GLUT_KEY_UP; break; - case K_RIGHT: - specialkey = GLUT_KEY_RIGHT; break; - case K_DOWN: - specialkey = GLUT_KEY_DOWN; break; - case K_PGUP: - specialkey = GLUT_KEY_PAGE_UP; break; - case K_PGDN: - specialkey = GLUT_KEY_PAGE_DOWN; break; - case K_FIND: - specialkey = GLUT_KEY_HOME; break; - case K_SELECT: - specialkey = GLUT_KEY_END; break; - case K_INSERT: - specialkey = GLUT_KEY_INSERT; break; - case K_REMOVE: - labelval = '\b'; - break; - case K_ENTER: - labelval = '\r'; break; - } - - /* likely a keypad input, but depends on keyboard mapping, ignore */ - if(labelval == 512) - return 1; - - /* dispatch callback */ - if(specialkey) - HandleSpecialPress(specialkey, release); - else { - char c = labelval; - - if(KeyboardLedState & LED_CAP) { - if(c >= 'A' && c <= 'Z') - c += 'a' - 'A'; - else - if(c >= 'a' && c <= 'z') - c += 'A' - 'a'; - } - HandleKeyPress(c, release); - } - return 1; -} - -void glutIgnoreKeyRepeat(int ignore) -{ - KeyRepeatMode = ignore ? GLUT_KEY_REPEAT_OFF : GLUT_KEY_REPEAT_ON; -} - -void glutSetKeyRepeat(int repeatMode) -{ - KeyRepeatMode = repeatMode; -} - -void glutForceJoystickFunc(void) -{ -} - -static void HandleMousePress(int button, int pressed) -{ - if(TryMenu(button, pressed)) - return; - - if(MouseFunc) - MouseFunc(button, pressed ? GLUT_DOWN : GLUT_UP, MouseX, MouseY); -} - -static int ReadMouse(void) -{ - int l, r, m; - static int ll, lm, lr; - signed char dx, dy; - -#ifdef HAVE_GPM - if(GpmMouse) { - Gpm_Event event; - struct pollfd pfd; - pfd.fd = gpm_fd; - pfd.events = POLLIN; - if(poll(&pfd, 1, 1) != 1) - return 0; - - if(Gpm_GetEvent(&event) != 1) - return 0; - - l = event.buttons & GPM_B_LEFT; - m = event.buttons & GPM_B_MIDDLE; - r = event.buttons & GPM_B_RIGHT; - - /* gpm is weird in that it gives a button number when the button - is released, with type set to GPM_UP, this is only a problem - if it is the last button released */ - - if(event.type & GPM_UP) - if(event.buttons == GPM_B_LEFT || event.buttons == GPM_B_MIDDLE || - event.buttons == GPM_B_RIGHT || event.buttons == GPM_B_FOURTH) - l = m = r = 0; - - dx = event.dx; - dy = event.dy; - } else -#endif - { - char data[4]; - - if(MouseFD == -1) - return 0; - - if(read(MouseFD, data, 4) != 4) - return 0; - - l = ((data[0] & 0x20) >> 3); - m = ((data[3] & 0x10) >> 3); - r = ((data[0] & 0x10) >> 4); - - dx = (((data[0] & 0x03) << 6) | (data[1] & 0x3F)); - dy = (((data[0] & 0x0C) << 4) | (data[2] & 0x3F)); - } - - MouseX += dx * MouseSpeed; - if(MouseX < 0) - MouseX = 0; - else - if(MouseX >= VarInfo.xres) - MouseX = VarInfo.xres - 1; - - MouseY += dy * MouseSpeed; - if(MouseY < 0) - MouseY = 0; - else - if(MouseY >= VarInfo.yres) - MouseY = VarInfo.yres - 1; - - if(l != ll) - HandleMousePress(GLUT_LEFT_BUTTON, l); - if(m != lm) - HandleMousePress(GLUT_MIDDLE_BUTTON, m); - if(r != lr) - HandleMousePress(GLUT_RIGHT_BUTTON, r); - - ll = l, lm = m, lr = r; - - if(dx || dy || !MouseVisible) { - if(l || m || r) { - if(MotionFunc) - MotionFunc(MouseX, MouseY); - } else - if(PassiveMotionFunc) - PassiveMotionFunc(MouseX, MouseY); - - EraseCursor(); - - MouseVisible = 1; - - if(ActiveMenu) - Redisplay = 1; - else - SwapCursor(); - } - - LastMouseTime = glutGet(GLUT_ELAPSED_TIME); - - return 1; -} - -void ReceiveInput(void) -{ - if(ConsoleFD != -1) - while(ReadKey()); - - while(ReadMouse()); - - /* implement a 2 second timeout on the mouse */ - if(MouseVisible && glutGet(GLUT_ELAPSED_TIME) - LastMouseTime > 2000) { - EraseCursor(); - MouseVisible = 0; - SwapCursor(); - } -} - -static void VTSwitchHandler(int sig) -{ - struct vt_stat st; - switch(sig) { - case SIGUSR1: - ioctl(ConsoleFD, VT_RELDISP, 1); - Active = 0; -#ifdef MULTIHEAD - VisiblePoll = 1; - TestVisible(); -#else - VisibleSwitch = 1; - Visible = 0; -#endif - break; - case SIGUSR2: - ioctl(ConsoleFD, VT_GETSTATE, &st); - if(st.v_active) - ioctl(ConsoleFD, VT_RELDISP, VT_ACKACQ); - - RestoreColorMap(); - - Active = 1; - Visible = 1; - VisibleSwitch = 1; - - Redisplay = 1; - break; - } -} - -void InitializeVT(int usestdin) -{ - struct termios tio; - struct vt_mode vt; - char console[128]; - - signal(SIGIO, SIG_IGN); - - Active = 1; - - if(usestdin) { - ConsoleFD = 0; - goto setattribs; - } - - /* detect the current vt if it was not specified */ - if(CurrentVT == 0) { - int fd = open("/dev/tty", O_RDWR | O_NDELAY, 0); - struct vt_stat st; - if(fd == -1) { - sprintf(exiterror, "Failed to open /dev/tty\n"); - exit(0); - } - - if(ioctl(fd, VT_GETSTATE, &st) == -1) { - fprintf(stderr, "Could not detect current vt, specify with -vt\n"); - fprintf(stderr, "Defaulting to stdin input\n"); - ConsoleFD = 0; - close(fd); - goto setattribs; - } - - CurrentVT = st.v_active; - close(fd); - } - - /* if we close with the modifier set in glutIconifyWindow, we won't - get the signal when they are released, so set to zero here */ - KeyboardModifiers = 0; - - /* open the console tty */ - sprintf(console, "/dev/tty%d", CurrentVT); - ConsoleFD = open(console, O_RDWR | O_NDELAY, 0); - if (ConsoleFD < 0) { - sprintf(exiterror, "error couldn't open %s," - " defaulting to stdin \n", console); - ConsoleFD = 0; - goto setattribs; - } - - signal(SIGUSR1, VTSwitchHandler); - signal(SIGUSR2, VTSwitchHandler); - - if (ioctl(ConsoleFD, VT_GETMODE, &OldVTMode) < 0) { - sprintf(exiterror,"Failed to grab %s, defaulting to stdin\n", console); - close(ConsoleFD); - ConsoleFD = 0; - goto setattribs; - } - - vt = OldVTMode; - - vt.mode = VT_PROCESS; - vt.waitv = 0; - vt.relsig = SIGUSR1; - vt.acqsig = SIGUSR2; - if (ioctl(ConsoleFD, VT_SETMODE, &vt) < 0) { - sprintf(exiterror, "error: ioctl(VT_SETMODE) failed: %s\n", - strerror(errno)); - close(ConsoleFD); - ConsoleFD = 0; - exit(1); - } - - if (ioctl(ConsoleFD, KDGKBMODE, &OldKDMode) < 0) { - sprintf(exiterror, "Warning: ioctl KDGKBMODE failed!\n"); - OldKDMode = K_XLATE; - } - - /* use SIGIO so VT switching can work if the program is locked */ - signal(SIGIO, KeyboardHandler); - - pipe(kbdpipe); - - if(fcntl(kbdpipe[0], F_SETFL, O_NONBLOCK | O_ASYNC) < 0) { - sprintf(exiterror, "Failed to set keyboard to non-blocking\n"); - exit(0); - } - - fcntl(ConsoleFD, F_SETOWN, getpid()); - - if(ioctl(ConsoleFD, KDGETMODE, &OldMode) < 0) - sprintf(exiterror, "Warning: Failed to get terminal mode\n"); - -#ifdef HAVE_GPM - if(!GpmMouse) -#endif - if(ioctl(ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0) - sprintf(exiterror,"Warning: Failed to set terminal to graphics\n"); - - if(ioctl(ConsoleFD, KDSKBMODE, K_MEDIUMRAW) < 0) { - sprintf(exiterror, "ioctl KDSKBMODE failed!\n"); - exit(0); - } - - if(ioctl(ConsoleFD, KDGKBLED, &KeyboardLedState) < 0) { - sprintf(exiterror, "ioctl KDGKBLED failed!\n"); - exit(0); - } - - setattribs: - /* enable async input input */ - if(fcntl(ConsoleFD, F_SETFL, O_ASYNC) < 0) { - sprintf(exiterror, "Failed to set O_ASYNC mode on fd %d\n", ConsoleFD); - exit(0); - } - - /* save old terminos settings */ - if (tcgetattr(ConsoleFD, &OldTermios) < 0) { - sprintf(exiterror, "tcgetattr failed\n"); - exit(0); - } - - tio = OldTermios; - - /* terminos settings for straight-through mode */ - tio.c_lflag &= ~(ICANON | ECHO | ISIG); - tio.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); - tio.c_iflag |= IGNBRK; - - tio.c_cc[VMIN] = 0; - tio.c_cc[VTIME] = 0; - - if (tcsetattr(ConsoleFD, TCSANOW, &tio) < 0) { - sprintf(exiterror, "tcsetattr failed\n"); - exit(0); - } -} - -void RestoreVT(void) -{ - if(ConsoleFD < 0) - return; - - if (tcsetattr(ConsoleFD, TCSANOW, &OldTermios) < 0) - sprintf(exiterror, "tcsetattr failed\n"); - - /* setting the mode to text from graphics restores the colormap */ - if( -#ifdef HAVE_GPM - !GpmMouse || -#endif - ConsoleFD == 0) - if(ioctl(ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0) - goto skipioctl; /* no need to fail twice */ - - if(ioctl(ConsoleFD, KDSETMODE, OldMode) < 0) - fprintf(stderr, "ioctl KDSETMODE failed!\n"); - - skipioctl: - - if(ConsoleFD == 0) - return; - - /* restore keyboard state */ - if (ioctl(ConsoleFD, VT_SETMODE, &OldVTMode) < 0) - fprintf(stderr, "Failed to set vtmode\n"); - - if (ioctl(ConsoleFD, KDSKBMODE, OldKDMode) < 0) - fprintf(stderr, "ioctl KDSKBMODE failed!\n"); - - close(ConsoleFD); - - close(kbdpipe[0]); - close(kbdpipe[1]); -} - -void InitializeMouse(void) -{ -#ifdef HAVE_GPM - if(!GpmMouse) -#endif - { - const char *mousedev = getenv("MOUSE"); - if(!mousedev) - mousedev = MOUSEDEV; - if((MouseFD = open(mousedev, O_RDONLY | O_NONBLOCK)) >= 0) { - if(!MouseSpeed) - MouseSpeed = 1; - NumMouseButtons = 3; - return; - } - } -#ifdef HAVE_GPM - { - Gpm_Connect conn; - int c; - conn.eventMask = ~0; /* Want to know about all the events */ - conn.defaultMask = 0; /* don't handle anything by default */ - conn.minMod = 0; /* want everything */ - conn.maxMod = ~0; /* all modifiers included */ - if(Gpm_Open(&conn, 0) != -1) { - if(!MouseSpeed) - MouseSpeed = 8; - NumMouseButtons = 3; - return; - } - fprintf(stderr, "Cannot open gpmctl.\n"); - } -#endif - fprintf(stderr,"Cannot open %s.\n" - "Continuing without Mouse\n", MOUSEDEV); -} - -void CloseMouse(void) -{ -#ifdef HAVE_GPM - if(GpmMouse) { - if(NumMouseButtons) - Gpm_Close(); - } else -#endif - if(MouseFD >= 0) - close(MouseFD); -} |