📄 event.c
字号:
/****************************************************************************** SciTech OS Portability Manager Library** ========================================================================** 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: Any** Description: Main implementation for the SciTech cross platform event* library. This module contains all the generic cross platform* code, and pulls in modules specific to each target OS* environment.*****************************************************************************/#include "event.h"#include "pmapi.h"#include <time.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "oshdr.h"/*--------------------------- Global variables ----------------------------*/#define EVENTQSIZE 100 /* Number of events in event queue */#define JOY_NUM_AXES 4 /* Number of joystick axes supported */static struct { int mx,my; /* Current mouse position */ int head; /* Head of event queue */ int tail; /* Tail of event queue */ int freeHead; /* Head of free list */ int count; /* No. of items currently in queue */ event_t evtq[EVENTQSIZE]; /* The queue structure itself */ int oldMove; /* Previous movement event */ int oldKey; /* Previous key repeat event */ int oldJoyMove; /* Previous joystick movement event */ int joyMask; /* Mask of joystick axes present */ int joyMin[JOY_NUM_AXES]; int joyCenter[JOY_NUM_AXES]; int joyMax[JOY_NUM_AXES]; int joyPrev[JOY_NUM_AXES]; int joyButState; ulong doubleClick; ulong autoRepeat; ulong autoDelay; ulong autoTicks; ulong doubleClickThresh; ulong firstAuto; int autoMouse_x; int autoMouse_y; event_t downMouse; ulong keyModifiers; /* Current keyboard modifiers */ uchar keyTable[128]; /* Table of key up/down flags */ ibool allowLEDS; /* True if LEDS should change */ _EVT_userEventFilter userEventCallback; _EVT_mouseMoveHandler mouseMove; _EVT_heartBeatCallback heartBeat; void *heartBeatParams; codepage_t *codePage; } EVT;/*---------------------------- Implementation -----------------------------*/#if defined(__REALDOS__) || defined(__SMX32__)/* {secret} */void EVTAPI _EVT_cCodeStart(void) {}#endif/* External assembler functions */int EVTAPI _EVT_readJoyAxis(int mask,int *axis);int EVTAPI _EVT_readJoyButtons(void);/* Forward declaration */ulong _EVT_getTicks(void);/****************************************************************************PARAMETERS:evt - Event to add to the event queueREMARKS:Adds an event to the event queue by tacking it onto the tail of the eventqueue. This routine assumes that at least one spot is available on thefreeList for the event to be inserted.NOTE: Interrupts MUST be OFF while this routine is called to ensure we have mutually exclusive access to our internal data structures for interrupt driven systems (like under DOS).****************************************************************************/static void addEvent( event_t *evt){ int evtID; /* Check for mouse double click events */ if (evt->what & EVT_MOUSEEVT) { EVT.autoMouse_x = evt->where_x; EVT.autoMouse_y = evt->where_y; if ((evt->what & EVT_MOUSEDOWN) && !(evt->message & EVT_DBLCLICK)) { /* Determine if the last mouse event was a double click event */ uint diff_x = ABS(evt->where_x - EVT.downMouse.where_x); uint diff_y = ABS(evt->where_y - EVT.downMouse.where_y); if ((evt->message == EVT.downMouse.message) && ((evt->when - EVT.downMouse.when) <= EVT.doubleClick) && (diff_x <= EVT.doubleClickThresh) && (diff_y <= EVT.doubleClickThresh)) { evt->message |= EVT_DBLCLICK; EVT.downMouse = *evt; EVT.downMouse.when = 0; } else EVT.downMouse = *evt; EVT.autoTicks = _EVT_getTicks(); } else if (evt->what & EVT_MOUSEUP) { EVT.downMouse.what = EVT_NULLEVT; EVT.firstAuto = true; } } /* Call user supplied callback to modify the event if desired */ if (EVT.userEventCallback) { if (!EVT.userEventCallback(evt)) return; } /* Get spot to place the event from the free list */ evtID = EVT.freeHead; EVT.freeHead = EVT.evtq[EVT.freeHead].next; /* Add to the EVT.tail of the event queue */ evt->next = -1; evt->prev = EVT.tail; if (EVT.tail != -1) EVT.evtq[EVT.tail].next = evtID; else EVT.head = evtID; EVT.tail = evtID; EVT.evtq[evtID] = *evt; EVT.count++;}/****************************************************************************REMARKS:Internal function to initialise the event queue to the empty state.****************************************************************************/static void initEventQueue(void){ int i; /* Build free list, and initialize global data structures */ for (i = 0; i < EVENTQSIZE; i++) EVT.evtq[i].next = i+1; EVT.evtq[EVENTQSIZE-1].next = -1; /* Terminate list */ EVT.count = EVT.freeHead = 0; EVT.head = EVT.tail = -1; EVT.oldMove = -1; EVT.oldKey = -1; EVT.oldJoyMove = -1; EVT.joyButState = 0; EVT.mx = EVT.my = 0; EVT.keyModifiers = 0; EVT.allowLEDS = true; /* Set default values for mouse double click and mouse auto events */ EVT.doubleClick = 440; EVT.autoRepeat = 55; EVT.autoDelay = 330; EVT.autoTicks = 0; EVT.doubleClickThresh = 5; EVT.firstAuto = true; EVT.autoMouse_x = EVT.autoMouse_y = 0; memset(&EVT.downMouse,0,sizeof(EVT.downMouse)); /* Setup default pointers for event library */ EVT.userEventCallback = NULL; EVT.codePage = &_CP_US_English; /* Initialise the joystick module and do basic calibration (which assumes * the joystick is centered. */ EVT.joyMask = EVT_joyIsPresent();}#if defined(NEED_SCALE_JOY_AXIS) || !defined(USE_OS_JOYSTICK)/****************************************************************************REMARKS:This function scales a joystick axis value to normalised form.****************************************************************************/static int scaleJoyAxis( int raw, int axis){ int scaled,range; /* Make sure the joystick is calibrated properly */ if (EVT.joyCenter[axis] - EVT.joyMin[axis] < 5) return raw; if (EVT.joyMax[axis] - EVT.joyCenter[axis] < 5) return raw; /* Now scale the coordinates to -128 to 127 */ raw -= EVT.joyCenter[axis]; if (raw < 0) range = EVT.joyCenter[axis]-EVT.joyMin[axis]; else range = EVT.joyMax[axis]-EVT.joyCenter[axis]; scaled = (raw * 128) / range; if (scaled < -128) scaled = -128; if (scaled > 127) scaled = 127; return scaled;}#endif#if defined(__SMX32__)#include "smx/event.c"#elif defined(__RTTARGET__)#include "rttarget/event.c"#elif defined(__REALDOS__)#include "dos/event.c"#elif defined(__WINDOWS32__)#include "win32/event.c"#elif defined(__OS2__)#if defined(__OS2_PM__)#include "os2pm/event.c"#else#include "os2/event.c"#endif#elif defined(__LINUX__)#if defined(__USE_X11__)#include "x11/event.c"#else#include "linux/event.c"#endif#elif defined(__QNX__)#if defined(__USE_PHOTON__)#include "photon/event.c"#elif defined(__USE_X11__)#include "x11/event.c"#else#include "qnx/event.c"#endif#elif defined(__BEOS__)#include "beos/event.c"#else#error Event library not ported to this platform yet!#endif/*------------------------ Public interface routines ----------------------*//* If USE_OS_JOYSTICK is defined, the OS specific libraries will implement * the joystick code rather than using the generic OS portable version. */#ifndef USE_OS_JOYSTICK/****************************************************************************DESCRIPTION:Returns the mask indicating what joystick axes are attached.HEADER:event.hREMARKS:This function is used to detect the attached joysticks, and determinewhat axes are present and functioning. This function will re-detect anyattached joysticks when it is called, so if the user forgot to attachthe joystick when the application started, you can call this function tore-detect any newly attached joysticks.SEE ALSO:EVT_joySetLowerRight, EVT_joySetCenter, EVT_joyIsPresent****************************************************************************/int EVTAPI EVT_joyIsPresent(void){ int mask,i; memset(EVT.joyMin,0,sizeof(EVT.joyMin)); memset(EVT.joyCenter,0,sizeof(EVT.joyCenter)); memset(EVT.joyMax,0,sizeof(EVT.joyMax)); memset(EVT.joyPrev,0,sizeof(EVT.joyPrev)); EVT.joyButState = 0;#ifdef __LINUX__ PM_init();#endif mask = _EVT_readJoyAxis(EVT_JOY_AXIS_ALL,EVT.joyCenter); if (mask) { for (i = 0; i < JOY_NUM_AXES; i++) EVT.joyMax[i] = EVT.joyCenter[i]*2; } return mask;}/****************************************************************************DESCRIPTION:Polls the joystick for position and button information.HEADER:event.hREMARKS:This routine is used to poll analogue joysticks for button and positioninformation. It should be called once for each main loop of the userapplication, just before processing all pending events via EVT_getNext.All information polled from the joystick will be posted to the eventqueue for later retrieval.Note: Most analogue joysticks will provide readings that change even though the joystick has not moved. Hence if you call this routine you will likely get an EVT_JOYMOVE event every time through your event loop.SEE ALSO:EVT_getNext, EVT_peekNext, EVT_joySetUpperLeft, EVT_joySetLowerRight,EVT_joySetCenter, EVT_joyIsPresent****************************************************************************/void EVTAPI EVT_pollJoystick(void){ event_t evt; int i,axis[JOY_NUM_AXES],newButState,mask,moved,ps; if (EVT.joyMask) { /* Read joystick axes and post movement events if they have * changed since the last time we polled. Until the events are * actually flushed, we keep modifying the same joystick movement * event, so you won't get multiple movement event */ mask = _EVT_readJoyAxis(EVT.joyMask,axis); newButState = _EVT_readJoyButtons(); moved = false; for (i = 0; i < JOY_NUM_AXES; i++) { if (mask & (EVT_JOY_AXIS_X1 << i)) axis[i] = scaleJoyAxis(axis[i],i); else axis[i] = EVT.joyPrev[i]; if (axis[i] != EVT.joyPrev[i]) moved = true; } if (moved) { memcpy(EVT.joyPrev,axis,sizeof(EVT.joyPrev)); ps = _EVT_disableInt(); if (EVT.oldJoyMove != -1) { /* Modify the existing joystick movement event */ EVT.evtq[EVT.oldJoyMove].message = newButState; EVT.evtq[EVT.oldJoyMove].where_x = EVT.joyPrev[0]; EVT.evtq[EVT.oldJoyMove].where_y = EVT.joyPrev[1]; EVT.evtq[EVT.oldJoyMove].relative_x = EVT.joyPrev[2]; EVT.evtq[EVT.oldJoyMove].relative_y = EVT.joyPrev[3]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -