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

1.9       cvs         1: /*
                      2:  *
                      3:  *  (c) COPYRIGHT MIT and INRIA, 1996.
                      4:  *  Please first read the full copyright statement in file COPYRIGHT.
                      5:  *
                      6:  */
1.75      cvs         7:   
1.14      cvs         8: /*
                      9:  * AHTBridge.c : This module implements the callback setup and
                     10:  * handlers between the Xt, libwww, and Amaya procedures. It's responsible
                     11:  * for assigning, modifying, and supressing Xt events to the active
                     12:  * requests.
                     13:  *
                     14:  * Author: J Kahan
1.67      cvs        15:  *         J. K./R. Guetari. Windows NT/95 routines
1.79      cvs        16:  *         J. K./S. Gully GTK routines
1.14      cvs        17:  *
                     18:  */
1.68      cvs        19: #ifdef _GTK
                     20: #include <glib.h>
                     21: #endif /* _GTK */
                     22: 
1.16      cvs        23: #define THOT_EXPORT extern
1.4       cvs        24: #include "amaya.h"
1.10      cvs        25: #include "AHTBridge_f.h"
                     26: #include "AHTFWrite_f.h"
                     27: #include "query_f.h"
                     28: #include "answer_f.h"
1.64      cvs        29: #include "HTEvtLst.h"
1.4       cvs        30: 
1.58      cvs        31: #if 0
                     32: #define DEBUG_LIBWWW
                     33: #define THD_TRACE 1
                     34: #endif
                     35: 
1.22      cvs        36: #ifndef _WINDOWS
1.79      cvs        37: #ifndef _GTK
1.4       cvs        38: /* Amaya's X appcontext */
1.16      cvs        39: extern ThotAppContext app_cont;
1.79      cvs        40: #endif /* !_GTK */
1.4       cvs        41: 
1.32      cvs        42: /* Private functions */
1.58      cvs        43: static void         RequestRegisterReadXtevent (SOCKET);
                     44: static void         RequestKillReadXtevent (SOCKET);
                     45: static void         RequestRegisterWriteXtevent ( SOCKET);
                     46: static void         RequestKillWriteXtevent (SOCKET);
                     47: static void         RequestRegisterExceptXtevent ( SOCKET);
                     48: static void         RequestKillExceptXtevent (SOCKET);
1.59      cvs        49: #endif /* !_WINDOWS */
1.24      cvs        50: 
1.32      cvs        51: /* Private variables */
1.4       cvs        52: 
                     53: /*
1.58      cvs        54:  * this set of HTEventType map our WinSock "socket event HTEventType" into 
1.4       cvs        55:  * our read and write sets. Note that under the canonical Unix model,
                     56:  * a non-blocking socket passed to an accept() call will appear as readable, 
                     57:  * whilst a non-blocking call to connect() will appear as writeable. In add.
                     58:  * if the connection has been closed, the socket will appear readable under
                     59:  * BSD Unix semantics 
                     60:  */
1.32      cvs        61: 
1.58      cvs        62: static const HTEventType ReadBits = HTEvent_READ | HTEvent_ACCEPT | HTEvent_CLOSE;
                     63: static const HTEventType WriteBits = HTEvent_WRITE | HTEvent_CONNECT;
                     64: static const HTEventType ExceptBits = HTEvent_OOB;
                     65: 
1.79      cvs        66: #ifndef _GTK
1.58      cvs        67: typedef struct sStatus {
1.79      cvs        68:   XtInputId read;             /* the different Xt Id's */
1.58      cvs        69:   XtInputId write;
                     70:   XtInputId except;
                     71: } SocketStatus;
1.79      cvs        72: #endif /*! _GTK */
                     73: 
                     74: #ifdef _GTK
                     75: typedef struct sStatus {
                     76:   gint read;             /* the different GTK Id's */
                     77:   gint write;
                     78:   gint except;
                     79: } SocketStatus;
                     80: #endif /* _GTK */
1.4       cvs        81: 
1.38      cvs        82: #define SOCK_TABLE_SIZE 67
                     83: #define HASH(s) ((s) % SOCK_TABLE_SIZE)
1.58      cvs        84: static SocketStatus persSockets[SOCK_TABLE_SIZE];
1.4       cvs        85: 
1.10      cvs        86: /*--------------------------------------------------------------------
                     87:   AHTCallback_bridge
1.11      cvs        88:   this function acts as a bridge between Xt and libwww. From the Xt
                     89:   point of view, this function is the callback handler whenever there's
                     90:   any activity on the sockets associated with the active requests. From
                     91:   the libwww point of view, this is the function that takes the initiative
                     92:   to invoke the callback function associated with an active request,
                     93:   whenever there's an activity in the socket associated to it.
                     94:   In this latter  aspect, this function is similar to the library's
                     95:   own __DoCallback()  function.
                     96:   Upon activation, the function looks up the request associated with the
                     97:   active socket and then looks up the cbf associated with that request.
                     98:   Upon completion of the execution of the request's cbf, it verifies
                     99:   the state of the request and, if it's an asynchronous request, deletes
                    100:   the memory allocated to it.
1.10      cvs       101:   -------------------------------------------------------------------*/
1.37      cvs       102: #ifndef _WINDOWS
1.68      cvs       103: #ifndef _GTK
1.80      kahan     104: void *AHTCallback_bridge (caddr_t cd, int *s, XtInputId * id)
1.4       cvs       105: {
1.11      cvs       106:    int                 status;  /* the status result of the libwwww call */
1.58      cvs       107:    HTEventType         type  = HTEvent_ALL;    
1.38      cvs       108:    int                 v;
1.40      cvs       109:    int                        socket = *s;
1.58      cvs       110:    ms_t                now = HTGetTimeInMillis();
                    111:    
                    112:    v = HASH (socket);
1.4       cvs       113: 
1.58      cvs       114:    /* convert the FD into an HTEventType which will allow us to find the
                    115:       request associated with the socket */
1.47      cvs       116: 
1.58      cvs       117:    /* I could send some other data here, like the event itself, right */
                    118:    switch ((XtInputId) cd) 
1.47      cvs       119:      {
1.58      cvs       120:      case XtInputReadMask:
                    121:        type = HTEvent_READ;
                    122:        break;
                    123:      case XtInputWriteMask:
                    124:        type = HTEvent_WRITE;
                    125:        break;
                    126:      case XtInputExceptMask:
                    127:        type = HTEvent_OOB;
                    128:        break;
                    129:      default:
                    130:        type = HTEvent_ALL; 
                    131:        break;
                    132:      } /* switch */
1.47      cvs       133:    
1.32      cvs       134:    /* Invokes the callback associated to the requests */
                    135:    
1.66      cvs       136:    /**   CanDoStop_set (FALSE); **/
1.58      cvs       137:    if ((status = HTEventList_dispatch (socket, type, now)) != HT_OK)
                    138:      {
1.36      cvs       139: #ifdef DEBUG_LIBWWW
1.58      cvs       140:      HTTrace ("Callback.... returned a value != HT_OK");
1.36      cvs       141: #endif
1.58      cvs       142:      }
1.41      cvs       143: 
1.66      cvs       144:    /***   CanDoStop_set (TRUE); **/
1.38      cvs       145: 
1.7       cvs       146:    return (0);
1.4       cvs       147: }
1.79      cvs       148: #else /* _GTK */
                    149: static void AHTCallback_bridgeGTK (gpointer data,  gint source, GdkInputCondition condition)
                    150: {
                    151:    int                 status;  /* the status result of the libwwww call */
                    152:    HTEventType         type  = HTEvent_ALL;    
                    153:    int                 v;
                    154:    int                        socket;
                    155:    ms_t                now = HTGetTimeInMillis();
                    156:    
                    157:    socket = (SOCKET) data;
                    158:    v = HASH (socket);
                    159: 
                    160:    /* convert the FD into an HTEventType which will allow us to find the
                    161:       request associated with the socket */
                    162: 
                    163:    /* I could send some other data here, like the event itself, right */
                    164:    switch (condition) 
                    165:      {
                    166:      case GDK_INPUT_READ:
                    167:        type = HTEvent_READ;
                    168:        break;
                    169:      case GDK_INPUT_WRITE:
                    170:        type = HTEvent_WRITE;
                    171:        break;
                    172:      case GDK_INPUT_EXCEPTION:
                    173:        type = HTEvent_OOB;
                    174:        break;
                    175:      default:
                    176:        type = HTEvent_ALL; 
                    177:        break;
                    178:      } /* switch */
                    179:    
                    180:    /* Invokes the callback associated to the requests */
                    181:    
                    182:    /**   CanDoStop_set (FALSE); **/
                    183:    if ((status = HTEventList_dispatch (socket, type, now)) != HT_OK)
                    184:      {
                    185: #ifdef DEBUG_LIBWWW
                    186:      HTTrace ("Callback.... returned a value != HT_OK");
                    187: #endif
                    188:      }
                    189:    /***   CanDoStop_set (TRUE); **/
                    190: }
                    191: #endif /* !_GTK */
1.37      cvs       192: #endif /* !_WINDOWS */
1.41      cvs       193: 
                    194: /*--------------------------------------------------------------------
                    195:   ProcessTerminateRequest
                    196:   This function is called whenever a request has ended. If the requested
                    197:   ended normally, the function will call any callback associated to the
                    198:   request. Otherwise, it will just mark the request as over.
                    199:   -------------------------------------------------------------------*/
1.82    ! vatton    200: void  ProcessTerminateRequest (HTRequest *request, HTResponse *response,
        !           201:                               void *param, int status)
1.41      cvs       202: {   
1.58      cvs       203:   AHTReqContext *me = HTRequest_context (request);
1.56      cvs       204: 
1.58      cvs       205:   /* choose a correct treatment in function of the request's
1.41      cvs       206:      being associated with an error, with an interruption, or with a
                    207:      succesful completion */
1.64      cvs       208: 
                    209: #ifdef DEBUG_LIBWWW  
                    210:   if (THD_TRACE)
1.82    ! vatton    211:     fprintf (stderr,"ProcessTerminateRequest: processing req %p, url %s,\
        !           212:  status %d\n", me, me->urlName, me->reqStatus);  
1.64      cvs       213: #endif /* DEBUG_LIBWWW */
1.82    ! vatton    214:   if (me->reqStatus == HT_END && status >= 0)
1.41      cvs       215:     {
1.58      cvs       216:       if (AmayaIsAlive ()  && me->terminate_cbf)
1.82    ! vatton    217:        (*me->terminate_cbf) (me->docid, 0, me->urlName, me->outputfile,
        !           218:                              &(me->http_headers), me->context_tcbf);
1.58      cvs       219: 
1.41      cvs       220:     }
1.42      cvs       221:   else if (me->reqStatus == HT_ABORT)
1.41      cvs       222:     /* either the application ended or the user pressed the stop 
                    223:        button. We erase the incoming file, if it exists */
                    224:     {
1.52      cvs       225:       if (AmayaIsAlive () && me->terminate_cbf)
1.82    ! vatton    226:        (*me->terminate_cbf) (me->docid, -1, me->urlName, me->outputfile,
        !           227:                              &(me->http_headers), me->context_tcbf);
1.78      cvs       228:       if (me->outputfile && me->outputfile[0] != EOS)
1.41      cvs       229:        {
1.70      cvs       230:          TtaFileUnlink (me->outputfile);
1.78      cvs       231:          me->outputfile[0] = EOS; 
1.70      cvs       232:        } 
1.41      cvs       233:     }
1.82    ! vatton    234:   else if (me->reqStatus == HT_ERR ||
        !           235:           (me->reqStatus == HT_END && status < 0))
1.41      cvs       236:     {
                    237:       /* there was an error */
1.58      cvs       238:       if (AmayaIsAlive && me->terminate_cbf)
1.82    ! vatton    239:        (*me->terminate_cbf) (me->docid, -2, me->urlName, me->outputfile,
        !           240:                              &(me->http_headers), me->context_tcbf);
1.41      cvs       241:       
1.78      cvs       242:       if (me->outputfile && me->outputfile[0] != EOS)
1.41      cvs       243:        {
1.70      cvs       244:          TtaFileUnlink (me->outputfile);
1.78      cvs       245:          me->outputfile[0] = EOS;
1.41      cvs       246:        }
                    247:     }
1.58      cvs       248: 
1.41      cvs       249:    /* we erase the context if we're dealing with an asynchronous request */
1.61      cvs       250:   if ((me->mode & AMAYA_ASYNC)
                    251:       || (me->mode & AMAYA_IASYNC))
1.58      cvs       252:     {
1.63      cvs       253:       Document doc = me->docid;
1.58      cvs       254:       me->reqStatus = HT_END;
                    255:       /*** @@@ do we need this? yes!! **/
                    256:       AHTLoadTerminate_handler (request, response, param, status);
                    257:       AHTReqContext_delete (me);
1.63      cvs       258:       AHTPrintPendingRequestStatus (doc, YES);
1.58      cvs       259:     }
                    260: }
1.4       cvs       261: 
1.32      cvs       262: #ifdef _WINDOWS
1.29      cvs       263: /*----------------------------------------------------------------
1.32      cvs       264:   WIN_Activate_Request
1.29      cvs       265:   when there are more open requests than available sockets, the 
                    266:   requests are put in a "pending state." When a socket becomes
                    267:   available, libwww associates it with a pending request and then
                    268:   calls this callback function. This function is responsible for
                    269:   opening the temporary file where the GET and POST  results
                    270:   will be stored. The function is also responsible for 
                    271:   registering the socket with the Xt event loop.
                    272:   Consult the libwww manual for more details on the signature
                    273:   of this function.
                    274:   ----------------------------------------------------------------*/
