Annotation of sbbs/src/conio/mouse.c, revision 1.1.1.2

1.1.1.2 ! root        1: /* $Id: mouse.c,v 1.37 2008/06/08 01:42:27 deuce Exp $ */
1.1       root        2: 
                      3: /****************************************************************************
                      4:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      5:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                      6:  *                                                                                                                                                     *
                      7:  * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html         *
                      8:  *                                                                                                                                                     *
                      9:  * This library is free software; you can redistribute it and/or                       *
                     10:  * modify it under the terms of the GNU Lesser General Public License          *
                     11:  * as published by the Free Software Foundation; either version 2                      *
                     12:  * of the License, or (at your option) any later version.                                      *
                     13:  * See the GNU Lesser General Public License for more details: lgpl.txt or     *
                     14:  * http://www.fsf.org/copyleft/lesser.html                                                                     *
                     15:  *                                                                                                                                                     *
                     16:  * Anonymous FTP access to the most recent released source is available at     *
                     17:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     18:  *                                                                                                                                                     *
                     19:  * Anonymous CVS access to the development source and modification history     *
                     20:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     21:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     22:  *     (just hit return, no password is necessary)                                                     *
                     23:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     24:  *                                                                                                                                                     *
                     25:  * For Synchronet coding style and modification guidelines, see                                *
                     26:  * http://www.synchro.net/source.html                                                                          *
                     27:  *                                                                                                                                                     *
                     28:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     29:  * format) via e-mail to [email protected]                                                                      *
                     30:  *                                                                                                                                                     *
                     31:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     32:  ****************************************************************************/
                     33: 
                     34: #include <stdlib.h>
                     35: #include <string.h>
                     36: 
                     37: #include <genwrap.h>
                     38: #include <semwrap.h>
                     39: #include <threadwrap.h>
                     40: #include <link_list.h>
                     41: 
                     42: #include "mouse.h"
                     43: 
                     44: #define MSEC_CLOCK()   (msclock()*MSCLOCKS_PER_SEC/1000)
                     45: 
                     46: enum {
                     47:         MOUSE_NOSTATE
                     48:        ,MOUSE_SINGLEPRESSED
                     49:        ,MOUSE_CLICKED
                     50:        ,MOUSE_DOUBLEPRESSED
                     51:        ,MOUSE_DOUBLECLICKED
                     52:        ,MOUSE_TRIPLEPRESSED
                     53:        ,MOUSE_TRIPLECLICKED
                     54:        ,MOUSE_QUADPRESSED
                     55:        ,MOUSE_QUADCLICKED
                     56:        ,MOUSE_DRAGSTARTED
                     57: };
                     58: 
                     59: struct in_mouse_event {
                     60:        int     event;
                     61:        int     x;
                     62:        int     y;
                     63:        clock_t ts;
                     64:        void    *nextevent;
                     65: };
                     66: 
                     67: struct out_mouse_event {
                     68:        int event;
                     69:        int bstate;
                     70:        int kbsm;               /* Known button state mask */
                     71:        int startx;
                     72:        int starty;
                     73:        int endx;
                     74:        int endy;
                     75:        void *nextevent;
                     76: };
                     77: 
                     78: struct mouse_state {
                     79:        int     buttonstate;                    /* Current state of all buttons - bitmap */
                     80:        int     knownbuttonstatemask;   /* Mask of buttons that have done something since
                     81:                                                                 * We started watching... the rest are actually in
                     82:                                                                 * an unknown state */
                     83:        int     button_state[3];                /* Expanded state of each button */
                     84:        int     button_x[3];                    /* Start X/Y position of the current state */
                     85:        int     button_y[3];
                     86:        clock_t timeout[3];     /* Button event timeouts (timespecs ie: time of expiry) */
                     87:        int     curx;                                   /* Current X position */
                     88:        int     cury;                                   /* Current Y position */
                     89:        int     events;                                 /* Currently enabled events */
                     90:        int     click_timeout;                  /* Timeout between press and release events for a click (ms) */
                     91:        int     multi_timeout;                  /* Timeout after a click for detection of multi clicks (ms) */
                     92:        int     click_drift;                    /* Allowed "drift" during a click event */
                     93:        link_list_t     input;
                     94:        link_list_t     output;
                     95: };
                     96: 
                     97: struct mouse_state state;
                     98: int mouse_events=0;
                     99: int ciolib_mouse_initialized=0;
