home *** CD-ROM | disk | FTP | other *** search
/ Shareware 1 2 the Maxx / sw_1.zip / sw_1 / PROGRAM / CBGRX100.ZIP / CONTRIB / LIBGRX / SRC / MOUSE.C < prev    next >
Text File  |  1992-04-10  |  15KB  |  619 lines

  1. /** 
  2.  ** MOUSE.C 
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #include "grx.h"
  25. #include "mousex.h"
  26. #include "libgrx.h"
  27. #include "interrup.h"
  28. #include "clipping.h"
  29.  
  30. #include "../events/eventque.h"
  31. #include <string.h>
  32. #include <stdarg.h>
  33.  
  34. #ifdef __TURBOC__
  35. # include <time.h>
  36. # include <conio.h>
  37. #endif
  38.  
  39. /*
  40.  * mouse status flags
  41.  */
  42. #define UNKNOWN         0
  43. #define MISSING         1
  44. #define PRESENT         2
  45. #define INITTED         3
  46. #define QUEUED         4
  47.  
  48. #define DRAW_STACK   1024
  49. #define QUEUE_SIZE   100
  50.  
  51. #define CHECK_CONTEXT(cxt)  ((cxt)->gc_baseaddr == SCREEN->gc_baseaddr)
  52.  
  53. extern GrCursor *_GrMouseCursor;    /* current mouse cursor */
  54.  
  55. static EventQueue *queue,qbuf;
  56. static int mouse_status = UNKNOWN;
  57. static int own_cursor    = FALSE;
  58. static int use_queue    = FALSE;
  59. static int kb_enable    = TRUE;
  60. static int ms_enable    = TRUE;
  61. static int ms_curmode    = M_CUR_NORMAL;
  62. static int ms_xanchor,ms_yanchor;
  63. static int ms_dx2,ms_dy2;
  64. static int ms_curcolor;
  65. static int ms_buttons;
  66. static int ms_xpos;
  67. static int ms_ypos;
  68.  
  69. #define ms_dx1  ms_xanchor
  70. #define ms_dy1  ms_yanchor
  71.  
  72. static void (*getevent)(int flags,MouseEvent *event);
  73.  
  74. static char ptr12x16bits[] = {
  75.     0,1,0,0,0,0,0,0,0,0,0,0,
  76.     1,2,1,0,0,0,0,0,0,0,0,0,
  77.     1,2,2,1,0,0,0,0,0,0,0,0,
  78.     1,2,2,2,1,0,0,0,0,0,0,0,
  79.     1,2,2,2,2,1,0,0,0,0,0,0,
  80.     1,2,2,2,2,2,1,0,0,0,0,0,
  81.     1,2,2,2,2,2,2,1,0,0,0,0,
  82.     1,2,2,2,2,2,2,2,1,0,0,0,
  83.     1,2,2,2,2,2,2,2,2,1,0,0,
  84.     1,2,2,2,2,2,2,2,2,2,1,0,
  85.     1,2,2,2,2,2,2,2,2,2,2,1,
  86.     1,2,2,2,2,1,1,1,1,1,1,0,
  87.     1,2,2,2,1,0,0,0,0,0,0,0,
  88.     1,2,2,1,0,0,0,0,0,0,0,0,
  89.     1,2,1,0,0,0,0,0,0,0,0,0,
  90.     0,1,0,0,0,0,0,0,0,0,0,0,
  91. };
  92.  
  93. static int check_mouse(void)
  94. {
  95.     if(mouse_status < INITTED) {
  96.         if(mouse_status != MISSING) MouseInit();
  97.         if(mouse_status <  INITTED) return(FALSE);
  98.     }
  99.     return(TRUE);
  100. }
  101.  
  102. static void draw_special(void)
  103. {
  104.     int x = _GrMouseCursor->cr_xcord;
  105.     int y = _GrMouseCursor->cr_ycord;
  106.     int msflag = _GrMouseCheck;
  107.     GrContext csave;
  108.  
  109.     csave = *CURC;
  110.     *CURC = *SCREEN;
  111.     _GrMouseCheck = FALSE;
  112.     switch(ms_curmode) {
  113.       case M_CUR_RUBBER:
  114.         GrBox(x,y,ms_xanchor,ms_yanchor,ms_curcolor);
  115.         break;
  116.       case M_CUR_LINE:
  117.         GrLine(x,y,ms_xanchor,ms_yanchor,ms_curcolor);
  118.         break;
  119.       case M_CUR_BOX:
  120.         GrBox(x+ms_dx1,y+ms_dy1,x+ms_dx2,y+ms_dy2,ms_curcolor);
  121.         break;
  122.     }
  123.     *CURC = csave;
  124.     _GrMouseCheck = msflag;
  125. }
  126.  
  127. static void draw_mouse(void)
  128. {
  129.     if(_GrMouseCursor->cr_displayed) return;
  130.     GrMoveCursor(_GrMouseCursor,queue->evq_xpos,queue->evq_ypos);
  131.     GrDisplayCursor(_GrMouseCursor);
  132.     if(ms_curmode != M_CUR_NORMAL) draw_special();
  133. }
  134.  
  135. static void erase_mouse(void)
  136. {
  137.     if(!_GrMouseCursor->cr_displayed) return;
  138.     if(ms_curmode != M_CUR_NORMAL) draw_special();
  139.     GrEraseCursor(_GrMouseCursor);
  140. }
  141.  
  142. static void move_mouse(void)
  143. {
  144.     if(!_GrMouseCursor->cr_displayed) {
  145.         GrMoveCursor(_GrMouseCursor,queue->evq_xpos,queue->evq_ypos);
  146.         return;
  147.     }
  148.     if(ms_curmode != M_CUR_NORMAL) draw_special();
  149.     GrMoveCursor(_GrMouseCursor,queue->evq_xpos,queue->evq_ypos);
  150.     if(ms_curmode != M_CUR_NORMAL) draw_special();
  151. }
  152.  
  153. static void get_polled_event(int flags,MouseEvent *e)
  154. {
  155.     REGISTERS regs;
  156.     int moved;
  157.     int diff;
  158.  
  159.     for( ; ; ) {
  160.         if((flags & M_KEYPRESS) && kbhit()) {
  161.         e->flags  = M_KEYPRESS;
  162.         e->key      = getkey();
  163.         e->kbstat = getkbstat();
  164.         e->time      = clock();
  165.         return;
  166.         }
  167.         moved = 0;
  168.         regs.r_ax = 11;
  169.         int33(®s);
  170.         if((diff = (short)regs.r_cx) != 0) {
  171.         ms_xpos += diff;
  172.         if((diff = ms_xpos / queue->evq_xspeed) != 0) {
  173.             ms_xpos %= queue->evq_xspeed;
  174.             if(IABS(diff) >= queue->evq_thresh)
  175.             diff *= queue->evq_accel;
  176.             diff += queue->evq_xpos;
  177.             if(diff <= queue->evq_xmin) diff = queue->evq_xmin;
  178.             if(diff >= queue->evq_xmax) diff = queue->evq_xmax;
  179.             if(diff != queue->evq_xpos) {
  180.             queue->evq_xpos  = diff;
  181.             queue->evq_moved = 1;
  182.             moved = M_MOTION;
  183.             }
  184.         }
  185.         }
  186.         if((diff = (short)regs.r_dx) != 0) {
  187.         ms_ypos += diff;
  188.         if((diff = ms_ypos / queue->evq_yspeed) != 0) {
  189.             ms_ypos %= queue->evq_yspeed;
  190.             if(IABS(diff) >= queue->evq_thresh)
  191.             diff *= queue->evq_accel;
  192.             diff += queue->evq_ypos;
  193.             if(diff <= queue->evq_ymin) diff = queue->evq_ymin;
  194.             if(diff >= queue->evq_ymax) diff = queue->evq_ymax;
  195.             if(diff != queue->evq_ypos) {
  196.             queue->evq_ypos  = diff;
  197.             queue->evq_moved = 1;
  198.             moved = M_MOTION;
  199.             }
  200.         }
  201.         }
  202.         if(moved && queue->evq_drawmouse) move_mouse();
  203.         regs.r_ax = 3;
  204.         int33(®s);
  205.         if(flags & M_BUTTON_DOWN) {
  206.         diff = (regs.r_bx & ~ms_buttons);
  207.         if(diff & M_LEFT)   moved |= M_LEFT_DOWN;
  208.         if(diff & M_MIDDLE) moved |= M_MIDDLE_DOWN;
  209.         if(diff & M_RIGHT)  moved |= M_RIGHT_DOWN;
  210.         }
  211.         if(flags & M_BUTTON_UP) {
  212.         diff = (~regs.r_bx & ms_buttons);
  213.         if(diff & M_LEFT)   moved |= M_LEFT_UP;
  214.         if(diff & M_MIDDLE) moved |= M_MIDDLE_UP;
  215.         if(diff & M_RIGHT)  moved |= M_RIGHT_UP;
  216.         }
  217.         ms_buttons = regs.r_bx & (M_LEFT | M_MIDDLE | M_RIGHT);
  218.         if(flags & (moved | M_POLL)) {
  219.         e->flags   = moved & flags;
  220.         e->x       = queue->evq_xpos;
  221.         e->y       = queue->evq_ypos;
  222.         e->buttons = ms_buttons;
  223.         e->kbstat  = getkbstat();
  224.         e->time       = clock();
  225.         return;
  226.         }
  227.     }
  228. }
  229.  
  230. static void get_queued_event(int flags,MouseEvent *e)
  231. {
  232.     EventRecord evr;
  233.     int moved = 0;
  234.  
  235.     for( ; ; ) {
  236.         if(queue->evq_moved) {
  237.         moved = M_MOTION;
  238.         queue->evq_moved = 0;
  239.         }
  240.         if(EventQueueNextEvent(queue,&evr)) {
  241.         switch(evr.evt_type) {
  242.           case EVENT_KEYBD:
  243.             if(flags & M_KEYPRESS) {
  244.             e->flags   = M_KEYPRESS;
  245.             e->key       = evr.evt_keycode;
  246.             e->kbstat  = evr.evt_kbstat;
  247.             e->time       = evr.evt_time;
  248.             return;
  249.             }
  250.             break;
  251.           case EVENT_MOUSE:
  252.             ms_buttons = evr.evt_button;
  253.             if(flags & evr.evt_mask) {
  254.             e->flags   = flags & (evr.evt_mask | moved);
  255.             e->x       = evr.evt_xpos;
  256.             e->y       = evr.evt_ypos;
  257.             e->buttons = evr.evt_button;
  258.             e->kbstat  = evr.evt_kbstat;
  259.             e->time       = evr.evt_time;
  260.             return;
  261.             }
  262.             break;
  263.         }
  264.         continue;
  265.         }
  266.         if(flags & (moved | M_POLL)) {
  267.         e->flags   = flags & moved;
  268.         e->x       = queue->evq_xpos;
  269.         e->y       = queue->evq_ypos;
  270.         e->buttons = ms_buttons;
  271.         e->kbstat  = getkbstat();
  272.         e->time       = clock();
  273.         return;
  274.         }
  275.     }
  276. }
  277.  
  278. void MouseEventMode(int use_interrupts)
  279. {
  280.     use_queue = use_interrupts;
  281. }
  282.  
  283. int MouseDetect(void)
  284. {
  285.     REGISTERS regs;
  286.  
  287.     if(mouse_status == UNKNOWN) {
  288.         regs.r_ax = 0;
  289.         int33(®s);
  290.         mouse_status = (regs.r_ax == 0) ? MISSING : PRESENT;
  291.     }
  292.     return((mouse_status == MISSING) ? FALSE : TRUE);
  293. }
  294.  
  295. void MouseUnInit(void)
  296. {
  297.     REGISTERS regs;
  298.  
  299.     if(mouse_status >= INITTED) {
  300.         if(mouse_status == QUEUED) {
  301.         EventQueueDeInit();
  302.         queue = NULL;
  303.         }
  304.         else {
  305.         regs.r_ax = 0;
  306.         int33(®s);
  307.         }
  308.         if(_GrMouseDrawn) erase_mouse();
  309.         mouse_status = PRESENT;
  310.     }
  311. }
  312.  
  313. void MouseInit(void)
  314. {
  315.     REGISTERS regs;
  316.  
  317.     if(mouse_status != PRESENT) {
  318.         MouseDetect();
  319.         MouseUnInit();
  320.         if(mouse_status != PRESENT) return;
  321.     }
  322.     if(use_queue) {
  323.         queue = EventQueueInit(QUEUE_SIZE,DRAW_STACK,move_mouse);
  324.         if(queue != NULL) {
  325.         mouse_status = QUEUED;
  326.         getevent = get_queued_event;
  327.         queue->evq_drawmouse = FALSE;
  328.         }
  329.     }
  330.     if(mouse_status < INITTED) {
  331.         queue = &qbuf;
  332.         regs.r_ax = 0;
  333.         int33(®s);
  334.         regs.r_ax = 3;
  335.         int33(®s);
  336.         ms_buttons = regs.r_bx & (M_LEFT | M_MIDDLE | M_RIGHT);
  337.         regs.r_ax = 11;
  338.         int33(®s);
  339.         ms_xpos = 0;
  340.         ms_ypos = 0;
  341.         getevent = get_polled_event;
  342.         mouse_status = INITTED;
  343.     }
  344.     if(_GrMouseCursor == NULL) MouseSetColors(GrWhite(),GrBlack());
  345.     _GrMouseBlock    = MouseBlock;
  346.     _GrMouseUnBlock = MouseUnBlock;
  347.     _GrMouseUnInit  = MouseUnInit;
  348.     _GrMouseDrawn    = FALSE;
  349.     _GrMouseCheck    = FALSE;
  350.     MouseEventEnable(kb_enable,ms_enable);
  351.     MouseSetLimits(0,0,(_GrScreenX - 1),(_GrScreenY - 1));
  352.     MouseWarp((_GrScreenX >> 1),(_GrScreenY >> 1));
  353.     MouseSetSpeed(1);
  354.     MouseSetAccel(16,3);
  355. }
  356.  
  357. void MouseSetSpeed(int speed)
  358. {
  359.     if(!check_mouse()) return;
  360.     queue->evq_xspeed = speed;
  361.     queue->evq_yspeed = speed;
  362. }
  363.  
  364. void MouseSetAccel(int thresh,int accel)
  365. {
  366.     if(!check_mouse()) return;
  367.     queue->evq_thresh = thresh;
  368.     queue->evq_accel  = accel;
  369. }
  370.  
  371. void MouseSetLimits(int x1,int y1,int x2,int y2)
  372. {
  373.     if(!check_mouse()) return;
  374.     CLIPBOXTOCONTEXT(SCREEN,x1,y1,x2,y2);
  375.     queue->evq_xmin = x1;
  376.     queue->evq_ymin = y1;
  377.     queue->evq_xmax = x2;
  378.     queue->evq_ymax = y2;
  379.     MouseWarp(queue->evq_xpos,queue->evq_ypos);
  380. }
  381.  
  382. void MouseGetLimits(int *x1,int *y1,int *x2,int *y2)
  383. {
  384.     if(!check_mouse()) return;
  385.     *x1 = queue->evq_xmin;
  386.     *y1 = queue->evq_ymin;
  387.     *x2 = queue->evq_xmax;
  388.     *y2 = queue->evq_ymax;
  389. }
  390.  
  391. void MouseWarp(int x,int y)
  392. {
  393.     char msdraw;
  394.  
  395.     if(!check_mouse()) return;
  396.     msdraw = queue->evq_drawmouse;
  397.     queue->evq_drawmouse = FALSE;
  398.     if(x < queue->evq_xmin) x = queue->evq_xmin;
  399.     if(y < queue->evq_ymin) y = queue->evq_ymin;
  400.     if(x > queue->evq_xmax) x = queue->evq_xmax;
  401.     if(y > queue->evq_ymax) y = queue->evq_ymax;
  402.     queue->evq_xpos = x;
  403.     queue->evq_ypos = y;
  404.     if(_GrMouseDrawn) move_mouse();
  405.     queue->evq_drawmouse = msdraw;
  406. }
  407.  
  408. void MouseSetCursor(GrCursor *cursor)
  409. {
  410.     GrCursor *old = _GrMouseCursor;
  411.     char msdraw;
  412.  
  413.     if(cursor != NULL) {
  414.         if(mouse_status >= INITTED) {
  415.         msdraw = queue->evq_drawmouse;
  416.         queue->evq_drawmouse = FALSE;
  417.         if(_GrMouseDrawn) erase_mouse();
  418.         }
  419.         _GrMouseCursor = cursor;
  420.         if(own_cursor) GrDestroyCursor(old);
  421.         own_cursor = FALSE;
  422.         if(mouse_status >= INITTED) {
  423.         if(_GrMouseDrawn) draw_mouse();
  424.         queue->evq_drawmouse = msdraw;
  425.         }
  426.     }
  427. }
  428.  
  429. void MouseSetColors(int fg,int bg)
  430. {
  431.     GrCursor *new;
  432.     int cols[3];
  433.  
  434.     cols[0] = 2;
  435.     cols[1] = bg;
  436.     cols[2] = fg;
  437.     new = GrBuildCursor(ptr12x16bits,12,16,1,1,cols);
  438.     if(new != NULL) {
  439.         MouseSetCursor(new);
  440.         own_cursor = TRUE;
  441.     }
  442. }
  443.  
  444. void MouseSetCursorMode(int mode,...)
  445. {
  446.     va_list ap;
  447.     char msdraw;
  448.  
  449.     if(mouse_status >= INITTED) {
  450.         msdraw = queue->evq_drawmouse;
  451.         queue->evq_drawmouse = FALSE;
  452.         if(_GrMouseDrawn && (ms_curmode != M_CUR_NORMAL)) draw_special();
  453.     }
  454.     va_start(ap,mode);
  455.     switch(mode) {
  456.       case M_CUR_RUBBER:
  457.         ms_curmode  = M_CUR_RUBBER;
  458.         ms_xanchor  = va_arg(ap,int);
  459.         ms_yanchor  = va_arg(ap,int);
  460.         ms_curcolor = (va_arg(ap,int) & C_COLOR) | GrXOR;
  461.         break;
  462.       case M_CUR_LINE:
  463.         ms_curmode  = M_CUR_LINE;
  464.         ms_xanchor  = va_arg(ap,int);
  465.         ms_yanchor  = va_arg(ap,int);
  466.         ms_curcolor = (va_arg(ap,int) & C_COLOR) | GrXOR;
  467.         break;
  468.       case M_CUR_BOX:
  469.         ms_curmode  = M_CUR_BOX;
  470.         ms_dx1    = va_arg(ap,int);
  471.         ms_dy1    = va_arg(ap,int);
  472.         ms_dx2    = va_arg(ap,int);
  473.         ms_dy2    = va_arg(ap,int);
  474.         ms_curcolor = (va_arg(ap,int) & C_COLOR) | GrXOR;
  475.         break;
  476.       default:
  477.         ms_curmode  = M_CUR_NORMAL;
  478.         break;
  479.     }
  480.     va_end(ap);
  481.     if(mouse_status >= INITTED) {
  482.         if(_GrMouseDrawn && (ms_curmode != M_CUR_NORMAL)) draw_special();
  483.         queue->evq_drawmouse = msdraw;
  484.     }
  485. }
  486.  
  487. GrCursor *MouseGetCursor(void)
  488. {
  489.     return(_GrMouseCursor);
  490. }
  491.  
  492. int MouseCursorIsDisplayed(void)
  493. {
  494.     return(_GrMouseDrawn);
  495. }
  496.  
  497. void MouseDisplayCursor(void)
  498. {
  499.     if((mouse_status < INITTED) || _GrMouseDrawn) return;
  500.     draw_mouse();
  501.     _GrMouseDrawn = TRUE;
  502.     _GrMouseCheck = CHECK_CONTEXT(CURC) ? TRUE : FALSE;
  503.     queue->evq_drawmouse = TRUE;
  504. }
  505.  
  506. void MouseEraseCursor(void)
  507. {
  508.     if((mouse_status < INITTED) || !_GrMouseDrawn) return;
  509.     queue->evq_drawmouse = FALSE;
  510.     _GrMouseDrawn = FALSE;
  511.     _GrMouseCheck = FALSE;
  512.     erase_mouse();
  513. }
  514.  
  515. int MouseBlock(GrContext *c,int x1,int y1,int x2,int y2)
  516. {
  517.     int mx1,my1,mx2,my2;
  518.     int cx1,cy1,cx2,cy2;
  519.  
  520.     if(c == NULL) c = CURC;
  521.     if((mouse_status < INITTED) || !_GrMouseDrawn || !CHECK_CONTEXT(c))
  522.         return(FALSE);
  523.     queue->evq_drawmouse = FALSE;
  524.     queue->evq_moved = FALSE;
  525.     x1 += c->gc_xoffset; y1 += c->gc_yoffset;
  526.     x2 += c->gc_xoffset; y2 += c->gc_yoffset;
  527.     mx1 = _GrMouseCursor->cr_xwpos;
  528.     my1 = _GrMouseCursor->cr_ywpos;
  529.     mx2 = mx1 + _GrMouseCursor->cr_xwork - 1;
  530.     my2 = my1 + _GrMouseCursor->cr_ywork - 1;
  531.     if(ms_curmode != M_CUR_NORMAL) {
  532.         cx1 = _GrMouseCursor->cr_xcord;
  533.         cy1 = _GrMouseCursor->cr_ycord;
  534.         switch(ms_curmode) {
  535.           case M_CUR_RUBBER:
  536.         cx2 = ms_xanchor;
  537.         cy2 = ms_yanchor;
  538.         break;
  539.           case M_CUR_LINE:
  540.         cx2 = ms_xanchor;
  541.         cy2 = ms_yanchor;
  542.         break;
  543.           case M_CUR_BOX:
  544.         cx2 = cx1 + ms_dx2;
  545.         cy2 = cy1 + ms_dy2;
  546.         cx1 += ms_dx1;
  547.         cy2 += ms_dy1;
  548.         break;
  549.         }
  550.         SORT2(cx1,cx2);
  551.         SORT2(cy1,cy2);
  552.         if(cx1 < mx1) mx1 = cx1;
  553.         if(cy1 < my1) my1 = cy1;
  554.         if(cx2 > mx2) mx2 = cx2;
  555.         if(cy2 > my2) my2 = cy2;
  556.     }
  557.     if(mx1 > x1) x1 = mx1;
  558.     if(my1 > y1) y1 = my1;
  559.     if(mx2 < x2) x2 = mx2;
  560.     if(my2 < y2) y2 = my2;
  561.     if((x1 <= x2) && (y1 <= y2)) {
  562.         _GrMouseDrawn = FALSE;
  563.         erase_mouse();
  564.     }
  565.     _GrMouseCheck = FALSE;
  566.     return(TRUE);
  567. }
  568.  
  569. void MouseUnBlock(void)
  570. {
  571.     if(mouse_status < INITTED) return;
  572.     if(queue->evq_moved) move_mouse();
  573.     if(!_GrMouseDrawn) draw_mouse();
  574.     _GrMouseDrawn = TRUE;
  575.     _GrMouseCheck = CHECK_CONTEXT(CURC) ? TRUE : FALSE;
  576.     queue->evq_drawmouse = TRUE;
  577. }
  578.  
  579. void MouseEventEnable(int enable_kb,int enable_ms)
  580. {
  581.     if(mouse_status >= INITTED) {
  582.         queue->evq_enable =
  583.         (enable_kb ? EVENT_ENABLE(EVENT_KEYBD) : 0) |
  584.         (enable_ms ? EVENT_ENABLE(EVENT_MOUSE) : 0);
  585.     }
  586.     kb_enable = enable_kb;
  587.     ms_enable = enable_ms;
  588. }
  589.  
  590. void MouseGetEvent(int flags,MouseEvent *e)
  591. {
  592.     int erase = FALSE;
  593.  
  594.     if(!kb_enable) flags &= ~M_KEYPRESS;
  595.     if(!ms_enable) flags &= ~(M_MOTION | M_BUTTON_DOWN | M_BUTTON_UP);
  596.     if(!(flags & M_EVENT)) { e->flags = 0; return; }
  597.     if(!check_mouse()) {
  598.         e->flags = 0;
  599.         if((flags & M_KEYPRESS) && (!(flags & M_POLL) || kbhit())) {
  600.         e->flags  = M_KEYPRESS;
  601.         e->key      = getkey();
  602.         e->kbstat = getkbstat();
  603.         e->time      = clock();
  604.         }
  605.         return;
  606.     }
  607.     if(!_GrMouseDrawn && !(flags & M_NOPAINT)) {
  608.         draw_mouse();
  609.         queue->evq_drawmouse = TRUE;
  610.         erase = TRUE;
  611.     }
  612.     (*getevent)(flags,e);
  613.     if(erase) {
  614.         queue->evq_drawmouse = FALSE;
  615.         erase_mouse();
  616.     }
  617. }
  618.  
  619.