1.79      cvs       275: int WIN_Activate_Request (HTRequest * request, HTAlertOpcode op, int msgnum, const char *dfault, void *input, HTAlertPar * reply)
1.29      cvs       276: {
                    277:    AHTReqContext      *me = HTRequest_context (request);
                    278: 
1.58      cvs       279:    if (me->reqStatus == HT_NEW) 
                    280:      {
                    281:        if (!(me->output)
                    282:           && (me->output != stdout) 
                    283:           && me->outputfile
1.78      cvs       284:           &&  (me->output = fopen (me->outputfile, "wb")) == NULL) {
1.58      cvs       285:         /* the request is associated with a file */
1.78      cvs       286:         me->outputfile[0] = EOS;       /* file could not be opened */
1.70      cvs       287:         TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE), me->outputfile);
1.58      cvs       288:         me->reqStatus = HT_ERR;
                    289: 
                    290:         if (me->error_html)
                    291:           DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR; /* so we can show the error message */
                    292:        } 
                    293:        else
                    294:         {
                    295: #ifdef DEBUG_LIBWWW
                    296:           if (THD_TRACE)
                    297:             fprintf (stderr, "WIN_Activate_Request: Activating pending %s. "
                    298:                      "Open fd %d\n", me->urlName, (int) me->output);
                    299: #endif /* DEBUG_LIBWWW */
                    300:           HTRequest_setOutputStream (me->request, AHTFWriter_new (me->request, me->output, YES));    
                    301:           /*change the status of the request */
                    302:           me->reqStatus = HT_WAITING;
                    303:         }
                    304:      } 
                    305:    else if (me->reqStatus == HT_WAITING)
                    306:      {
                    307:        /*change the status of the request */
                    308:        rewind (me->output);
                    309:        if (HTRequest_outputStream (me->request) == NULL)
                    310:         HTRequest_setOutputStream (me->request, AHTFWriter_new (me->request, me->output, YES));
                    311:      } 
1.32      cvs       312:    else {
1.36      cvs       313:      me->reqStatus = HT_ERR;
1.32      cvs       314:    }
                    315:    
1.36      cvs       316:    return ((me->reqStatus != HT_ERR) ? HT_OK : HT_ERROR);
1.32      cvs       317: }
                    318: 
1.60      cvs       319: #endif /* WINDOWS but should be an else */
                    320: /* #else  */ /* _WINDOWS */
                    321: 
                    322: #ifndef _WINDOWS
1.11      cvs       323: /*----------------------------------------------------------------------
                    324:   AHTEvent_register
                    325:   callback called by libwww whenever a socket is open and associated
                    326:   to a request. It sets the pertinent Xt events so that the Xt Event
                    327:   loops gets an interruption whenever there's action of the socket. 
                    328:   In addition, it registers the request with libwww.
                    329:   ----------------------------------------------------------------------*/
1.58      cvs       330: int AHTEvent_register (SOCKET sock, HTEventType type, HTEvent *event)
1.4       cvs       331: {
1.58      cvs       332:   int  status;
1.7       cvs       333: 
1.40      cvs       334:   if (sock == INVSOC)
                    335:     {
1.36      cvs       336: #ifdef DEBUG_LIBWWW
1.58      cvs       337:       fprintf(stderr, "AHTEvent_register: sock = INVSOC\n");
1.37      cvs       338: #endif /* DEBUG_LIBWWW */
1.58      cvs       339:       return (0);
                    340:     }
1.43      cvs       341: 
1.33      cvs       342: #ifndef _WINDOWS
1.58      cvs       343:        /* need something special for HTEvent_CLOSE */
                    344:   if (type & ReadBits)
                    345:     RequestRegisterReadXtevent (sock);
                    346:   
                    347:   if (type & WriteBits)
                    348:     RequestRegisterWriteXtevent (sock);
                    349:   
                    350:   if (type & ExceptBits)
                    351:     RequestRegisterExceptXtevent (sock);
1.33      cvs       352: #endif  /* !_WINDOWS */
1.58      cvs       353:   
1.51      cvs       354: #ifdef _WINDOWS   
1.50      cvs       355:   /* under windows, libwww requires an explicit FD_CLOSE registration 
1.58      cvs       356:      to detect HTTP responses not having a Content-Length header */
                    357:   status = HTEventList_register (sock, type | HTEvent_CLOSE , event);
1.50      cvs       358: #else
1.58      cvs       359:   status = HTEventList_register (sock, type, event);
1.51      cvs       360: #endif /* _WINDOWS */
1.58      cvs       361:   
                    362:   return (status);
                    363: }
1.68      cvs       364: #endif /* _WINDOWS */
1.50      cvs       365: 
1.34      cvs       366: /*----------------------------------------------------------------------
                    367:   AHTEvent_unregister
                    368:   callback called by libwww each time a request is unregistered. This
                    369:   function takes care of unregistering the pertinent Xt events
                    370:   associated with the request's socket. In addition, it unregisters
                    371:   the request from libwww.
                    372:   ----------------------------------------------------------------------*/
