mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
rainbow: LinuxFb: vt console switch support
git-svn-id: svn://ultimatepp.org/upp/trunk@3690 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
c0139840cd
commit
68a2f22a28
3 changed files with 167 additions and 95 deletions
|
|
@ -42,9 +42,9 @@ int has_imps2(int fd);
|
|||
int set_imps2(int fd, int b);
|
||||
void dupkmap(int fd);
|
||||
|
||||
int readevents(int ms);
|
||||
void handle_mouse();
|
||||
void handle_keyboard();
|
||||
void switchvt(int ii);
|
||||
|
||||
void SaveModKeys(dword keycode, dword pressed);
|
||||
dword fbKEYtoK(dword keycode);
|
||||
|
|
|
|||
|
|
@ -175,13 +175,9 @@ void handle_keyboard()
|
|||
keyup = (buf[i] & 0x80)?(K_KEYUP):(0);
|
||||
bool b;
|
||||
|
||||
//char c = ((!keyup)?'=':' ');
|
||||
//fprintf(stderr, "KEY %c: <%c> (%X) [%X]\n", c, keycode, keycode, buf[i]);
|
||||
|
||||
SaveModKeys(keycode, !keyup);
|
||||
|
||||
//Ctrl+Alt+FN for vt switch ??
|
||||
|
||||
//we dont support both sides, fall back to left
|
||||
switch(keycode)
|
||||
{
|
||||
case SCANCODE_RIGHTALT: keycode = SCANCODE_LEFTALT; break;
|
||||
|
|
@ -190,11 +186,34 @@ void handle_keyboard()
|
|||
}
|
||||
|
||||
dword uppcode = fbKEYtoK(keycode) | keyup;
|
||||
//fprintf(stderr, "UPP: %X - %X\n", uppcode, q);
|
||||
|
||||
if(!keyup && uppcode == K_SPACE)
|
||||
uppcode = 0; //prevent double send with unicode
|
||||
|
||||
//vtswitch
|
||||
int vtck = uppcode & (K_DELTA | 0xFFFF);
|
||||
switch(vtck) {
|
||||
case K_F11:
|
||||
case K_F12:
|
||||
vtck -= 18; //dirty hack: after F10 doesnt come F11, see vgakeyboard.h
|
||||
case K_F1:
|
||||
case K_F2:
|
||||
case K_F3:
|
||||
case K_F4:
|
||||
case K_F5:
|
||||
case K_F6:
|
||||
case K_F7:
|
||||
case K_F8:
|
||||
case K_F9:
|
||||
case K_F10:
|
||||
if(GetCtrl() && GetAlt()) {
|
||||
int ii = vtck - K_F1 + 1;
|
||||
if(!keyup)
|
||||
switchvt(ii);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//first, the upp keycode
|
||||
if(uppcode)
|
||||
b = Ctrl::DoKeyFB(uppcode, 1);
|
||||
|
|
@ -208,47 +227,9 @@ void handle_keyboard()
|
|||
}
|
||||
|
||||
//helper quit
|
||||
#if _DD
|
||||
static int ii = 0;
|
||||
#endif
|
||||
if(uppcode == (K_SHIFT_CTRL | K_ESCAPE)
|
||||
#ifdef _DD
|
||||
|| (++ii >= 100)
|
||||
#endif
|
||||
)
|
||||
if(uppcode == (K_SHIFT_CTRL | K_ESCAPE))
|
||||
Ctrl::EndSession();
|
||||
}
|
||||
}
|
||||
|
||||
//returns 0 if timeout, 1 for mouse, 2 for keyboard
|
||||
//common for waitforevents and sleep
|
||||
int readevents(int ms)
|
||||
{
|
||||
fd_set fdset;
|
||||
int max_fd;
|
||||
static struct timeval to;
|
||||
to.tv_sec = ms / 1000;
|
||||
to.tv_usec = ms % 1000 * 1000;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
max_fd = 0;
|
||||
if(mouse_fd >= 0) {
|
||||
FD_SET(mouse_fd, &fdset);
|
||||
if(max_fd < mouse_fd) max_fd = mouse_fd;
|
||||
}
|
||||
if(keyb_fd >= 0) {
|
||||
FD_SET(keyb_fd, &fdset);
|
||||
if(max_fd < keyb_fd) max_fd = keyb_fd;
|
||||
}
|
||||
if(select(max_fd+1, &fdset, NULL, NULL, &to) > 0) {
|
||||
if(mouse_fd >= 0) {
|
||||
if(FD_ISSET(mouse_fd, &fdset)) return 1;
|
||||
}
|
||||
if(keyb_fd >= 0) {
|
||||
if(FD_ISSET(keyb_fd, &fdset)) return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -21,52 +21,7 @@ dword mouseb = 0;
|
|||
int keyb_fd = -1;
|
||||
int cvt = -1;
|
||||
|
||||
void FBQuitSession()
|
||||
{
|
||||
Ctrl::EndSession();
|
||||
}
|
||||
|
||||
int pend = 0;
|
||||
|
||||
bool FBIsWaitingEvent()
|
||||
{
|
||||
pend = readevents(0);
|
||||
return pend > 0;
|
||||
}
|
||||
|
||||
bool FBProcessEvent(bool *quit)
|
||||
{
|
||||
if(pend)
|
||||
{
|
||||
if(pend & 1) handle_mouse();
|
||||
if(pend & 2) handle_keyboard();
|
||||
pend = 0; //need to reset, since with repeated call is not updated here, would stuck
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FBSleep(int ms)
|
||||
{
|
||||
pend = readevents(ms); //interruptable sleep
|
||||
|
||||
//keep queue busy, see SDLFb/Win.cpp for why
|
||||
//this indicates that some stuff is pending, returning true in FBProcessEvent
|
||||
//while nothing is actually processed
|
||||
pend |= 4;
|
||||
}
|
||||
|
||||
void FBUpdate(const Rect& inv)
|
||||
{
|
||||
//FIXME accelerate
|
||||
const ImageBuffer& framebuffer = Ctrl::GetFrameBuffer();
|
||||
memcpy(fbp, ~framebuffer, framebuffer.GetLength() * sizeof(RGBA));
|
||||
}
|
||||
|
||||
void FBFlush()
|
||||
{
|
||||
|
||||
}
|
||||
//
|
||||
|
||||
int oldvt;
|
||||
struct termios oldtermios;
|
||||
|
|
@ -120,6 +75,48 @@ int entervt()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void switchvt_pre()
|
||||
{
|
||||
ioctl(keyb_fd, KDSETMODE, KD_TEXT);
|
||||
ioctl(keyb_fd, VT_UNLOCKSWITCH, 1);
|
||||
}
|
||||
|
||||
void switchvt_post()
|
||||
{
|
||||
ioctl(keyb_fd, VT_LOCKSWITCH, 1);
|
||||
ioctl(keyb_fd, KDSETMODE, KD_GRAPHICS);
|
||||
}
|
||||
|
||||
int switched_away = 0;
|
||||
|
||||
void switchvt(int ii)
|
||||
{
|
||||
struct vt_stat vtst;
|
||||
|
||||
/* Figure out whether or not we're switching to a new console */
|
||||
if(ioctl(keyb_fd, VT_GETSTATE, &vtst) < 0)
|
||||
{
|
||||
fprintf(stderr, "Error: could not read tty state");
|
||||
return;
|
||||
}
|
||||
if(ii == vtst.v_active)
|
||||
return;
|
||||
|
||||
LLOG("trying to switch to VT " << ii);
|
||||
|
||||
GuiLock __;
|
||||
|
||||
switchvt_pre();
|
||||
|
||||
if(ioctl(keyb_fd, VT_ACTIVATE, ii) == 0) {
|
||||
ioctl(keyb_fd, VT_WAITACTIVE, ii);
|
||||
switched_away = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
switchvt_post();
|
||||
}
|
||||
|
||||
void leavevt()
|
||||
{
|
||||
if(oldmode < 0) return;
|
||||
|
|
@ -141,6 +138,97 @@ void leavevt()
|
|||
ioctl(keyb_fd, VT_ACTIVATE, oldvt);
|
||||
}
|
||||
|
||||
int pend = 0;
|
||||
|
||||
//returns 0 if timeout, 1 for mouse, 2 for keyboard
|
||||
//common for waitforevents and sleep
|
||||
int readevents(int ms)
|
||||
{
|
||||
fd_set fdset;
|
||||
int max_fd;
|
||||
static struct timeval to;
|
||||
to.tv_sec = ms / 1000;
|
||||
to.tv_usec = ms % 1000 * 1000;
|
||||
|
||||
if(switched_away) {
|
||||
struct vt_stat vtst;
|
||||
GuiLock __;
|
||||
if((ioctl(keyb_fd, VT_GETSTATE, &vtst) == 0) &&
|
||||
vtst.v_active == cvt) {
|
||||
switched_away = 0;
|
||||
switchvt_post();
|
||||
}
|
||||
}
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
max_fd = 0;
|
||||
if(mouse_fd >= 0) {
|
||||
FD_SET(mouse_fd, &fdset);
|
||||
if(max_fd < mouse_fd) max_fd = mouse_fd;
|
||||
}
|
||||
if(keyb_fd >= 0) {
|
||||
FD_SET(keyb_fd, &fdset);
|
||||
if(max_fd < keyb_fd) max_fd = keyb_fd;
|
||||
}
|
||||
if(select(max_fd+1, &fdset, NULL, NULL, &to) > 0) {
|
||||
if(mouse_fd >= 0) {
|
||||
if(FD_ISSET(mouse_fd, &fdset)) return 1;
|
||||
}
|
||||
if(keyb_fd >= 0) {
|
||||
if(FD_ISSET(keyb_fd, &fdset)) return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void FBQuitSession()
|
||||
{
|
||||
Ctrl::EndSession();
|
||||
}
|
||||
|
||||
bool FBIsWaitingEvent()
|
||||
{
|
||||
pend = readevents(0);
|
||||
return pend > 0;
|
||||
}
|
||||
|
||||
bool FBProcessEvent(bool *quit)
|
||||
{
|
||||
if(pend)
|
||||
{
|
||||
if(pend & 1) handle_mouse();
|
||||
if(pend & 2) handle_keyboard();
|
||||
pend = 0; //need to reset, since with repeated call is not updated here, would stuck
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FBSleep(int ms)
|
||||
{
|
||||
pend = readevents(ms); //interruptable sleep
|
||||
|
||||
//keep queue busy, see SDLFb/Win.cpp for why
|
||||
//this indicates that some stuff is pending, returning true in FBProcessEvent
|
||||
//while nothing is actually processed
|
||||
pend |= 4;
|
||||
}
|
||||
|
||||
void FBUpdate(const Rect& inv)
|
||||
{
|
||||
if(switched_away) return; //backdraw
|
||||
//FIXME accelerate
|
||||
const ImageBuffer& framebuffer = Ctrl::GetFrameBuffer();
|
||||
memcpy(fbp, ~framebuffer, framebuffer.GetLength() * sizeof(RGBA));
|
||||
}
|
||||
|
||||
void FBFlush()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FBInit(const String& fbdevice)
|
||||
{
|
||||
Ctrl::InitFB();
|
||||
|
|
@ -255,17 +343,20 @@ void FBInit(const String& fbdevice)
|
|||
|
||||
if(keyb_fd < 0) {
|
||||
LLOG("Using already assigned VT, must not detach");
|
||||
struct vt_stat vtstate;
|
||||
struct vt_stat vtst;
|
||||
|
||||
keyb_fd = open("/dev/tty", O_RDWR);
|
||||
|
||||
if(ioctl(keyb_fd, VT_GETSTATE, &vtstate) < 0) {
|
||||
if(ioctl(keyb_fd, VT_GETSTATE, &vtst) < 0) {
|
||||
cvt = 0;
|
||||
} else {
|
||||
cvt = vtstate.v_active;
|
||||
cvt = vtst.v_active;
|
||||
}
|
||||
}
|
||||
|
||||
if(cvt>0)
|
||||
fprintf(stdout, "started on VT %d\n", cvt);
|
||||
|
||||
ASSERT(keyb_fd>=0);
|
||||
oldmode = -1;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue