/** ** dosinput.c ---- polled mode mouse and keyboard interface for DOS ** ** Copyright (c) 1995 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221 ** [e-mail: csaba@vuse.vanderbilt.edu] ** ** This file is part of the GRX graphics library. ** ** The GRX graphics library is free software; you can redistribute it ** and/or modify it under some conditions; see the "copying.grx" file ** for details. ** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** **/ #include #if defined(__TURBOC__) || defined(__WATCOMC__) /* GS - Watcom C++ 11.0 */ #include #endif #ifdef __DJGPP__ #include #endif #include "libgrx.h" #include "grxkeys.h" #include "allocate.h" #include "arith.h" #include "int86.h" #include "memcopy.h" #include "memfill.h" #include "mouse/input.h" static int kbd_enabled = TRUE; static int mou_enabled = TRUE; static int mou_buttons = 0; static long evt_lasttime; static void uninit(void) { if(MOUINFO->msstatus > 1) MOUINFO->msstatus = 1; } int GrMouseDetect(void) { Int86Regs r; if(MOUINFO->msstatus == 0) { MOUINFO->msstatus = (-1); /* assume missing */ sttzero(&r); int33(&r); if(IREG_AX(r) != 0) { atexit(uninit); MOUINFO->msstatus = 1; /* present, but not initted */ } } return((MOUINFO->msstatus > 0) ? TRUE : FALSE); } void GrMouseInitN(int queue_size) { uninit(); queue_size = umax(4,umin(256,queue_size)); init_queue(queue_size); if(GrMouseDetect()) { GrMouseSetSpeed(1,1); GrMouseSetAccel(100,1); GrMouseSetLimits(0,0,SCRN->gc_xmax,SCRN->gc_ymax); GrMouseWarp((SCRN->gc_xmax >> 1),(SCRN->gc_ymax >> 1)); _GrInitMouseCursor(); MOUINFO->msstatus = 2; mou_buttons = 0; } GrMouseEventEnable(TRUE,TRUE); real_time(evt_lasttime); MOUINFO->uninit = uninit; } void GrMouseSetSpeed(int spmult,int spdiv) { MOUINFO->spmult = umin(16,umax(1,spmult)); MOUINFO->spdiv = umin(16,umax(1,spdiv)); } void GrMouseSetAccel(int thresh,int accel) { MOUINFO->thresh = umin(64,umax(1,thresh)); MOUINFO->accel = umin(16,umax(1,accel)); } void GrMouseSetLimits(int x1,int y1,int x2,int y2) { isort(x1,x2); isort(y1,y2); MOUINFO->xmin = imax(0,imin(x1,SCRN->gc_xmax)); MOUINFO->ymin = imax(0,imin(y1,SCRN->gc_ymax)); MOUINFO->xmax = imax(0,imin(x2,SCRN->gc_xmax)); MOUINFO->ymax = imax(0,imin(y2,SCRN->gc_ymax)); } void GrMouseWarp(int x,int y) { MOUINFO->xpos = imax(MOUINFO->xmin,imin(MOUINFO->xmax,x)); MOUINFO->ypos = imax(MOUINFO->ymin,imin(MOUINFO->ymax,y)); GrMouseUpdateCursor(); } void GrMouseEventEnable(int enable_kb,int enable_ms) { kbd_enabled = enable_kb; mou_enabled = enable_ms; } void _GrUpdateInputs(void) { for( ; ; ) { Int86Regs r; GrMouseEvent ev; int gotevt = FALSE; if(mou_enabled && (MOUINFO->msstatus == 2)) { int mick,btn; sttzero(&r); IREG_AX(r) = 11; /* read mickey counters */ int33(&r); if((mick = (short)IREG_CX(r)) != 0) { update_coord(x,mick); } if((mick = (short)IREG_DX(r)) != 0) { update_coord(y,mick); } IREG_AX(r) = 3; /* read button state */ int33(&r); btn = IREG_BX(r); if(btn != mou_buttons) { fill_mouse_ev( ev, mou_buttons,btn, GR_M_LEFT, GR_M_MIDDLE, GR_M_RIGHT, GrKeyStat() ); real_dtime(ev.dtime,evt_lasttime); enqueue_event(ev); MOUINFO->moved = FALSE; mou_buttons = btn; gotevt = TRUE; } } if(kbd_enabled && GrKeyPressed()) { fill_keybd_ev(ev,GrKeyRead(),GrKeyStat()); real_dtime(ev.dtime,evt_lasttime); enqueue_event(ev); MOUINFO->moved = FALSE; gotevt = TRUE; } if(!gotevt) break; } } void GrMouseGetEventT(int flags,GrMouseEvent *ev,long tout) { int msdraw; long prevtime; if(MOUINFO->msstatus == 0) GrMouseInit(); msdraw = !MOUINFO->displayed && !(flags & GR_M_NOPAINT); if(msdraw) GrMouseDisplayCursor(); real_time(prevtime); for( ; ; ) { _GrUpdateInputs(); GrMouseUpdateCursor(); while(MOUINFO->qlength > 0) { dequeue_event((*ev)); if(ev->flags & flags) { if(msdraw) GrMouseEraseCursor(); return; } } if((flags & GR_M_POLL) || (tout == 0L) || (MOUINFO->moved && (flags & GR_M_MOTION))) { fill_mouse_ev( (*ev), mou_buttons,mou_buttons, GR_M_LEFT, GR_M_MIDDLE, GR_M_RIGHT, GrKeyStat() ); if ( ev->flags ) /* something happend */ real_dtime(ev->dtime,evt_lasttime); else ev->dtime = -1; /* special time if nothing happend */ MOUINFO->moved = FALSE; if(msdraw) GrMouseEraseCursor(); return; } if(tout > 0L) { long dtime; real_dtime(dtime,prevtime); if((tout -= dtime) < 0L) tout = 0L; } } }