1.58      cvs       373: int AHTEvent_unregister (SOCKET sock, HTEventType type)
1.34      cvs       374: {
1.58      cvs       375:   int    status;
1.76      kahan     376:   
                    377:   if (sock == INVSOC)
                    378:     return HT_OK;
1.38      cvs       379: 
                    380: #ifndef _WINDOWS   
1.58      cvs       381:    /* remove the Xt event hooks */
                    382:    if (type & ReadBits) 
                    383:      RequestKillReadXtevent (sock);
                    384:    
                    385:    if (type & WriteBits)
                    386:      RequestKillWriteXtevent (sock);
                    387:    
                    388:    if (type & ExceptBits) 
                    389:      RequestKillExceptXtevent (sock);
1.36      cvs       390: #endif /* !_WINDOWS */
1.35      cvs       391: 
1.58      cvs       392:    /* @@@ if this is the default for windows, no need to have AHTEvent_..
                    393:       in windows!! */
1.35      cvs       394: 
1.58      cvs       395:    /* call libwww's default routine */
                    396:    status = HTEventList_unregister (sock, type);
                    397:    
1.7       cvs       398:    return (status);
1.4       cvs       399: }
1.35      cvs       400: 
                    401: #ifndef _WINDOWS
1.58      cvs       402: /* Private functions */
                    403: 
1.11      cvs       404: /*----------------------------------------------------------------------
                    405:   RequestKillAllXtevents
                    406:   front-end for kill all Xt events associated with the request pointed
                    407:   to by "me".
                    408:   ----------------------------------------------------------------------*/
1.79      cvs       409: void RequestKillAllXtevents (AHTReqContext * me)
1.4       cvs       410: {
1.58      cvs       411:   int sock = INVSOC;
                    412: 
                    413:   return;
                    414: 
                    415:   /* @@@ what to do with this one? @@@ */
                    416:   if (me->read_sock != INVSOC)
                    417:     sock = me->read_sock;
                    418:   else
                    419:     if (me->write_sock != INVSOC)
                    420:           sock = me->write_sock;
                    421:   else
                    422:     if (me->except_sock != INVSOC)
                    423:           sock = me->except_sock;
                    424: 
                    425: #ifdef DEBUG_LIBWWW
1.7       cvs       426:    if (THD_TRACE)
1.58      cvs       427:       fprintf (stderr, "RequestKillAllXtEvents: Clearing XtInputs\n");
                    428: #endif /* DEBUG_LIBWWW */
1.4       cvs       429: 
1.58      cvs       430: 
                    431:    RequestKillReadXtevent (sock);
                    432:    RequestKillWriteXtevent (sock);
                    433:    RequestKillExceptXtevent (sock);
1.4       cvs       434: }
                    435: 
1.11      cvs       436: /*----------------------------------------------------------------------
1.18      cvs       437:   RequestRegisterReadXtevent
                    438:   Registers with Xt the read events associated with socket sock
                    439:   ----------------------------------------------------------------------*/
1.79      cvs       440: static void RequestRegisterReadXtevent (SOCKET sock)
1.18      cvs       441: {
1.58      cvs       442:   int v;
                    443: 
                    444:   v = HASH (sock);
                    445: 
                    446:   if (!persSockets[v].read)
1.18      cvs       447:     {
1.79      cvs       448: #ifndef _GTK
1.58      cvs       449:       persSockets[v].read  =
                    450:        XtAppAddInput (app_cont,
                    451:                       sock,
                    452:                       (XtPointer) XtInputReadMask,
                    453:                       (XtInputCallbackProc) AHTCallback_bridge,
                    454:                       (XtPointer) XtInputReadMask);
1.79      cvs       455: #else  /* _GTK */
                    456:      persSockets[v].read  =
                    457:        gdk_input_add ((gint) sock,
                    458:                      GDK_INPUT_READ,
                    459:                      AHTCallback_bridgeGTK,
                    460:                      (gpointer) sock);
                    461: #endif /* !_GTK */
                    462: 
1.58      cvs       463: #ifdef DEBUG_LIBWWW
1.18      cvs       464:       if (THD_TRACE)
1.58      cvs       465:        fprintf (stderr, "RegisterReadXtEvent: adding XtInput %lu Socket %d\n",
                    466:                 persSockets[v].read, sock);
                    467: #endif /* DEBUG_LIBWWW */
1.18      cvs       468:     }
                    469: 
                    470: }
                    471: 
                    472: /*----------------------------------------------------------------------
1.11      cvs       473:   RequestKillReadXtevent
                    474:   kills any read Xt event associated with the request pointed to by "me".
                    475:   ----------------------------------------------------------------------*/
1.79      cvs       476: static void RequestKillReadXtevent (SOCKET sock)
1.4       cvs       477: {
1.58      cvs       478:   int v;
                    479: 
                    480:   v = HASH (sock);
                    481: 
                    482:   if (persSockets[v].read)
                    483:     {
                    484: #ifdef DEBUG_LIBWWW
                    485:       if (THD_TRACE)
                    486:        fprintf (stderr, "UnregisterReadXtEvent: Clearing XtInput %lu\n",
                    487:                 persSockets[v].read);
                    488: #endif /* DEBUG_LIBWWW */
1.79      cvs       489: #ifndef _GTK
1.58      cvs       490:       XtRemoveInput (persSockets[v].read);
                    491:       persSockets[v].read = (XtInputId) NULL;
1.79      cvs       492: #else  /* _GTK */
                    493:       gdk_input_remove (persSockets[v].read);
                    494:       persSockets[v].read = (gint) 0;
                    495: #endif /* !_GTK */
1.58      cvs       496:     }
1.18      cvs       497: }
                    498: 
                    499: /*----------------------------------------------------------------------
                    500:   RequestRegisterWriteXtevent
                    501:   Registers with Xt the write events associated with socket sock
                    502:   ----------------------------------------------------------------------*/
