diff options
Diffstat (limited to 'src/glut/fbdev/input.c')
-rw-r--r-- | src/glut/fbdev/input.c | 348 |
1 files changed, 205 insertions, 143 deletions
diff --git a/src/glut/fbdev/input.c b/src/glut/fbdev/input.c index 2528a74a105..1445682c760 100644 --- a/src/glut/fbdev/input.c +++ b/src/glut/fbdev/input.c @@ -53,7 +53,7 @@ int GpmMouse; #endif -int CurrentVT; +int CurrentVT = 0; int ConsoleFD = -1; int KeyboardModifiers; @@ -65,8 +65,8 @@ double MouseSpeed = 0; int KeyRepeatMode = GLUT_KEY_REPEAT_DEFAULT; -/* only display the mouse if there is a registered callback for it */ -int MouseEnabled = 0; +int MouseVisible = 0; +int LastMouseTime = 0; static int OldKDMode = -1; static int OldMode = KD_TEXT; @@ -79,6 +79,8 @@ static int MouseFD; static int kbdpipe[2]; +static int LastStdinKeyTime, LastStdinSpecialKey = -1, LastStdinCode = -1; + #define MODIFIER(mod) \ KeyboardModifiers = release ? KeyboardModifiers & ~mod \ : KeyboardModifiers | mod; @@ -93,7 +95,6 @@ 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 */ @@ -163,10 +164,46 @@ static void LedModifier(int led, int release) 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) { @@ -175,8 +212,14 @@ static int ReadKey(void) int specialkey = 0; struct kbentry entry; - if(READKEY != 1) + 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; @@ -185,65 +228,82 @@ static int ReadKey(void) KeyboardModifiers = 0; altset: if(code == 27 && READKEY == 1) { - switch(code) { - case 79: /* function key */ - READKEY; - if(code == 50) { - READKEY; - shiftfunc: - KeyboardModifiers |= GLUT_ACTIVE_SHIFT; - specialkey = GLUT_KEY_F1 + code - 53; - READKEY; - } else { - READKEY; - specialkey = GLUT_KEY_F1 + code - 80; - } - break; - case 91: - 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 53: - specialkey = GLUT_KEY_PAGE_UP; READKEY; break; - case 54: - specialkey = GLUT_KEY_PAGE_DOWN; READKEY; break; - case 49: - specialkey = GLUT_KEY_HOME; READKEY; break; - case 52: - specialkey = GLUT_KEY_END; READKEY; break; - case 50: - READKEY; - if(code != 126) - goto shiftfunc; - specialkey = GLUT_KEY_INSERT; - break; - case 51: - code = '\b'; - goto stdkey; - case 91: - READKEY; - specialkey = GLUT_KEY_F1 + code - 65; - break; - default: - return 0; - } - break; - default: + 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) { - if(SpecialFunc) - SpecialFunc(specialkey, MouseX, MouseY); + 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; @@ -255,8 +315,15 @@ static int ReadKey(void) KeyboardModifiers |= GLUT_ACTIVE_SHIFT; stdkey: - if(KeyboardFunc) - KeyboardFunc(code, MouseX, MouseY); + 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; } @@ -342,19 +409,17 @@ static int ReadKey(void) labelval = '\b'; break; case K_ENTER: - case K_ENTER - 1: /* keypad enter */ labelval = '\r'; break; } + /* likely a keypad input, but depends on keyboard mapping, ignore */ + if(labelval == 512) + return 1; + /* dispatch callback */ - if(specialkey) { - if(release) { - if(SpecialUpFunc) - SpecialUpFunc(specialkey, MouseX, MouseY); - } else - if(SpecialFunc) - SpecialFunc(specialkey, MouseX, MouseY); - } else { + if(specialkey) + HandleSpecialPress(specialkey, release); + else { char c = labelval; if(KeyboardLedState & LED_CAP) { @@ -364,12 +429,7 @@ static int ReadKey(void) if(c >= 'a' && c <= 'z') c += 'A' - 'a'; } - if(release) { - if(KeyboardUpFunc) - KeyboardUpFunc(c, MouseX, MouseY); - } else - if(KeyboardFunc) - KeyboardFunc(c, MouseX, MouseY); + HandleKeyPress(c, release); } return 1; } @@ -432,28 +492,22 @@ static int ReadMouse(void) dy = event.dy; } else #endif - { - char data[4]; - - if(MouseFD == -1) - return 0; + { + char data[4]; - if(fcntl(MouseFD, F_SETFL, O_NONBLOCK) == -1) { - close(MouseFD); - MouseFD = -1; - return 0; - } + if(MouseFD == -1) + return 0; - if(read(MouseFD, data, 4) != 4) - 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); + 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)); - } + dx = (((data[0] & 0x03) << 6) | (data[1] & 0x3F)); + dy = (((data[0] & 0x0C) << 4) | (data[2] & 0x3F)); + } MouseX += dx * MouseSpeed; if(MouseX < 0) @@ -478,7 +532,7 @@ static int ReadMouse(void) ll = l, lm = m, lr = r; - if(dx || dy) { + if(dx || dy || !MouseVisible) { if(l || m || r) { if(MotionFunc) MotionFunc(MouseX, MouseY); @@ -488,12 +542,16 @@ static int ReadMouse(void) EraseCursor(); + MouseVisible = 1; + if(ActiveMenu) Redisplay = 1; else SwapCursor(); } + LastMouseTime = glutGet(GLUT_ELAPSED_TIME); + return 1; } @@ -502,8 +560,14 @@ void ReceiveInput(void) if(ConsoleFD != -1) while(ReadKey()); - if(MouseEnabled) - while(ReadMouse()); + 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) @@ -526,9 +590,6 @@ static void VTSwitchHandler(int sig) if(st.v_active) ioctl(ConsoleFD, VT_RELDISP, VT_ACKACQ); - /* this is a hack to turn the cursor off */ - ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &VarInfo); - RestoreColorMap(); Active = 1; @@ -536,7 +597,6 @@ static void VTSwitchHandler(int sig) VisibleSwitch = 1; Redisplay = 1; - break; } } @@ -549,37 +609,11 @@ void InitializeVT(int usestdin) signal(SIGIO, SIG_IGN); - /* save old terminos settings */ - if (tcgetattr(0, &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(0, TCSANOW, &tio) < 0) { - sprintf(exiterror, "tcsetattr failed\n"); - exit(0); - } - - if(fcntl(0, F_SETFL, O_NONBLOCK | O_ASYNC) < 0) { - sprintf(exiterror, "Failed to set keyboard to non-blocking\n"); - exit(0); - } - Active = 1; if(usestdin) { ConsoleFD = 0; - return; + goto setattribs; } /* detect the current vt if it was not specified */ @@ -590,15 +624,16 @@ void InitializeVT(int usestdin) 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); - return; - } else - CurrentVT = st.v_active; + goto setattribs; + } + CurrentVT = st.v_active; close(fd); } @@ -613,7 +648,7 @@ void InitializeVT(int usestdin) sprintf(exiterror, "error couldn't open %s," " defaulting to stdin \n", console); ConsoleFD = 0; - return; + goto setattribs; } signal(SIGUSR1, VTSwitchHandler); @@ -623,7 +658,7 @@ void InitializeVT(int usestdin) sprintf(exiterror,"Failed to grab %s, defaulting to stdin\n", console); close(ConsoleFD); ConsoleFD = 0; - return; + goto setattribs; } vt = OldVTMode; @@ -655,7 +690,7 @@ void InitializeVT(int usestdin) exit(0); } - fcntl(0, F_SETOWN, getpid()); + fcntl(ConsoleFD, F_SETOWN, getpid()); if(ioctl(ConsoleFD, KDGETMODE, &OldMode) < 0) sprintf(exiterror, "Warning: Failed to get terminal mode\n"); @@ -668,7 +703,6 @@ void InitializeVT(int usestdin) if(ioctl(ConsoleFD, KDSKBMODE, K_MEDIUMRAW) < 0) { sprintf(exiterror, "ioctl KDSKBMODE failed!\n"); - tcsetattr(0, TCSANOW, &OldTermios); exit(0); } @@ -676,6 +710,34 @@ void InitializeVT(int usestdin) 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) @@ -683,13 +745,13 @@ void RestoreVT(void) if(ConsoleFD < 0) return; - if (tcsetattr(0, TCSANOW, &OldTermios) < 0) - fprintf(stderr, "tcsetattr failed\n"); + if (tcsetattr(ConsoleFD, TCSANOW, &OldTermios) < 0) + sprintf(exiterror, "tcsetattr failed\n"); - /* setting the mode to text from graphics restores the colormap*/ + /* setting the mode to text from graphics restores the colormap */ if( #ifdef HAVE_GPM - GpmMouse || + !GpmMouse || #endif ConsoleFD == 0) if(ioctl(ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0) @@ -725,11 +787,11 @@ void InitializeMouse(void) const char *mousedev = getenv("MOUSE"); if(!mousedev) mousedev = MOUSEDEV; - if((MouseFD = open(mousedev, O_RDONLY)) >= 0) { - if(!MouseSpeed) - MouseSpeed = 1; - NumMouseButtons = 3; - return; + if((MouseFD = open(mousedev, O_RDONLY | O_NONBLOCK)) >= 0) { + if(!MouseSpeed) + MouseSpeed = 1; + NumMouseButtons = 3; + return; } } #ifdef HAVE_GPM |