Annotation of Amaya/amaya/AHTBridge.c, revision 1.1.1.1

1.1       cvs         1: /*                                                                  AHTBridge.c
                      2:  *      INTERFACE BRIDGE TO XT, LIBWWW, and AMAYA
                      3:  *
                      4:  *      (c) COPYRIGHT 
                      5:  *      Please first read the full copyright statement in the file COPYRIGH.
                      6:  *
                      7:  *      This module implments the callback setup and handlers between
                      8:  *      the Xt, libwww, and Amaya procedures
                      9:  *
                     10:  * History:
                     11:  *      May 02 96 JK    First semi-stable version, Jose Kahan
                     12:  *      June 01 96 JK   First almost-complete version, Jose Kahan 
                     13: */
                     14: 
                     15: /* Unix/C/X */
                     16: #include "thot_gui.h"
                     17: #include "thot_sys.h"
                     18: #include "message.h"
                     19: #include "dialog.h"
                     20: #include "application.h"
                     21: #include "content.h"
                     22: #include "view.h"
                     23: #include "interface.h"
                     24: #include "amaya.h"
                     25: 
                     26: #if 0
                     27: #include "AHTCommon.h"
                     28: #include "query.h"
                     29: #endif
                     30: 
                     31: #include "AHTBridge.h"   /* implemented here */
                     32: 
                     33: #ifdef WWW_XWINDOWS
                     34: /* Amaya's X appcontext */
                     35: extern XtAppContext app_cont;
                     36: #endif
                     37: 
                     38: 
                     39: #ifndef HACK_WWW
                     40: extern PUBLIC HTEventCallback* HTEvent_Retrieve (SOCKET, SockOps, HTRequest** arp);
                     41: #endif
                     42: 
                     43: /*
                     44: ** Private functions
                     45: */
                     46: #ifdef __STDC__
                     47: static void RequestKillReadXtevent   (AHTReqContext*);
                     48: static void RequestKillWriteXtevent  (AHTReqContext*);
                     49: static void RequestKillExceptXtevent (AHTReqContext*);
                     50: #else
                     51: static void RequestKillReadXtevent   ();
                     52: static void RequestKillWriteXtevent  ();
                     53: static void RequestKillExceptXtevent ();
                     54: #endif /*__STDC__*/
                     55: 
                     56: /*
                     57:  * Private variables 
                     58:  */
                     59: 
                     60: /*
                     61:  * this set of SockOps map our WinSock "socket event SockOps" into 
                     62:  * our read and write sets. Note that under the canonical Unix model,
                     63:  * a non-blocking socket passed to an accept() call will appear as readable, 
                     64:  * whilst a non-blocking call to connect() will appear as writeable. In add.
                     65:  * if the connection has been closed, the socket will appear readable under
                     66:  * BSD Unix semantics 
                     67:  */
                     68: PRIVATE const SockOps ReadBits = FD_READ | FD_ACCEPT  | FD_CLOSE;
                     69: PRIVATE const SockOps WriteBits = FD_WRITE | FD_CONNECT ;
                     70: PRIVATE const SockOps ExceptBits = FD_OOB ;
                     71: 
                     72: /*
                     73:  * Private functions
                     74:  */
                     75: 
                     76: /*
                     77:  * Callback that acts as a bridge between X and wwwlib.
                     78:  * This function is equivalent to the library's __DoCallback()
                     79:  * function, but with a different API, to conform to Xt's event loop
                     80:  * specifications. For more info, cf. the library's HTEvntrg.c module.
                     81:  */
                     82: 
                     83: #ifdef WWW_XWINDOWS
                     84: #ifdef __STDC__
                     85: XtInputCallbackProc AHTCallback_bridge (caddr_t cd, int* s, XtInputId* id)
                     86: #else 
                     87: XtInputCallbackProc AHTCallback_bridge (cd, s, id)
                     88: caddr_t    cd ;
                     89: int*       s  ;
                     90: XtInputId* id ;
                     91: #endif /* __STDC__ */
                     92: 
                     93: #else /* WWW_XWINDOWS */
                     94: /* some winproc someday? */
                     95: LONG AHTCallback_bridge (caddr_t cd, int* s)
                     96: #endif /* !WWW_XWINDOWS */
                     97: {
                     98:     int            status;
                     99:     HTRequest*     rqp = NULL;
                    100:     AHTReqContext* me;
                    101:     SOCKET         sock;
                    102:     SockOps        ops; /* what value goes here ? Ask eric */
                    103: 
                    104:    /* Libwww 4.1 does not take into account the third parameter
                    105:       for this function call */
                    106: 
                    107: #ifdef HACK_WWW
                    108:     HTEventCallback* cbf;
                    109: #else
                    110:     HTEventCallback* cbf = (HTEventCallback*) __RetrieveCBF(*s, ops, &rqp);
                    111: #endif
                    112:     me = HTRequest_context (rqp);
                    113: 
                    114: #if 0
                    115:     switch ((XtInputId) cd) {
                    116:           case XtInputReadMask:
                    117:                ops = me->read_ops;
                    118:                if (me->read_xtinput_id) {
                    119:                   XtRemoveInput (me->read_xtinput_id);
                    120:                   if (THD_TRACE)
                    121:                      fprintf (stderr, "(BT) removing Xtinput %lu R (AHTBridge before cbf), sock %d\n", me->read_xtinput_id, *s);
                    122:                   me->read_xtinput_id = 0;
                    123:                 }
                    124:                break;
                    125:            case XtInputWriteMask:
                    126:                 ops = me->write_ops;
                    127:                 if (me->write_xtinput_id) {
                    128:                   XtRemoveInput(me->write_xtinput_id);
                    129:                    if (THD_TRACE)
                    130:                      fprintf (stderr, "(BT) removing Xtinput %lu W (AHTBridge before cbf), sock %d\n", me->write_xtinput_id, *s);
                    131:                    me->write_xtinput_id = 0;
                    132:                 }
                    133:                 break;
                    134:            case XtInputExceptMask:
                    135:                 ops = me->except_ops;
                    136:                 if (me->except_xtinput_id) {
                    137:                   XtRemoveInput (me->except_xtinput_id);
                    138:                    if (THD_TRACE)
                    139:                      fprintf(stderr, "(BT) removing Xtinput %lu E (AHTBridge before cbf), sock %d\n", me->except_xtinput_id, *s);
                    140:                     me->except_xtinput_id = 0;
                    141:                 }
                    142:                 break;
                    143:     } /* switch */
                    144: #endif
                    145: 
                    146:     if (THD_TRACE) 
                    147:       fprintf (stderr, "AHTBridge: Processing url %s \n", me->urlName);
                    148: 
                    149: 
                    150: #ifdef WWW_XWINDOWS
                    151:     switch ((XtInputId) cd) {
                    152:            case XtInputReadMask:
                    153:                ops = me->read_ops;
                    154:                ops = FD_READ;
                    155:                break;
                    156:            case XtInputWriteMask:
                    157:                ops = me->write_ops;
                    158:                ops = FD_WRITE;
                    159:                break;
                    160:            case XtInputExceptMask:
                    161:                 ops = me->except_ops;
                    162:                 ops = FD_OOB;
                    163:                break;
                    164:     } /* switch */
                    165: #endif WWW_XWINDOWS
                    166: 
                    167:     /* 
                    168:      * Liberate the input, so that when a pending socket is activated,
                    169:      * the socket status will be ... available 
                    170:      * 
                    171:      * verify if I can limit this to the unregister function 
                    172:      * does not look so
                    173:      *
                    174:      * although it makes no sense, callbacks can be null 
                    175:      */
                    176: 
                    177:     if (!cbf || !rqp || rqp->priority == HT_PRIORITY_OFF) {
                    178:        if (THD_TRACE)
                    179:            HTTrace("Callback.... No callback found\n");
                    180:        /* put some more code to correctly destroy this request */
                    181:        return (0);
                    182:     }
                    183: 
                    184:     me->reqStatus = HT_BUSY;
                    185: 
                    186:     if ((status = (*cbf) (*s, rqp, ops)) != HT_OK)
                    187:        HTTrace("Callback.... received != HT_OK");
                    188: 
                    189:     /* Several states can happen after this callback. They
                    190:      * are indicated by the me->reqStatus structure member and
                    191:      * the fds external variables. The following lines examine
                    192:      * the states and correspondly update the Xt event register
                    193:      *
                    194:      * Regarding the me->reqStatus member, we have the following
                    195:      * possible states:
                    196:      *   
                    197:      * HT_BUSY:    Request has blocked
                    198:      * HT_WAITING: Request has been reissued
                    199:      * HT_ABORT:   Request has been stopped
                    200:      * HT_END:     Request has ended
                    201:      */
                    202: 
                    203:     /* Has the request been stopped? 
                    204:      *
                    205:      * we verify if the request exists. If it has ended, me will have
                    206:      *  a reqStatus with an HT_END value */
                    207: 
                    208:     /* Was the stop button pressed? */
                    209: 
                    210:  #ifdef WWW_XWINDOWS
                    211:     if (me->reqStatus == HT_ABORT) {
                    212:        me->reqStatus = HT_WAITING;
                    213:        StopRequest (me->docid);
                    214:         if (THD_TRACE)
                    215:            fprintf(stderr, "(BF) removing Xtinput %lu !RWE (Stop buttonl), sock %d\n", me->read_xtinput_id, sock);
                    216:        return(0);
                    217:     }
                    218: #endif /* WWW_XWINDOWS */
                    219: 
                    220:     /* the request is being reissued */
                    221: 
                    222:     if (me->reqStatus == HT_WAITING) {
                    223:        /*
                    224:         * (1) The old request has ended and the library
                    225:         * assigned the old socket number to a pending
                    226:         * request.
                    227:         *
                    228:         * (2) The request has been reissued after an 
                    229:         * authentication or redirection directive and
                    230:         * we are using the same old socket number.
                    231:         */
                    232:       
                    233:         if (THD_TRACE)
                    234:           fprintf(stderr, "*** detected a reissue of request \n");
                    235:       return(0);
                    236:     }
                    237: 
                    238:         
                    239:     /* verify if the request is still alive !! */
                    240: 
                    241:     if ((me->request->net == (HTNet*) NULL) || (me->reqStatus == HT_END || me->reqStatus == HT_ERR)) {
                    242:       /* the socket is now being used by a different request, so the request has ended */
                    243: #ifdef WWW_XWINDOWS
                    244:        if (THD_TRACE)
                    245:          fprintf(stderr, "(BF) removing Xtinput %lu !RWE, sock %d (Request has ended)\n", *id, *s);
                    246: #endif
                    247:        if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC)) {
                    248:         AHTPrintPendingRequestStatus (me->docid, YES);
                    249:         AHTReqContext_delete(me);
                    250:        }
                    251:        else
                    252:         if (me->reqStatus != HT_END && HTError_hasSeverity(HTRequest_error(me->request), ERR_NON_FATAL))
                    253:           me->reqStatus = HT_ERR;
                    254:        return(0);
                    255:     }
                    256:     me->reqStatus = HT_WAITING;
                    257:     return (0);
                    258: }
                    259: 
                    260: 
                    261: /* 
                    262:  * This function is called whenever a socket is available
                    263:  * for a request. It  the necessary events to the Xt
                    264:  * A small interface to the HTLoadAnchor libwww function.
                    265:  * It prepares Xt to handle the asynchronous data requests.
                    266:  */
                    267: 
                    268: #ifdef __STDC__
                    269: int Add_NewSocket_to_Loop (HTRequest* request, HTAlertOpcode op, int msgnum, const char* dfault, void* input, HTAlertPar* reply)
                    270: #else
                    271: int Add_NewSocket_to_Loop (request, op, msgnum, dfault, input, reply)
                    272: HTRequest*    request;
                    273: HTAlertOpcode op;
                    274: int           msgnum;
                    275: const char*   dfault;
                    276: void*         input;
                    277: HTAlertPar*   reply;
                    278: #endif /*__STDC__*/
                    279: {
                    280:     SOCKET         req_socket;
                    281:     AHTReqContext* me = HTRequest_context (request);
                    282: 
                    283:     /* AmayaOpenRequests *reqState; */
                    284: 
                    285:     if(me->reqStatus == HT_NEW_PENDING) {
                    286:       /* we are opening a pending request */
                    287:       if ((me->output = fopen (me->outputfile, "w")) == NULL) {
                    288:        me->outputfile[0] = '\0';       /* file could not be opened */
                    289:        TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
                    290:                      me->outputfile);
                    291:        me->reqStatus = HT_ERR;
                    292:        return(HT_ERROR);
                    293:       }
                    294:       if (THD_TRACE)
                    295:        fprintf(stderr, "Add_NewSocket_to_Loop: Activating pending %s . Open fd %d\n", me->urlName, (int) me->output);
                    296:       HTRequest_setOutputStream (me->request,
                    297:                                 AHTFWriter_new (me->request, me->output, YES));
                    298:     }
                    299: 
                    300:     me->reqStatus = HT_WAITING;
                    301: 
                    302:     if (THD_TRACE)
                    303:        fprintf(stderr, "(Activating a pending request\n");
                    304: 
                    305:     /* reusing this function to save on file descriptors */
                    306: 
                    307: 
                    308:     return (HT_OK);
                    309: 
                    310:     /***
                    311:     if(me->method == METHOD_PUT || me->method == METHOD_POST)
                    312:        return (HT_OK);
                    313:     ***/
                    314: 
                    315:     /* get the socket number associated to the request */
                    316: 
                    317:     req_socket = HTNet_socket(request->net);
                    318:     
                    319:     if (req_socket == INVSOC) {
                    320:        /* this should never be true */
                    321:        return (HT_ERROR);
                    322:     }
                    323: 
                    324:     /* add the input */
                    325: 
                    326: #ifdef WWW_XWINDOWS
                    327:     me->write_xtinput_id = 
                    328:       XtAppAddInput (app_cont,req_socket, (XtPointer) XtInputWriteMask,
                    329:                     (XtInputCallbackProc) AHTCallback_bridge, NULL);
                    330:     if (THD_TRACE)
                    331:       fprintf(stderr, "(BT) adding   Xtinput %lu Socket %d W \n", me->write_xtinput_id, req_socket);
                    332:     
                    333:     if (me->write_xtinput_id == (XtInputId) NULL) {
                    334:       TtaSetStatus(me->docid, 1, TtaGetMessage(AMAYA, AM_XT_ERROR), me->urlName);
                    335:       
                    336:       /* I still need to add some error treatment here, to liberate memory */
                    337:       return (HT_ERROR);
                    338:     }
                    339: 
                    340: #endif /* WWW_XWINDOWS */
                    341:     /* To speed up the stop performances, we move the active requests to the top of the Amaya list */
                    342: 
                    343:     /*
                    344:     reqState  = DocRequestState(Amaya->open_requests, me->docid);
                    345: 
                    346:     if(reqState->counter > 1) {
                    347:       HTList_removeObject (Amaya->reqlist, (void *) me);
                    348:       HTList_addObject (Amaya->reqlist, (void *) me);
                    349:     }
                    350:     */
                    351:     return (HT_OK);
                    352: }
                    353: 
                    354: 
                    355: /* 
                    356:  * This function is called whenever a socket is available
                    357:  * for a request. It  the necessary events to the Xt
                    358:  * A small interface to the HTLoadAnchor libwww function.
                    359:  * It prepares Xt to handle the asynchronous data requests.
                    360:  */
                    361: 
                    362: #ifdef __STDC__
                    363: int AHTEvent_register(SOCKET sock, HTRequest* rqp, SockOps ops, HTEventCallback* cbf, HTPriority p)
                    364: #else
                    365: int AHTEvent_register(sock, rqp, ops,  cbf, p)
                    366: SOCKET           sock;
                    367: HTRequest*       rqp;
                    368: SockOps          ops;
                    369: HTEventCallback* cbf;
                    370: HTPriority       p;
                    371: #endif /*__STDC__*/
                    372: {
                    373:     AHTReqContext* me;
                    374:     int            status;
                    375:     
                    376:     if (sock == INVSOC)
                    377:       return (0);
                    378:     
                    379:     /* get the request associated to the socket number */
                    380: 
                    381:     if((status = HTEventrg_register (sock, rqp, ops,
                    382:                                     cbf,p )) != HT_OK )
                    383:       return (status);
                    384: 
                    385:     if(rqp) {
                    386:       
                    387:       me = HTRequest_context(rqp);
                    388: 
                    389:       /* verify if we need to open the fd */
                    390: 
                    391:       if(me->reqStatus == HT_NEW_PENDING) {
                    392:        /* we are opening a pending request */
                    393:        if ((me->output = fopen (me->outputfile, "w")) == NULL) {
                    394:          me->outputfile[0] = '\0';     /* file could not be opened */
                    395:          TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
                    396:                        me->outputfile);
                    397:          me->reqStatus = HT_ERR;
                    398:          return(HT_ERROR);
                    399:        }
                    400:        HTRequest_setOutputStream (me->request,
                    401:                                   AHTFWriter_new (me->request, me->output, YES));
                    402:        me->reqStatus = HT_WAITING;
                    403: 
                    404:       if (THD_TRACE)
                    405:        fprintf(stderr,"AHTEvent_register: Activating pending request url %s, fd %d\n", me->urlName, (int) me->output);
                    406:       }
                    407: 
                    408:       if (THD_TRACE)
                    409:        fprintf(stderr,"AHTEvent_register: url %s, sock %d, ops %lu \n",
                    410:                me->urlName, sock, ops);
                    411: 
                    412:       /* add the input */
                    413:       if(me->reqStatus == HT_NEW)
                    414:        me->reqStatus = HT_WAITING;
                    415:       
                    416:       if (ops & ReadBits)      {
                    417:        me->read_ops = ops;
                    418: 
                    419: #ifdef WWW_XWINDOWS
                    420:        if(me->read_xtinput_id)
                    421:          XtRemoveInput(me->read_xtinput_id);
                    422:        me->read_xtinput_id = 
                    423:          XtAppAddInput(app_cont,
                    424:                        sock,
                    425:                        (XtPointer) XtInputReadMask,
                    426:                        (XtInputCallbackProc) AHTCallback_bridge,
                    427:                        (XtPointer) XtInputReadMask);
                    428:        if (THD_TRACE) 
                    429:          fprintf(stderr, "(BT) adding Xtinput %lu Socket %d R\n",
                    430:                  me->read_xtinput_id, sock);
                    431: #endif /* WWW_XWINDOWS */
                    432:       }
                    433: 
                    434:       if(ops & WriteBits) {
                    435:        me->write_ops= ops;
                    436: #ifdef WWW_XWINDOWS
                    437:        if (me->write_xtinput_id)
                    438:           XtRemoveInput(me->write_xtinput_id);
                    439:           me->write_xtinput_id = XtAppAddInput (app_cont, sock,
                    440:                                               (XtPointer) XtInputWriteMask,
                    441:                                               (XtInputCallbackProc) AHTCallback_bridge,
                    442:                                               (XtPointer) XtInputWriteMask);
                    443:          if (THD_TRACE) 
                    444:            fprintf(stderr, "(BT) adding Xtinput %lu Socket %d W\n",
                    445:                    me->write_xtinput_id, sock);
                    446: #endif /* WWW_XWINDOWS */
                    447:       } 
                    448: 
                    449:       if (ops & ExceptBits) {
                    450:        me->except_ops = ops;
                    451: #ifdef WWW_XWINDOWS
                    452:        if (me->except_xtinput_id)
                    453:          XtRemoveInput(me->except_xtinput_id);
                    454: 
                    455:        me->except_xtinput_id = XtAppAddInput (app_cont, sock,
                    456:                                               (XtPointer) XtInputExceptMask,
                    457:                                               (XtInputCallbackProc) AHTCallback_bridge,
                    458:                                               (XtPointer) XtInputExceptMask);
                    459:        if (THD_TRACE) 
                    460:          fprintf(stderr, "(BT) adding Xtinput %lu Socket %d E\n", me->except_xtinput_id, sock);
                    461: #endif /* WWW_XWINDOWS */
                    462:       }
                    463:     }
                    464: 
                    465: 
                    466: 
                    467: #if 0
                    468:     if (me->xtinput_id == (XtInputId) NULL) {
                    469:        TtaSetStatus(me->docid, 1, TtaGetMessage(AMAYA, AM_XT_ERROR), me->urlName);
                    470:        
                    471:       /* I still need to add some error treatment here, to liberate memory */
                    472:        return (HT_ERROR);
                    473:     }
                    474: 
                    475: #endif
                    476: 
                    477:   return (status);
                    478: }
                    479: 
                    480: #ifdef __STDC__
                    481: int AHTEvent_unregister (SOCKET sock, SockOps ops)
                    482: #else
                    483: int AHTEvent_unregister (sock, ops)
                    484: SOCKET  sock;
                    485: SockOps ops;
                    486: #endif /*__STDC__*/
                    487: {
                    488:     int status;
                    489: 
                    490:     HTRequest*     rqp = NULL;
                    491:     AHTReqContext* me;
                    492:     
                    493:    /* Libwww 4.1 does not take into account the third parameter
                    494:    **  for this function call */
                    495: 
                    496:     HTEventCallback* cbf = (HTEventCallback*) __RetrieveCBF(sock, (SockOps) NULL, &rqp);
                    497: 
                    498:    if (cbf) {
                    499: #ifdef WWW_XWINDOWS
                    500:      if(rqp) {
                    501:        me = HTRequest_context(rqp);
                    502: 
                    503:        if(ops & ReadBits)
                    504:         RequestKillReadXtevent (me);
                    505:        
                    506:        if(ops & WriteBits)
                    507:         RequestKillWriteXtevent (me);
                    508:        
                    509:        if(ops & ExceptBits)
                    510:         RequestKillExceptXtevent (me);
                    511:        
                    512: #endif /* WWW_XWINDOWS */
                    513:        
                    514:      }
                    515:    }
                    516:    
                    517:      status = HTEventrg_unregister(sock, ops);
                    518:      return(status);
                    519: }
                    520: 
                    521: #ifdef __STDC__
                    522: void RequestKillAllXtevents (AHTReqContext* me)
                    523: #else
                    524: void RequestKillAllXtevents (me)
                    525: AHTReqContext* me;
                    526: #endif /*__STDC__*/
                    527: {
                    528: #ifdef WWW_XWINDOWS
                    529:     if (THD_TRACE)
                    530:        fprintf(stderr, "Request_kill: Clearing Xtinputs\n");
                    531: 
                    532:     RequestKillReadXtevent   (me);
                    533:     RequestKillWriteXtevent  (me);
                    534:     RequestKillExceptXtevent (me);
                    535: #endif /* WWW_XWINDOWS */
                    536: }
                    537: 
                    538: #ifdef __STDC__
                    539: static void RequestKillReadXtevent (AHTReqContext* me)
                    540: #else
                    541: static void RequestKillReadXtevent (me)
                    542: AHTReqContext* me;
                    543: #endif /*__STDC__*/
                    544: {
                    545: #ifdef WWW_XWINDOWS
                    546:     if (me->read_xtinput_id) {
                    547:        if (THD_TRACE)
                    548:           fprintf (stderr, "Request_kill: Clearing Read Xtinputs%lu\n", me->read_xtinput_id);
                    549:        XtRemoveInput (me->read_xtinput_id);
                    550:        me->read_xtinput_id = (XtInputId) NULL; 
                    551:     }
                    552: #endif /* WWW_XWINDOWS */
                    553: }
                    554: 
                    555: #ifdef __STDC__
                    556: static void RequestKillWriteXtevent (AHTReqContext* me)
                    557: #else
                    558: static void RequestKillWriteXtevent (me)
                    559: AHTReqContext* me;
                    560: #endif /*__STDC__*/
                    561: {
                    562: #ifdef WWW_XWINDOWS
                    563:     if (me->write_xtinput_id) {
                    564:        if (THD_TRACE)
                    565:           fprintf(stderr, "Request_kill: Clearing Write Xtinputs %lu\n", me->write_xtinput_id);
                    566:        XtRemoveInput(me->write_xtinput_id);
                    567:        me->write_xtinput_id = (XtInputId) NULL; 
                    568:     }
                    569: #endif /* WWW_XWINDOWS */
                    570: }
                    571: 
                    572: #ifdef __STDC__
                    573: static void RequestKillExceptXtevent (AHTReqContext* me)
                    574: #else
                    575: static void RequestKillExceptXtevent (me)
                    576: AHTReqContext* me;
                    577: #endif /*__STDC__*/
                    578: {
                    579: #ifdef WWW_XWINDOWS
                    580:     if (me->except_xtinput_id) {
                    581:        if (THD_TRACE)
                    582:           fprintf (stderr, "Request_kill: Clearing Except Xtinputs %lu\n", me->except_xtinput_id);
                    583:        XtRemoveInput (me->except_xtinput_id);
                    584:        me->except_xtinput_id = (XtInputId) NULL; 
                    585:     }
                    586: #endif /* WWW_XWINDOWS */
                    587: }
                    588: 
                    589: 
                    590: 
                    591: 
                    592: 
                    593: 

Webmaster