1.79      cvs       503: static void RequestRegisterWriteXtevent (SOCKET sock)
1.18      cvs       504: {
1.58      cvs       505:   int v;
                    506:   v = HASH (sock);
1.18      cvs       507: 
1.58      cvs       508:   if (!persSockets[v].write)
                    509:     {   
1.79      cvs       510: #ifndef _GTK
1.58      cvs       511:       persSockets[v].write =
                    512:        XtAppAddInput (app_cont,
                    513:                       sock,
1.18      cvs       514:                   (XtPointer) XtInputWriteMask,
                    515:                   (XtInputCallbackProc) AHTCallback_bridge,
                    516:                   (XtPointer) XtInputWriteMask);
1.79      cvs       517: #else  /* _GTK */
                    518:      persSockets[v].write  =
                    519:        gdk_input_add ((gint) sock,
                    520:                      GDK_INPUT_WRITE,
                    521:                      AHTCallback_bridgeGTK,
                    522:                      (gpointer) sock);
                    523: #endif /* !_GTK */
                    524: 
1.58      cvs       525: #ifdef DEBUG_LIBWWW   
1.18      cvs       526:   if (THD_TRACE)
1.58      cvs       527:     fprintf (stderr, "RegisterWriteXtEvent: Adding XtInput %lu Socket %d\n",
                    528:             persSockets[v].write, sock);
                    529: #endif /* DEBUG_LIBWWW */
                    530:   
                    531:     }
1.4       cvs       532: }
                    533: 
1.11      cvs       534: /*----------------------------------------------------------------------
                    535:   RequestKillWriteXtevent
                    536:   kills any write Xt event associated with the request pointed to
                    537:   by "me".
                    538:   ----------------------------------------------------------------------*/
1.79      cvs       539: static void RequestKillWriteXtevent (SOCKET sock)
1.4       cvs       540: {
1.58      cvs       541:   int v;
                    542: 
                    543:   v = HASH (sock);
                    544: 
                    545:   if (persSockets[v].write)
                    546:     {
                    547: #ifdef DEBUG_LIBWWW   
                    548:       if (THD_TRACE)
                    549:        fprintf (stderr, "UnRegisterWriteXtEvent: Clearing Write XtInputs "
                    550:                 "%lu\n",
                    551:                 persSockets[v].write);
                    552: #endif /* DEBUG_LIBWWW */
1.79      cvs       553: #ifndef _GTK
1.58      cvs       554:       XtRemoveInput (persSockets[v].write);
                    555:       persSockets[v].write =  (XtInputId) NULL;
1.79      cvs       556: #else  /* _GTK */
                    557:       gdk_input_remove (persSockets[v].write);
                    558:       persSockets[v].write = (gint) 0;
                    559: #endif /* !_GTK */
1.58      cvs       560:     }
1.18      cvs       561: }
                    562: 
                    563: /*----------------------------------------------------------------------
                    564:   RequestRegisterExceptXtevent
                    565:   Registers with Xt the except events associated with socket sock
                    566:   ----------------------------------------------------------------------*/
1.79      cvs       567: static void RequestRegisterExceptXtevent (SOCKET sock)
1.18      cvs       568: {
1.58      cvs       569:   int v;
                    570: 
                    571:   v = HASH (sock);
                    572: 
                    573:    if (!persSockets[v].except)
1.18      cvs       574:      {
1.79      cvs       575: #ifndef _GTK   
1.58      cvs       576:        persSockets[v].except =
                    577:         XtAppAddInput (app_cont,
                    578:                        sock,
                    579:                        (XtPointer) XtInputExceptMask,
                    580:                        (XtInputCallbackProc) AHTCallback_bridge,
                    581:                        (XtPointer) XtInputExceptMask);
1.79      cvs       582: #else  /* _GTK */
                    583:      persSockets[v].except  =
                    584:        gdk_input_add ((gint) sock,
                    585:                      GDK_INPUT_EXCEPTION,
                    586:                      AHTCallback_bridgeGTK,
                    587:                      (gpointer) sock);
                    588: #endif /* !_GTK */
1.58      cvs       589: #ifdef DEBUG_LIBWWW      
                    590:    if (THD_TRACE)
                    591:      fprintf (stderr, "RegisterExceptXtEvent: adding XtInput %lu Socket %d\n",
                    592:              persSockets[v].except, sock);
                    593: #endif /* DEBUG_LIBWWW */
1.18      cvs       594:      }
1.4       cvs       595: }
                    596: 
