summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/pm/linux/event.svga
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/linux/event.svga')
-rw-r--r--board/MAI/bios_emulator/scitech/src/pm/linux/event.svga1058
1 files changed, 1058 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/linux/event.svga b/board/MAI/bios_emulator/scitech/src/pm/linux/event.svga
new file mode 100644
index 0000000000..c0358a0f8a
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/pm/linux/event.svga
@@ -0,0 +1,1058 @@
+/****************************************************************************
+*
+* The SuperVGA Kit - UniVBE Software Development Kit
+*
+* ========================================================================
+*
+* The contents of this file are subject to the SciTech MGL Public
+* License Version 1.0 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.scitechsoft.com/mgl-license.txt
+*
+* Software distributed under the License is distributed on an
+* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
+*
+* The Initial Developer of the Original Code is SciTech Software, Inc.
+* All Rights Reserved.
+*
+* ========================================================================
+*
+* Language: ANSI C
+* Environment: IBM PC (MS DOS)
+*
+* Description: Routines to provide a Linux event queue, which automatically
+* handles keyboard and mouse events for the Linux compatability
+* libraries. Based on the event handling code in the MGL.
+*
+****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+#include <termios.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <linux/keyboard.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include <gpm.h>
+#include "pm.h"
+#include "vesavbe.h"
+#include "wdirect.h"
+
+/*--------------------------- Global variables ----------------------------*/
+
+#define EVENTQSIZE 100 /* Number of events in event queue */
+
+static int head = -1; /* Head of event queue */
+static int tail = -1; /* Tail of event queue */
+static int freeHead = -1; /* Head of free list */
+static int count = 0; /* No. of items currently in queue */
+static WD_event evtq[EVENTQSIZE]; /* The queue structure itself */
+static int oldMove = -1; /* Previous movement event */
+static int oldKey = -1; /* Previous key repeat event */
+static int mx,my; /* Current mouse position */
+static int xRes,yRes; /* Screen resolution coordinates */
+static void *stateBuf; /* Pointer to console state buffer */
+static int conn; /* GPM file descriptor for mouse handling */
+static int tty_fd; /* File descriptor for /dev/console */
+extern int tty_vc; /* Virtual console ID, from the PM/Pro library */
+static ibool key_down[128]; /* State of all keyboard keys */
+static struct termios old_conf; /* Saved terminal configuration */
+static int oldkbmode; /* and previous keyboard mode */
+struct vt_mode oldvtmode; /* Old virtual terminal mode */
+static int old_flags; /* Old flags for fcntl */
+static ulong key_modifiers; /* Keyboard modifiers */
+static int forbid_vt_release=0;/* Flag to forbid release of VT */
+static int forbid_vt_acquire=0;/* Flag to forbid cature of VT */
+static int oldmode; /* Old SVGA mode saved for VT switch*/
+static int initmode; /* Initial text mode */
+static ibool installed = false; /* True if we are installed */
+static void (_ASMAPI *moveCursor)(int x,int y) = NULL;
+static int (_ASMAPI *suspendAppCallback)(int flags) = NULL;
+
+#if 0
+/* Keyboard Translation table from scancodes to ASCII */
+
+static uchar keyTable[128] =
+"\0\0331234567890-=\010"
+"\011qwertyuiop[]\015"
+"\0asdfghjkl;'`\0\\"
+"zxcvbnm,./\0*\0 \0"
+"\0\0\0\0\0\0\0\0\0\0\0\0" /* Function keys */
+"789-456+1230.\0\0\0\0\0" /* Keypad keys */
+"\0\0\0\0\0\0\0\015\0/";
+
+static uchar keyTableShifted[128] =
+"\0\033!@#$%^&*()_+\010"
+"\011QWERTYUIOP{}\015"
+"\0ASDFGHJKL:\"~\0|"
+"ZXCVBNM<>?\0*\0 \0"
+"\0\0\0\0\0\0\0\0\0\0\0\0" /* Function keys */
+"789-456+1230.\0\0\0\0\0" /* Keypad keys */
+"\0\0\0\0\0\0\0\015\0/";
+#endif
+
+/* Macros to keep track of the CAPS and NUM lock states */
+
+#define EVT_CAPSSTATE 0x0100
+#define EVT_NUMSTATE 0x0200
+
+/* Helper macros for dealing with timers */
+
+#define TICKS_TO_USEC(t) ((t)*65536.0/1.193180)
+#define USEC_TO_TICKS(u) ((u)*1.193180/65536.0)
+
+/* Number of keycodes to read at a time from the console */
+
+#define KBDREADBUFFERSIZE 32
+
+/*---------------------------- Implementation -----------------------------*/
+
+/****************************************************************************
+REMARKS:
+Returns the current time stamp in units of 18.2 ticks per second.
+****************************************************************************/
+static ulong getTimeStamp(void)
+{
+ return (ulong)(clock() / (CLOCKS_PER_SEC / 18.2));
+}
+
+/****************************************************************************
+PARAMETERS:
+evt - Event to place onto event queue
+
+REMARKS:
+Adds an event to the event queue by tacking it onto the tail of the event
+queue. This routine assumes that at least one spot is available on the
+freeList for the event to be inserted.
+****************************************************************************/
+static void addEvent(
+ WD_event *evt)
+{
+ int evtID;
+
+ /* Get spot to place the event from the free list */
+ evtID = freeHead;
+ freeHead = evtq[freeHead].next;
+
+ /* Add to the tail of the event queue */
+ evt->next = -1;
+ evt->prev = tail;
+ if (tail != -1)
+ evtq[tail].next = evtID;
+ else
+ head = evtID;
+ tail = evtID;
+ evtq[evtID] = *evt;
+ count++;
+}
+
+/****************************************************************************
+PARAMETERS:
+what - Event code
+message - Event message
+modifiers - keyboard modifiers
+x - Mouse X position at time of event
+y - Mouse Y position at time of event
+but_stat - Mouse button status at time of event
+
+REMARKS:
+Adds a new mouse event to the event queue. This routine is called from
+within the mouse interrupt subroutine, so it must be efficient.
+****************************************************************************/
+static void addMouseEvent(
+ uint what,
+ uint message,
+ int x,
+ int y,
+ uint but_stat)
+{
+ WD_event evt;
+
+ if (count < EVENTQSIZE) {
+ evt.what = what;
+ evt.when = getTimeStamp();
+ evt.message = message;
+ evt.modifiers = but_stat | key_modifiers;
+ evt.where_x = x;
+ evt.where_y = y;
+ fprintf(stderr, "(%d,%d), buttons %ld\n", x,y, evt.modifiers);
+ addEvent(&evt); /* Add to tail of event queue */
+ }
+}
+
+/****************************************************************************
+PARAMETERS:
+scancode - Raw keyboard scan code
+modifiers - Keyboard modifiers flags
+
+REMARKS:
+Converts the raw scan code into the appropriate ASCII code using the scan
+code and the keyboard modifier flags.
+****************************************************************************/
+static ulong getKeyMessage(
+ uint scancode,
+ ulong modifiers)
+{
+ ushort code = scancode << 8;
+ ushort ascii;
+ struct kbentry ke;
+
+ ke.kb_index = scancode;
+
+ /* Find the basic ASCII code for the scan code */
+ if (modifiers & EVT_CAPSSTATE) {
+ if (modifiers & EVT_SHIFTKEY)
+ ke.kb_table = K_NORMTAB;
+ // ascii = tolower(keyTableShifted[scancode]);
+ else
+ ke.kb_table = K_SHIFTTAB;
+ // ascii = toupper(keyTable[scancode]);
+ }
+ else {
+ if (modifiers & EVT_SHIFTKEY)
+ ke.kb_table = K_SHIFTTAB;
+ // ascii = keyTableShifted[scancode];
+ else
+ ke.kb_table = K_NORMTAB;
+ // ascii = keyTable[scancode];
+ }
+ if(modifiers & EVT_ALTSTATE)
+ ke.kb_table |= K_ALTTAB;
+
+ if (ioctl(tty_fd, KDGKBENT, (unsigned long)&ke)) {
+ fprintf(stderr, "KDGKBENT at index %d in table %d: ",
+ scancode, ke.kb_table);
+ return 0;
+ }
+ ascii = ke.kb_value;
+
+ /* Add ASCII code if key is not alt'ed or ctrl'ed */
+ if (!(modifiers & (EVT_ALTSTATE | EVT_CTRLSTATE)))
+ code |= ascii;
+
+ return code;
+}
+
+/****************************************************************************
+PARAMETERS:
+what - Event code
+scancode - Raw scancode of keyboard event to add
+
+REMARKS:
+Adds a new keyboard event to the event queue. We only take KEYUP and
+KEYDOWN event codes, however if a key is already down we convert the KEYDOWN
+to a KEYREPEAT.
+****************************************************************************/
+static void addKeyEvent(
+ uint what,
+ uint scancode)
+{
+ WD_event evt;
+
+ if (count < EVENTQSIZE) {
+ evt.what = what;
+ evt.when = getTimeStamp();
+ evt.message = getKeyMessage(scancode,key_modifiers) | 0x10000UL;
+ evt.where_x = evt.where_y = 0;
+ evt.modifiers = key_modifiers;
+ if (evt.what == EVT_KEYUP)
+ key_down[scancode] = false;
+ else if (evt.what == EVT_KEYDOWN) {
+ if (key_down[scancode]) {
+ if (oldKey != -1) {
+ evtq[oldKey].message += 0x10000UL;
+ }
+ else {
+ evt.what = EVT_KEYREPEAT;
+ oldKey = freeHead;
+ addEvent(&evt);
+ oldMove = -1;
+ }
+ return;
+ }
+ key_down[scancode] = true;
+ }
+
+ addEvent(&evt);
+ oldMove = -1;
+ }
+}
+
+/****************************************************************************
+PARAMETERS:
+sig - Signal being sent to this signal handler
+
+REMARKS:
+Signal handler for the timer. This routine takes care of periodically
+posting timer events to the event queue.
+****************************************************************************/
+void timerHandler(
+ int sig)
+{
+ WD_event evt;
+
+ if (sig == SIGALRM) {
+ if (count < EVENTQSIZE) {
+ evt.when = getTimeStamp();
+ evt.what = EVT_TIMERTICK;
+ evt.message = 0;
+ evt.where_x = evt.where_y = 0;
+ evt.modifiers = 0;
+ addEvent(&evt);
+ oldMove = -1;
+ oldKey = -1;
+ }
+ signal(SIGALRM, timerHandler);
+ }
+}
+
+/****************************************************************************
+REMARKS:
+Restore the terminal to normal operation on exit
+****************************************************************************/
+static void restore_term(void)
+{
+ RMREGS regs;
+
+ if (installed) {
+ /* Restore text mode and the state of the console */
+ regs.x.ax = 0x3;
+ PM_int86(0x10,&regs,&regs);
+ PM_restoreConsoleState(stateBuf,tty_fd);
+
+ /* Restore console to normal operation */
+ ioctl(tty_fd, VT_SETMODE, &oldvtmode);
+ ioctl(tty_fd, KDSKBMODE, oldkbmode);
+ tcsetattr(tty_fd, TCSAFLUSH, &old_conf);
+ fcntl(tty_fd,F_SETFL,old_flags &= ~O_NONBLOCK);
+ PM_closeConsole(tty_fd);
+
+ /* Close the mouse driver */
+ close(conn);
+
+ /* Flag that we are not no longer installed */
+ installed = false;
+ }
+}
+
+/****************************************************************************
+REMARKS:
+Signal handler to capture forced program termination conditions so that
+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:
+Halts program execution until a specified event occurs. The event is
+returned. All pending events not in the specified mask will be ignored and
+removed from the queue.
+****************************************************************************/
+void _WDAPI WD_haltEvent(
+ WD_event *evt,
+ uint mask)
+{
+ do { /* Wait for an event */
+ WD_getEvent(evt,EVT_EVERYEVT);
+ } while (!(evt->what & mask));
+}
+
+/****************************************************************************
+PARAMETERS:
+evt - Place to store event
+mask - Event mask to use
+
+RETURNS:
+True if an event was pending.
+
+REMARKS:
+Retrieves the next pending event defined in 'mask' from the event queue.
+The event queue is adjusted to reflect the new state after the event has
+been removed.
+****************************************************************************/
+ibool _WDAPI WD_getEvent(
+ WD_event *evt,
+ uint mask)
+{
+ int evtID,next,prev;
+
+ pumpEvents();
+ if (moveCursor)
+ moveCursor(mx,my); /* Move the mouse cursor */
+ evt->what = EVT_NULLEVT; /* Default to null event */
+
+ if (count) {
+ for (evtID = head; evtID != -1; evtID = evtq[evtID].next) {
+ if (evtq[evtID].what & mask)
+ break; /* Found an event */
+ }
+ if (evtID == -1)
+ return false; /* Event was not found */
+ next = evtq[evtID].next;
+ prev = evtq[evtID].prev;
+ if (prev != -1)
+ evtq[prev].next = next;
+ else
+ head = next;
+ if (next != -1)
+ evtq[next].prev = prev;
+ else
+ tail = prev;
+ *evt = evtq[evtID]; /* Return the event */
+ evtq[evtID].next = freeHead; /* and return to free list */
+ freeHead = evtID;
+ count--;
+ if (evt->what == EVT_MOUSEMOVE)
+ oldMove = -1;
+ if (evt->what == EVT_KEYREPEAT)
+ oldKey = -1;
+ }
+ return evt->what != EVT_NULLEVT;
+}
+
+/****************************************************************************
+PARAMETERS:
+evt - Place to store event
+mask - Event mask to use
+
+RETURNS:
+True if an event is pending.
+
+REMARKS:
+Peeks at the next pending event defined in 'mask' in the event queue. The
+event is not removed from the event queue.
+****************************************************************************/
+ibool _WDAPI WD_peekEvent(
+ WD_event *evt,
+ uint mask)
+{
+ int evtID;
+
+ pumpEvents();
+ if (moveCursor)
+ moveCursor(mx,my); /* Move the mouse cursor */
+ evt->what = EVT_NULLEVT; /* Default to null event */
+
+ if (count) {
+ for (evtID = head; evtID != -1; evtID = evtq[evtID].next) {
+ if (evtq[evtID].what & mask)
+ break; /* Found an event */
+ }
+ if (evtID == -1)
+ return false; /* Event was not found */
+
+ *evt = evtq[evtID]; /* Return the event */
+ }
+ return evt->what != EVT_NULLEVT;
+}
+
+/****************************************************************************
+PARAMETERS:
+hwndMain - Handle to main window
+_xRes - X resolution of graphics mode to be used
+_yRes - Y resolulion of graphics mode to be used
+
+RETURNS:
+Handle to the fullscreen event window if (we return hwndMain on Linux)
+
+REMARKS:
+Initiliase the event handling module. Here we install our mouse handling
+ISR to be called whenever any button's are pressed or released. We also
+build the free list of events in the event queue.
+****************************************************************************/
+WD_HWND _WDAPI WD_startFullScreen(
+ WD_HWND hwndMain,
+ int _xRes,
+ int _yRes)
+{
+ int i;
+ struct termios conf;
+ if (!installed) {
+ Gpm_Connect gpm;
+
+ /* Build free list, and initialise global data structures */
+ for (i = 0; i < EVENTQSIZE; i++)
+ evtq[i].next = i+1;
+ evtq[EVENTQSIZE-1].next = -1; /* Terminate list */
+ count = freeHead = 0;
+ head = tail = -1;
+ oldMove = -1;
+ oldKey = -1;
+ xRes = _xRes;
+ yRes = _yRes;
+
+ /* Open the console device and initialise it for raw mode */
+ tty_fd = PM_openConsole();
+
+ /* Wait until virtual terminal is active and take over control */
+ wait_vt_active();
+ take_vt_control();
+
+ /* Initialise keyboard handling to raw mode */
+ if (ioctl(tty_fd, KDGKBMODE, &oldkbmode)) {
+ printf("WD_startFullScreen: cannot get keyboard mode.\n");
+ exit(-1);
+ }
+ old_flags = fcntl(tty_fd,F_GETFL);
+ fcntl(tty_fd,F_SETFL,old_flags |= O_NONBLOCK);
+ tcgetattr(tty_fd, &conf);
+ old_conf = conf;
+ conf.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | NOFLSH | ISIG);
+ conf.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | BRKINT | PARMRK | INPCK | IUCLC | IXON | IXOFF);
+ conf.c_iflag |= (IGNBRK | IGNPAR);
+ conf.c_cc[VMIN] = 1;
+ conf.c_cc[VTIME] = 0;
+ conf.c_cc[VSUSP] = 0;
+ tcsetattr(tty_fd, TCSAFLUSH, &conf);
+ ioctl(tty_fd, KDSKBMODE, K_MEDIUMRAW);
+
+ /* Clear the keyboard state information */
+ memset(key_down, 0, sizeof(key_down));
+ ioctl(tty_fd,KDSETLED,key_modifiers = 0);
+
+ /* Initialize the mouse connection
+ The user *MUST* run gpm with the option -R for this to work (or have a MouseSystems mouse)
+ */
+ if(Gpm_Open(&gpm,0) > 0){ /* GPM available */
+ if ((conn = open(GPM_NODE_FIFO,O_RDONLY|O_SYNC)) < 0)
+ fprintf(stderr,"WD_startFullScreen: Can't open mouse connection.\n");
+ }else{
+ fprintf(stderr,"Warning: when not using gpm -R, only MouseSystems mice are currently supported.\n");
+ if ((conn = open("/dev/mouse",O_RDONLY|O_SYNC)) < 0)
+ fprintf(stderr,"WD_startFullScreen: Can't open /dev/mouse.\n");
+ }
+ Gpm_Close();
+
+ /* TODO: Scale the mouse coordinates to the specific resolution */
+
+ /* Save the state of the console */
+ if ((stateBuf = malloc(PM_getConsoleStateSize())) == NULL) {
+ printf("Out of memory!\n");
+ exit(-1);
+ }
+ PM_saveConsoleState(stateBuf,tty_fd);
+ initmode = VBE_getVideoMode();
+
+ /* Initialize the signal handler for timer events */
+ signal(SIGALRM, timerHandler);
+
+ /* Capture termination signals so we can clean up properly */
+ signal(SIGTERM, exitHandler);
+ signal(SIGINT, exitHandler);
+ signal(SIGQUIT, exitHandler);
+ atexit(restore_term);
+
+ /* Signal that we are installed */
+ installed = true;
+ }
+ return hwndMain;
+}
+
+/****************************************************************************
+REMARKS:
+Lets the library know when fullscreen graphics mode has been initialized so
+that we can properly scale the mouse driver coordinates.
+****************************************************************************/
+void _WDAPI WD_inFullScreen(void)
+{
+ /* Nothing to do in here */
+}
+
+/****************************************************************************
+REMARKS:
+Suspends all of our event handling operations. This is also used to
+de-install the event handling code.
+****************************************************************************/
+void _WDAPI WD_restoreGDI(void)
+{
+ restore_term();
+}
+
+/****************************************************************************
+PARAMETERS:
+ticks - Number of ticks between timer tick messages
+
+RETURNS:
+Previous value for the timer tick event spacing.
+
+REMARKS:
+The event module will automatically generate periodic timer tick events for
+you, with 'ticks' between each event posting. If you set the value of
+'ticks' to 0, the timer tick events are turned off.
+****************************************************************************/
+int _WDAPI WD_setTimerTick(
+ int ticks)
+{
+ int old;
+ struct itimerval tim;
+ long ms = TICKS_TO_USEC(ticks);
+
+ getitimer(ITIMER_REAL, &tim);
+ old = USEC_TO_TICKS(tim.it_value.tv_sec*1000000.0 + tim.it_value.tv_usec);
+ tim.it_interval.tv_sec = ms / 1000000;
+ tim.it_interval.tv_usec = ms % 1000000;
+ setitimer(ITIMER_REAL, &tim, NULL);
+ return old;
+}
+
+/****************************************************************************
+PARAMETERS:
+saveState - Address of suspend app callback to register
+
+REMARKS:
+Registers a user application supplied suspend application callback so that
+we can properly handle virtual terminal switching.
+****************************************************************************/
+void _WDAPI WD_setSuspendAppCallback(
+ int (_ASMAPI *saveState)(int flags))
+{
+ suspendAppCallback = saveState;
+}
+
+/****************************************************************************
+PARAMETERS:
+x - New X coordinate to move the mouse cursor to
+y - New Y coordinate to move the mouse cursor to
+
+REMARKS:
+Moves to mouse cursor to the specified coordinate.
+****************************************************************************/
+void _WDAPI WD_setMousePos(
+ int x,
+ int y)
+{
+ mx = x;
+ my = y;
+}
+
+/****************************************************************************
+PARAMETERS:
+x - Place to store X coordinate of mouse cursor
+y - Place to store Y coordinate of mouse cursor
+
+REMARKS:
+Reads the current mouse cursor location int *screen* coordinates.
+****************************************************************************/
+void _WDAPI WD_getMousePos(
+ int *x,
+ int *y)
+{
+ *x = mx;
+ *y = my;
+}
+
+/****************************************************************************
+PARAMETERS:
+mcb - Address of mouse callback function
+
+REMARKS:
+Registers an application supplied mouse callback function that is called
+whenever the mouse cursor moves.
+****************************************************************************/
+void _WDAPI WD_setMouseCallback(
+ void (_ASMAPI *mcb)(int x,int y))
+{
+ moveCursor = mcb;
+}
+
+/****************************************************************************
+PARAMETERS:
+xRes - New X resolution of graphics mode
+yRes - New Y resolution of graphics mode
+
+REMARKS:
+This is called to inform the event handling code that the screen resolution
+has changed so that the mouse coordinates can be scaled appropriately.
+****************************************************************************/
+void _WDAPI WD_changeResolution(
+ int xRes,
+ int yRes)
+{
+ // Gpm_FitValues(xRes, yRes); // ??
+}
+
+/****************************************************************************
+PARAMETERS:
+scancode - Scan code to check if a key is down
+
+REMARKS:
+Determines if a particular key is down based on the scan code for the key.
+****************************************************************************/
+ibool _WDAPI WD_isKeyDown(
+ uchar scancode)
+{
+ return key_down[scancode];
+}
+
+/****************************************************************************
+REMARKS:
+Determines if the application needs to run in safe mode. Not necessary for
+anything but broken Windows 95 display drivers so we return false for
+Linux.
+****************************************************************************/
+int _WDAPI WD_isSafeMode(void)
+{
+ return false;
+}
+
+
OpenPOWER on IntegriCloud