1.1.1.2 ! root      100: static int ungot=0;
        !           101: pthread_mutex_t unget_mutex;
1.1       root      102: 
                    103: void init_mouse(void)
                    104: {
                    105:        memset(&state,0,sizeof(state));
                    106:        state.click_timeout=0;
                    107:        state.multi_timeout=300;
                    108:        listInit(&state.input,LINK_LIST_SEMAPHORE|LINK_LIST_MUTEX);
                    109:        listInit(&state.output,LINK_LIST_SEMAPHORE|LINK_LIST_MUTEX);
1.1.1.2 ! root      110:        pthread_mutex_init(&unget_mutex, NULL);
1.1       root      111:        ciolib_mouse_initialized=1;
                    112: }
                    113: 
                    114: int ciomouse_setevents(int events)
                    115: {
                    116:        mouse_events=events;
                    117:        return mouse_events;
                    118: }
                    119: 
                    120: int ciomouse_addevents(int events)
                    121: {
                    122:        mouse_events |= events;
                    123:        return mouse_events;
                    124: }
                    125: 
                    126: int ciomouse_delevents(int events)
                    127: {
                    128:        mouse_events &= ~events;
                    129:        return mouse_events;
                    130: }
                    131: 
                    132: int ciomouse_addevent(int event)
                    133: {
                    134:        mouse_events |= (1<<event);
                    135:        return mouse_events;
                    136: }
                    137: 
                    138: int ciomouse_delevent(int event)
                    139: {
                    140:        mouse_events &= ~(1<<event);
                    141:        return mouse_events;
                    142: }
                    143: 
                    144: void ciomouse_gotevent(int event, int x, int y)
                    145: {
                    146:        struct in_mouse_event *ime;
                    147: 
                    148:        while(!ciolib_mouse_initialized)
                    149:                SLEEP(1);
                    150:        ime=(struct in_mouse_event *)malloc(sizeof(struct in_mouse_event));
                    151:        ime->ts=MSEC_CLOCK();
                    152:        ime->event=event;
                    153:        ime->x=x;
                    154:        ime->y=y;
                    155:        ime->nextevent=NULL;
                    156: 
                    157:        listPushNode(&state.input,ime);
                    158: }
                    159: 
                    160: void add_outevent(int event, int x, int y)
                    161: {
                    162:        struct out_mouse_event *ome;
                    163:        int     but;
                    164: 
                    165:        if(!(mouse_events & 1<<event))
                    166:                return;
                    167:        ome=(struct out_mouse_event *)malloc(sizeof(struct out_mouse_event));
                    168: 
                    169:        but=CIOLIB_BUTTON_NUMBER(event);
                    170:        ome->event=event;
                    171:        ome->bstate=state.buttonstate;
                    172:        ome->kbsm=state.knownbuttonstatemask;
                    173:        ome->startx=but?state.button_x[but-1]:state.curx;
                    174:        ome->starty=but?state.button_y[but-1]:state.cury;
                    175:        ome->endx=x;
                    176:        ome->endy=y;
                    177:        ome->nextevent=(struct out_mouse_event *)NULL;
                    178: 
                    179:        listPushNode(&state.output,ome);
                    180: }
                    181: 
                    182: int more_multies(int button, int clicks)
                    183: {
                    184:        switch(clicks) {
                    185:                case 0:
                    186:                        if(mouse_events & (1<<CIOLIB_BUTTON_CLICK(button)))
                    187:                                return(1);
                    188:                case 1:
                    189:                        if(mouse_events & (1<<CIOLIB_BUTTON_DBL_CLICK(button)))
                    190:                                return(1);
                    191:                case 2:
                    192:                        if(mouse_events & (1<<CIOLIB_BUTTON_TRPL_CLICK(button)))
                    193:                                return(1);
                    194:                case 3:
                    195:                        if(mouse_events & (1<<CIOLIB_BUTTON_QUAD_CLICK(button)))
                    196:                                return(1);
                    197:        }
                    198:        return(0);
                    199: }
                    200: 
                    201: void ciolib_mouse_thread(void *data)
                    202: {
                    203:        int     timedout;
                    204:        int timeout_button=0;
                    205:        int but;
                    206:        int delay;
                    207:        clock_t ttime=0;
                    208: 
                    209:        init_mouse();
                    210:        while(1) {
                    211:                timedout=0;
                    212:                if(timeout_button) {
                    213:                        delay=state.timeout[timeout_button-1]-MSEC_CLOCK();
                    214:                        if(delay<=0) {
                    215:                                timedout=1;
                    216:                        }
                    217:                        else {
                    218:                                timedout=!listSemTryWaitBlock(&state.input,delay);
                    219:                        }
                    220:                }
                    221:                else {
                    222:                        listSemWait(&state.input);
                    223:                }
                    224:                if(timedout) {
                    225:                        state.timeout[timeout_button-1]=0;
                    226:                        switch(state.button_state[timeout_button-1]) {
                    227:                                case MOUSE_SINGLEPRESSED:
                    228:                                        /* Press event */
                    229:                                        add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    230:                                        break;
                    231:                                case MOUSE_CLICKED:
                    232:                                        /* Click Event */
                    233:                                        add_outevent(CIOLIB_BUTTON_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    234:                                        break;
                    235:                                case MOUSE_DOUBLEPRESSED:
                    236:                                        /* Click event, then press event */
                    237:                                        add_outevent(CIOLIB_BUTTON_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    238:                                        add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    239:                                        break;
                    240:                                case MOUSE_DOUBLECLICKED:
                    241:                                        /* Double-click event */
                    242:                                        add_outevent(CIOLIB_BUTTON_DBL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    243:                                        break;
                    244:                                case MOUSE_TRIPLEPRESSED:
                    245:                                        /* Double-click event, then press event */
                    246:                                        add_outevent(CIOLIB_BUTTON_DBL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    247:                                        add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    248:                                        break;
                    249:                                case MOUSE_TRIPLECLICKED:
                    250:                                        /* Triple-click event */
                    251:                                        add_outevent(CIOLIB_BUTTON_TRPL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    252:                                        break;
                    253:                                case MOUSE_QUADPRESSED:
                    254:                                        /* Triple-click evetn then press event */
                    255:                                        add_outevent(CIOLIB_BUTTON_TRPL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    256:                                        add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    257:                                        break;
                    258:                                case MOUSE_QUADCLICKED:
                    259:                                        add_outevent(CIOLIB_BUTTON_QUAD_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    260:                                        /* Quad click event (This doesn't need a timeout does it? */
                    261:                                        break;
                    262:                        }
                    263:                        state.button_state[timeout_button-1]=MOUSE_NOSTATE;
                    264:                }
                    265:                else {
                    266:                        struct in_mouse_event *in;
                    267: 
                    268:                        in=listShiftNode(&state.input);
                    269:                        if(in==NULL) {
                    270:                                YIELD();
                    271:                                continue;
                    272:                        }
                    273:                        but=CIOLIB_BUTTON_NUMBER(in->event);
                    274:                        switch(CIOLIB_BUTTON_BASE(in->event)) {
                    275:                                case CIOLIB_MOUSE_MOVE:
                    276:                                        if(in->x==state.curx
                    277:                                                        && in->y==state.cury)
                    278:                                                break;
                    279:                                        add_outevent(CIOLIB_MOUSE_MOVE,in->x,in->y);
                    280:                                        for(but=1;but<=3;but++) {
                    281:                                                switch(state.button_state[but-1]) {
                    282:                                                        case MOUSE_NOSTATE:
                    283:                                                                if(state.buttonstate & CIOLIB_BUTTON(but)) {
                    284:                                                                        add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    285:                                                                        add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    286:                                                                        state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    287:                                                                }
                    288:                                                                break;
                    289:                                                        case MOUSE_SINGLEPRESSED:
                    290:                                                                add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    291:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    292:                                                                state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    293:                                                                break;
                    294:                                                        case MOUSE_CLICKED:
                    295:                                                                add_outevent(CIOLIB_BUTTON_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    296:                                                                state.button_state[but-1]=MOUSE_NOSTATE;
                    297:                                                                break;
                    298:                                                        case MOUSE_DOUBLEPRESSED:
                    299:                                                                add_outevent(CIOLIB_BUTTON_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    300:                                                                add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    301:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    302:                                                                state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    303:                                                                break;
                    304:                                                        case MOUSE_DOUBLECLICKED:
                    305:                                                                add_outevent(CIOLIB_BUTTON_DBL_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    306:                                                                state.button_state[but-1]=MOUSE_NOSTATE;
                    307:                                                                break;
                    308:                                                        case MOUSE_TRIPLEPRESSED:
                    309:                                                                add_outevent(CIOLIB_BUTTON_DBL_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    310:                                                                add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    311:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    312:                                                                state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    313:                                                                break;
                    314:                                                        case MOUSE_TRIPLECLICKED:
                    315:                                                                add_outevent(CIOLIB_BUTTON_TRPL_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    316:                                                                state.button_state[but-1]=MOUSE_NOSTATE;
                    317:                                                                break;
                    318:                                                        case MOUSE_QUADPRESSED:
                    319:                                                                add_outevent(CIOLIB_BUTTON_TRPL_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    320:                                                                add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    321:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    322:                                                                state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    323:                                                                break;
                    324:                                                        case MOUSE_DRAGSTARTED:
                    325:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    326:                                                                break;
                    327:                                                }
                    328:                                        }
                    329:                                        break;
                    330:                                case CIOLIB_BUTTON_1_PRESS:
                    331:                                        state.buttonstate|=1<<(but-1);
                    332:                                        state.knownbuttonstatemask|=1<<(but-1);
                    333:                                        switch(state.button_state[but-1]) {
                    334:                                                case MOUSE_NOSTATE:
                    335:                                                        state.button_state[but-1]=MOUSE_SINGLEPRESSED;
                    336:                                                        state.button_x[but-1]=in->x;
                    337:                                                        state.button_y[but-1]=in->y;
                    338:                                                        state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout;
                    339:                                                        if(state.timeout[but-1]==0)
                    340:                                                                state.timeout[but-1]=1;
                    341:                                                        if(state.click_timeout==0)
                    342:                                                                state.timeout[but-1]=0;
                    343:                                                        if(!more_multies(but,0)) {
                    344:                                                                add_outevent(CIOLIB_BUTTON_PRESS(but),state.button_x[but-1],state.button_y[but-1]);
                    345:                                                                state.button_state[but-1]=MOUSE_NOSTATE;
                    346:                                                                state.timeout[but-1]=0;
                    347:                                                        }
                    348:                                                        break;
                    349:                                                case MOUSE_CLICKED:
                    350:                                                        state.button_state[but-1]=MOUSE_DOUBLEPRESSED;
                    351:                                                        state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout;
                    352:                                                        if(state.timeout[but-1]==0)
                    353:                                                                state.timeout[but-1]=1;
                    354:                                                        if(state.click_timeout==0)
                    355:                                                                state.timeout[but-1]=0;
                    356:                                                        break;
                    357:                                                case MOUSE_DOUBLECLICKED:
                    358:                                                        state.button_state[but-1]=MOUSE_TRIPLEPRESSED;
                    359:                                                        state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout;
                    360:                                                        if(state.timeout[but-1]==0)
                    361:                                                                state.timeout[but-1]=1;
                    362:                                                        if(state.click_timeout==0)
                    363:                                                                state.timeout[but-1]=0;
                    364:                                                        break;
                    365:                                                case MOUSE_TRIPLECLICKED:
                    366:                                                        state.button_state[but-1]=MOUSE_QUADPRESSED;
                    367:                                                        state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout;
                    368:                                                        if(state.timeout[but-1]==0)
                    369:                                                                state.timeout[but-1]=1;
                    370:                                                        if(state.click_timeout==0)
                    371:                                                                state.timeout[but-1]=0;
                    372:                                                        break;
                    373:                                        }
                    374:                                        break;
                    375:                                case CIOLIB_BUTTON_1_RELEASE:
                    376:                                        state.buttonstate&= ~(1<<(but-1));
                    377:                                        state.knownbuttonstatemask|=1<<(but-1);
                    378:                                        switch(state.button_state[but-1]) {
                    379:                                                case MOUSE_NOSTATE:
                    380:                                                        state.button_x[but-1]=in->x;
                    381:                                                        state.button_y[but-1]=in->y;
                    382:                                                        add_outevent(CIOLIB_BUTTON_RELEASE(but),state.button_x[but-1],state.button_y[but-1]);
                    383:                                                        break;
                    384:                                                case MOUSE_SINGLEPRESSED:
                    385:                                                        state.button_state[but-1]=MOUSE_CLICKED;
                    386:                                                        state.timeout[but-1]=more_multies(but,1)?MSEC_CLOCK()+state.multi_timeout:MSEC_CLOCK();
                    387:                                                        if(state.timeout[but-1]==0)
                    388:                                                                state.timeout[but-1]=1;
                    389:                                                        break;
                    390:                                                case MOUSE_DOUBLEPRESSED:
                    391:                                                        state.button_state[but-1]=MOUSE_DOUBLECLICKED;
                    392:                                                        state.timeout[but-1]=more_multies(but,2)?MSEC_CLOCK()+state.multi_timeout:MSEC_CLOCK();
                    393:                                                        if(state.timeout[but-1]==0)
                    394:                                                                state.timeout[but-1]=1;
                    395:                                                        break;
                    396:                                                case MOUSE_TRIPLEPRESSED:
                    397:                                                        state.button_state[but-1]=MOUSE_TRIPLECLICKED;
                    398:                                                        state.timeout[but-1]=more_multies(but,3)?MSEC_CLOCK()+state.multi_timeout:MSEC_CLOCK();
                    399:                                                        if(state.timeout[but-1]==0)
                    400:                                                                state.timeout[but-1]=1;
                    401:                                                        break;
                    402:                                                case MOUSE_QUADPRESSED:
                    403:                                                        state.button_state[but-1]=MOUSE_NOSTATE;
                    404:                                                        add_outevent(CIOLIB_BUTTON_QUAD_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    405:                                                        state.timeout[but-1]=0;
                    406:                                                        if(state.timeout[but-1]==0)
                    407:                                                                state.timeout[but-1]=1;
                    408:                                                        break;
                    409:                                                case MOUSE_DRAGSTARTED:
                    410:                                                        add_outevent(CIOLIB_BUTTON_DRAG_END(but),in->x,in->y);
                    411:                                                        state.button_state[but-1]=0;
                    412:                                        }
                    413:                        }
                    414:                        state.curx=in->x;
                    415:                        state.cury=in->y;
                    416: 
                    417:                        free(in);
                    418:                }
                    419: 
                    420:                timeout_button=0;
                    421:                for(but=1;but<=3;but++) {
                    422:                        if(state.button_state[but-1]!=MOUSE_NOSTATE 
                    423:                                        && state.button_state[but-1]!=MOUSE_DRAGSTARTED 
                    424:                                        && state.timeout[but-1]!=0
                    425:                                        && (timeout_button==0 || state.timeout[but-1]<ttime)) {
                    426:                                ttime=state.timeout[but-1];
                    427:                                timeout_button=but;
                    428:                        }
                    429:                }
                    430:        }
                    431: }
                    432: 
                    433: int mouse_trywait(void)
                    434: {
1.1.1.2 ! root      435:        int     result;
        !           436: 
1.1       root      437:        while(!ciolib_mouse_initialized)
                    438:                SLEEP(1);
1.1.1.2 ! root      439:        while(1) {
        !           440:                result=listSemTryWait(&state.output);
        !           441:                pthread_mutex_lock(&unget_mutex);
        !           442:                if(ungot==0) {
        !           443:                        pthread_mutex_unlock(&unget_mutex);
        !           444:                        return(result);
        !           445:                }
        !           446:                ungot--;
        !           447:                pthread_mutex_unlock(&unget_mutex);
        !           448:        }
1.1       root      449: }
                    450: 
                    451: int mouse_wait(void)
                    452: {
1.1.1.2 ! root      453:        int result;
        !           454: 
1.1       root      455:        while(!ciolib_mouse_initialized)
                    456:                SLEEP(1);
1.1.1.2 ! root      457:        while(1) {
        !           458:                result=listSemWait(&state.output);
        !           459:                pthread_mutex_lock(&unget_mutex);
        !           460:                if(ungot==0) {
        !           461:                        pthread_mutex_unlock(&unget_mutex);
        !           462:                        return(result);
        !           463:                }
        !           464:                ungot--;
        !           465:                pthread_mutex_unlock(&unget_mutex);
        !           466:        }
1.1       root      467: }
                    468: 
                    469: int mouse_pending(void)
                    470: {
                    471:        while(!ciolib_mouse_initialized)
                    472:                SLEEP(1);
                    473:        return(listCountNodes(&state.output));
                    474: }
                    475: 
                    476: int ciolib_getmouse(struct mouse_event *mevent)
                    477: {
                    478:        int retval=0;
                    479: 
                    480:        while(!ciolib_mouse_initialized)
                    481:                SLEEP(1);
                    482:        if(listCountNodes(&state.output)) {
                    483:                struct out_mouse_event *out;
                    484:                out=listShiftNode(&state.output);
                    485:                if(out==NULL)
                    486:                        return(-1);
                    487:                mevent->event=out->event;
                    488:                mevent->bstate=out->bstate;
                    489:                mevent->kbsm=out->kbsm;
                    490:                mevent->startx=out->startx;
                    491:                mevent->starty=out->starty;
                    492:                mevent->endx=out->endx;
                    493:                mevent->endy=out->endy;
                    494:                free(out);
                    495:        }
                    496:        else {
1.1.1.2 ! root      497:                fprintf(stderr,"WARNING: attempt to get a mouse key when none pending!\n");
1.1       root      498:                memset(mevent,0,sizeof(struct mouse_event));
                    499:                retval=-1;
                    500:        }
                    501:        return(retval);
                    502: }
                    503: 
                    504: int ciolib_ungetmouse(struct mouse_event *mevent)
                    505: {
                    506:        struct mouse_event *me;
                    507: 
                    508:        if((me=(struct mouse_event *)malloc(sizeof(struct mouse_event)))==NULL)
                    509:                return(-1);
                    510:        memcpy(me,mevent,sizeof(struct mouse_event));
1.1.1.2 ! root      511:        pthread_mutex_lock(&unget_mutex);
        !           512:        if(listInsertNode(&state.output,me)==NULL) {
        !           513:                pthread_mutex_unlock(&unget_mutex);
        !           514:                return(FALSE);
        !           515:        }
        !           516:        ungot++;
        !           517:        pthread_mutex_unlock(&unget_mutex);
        !           518:        return(TRUE);
1.1       root      519: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.