1.11      cvs       597: /*----------------------------------------------------------------------
                    598:   RequestKillExceptXtevent
                    599:   kills any exception Xt event associated with the request pointed to
                    600:   by "me".
                    601:   ----------------------------------------------------------------------*/
1.79      cvs       602: static void RequestKillExceptXtevent (SOCKET sock)
1.4       cvs       603: {
1.58      cvs       604:   int v;
                    605: 
                    606:   v = HASH (sock);
                    607:   if (persSockets[v].except)
                    608:     {
                    609: #ifdef DEBUG_LIBWWW   
                    610:       if (THD_TRACE)
                    611:        fprintf (stderr, "UnregisterExceptXtEvent: Clearing Except XtInputs "
                    612:                 "%lu\n", persSockets[v].except);
                    613: #endif /* DEBUG_LIBWWW */
1.79      cvs       614: #ifndef _GTK
1.58      cvs       615:       XtRemoveInput (persSockets[v].except);
                    616:       persSockets[v].except = (XtInputId) NULL;
1.79      cvs       617: #else  /* _GTK */
                    618:       gdk_input_remove (persSockets[v].except);
                    619:       persSockets[v].except = (gint) 0;
                    620: #endif /* !_GTK */
1.58      cvs       621:     }
                    622: }
                    623: 
                    624: /*----------------------------------------------------------------------
                    625:   Xt Timer functions 
                    626:   ----------------------------------------------------------------------*/
                    627: 
                    628: struct _HTTimer {
                    629:     ms_t        millis;         /* Relative value in millis */
                    630:     ms_t        expires;        /* Absolute value in millis */
                    631:     BOOL        relative;
                    632:     BOOL        repetitive;
                    633:     void *      param;          /* Client supplied context */
                    634:     HTTimerCallback * cbf;
                    635: };
                    636: 
                    637: struct _AmayaTimer {
                    638:   HTTimer *libwww_timer;
1.79      cvs       639: #ifndef _GTK
1.58      cvs       640:   XtIntervalId xt_timer;
1.79      cvs       641: #else  /* _GTK */
                    642:   guint  xt_timer;
                    643: #endif /* !_GTK */
1.58      cvs       644: };
                    645: 
                    646: typedef struct _AmayaTimer AmayaTimer;
                    647: 
                    648: static HTList *Timers = NULL;
                    649: 
                    650: /*----------------------------------------------------------------------
1.79      cvs       651:   TimerCallback
                    652:   called by the system event loop. Timers shouldn't be restarted
                    653:   on exiting.
1.58      cvs       654:   ----------------------------------------------------------------------*/
1.79      cvs       655: #ifndef _GTK
1.58      cvs       656: void *TimerCallback (XtPointer cdata, XtIntervalId *id)
                    657: {
                    658:   HTList *cur, *last;
                    659:   AmayaTimer *me;
                    660:   HTTimer *libwww_timer;
                    661: 
                    662:   if (!AmayaIsAlive () 
                    663:       || Timers == NULL)
                    664:     return (0);
                    665: 
                    666:   /* find the timer from the uid */
                    667:   last = cur = Timers;
                    668:   while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
                    669:     {
                    670:       if (me->xt_timer == *id)
                    671:        break;
                    672:       last = cur;
                    673:     }
                    674: 
                    675:   if (me)
                    676:     {
                    677:       libwww_timer = me->libwww_timer;
                    678:       /* remove the element from the list @@@ can be optimized later */
                    679:       HTList_quickRemoveElement(cur, last);
                    680:       TtaFreeMemory (me);
                    681:       HTTimer_dispatch (libwww_timer);
                    682:     }
                    683: 
                    684:   return (0);
                    685: }
                    686: 
1.79      cvs       687: #else  /* _GTK */
                    688: /*----------------------------------------------------------------------
                    689:   TimerCallbackGTK
1.81      kahan     690:   The callback returns FALSE to destroy the timer that called it.
1.79      cvs       691:   ----------------------------------------------------------------------*/
                    692: gboolean TimerCallbackGTK (gpointer id)
                    693: {
                    694:   HTList *cur, *last;
                    695:   AmayaTimer *me;
                    696:   HTTimer *libwww_timer;
                    697:   AmayaTimer *data;
                    698: 
                    699:   data = (AmayaTimer *) id;
                    700: 
                    701:   if (!AmayaIsAlive () 
                    702:       || Timers == NULL)
1.81      kahan     703:     return (FALSE);
1.79      cvs       704: 
                    705:   /* find the timer from the uid */
                    706:   last = cur = Timers;
                    707:   while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
                    708:     {
                    709:       if (me == data)
                    710:        break;
                    711:       last = cur;
                    712:     }
                    713: 
                    714:   if (me)
                    715:     {
                    716:       libwww_timer = me->libwww_timer;
                    717:       /* remove the element from the list @@@ can be optimized later */
                    718:       HTList_quickRemoveElement(cur, last);
                    719:       TtaFreeMemory (me);
                    720:       HTTimer_dispatch (libwww_timer);
                    721:     }
                    722: 
                    723:   return (FALSE);
                    724: }
                    725: #endif /* !_GTK */
                    726: 
