📄 event.svga
字号:
we can clean up properly.
****************************************************************************/
static void exitHandler(int sig)
{
exit(-1);
}
/****************************************************************************
REMARKS:
Sleep until the virtual terminal is active
****************************************************************************/
void wait_vt_active(void)
{
while (ioctl(tty_fd, VT_WAITACTIVE, tty_vc) < 0) {
if ((errno != EAGAIN) && (errno != EINTR)) {
perror("ioctl(VT_WAITACTIVE)");
exit(1);
}
usleep(150000);
}
}
/****************************************************************************
REMARKS:
Signal handler called when our virtual terminal has been released and we are
losing the active focus.
****************************************************************************/
static void release_vt_signal(int n)
{
forbid_vt_acquire = 1;
if (forbid_vt_release) {
forbid_vt_acquire = 0;
ioctl(tty_fd, VT_RELDISP, 0);
return;
}
// TODO: Call the user supplied suspendAppCallback and restore text
// mode (saving the existing mode so we can restore it).
//
// Also if the suspendAppCallback is NULL then we have to
// ignore the switch request!
if(suspendAppCallback){
oldmode = VBE_getVideoMode();
suspendAppCallback(true);
VBE_setVideoMode(initmode);
}
ioctl(tty_fd, VT_RELDISP, 1);
forbid_vt_acquire = 0;
wait_vt_active();
}
/****************************************************************************
REMARKS:
Signal handler called when our virtual terminal has been re-aquired and we
are now regaiing the active focus.
****************************************************************************/
static void acquire_vt_signal(int n)
{
forbid_vt_release = 1;
if (forbid_vt_acquire) {
forbid_vt_release = 0;
return;
}
// TODO: Restore the old display mode, call the user suspendAppCallback
// and and we will be back in graphics mode.
if(suspendAppCallback){
VBE_setVideoMode(oldmode);
suspendAppCallback(false);
}
ioctl(tty_fd, VT_RELDISP, VT_ACKACQ);
forbid_vt_release = 0;
}
/****************************************************************************
REMARKS:
Function to set the action for a specific signal to call our signal handler.
****************************************************************************/
static void set_sigaction(int sig,void (*handler)(int))
{
struct sigaction siga;
siga.sa_handler = handler;
siga.sa_flags = SA_RESTART;
memset(&(siga.sa_mask), 0, sizeof(sigset_t));
sigaction(sig, &siga, NULL);
}
/****************************************************************************
REMARKS:
Function to take over control of VT switching so that we can capture
virtual terminal release and aquire signals, allowing us to properly
support VT switching while in graphics modes.
****************************************************************************/
static void take_vt_control(void)
{
struct vt_mode vtmode;
ioctl(tty_fd, VT_GETMODE, &vtmode);
oldvtmode = vtmode;
vtmode.mode = VT_PROCESS;
vtmode.relsig = SIGUSR1;
vtmode.acqsig = SIGUSR2;
set_sigaction(SIGUSR1, release_vt_signal);
set_sigaction(SIGUSR2, acquire_vt_signal);
ioctl(tty_fd, VT_SETMODE, &oldvtmode);
}
/****************************************************************************
REMARKS:
Set the shift keyboard LED's based on the current keyboard modifiers flags.
****************************************************************************/
static void updateLEDStatus(void)
{
int state = 0;
if (key_modifiers & EVT_CAPSSTATE)
state |= LED_CAP;
if (key_modifiers & EVT_NUMSTATE)
state |= LED_NUM;
ioctl(tty_fd,KDSETLED,state);
}
/****************************************************************************
PARAMETERS:
scancode - Raw scan code to handle
REMARKS:
Handles the shift key modifiers and keeps track of the shift key states
so that we can return the correct ASCII codes for the keyboard.
****************************************************************************/
static void toggleModifiers(
int scancode)
{
static int caps_down = 0,num_down = 0;
if (scancode & 0x80) {
/* Handle key-release function */
scancode &= 0x7F;
if (scancode == 0x2A || scancode == 0x36)
key_modifiers &= ~EVT_SHIFTKEY;
else if (scancode == 0x1D || scancode == 0x61)
key_modifiers &= ~EVT_CTRLSTATE;
else if (scancode == 0x38 || scancode == 0x64)
key_modifiers &= ~EVT_ALTSTATE;
else if (scancode == 0x3A)
caps_down = false;
else if (scancode == 0x45)
num_down = false;
}
else {
/* Handle key-down function */
scancode &= 0x7F;
if (scancode == 0x2A || scancode == 0x36)
key_modifiers |= EVT_SHIFTKEY;
else if (scancode == 0x1D || scancode == 0x61)
key_modifiers |= EVT_CTRLSTATE;
else if (scancode == 0x38 || scancode == 0x64)
key_modifiers |= EVT_ALTSTATE;
else if (scancode == 0x3A) {
if (!caps_down) {
key_modifiers ^= EVT_CAPSSTATE;
updateLEDStatus();
}
caps_down = true;
}
else if (scancode == 0x45) {
if (!num_down) {
key_modifiers ^= EVT_NUMSTATE;
updateLEDStatus();
}
num_down = true;
}
}
}
/***************************************************************************
REMARKS:
Returns the number of bits that have changed from 0 to 1
(a negative value means the number of bits that have changed from 1 to 0)
**************************************************************************/
static int compareBits(short a, short b)
{
int ret = 0;
if( (a&1) != (b&1) ) ret += (b&1) ? 1 : -1;
if( (a&2) != (b&2) ) ret += (b&2) ? 1 : -1;
if( (a&4) != (b&4) ) ret += (b&4) ? 1 : -1;
return ret;
}
/***************************************************************************
REMARKS:
Turns off all keyboard state because we can't rely on them anymore as soon
as we switch VT's
***************************************************************************/
static void keyboard_clearstate(void)
{
key_modifiers = 0;
memset(key_down, 0, sizeof(key_down));
}
/****************************************************************************
REMARKS:
Pumps all events from the console event queue into the WinDirect event queue.
****************************************************************************/
static void pumpEvents(void)
{
static uchar buf[KBDREADBUFFERSIZE];
static char data[5];
static int old_buts, old_mx, old_my;
static struct timeval t;
fd_set fds;
int numkeys,i;
int dx, dy, buts;
/* Read all pending keypresses from keyboard buffer and process */
while ((numkeys = read(tty_fd, buf, KBDREADBUFFERSIZE)) > 0) {
for (i = 0; i < numkeys; i++) {
toggleModifiers(buf[i]);
if (key_modifiers & EVT_ALTSTATE){
int fkey = 0;
// Do VT switching here for Alt+Fx keypresses
switch(buf[i] & 0x7F){
case 59 ... 68: /* F1 to F10 */
fkey = (buf[i] & 0x7F) - 58;
break;
case 87: /* F11 */
case 88: /* F12 */
fkey = (buf[i] & 0x7F) - 76;
break;
}
if(fkey){
struct vt_stat vts;
ioctl(tty_fd, VT_GETSTATE, &vts);
if(fkey != vts.v_active){
keyboard_clearstate();
ioctl(tty_fd, VT_ACTIVATE, fkey);
}
}
}
if (buf[i] & 0x80)
addKeyEvent(EVT_KEYUP,buf[i] & 0x7F);
else
addKeyEvent(EVT_KEYDOWN,buf[i] & 0x7F);
}
// TODO: If we want to handle VC switching we will need to do it
// in here so that we can switch away from the VC and then
// switch back to it later. Right now VC switching is disabled
// and in order to enable it we need to save/restore the state
// of the graphics screen (using the suspendAppCallback and
// saving/restoring the state of the current display mode).
}
/* Read all pending mouse events and process them */
if(conn > 0){
FD_ZERO(&fds);
FD_SET(conn, &fds);
t.tv_sec = t.tv_usec = 0L;
while (select(conn+1, &fds, NULL, NULL, &t) > 0) {
if(read(conn, data, 5) == 5){
buts = (~data[0]) & 0x07;
dx = (char)(data[1]) + (char)(data[3]);
dy = -((char)(data[2]) + (char)(data[4]));
mx += dx; my += dy;
if (dx || dy)
addMouseEvent(EVT_MOUSEMOVE, 0, mx, my, buts);
if (buts != old_buts){
int c = compareBits(buts,old_buts);
if(c>0)
addMouseEvent(EVT_MOUSEDOWN, 0, mx, my, buts);
else if(c<0)
addMouseEvent(EVT_MOUSEUP, 0, mx, my, buts);
}
old_mx = mx; old_my = my;
old_buts = buts;
FD_SET(conn, &fds);
t.tv_sec = t.tv_usec = 0L;
}
}
}
}
/*------------------------ Public interface routines ----------------------*/
/****************************************************************************
PARAMETERS:
which - Which code for event to post
what - Event code for event to post
message - Event message
modifiers - Shift key/mouse button modifiers
RETURNS:
True if the event was posted, false if queue is full.
REMARKS:
Posts an event to the event queue. This routine can be used to post any type
of event into the queue.
****************************************************************************/
ibool _WDAPI WD_postEvent(
ulong which,
uint what,
ulong message,
ulong modifiers)
{
WD_event evt;
if (count < EVENTQSIZE) {
/* Save information in event record */
evt.which = which;
evt.what = what;
evt.when = getTimeStamp();
evt.message = message;
evt.modifiers = modifiers;
addEvent(&evt); /* Add to tail of event queue */
return true;
}
else
return false;
}
/****************************************************************************
PARAMETERS:
mask - Event mask to use
REMARKS:
Flushes all the event specified in 'mask' from the event queue.
****************************************************************************/
void _WDAPI WD_flushEvent(
uint mask)
{
WD_event evt;
do { /* Flush all events */
WD_getEvent(&evt,mask);
} while (evt.what != EVT_NULLEVT);
}
/****************************************************************************
PARAMETERS:
evt - Place to store event
mask - Event mask to use
REMARKS:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -