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

1.1       root        1: /* $Id: mouse.c,v 1.35 2006/05/29 14:30:37 deuce Exp $ */
                      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;
                    100: 
                    101: void init_mouse(void)
                    102: {
                    103:        memset(&state,0,sizeof(state));
                    104:        state.click_timeout=0;
                    105:        state.multi_timeout=300;
                    106:        listInit(&state.input,LINK_LIST_SEMAPHORE|LINK_LIST_MUTEX);
                    107:        listInit(&state.output,LINK_LIST_SEMAPHORE|LINK_LIST_MUTEX);
                    108:        ciolib_mouse_initialized=1;
                    109: }
                    110: 
                    111: int ciomouse_setevents(int events)
                    112: {
                    113:        mouse_events=events;
                    114:        return mouse_events;
                    115: }
                    116: 
                    117: int ciomouse_addevents(int events)
                    118: {
                    119:        mouse_events |= events;
                    120:        return mouse_events;
                    121: }
                    122: 
                    123: int ciomouse_delevents(int events)
                    124: {
                    125:        mouse_events &= ~events;
                    126:        return mouse_events;
                    127: }
                    128: 
                    129: int ciomouse_addevent(int event)
                    130: {
                    131:        mouse_events |= (1<<event);
                    132:        return mouse_events;
                    133: }
                    134: 
                    135: int ciomouse_delevent(int event)
                    136: {
                    137:        mouse_events &= ~(1<<event);
                    138:        return mouse_events;
                    139: }
                    140: 
                    141: void ciomouse_gotevent(int event, int x, int y)
                    142: {
                    143:        struct in_mouse_event *ime;
                    144: 
                    145:        while(!ciolib_mouse_initialized)
                    146:                SLEEP(1);
                    147:        ime=(struct in_mouse_event *)malloc(sizeof(struct in_mouse_event));
                    148:        ime->ts=MSEC_CLOCK();
                    149:        ime->event=event;
                    150:        ime->x=x;
                    151:        ime->y=y;
                    152:        ime->nextevent=NULL;
                    153: 
                    154:        listPushNode(&state.input,ime);
                    155: }
                    156: 
                    157: void add_outevent(int event, int x, int y)
                    158: {
                    159:        struct out_mouse_event *ome;
                    160:        int     but;
                    161: 
                    162:        if(!(mouse_events & 1<<event))
                    163:                return;
                    164:        ome=(struct out_mouse_event *)malloc(sizeof(struct out_mouse_event));
                    165: 
                    166:        but=CIOLIB_BUTTON_NUMBER(event);
                    167:        ome->event=event;
                    168:        ome->bstate=state.buttonstate;
                    169:        ome->kbsm=state.knownbuttonstatemask;
                    170:        ome->startx=but?state.button_x[but-1]:state.curx;
                    171:        ome->starty=but?state.button_y[but-1]:state.cury;
                    172:        ome->endx=x;
                    173:        ome->endy=y;
                    174:        ome->nextevent=(struct out_mouse_event *)NULL;
                    175: 
                    176:        listPushNode(&state.output,ome);
                    177: }
                    178: 
                    179: int more_multies(int button, int clicks)
                    180: {
                    181:        switch(clicks) {
                    182:                case 0:
                    183:                        if(mouse_events & (1<<CIOLIB_BUTTON_CLICK(button)))
                    184:                                return(1);
                    185:                case 1:
                    186:                        if(mouse_events & (1<<CIOLIB_BUTTON_DBL_CLICK(button)))
                    187:                                return(1);
                    188:                case 2:
                    189:                        if(mouse_events & (1<<CIOLIB_BUTTON_TRPL_CLICK(button)))
                    190:                                return(1);
                    191:                case 3:
                    192:                        if(mouse_events & (1<<CIOLIB_BUTTON_QUAD_CLICK(button)))
                    193:                                return(1);
                    194:        }
                    195:        return(0);
                    196: }
                    197: 
                    198: void ciolib_mouse_thread(void *data)
                    199: {
                    200:        int     timedout;
                    201:        int timeout_button=0;
                    202:        int but;
                    203:        int delay;
                    204:        clock_t ttime=0;
                    205: 
                    206:        init_mouse();
                    207:        while(1) {
                    208:                timedout=0;
                    209:                if(timeout_button) {
                    210:                        delay=state.timeout[timeout_button-1]-MSEC_CLOCK();
                    211:                        if(delay<=0) {
                    212:                                timedout=1;
                    213:                        }
                    214:                        else {
                    215:                                timedout=!listSemTryWaitBlock(&state.input,delay);
                    216:                        }
                    217:                }
                    218:                else {
                    219:                        listSemWait(&state.input);
                    220:                }
                    221:                if(timedout) {
                    222:                        state.timeout[timeout_button-1]=0;
                    223:                        switch(state.button_state[timeout_button-1]) {
                    224:                                case MOUSE_SINGLEPRESSED:
                    225:                                        /* Press event */
                    226:                                        add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    227:                                        break;
                    228:                                case MOUSE_CLICKED:
                    229:                                        /* Click Event */
                    230:                                        add_outevent(CIOLIB_BUTTON_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    231:                                        break;
                    232:                                case MOUSE_DOUBLEPRESSED:
                    233:                                        /* Click event, then press event */
                    234:                                        add_outevent(CIOLIB_BUTTON_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    235:                                        add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    236:                                        break;
                    237:                                case MOUSE_DOUBLECLICKED:
                    238:                                        /* Double-click event */
                    239:                                        add_outevent(CIOLIB_BUTTON_DBL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    240:                                        break;
                    241:                                case MOUSE_TRIPLEPRESSED:
                    242:                                        /* Double-click event, then press event */
                    243:                                        add_outevent(CIOLIB_BUTTON_DBL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    244:                                        add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    245:                                        break;
                    246:                                case MOUSE_TRIPLECLICKED:
                    247:                                        /* Triple-click event */
                    248:                                        add_outevent(CIOLIB_BUTTON_TRPL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    249:                                        break;
                    250:                                case MOUSE_QUADPRESSED:
                    251:                                        /* Triple-click evetn then press event */
                    252:                                        add_outevent(CIOLIB_BUTTON_TRPL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    253:                                        add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    254:                                        break;
                    255:                                case MOUSE_QUADCLICKED:
                    256:                                        add_outevent(CIOLIB_BUTTON_QUAD_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]);
                    257:                                        /* Quad click event (This doesn't need a timeout does it? */
                    258:                                        break;
                    259:                        }
                    260:                        state.button_state[timeout_button-1]=MOUSE_NOSTATE;
                    261:                }
                    262:                else {
                    263:                        struct in_mouse_event *in;
                    264: 
                    265:                        in=listShiftNode(&state.input);
                    266:                        if(in==NULL) {
                    267:                                YIELD();
                    268:                                continue;
                    269:                        }
                    270:                        but=CIOLIB_BUTTON_NUMBER(in->event);
                    271:                        switch(CIOLIB_BUTTON_BASE(in->event)) {
                    272:                                case CIOLIB_MOUSE_MOVE:
                    273:                                        if(in->x==state.curx
                    274:                                                        && in->y==state.cury)
                    275:                                                break;
                    276:                                        add_outevent(CIOLIB_MOUSE_MOVE,in->x,in->y);
                    277:                                        for(but=1;but<=3;but++) {
                    278:                                                switch(state.button_state[but-1]) {
                    279:                                                        case MOUSE_NOSTATE:
                    280:                                                                if(state.buttonstate & CIOLIB_BUTTON(but)) {
                    281:                                                                        add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    282:                                                                        add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    283:                                                                        state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    284:                                                                }
                    285:                                                                break;
                    286:                                                        case MOUSE_SINGLEPRESSED:
                    287:                                                                add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    288:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    289:                                                                state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    290:                                                                break;
                    291:                                                        case MOUSE_CLICKED:
                    292:                                                                add_outevent(CIOLIB_BUTTON_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    293:                                                                state.button_state[but-1]=MOUSE_NOSTATE;
                    294:                                                                break;
                    295:                                                        case MOUSE_DOUBLEPRESSED:
                    296:                                                                add_outevent(CIOLIB_BUTTON_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    297:                                                                add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    298:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    299:                                                                state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    300:                                                                break;
                    301:                                                        case MOUSE_DOUBLECLICKED:
                    302:                                                                add_outevent(CIOLIB_BUTTON_DBL_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    303:                                                                state.button_state[but-1]=MOUSE_NOSTATE;
                    304:                                                                break;
                    305:                                                        case MOUSE_TRIPLEPRESSED:
                    306:                                                                add_outevent(CIOLIB_BUTTON_DBL_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    307:                                                                add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    308:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    309:                                                                state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    310:                                                                break;
                    311:                                                        case MOUSE_TRIPLECLICKED:
                    312:                                                                add_outevent(CIOLIB_BUTTON_TRPL_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    313:                                                                state.button_state[but-1]=MOUSE_NOSTATE;
                    314:                                                                break;
                    315:                                                        case MOUSE_QUADPRESSED:
                    316:                                                                add_outevent(CIOLIB_BUTTON_TRPL_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    317:                                                                add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]);
                    318:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    319:                                                                state.button_state[but-1]=MOUSE_DRAGSTARTED;
                    320:                                                                break;
                    321:                                                        case MOUSE_DRAGSTARTED:
                    322:                                                                add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y);
                    323:                                                                break;
                    324:                                                }
                    325:                                        }
                    326:                                        break;
                    327:                                case CIOLIB_BUTTON_1_PRESS:
                    328:                                        state.buttonstate|=1<<(but-1);
                    329:                                        state.knownbuttonstatemask|=1<<(but-1);
                    330:                                        switch(state.button_state[but-1]) {
                    331:                                                case MOUSE_NOSTATE:
                    332:                                                        state.button_state[but-1]=MOUSE_SINGLEPRESSED;
                    333:                                                        state.button_x[but-1]=in->x;
                    334:                                                        state.button_y[but-1]=in->y;
                    335:                                                        state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout;
                    336:                                                        if(state.timeout[but-1]==0)
                    337:                                                                state.timeout[but-1]=1;
                    338:                                                        if(state.click_timeout==0)
                    339:                                                                state.timeout[but-1]=0;
                    340:                                                        if(!more_multies(but,0)) {
                    341:                                                                add_outevent(CIOLIB_BUTTON_PRESS(but),state.button_x[but-1],state.button_y[but-1]);
                    342:                                                                state.button_state[but-1]=MOUSE_NOSTATE;
                    343:                                                                state.timeout[but-1]=0;
                    344:                                                        }
                    345:                                                        break;
                    346:                                                case MOUSE_CLICKED:
                    347:                                                        state.button_state[but-1]=MOUSE_DOUBLEPRESSED;
                    348:                                                        state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout;
                    349:                                                        if(state.timeout[but-1]==0)
                    350:                                                                state.timeout[but-1]=1;
                    351:                                                        if(state.click_timeout==0)
                    352:                                                                state.timeout[but-1]=0;
                    353:                                                        break;
                    354:                                                case MOUSE_DOUBLECLICKED:
                    355:                                                        state.button_state[but-1]=MOUSE_TRIPLEPRESSED;
                    356:                                                        state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout;
                    357:                                                        if(state.timeout[but-1]==0)
                    358:                                                                state.timeout[but-1]=1;
                    359:                                                        if(state.click_timeout==0)
                    360:                                                                state.timeout[but-1]=0;
                    361:                                                        break;
                    362:                                                case MOUSE_TRIPLECLICKED:
                    363:                                                        state.button_state[but-1]=MOUSE_QUADPRESSED;
                    364:                                                        state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout;
                    365:                                                        if(state.timeout[but-1]==0)
                    366:                                                                state.timeout[but-1]=1;
                    367:                                                        if(state.click_timeout==0)
                    368:                                                                state.timeout[but-1]=0;
                    369:                                                        break;
                    370:                                        }
                    371:                                        break;
                    372:                                case CIOLIB_BUTTON_1_RELEASE:
                    373:                                        state.buttonstate&= ~(1<<(but-1));
                    374:                                        state.knownbuttonstatemask|=1<<(but-1);
                    375:                                        switch(state.button_state[but-1]) {
                    376:                                                case MOUSE_NOSTATE:
                    377:                                                        state.button_x[but-1]=in->x;
                    378:                                                        state.button_y[but-1]=in->y;
                    379:                                                        add_outevent(CIOLIB_BUTTON_RELEASE(but),state.button_x[but-1],state.button_y[but-1]);
                    380:                                                        break;
                    381:                                                case MOUSE_SINGLEPRESSED:
                    382:                                                        state.button_state[but-1]=MOUSE_CLICKED;
                    383:                                                        state.timeout[but-1]=more_multies(but,1)?MSEC_CLOCK()+state.multi_timeout:MSEC_CLOCK();
                    384:                                                        if(state.timeout[but-1]==0)
                    385:                                                                state.timeout[but-1]=1;
                    386:                                                        break;
                    387:                                                case MOUSE_DOUBLEPRESSED:
                    388:                                                        state.button_state[but-1]=MOUSE_DOUBLECLICKED;
                    389:                                                        state.timeout[but-1]=more_multies(but,2)?MSEC_CLOCK()+state.multi_timeout:MSEC_CLOCK();
                    390:                                                        if(state.timeout[but-1]==0)
                    391:                                                                state.timeout[but-1]=1;
                    392:                                                        break;
                    393:                                                case MOUSE_TRIPLEPRESSED:
                    394:                                                        state.button_state[but-1]=MOUSE_TRIPLECLICKED;
                    395:                                                        state.timeout[but-1]=more_multies(but,3)?MSEC_CLOCK()+state.multi_timeout:MSEC_CLOCK();
                    396:                                                        if(state.timeout[but-1]==0)
                    397:                                                                state.timeout[but-1]=1;
                    398:                                                        break;
                    399:                                                case MOUSE_QUADPRESSED:
                    400:                                                        state.button_state[but-1]=MOUSE_NOSTATE;
                    401:                                                        add_outevent(CIOLIB_BUTTON_QUAD_CLICK(but),state.button_x[but-1],state.button_y[but-1]);
                    402:                                                        state.timeout[but-1]=0;
                    403:                                                        if(state.timeout[but-1]==0)
                    404:                                                                state.timeout[but-1]=1;
                    405:                                                        break;
                    406:                                                case MOUSE_DRAGSTARTED:
                    407:                                                        add_outevent(CIOLIB_BUTTON_DRAG_END(but),in->x,in->y);
                    408:                                                        state.button_state[but-1]=0;
                    409:                                        }
                    410:                        }
                    411:                        state.curx=in->x;
                    412:                        state.cury=in->y;
                    413: 
                    414:                        free(in);
                    415:                }
                    416: 
                    417:                timeout_button=0;
                    418:                for(but=1;but<=3;but++) {
                    419:                        if(state.button_state[but-1]!=MOUSE_NOSTATE 
                    420:                                        && state.button_state[but-1]!=MOUSE_DRAGSTARTED 
                    421:                                        && state.timeout[but-1]!=0
                    422:                                        && (timeout_button==0 || state.timeout[but-1]<ttime)) {
                    423:                                ttime=state.timeout[but-1];
                    424:                                timeout_button=but;
                    425:                        }
                    426:                }
                    427:        }
                    428: }
                    429: 
                    430: int mouse_trywait(void)
                    431: {
                    432:        while(!ciolib_mouse_initialized)
                    433:                SLEEP(1);
                    434:        return(listSemTryWait(&state.output));
                    435: }
                    436: 
                    437: int mouse_wait(void)
                    438: {
                    439:        while(!ciolib_mouse_initialized)
                    440:                SLEEP(1);
                    441:        return(listSemWait(&state.output));
                    442: }
                    443: 
                    444: int mouse_pending(void)
                    445: {
                    446:        while(!ciolib_mouse_initialized)
                    447:                SLEEP(1);
                    448:        return(listCountNodes(&state.output));
                    449: }
                    450: 
                    451: int ciolib_getmouse(struct mouse_event *mevent)
                    452: {
                    453:        int retval=0;
                    454: 
                    455:        while(!ciolib_mouse_initialized)
                    456:                SLEEP(1);
                    457:        if(listCountNodes(&state.output)) {
                    458:                struct out_mouse_event *out;
                    459:                out=listShiftNode(&state.output);
                    460:                if(out==NULL)
                    461:                        return(-1);
                    462:                mevent->event=out->event;
                    463:                mevent->bstate=out->bstate;
                    464:                mevent->kbsm=out->kbsm;
                    465:                mevent->startx=out->startx;
                    466:                mevent->starty=out->starty;
                    467:                mevent->endx=out->endx;
                    468:                mevent->endy=out->endy;
                    469:                free(out);
                    470:        }
                    471:        else {
                    472:                memset(mevent,0,sizeof(struct mouse_event));
                    473:                retval=-1;
                    474:        }
                    475:        return(retval);
                    476: }
                    477: 
                    478: int ciolib_ungetmouse(struct mouse_event *mevent)
                    479: {
                    480:        struct mouse_event *me;
                    481: 
                    482:        if((me=(struct mouse_event *)malloc(sizeof(struct mouse_event)))==NULL)
                    483:                return(-1);
                    484:        memcpy(me,mevent,sizeof(struct mouse_event));
                    485:        return(listInsertNode(&state.output,me)==NULL);
                    486: }

unix.superglobalmegacorp.com

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