1.58      cvs       727: /*----------------------------------------------------------------------
1.59      cvs       728:   KillAllTimers
1.58      cvs       729:   ----------------------------------------------------------------------*/
1.59      cvs       730: void KillAllTimers (void)
1.58      cvs       731: {
                    732:   /* @@@ maybe add something else to kill the Xt things */
                    733:   if (Timers)
                    734:     HTList_delete (Timers);
1.65      cvs       735:   Timers = NULL;
1.58      cvs       736: }
                    737: 
                    738: /*----------------------------------------------------------------------
1.59      cvs       739:  AMAYA_SetTimer
                    740:  ----------------------------------------------------------------------*/
                    741: void AMAYA_SetTimer (HTTimer *libwww_timer)
1.58      cvs       742: {
                    743:   HTList *cur, *last;
                    744:   AmayaTimer *me;
                    745: 
                    746:   if (!AmayaIsAlive 
                    747:       || libwww_timer == NULL
                    748:       || libwww_timer->expires == 0)
                    749:     return;
                    750: 
                    751:   if (Timers == NULL)
                    752:     Timers = HTList_new ();
                    753: 
                    754:   /* see if this timer existed already */
                    755:   last = cur = Timers;
                    756:   while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
                    757:     {
                    758:       if (me->libwww_timer == libwww_timer)
                    759:        break;
                    760:       last = cur;
                    761:     }
                    762: 
                    763:   if (me)
                    764:     {
                    765:     /* remove the old timer */
                    766:       if (me->xt_timer) 
                    767:        {
1.79      cvs       768: #ifndef _GTK
1.58      cvs       769:          XtRemoveTimeOut (me->xt_timer);
1.59      cvs       770:          me->xt_timer = (XtIntervalId) NULL;
1.79      cvs       771: #else  /* _GTK */
                    772:          gtk_timeout_remove (me->xt_timer);
                    773:          me->xt_timer = (guint) 0;
                    774: #endif /* !_GTK */
1.58      cvs       775:        }
                    776:     }
                    777:   else
                    778:     {
                    779:       /* create a new element */
                    780:       me = TtaGetMemory (sizeof (AmayaTimer));
                    781:       /* and add it to the list */
                    782:       HTList_addObject(last, (void *) me);
                    783:       me->libwww_timer = libwww_timer;
                    784:     }
                    785: 
                    786:   /* add a new time out */
1.79      cvs       787: #ifndef _GTK
1.58      cvs       788:   me->xt_timer = XtAppAddTimeOut (app_cont,
                    789:                                 me->libwww_timer->millis,
                    790:                                 (XtTimerCallbackProc) TimerCallback,
                    791:                                 (XtPointer *) (void *) me);
1.79      cvs       792: #else  /* _GTK */
                    793:   me->xt_timer = gtk_timeout_add ((guint32) me->libwww_timer->millis,
                    794:                                  (GtkFunction) TimerCallbackGTK,
                    795:                                  (gpointer) me);
                    796: #endif /* !_GTK */
1.58      cvs       797: }
                    798: 
                    799: /*----------------------------------------------------------------------
1.59      cvs       800:   AMAYA_DeleteTimer
1.58      cvs       801:   ----------------------------------------------------------------------*/
1.59      cvs       802: void AMAYA_DeleteTimer (HTTimer *libwww_timer)
1.58      cvs       803: {
                    804:   HTList *cur, *last;
                    805:   AmayaTimer *me;
                    806: 
1.59      cvs       807:   if (Timers == NULL || libwww_timer == NULL)
1.58      cvs       808:     return;
                    809: 
                    810:   /* find the id */
                    811:   last = cur = Timers;
                    812:   while ((me = (AmayaTimer * ) HTList_nextObject (cur)))
                    813:     {
1.59      cvs       814:       if (me->libwww_timer == libwww_timer)
1.58      cvs       815:        break;
                    816:       last = cur;
                    817:     }
                    818: 
                    819:   if (me)
                    820:     {
                    821:       /* remove the Xt timer */
1.79      cvs       822: #ifndef _GTK
1.58      cvs       823:       XtRemoveTimeOut (me->xt_timer);
1.79      cvs       824: #else  /* _GTK */
                    825:       gtk_timeout_remove (me->xt_timer);
                    826: #endif /* !_GTK */
1.58      cvs       827:       /* and the element from the list */
1.65      cvs       828:       HTList_removeObject (Timers, me);
1.58      cvs       829:       TtaFreeMemory (me);
                    830:     }
1.31      cvs       831: }
1.32      cvs       832: #endif /* !_WINDOWS */

Webmaster