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

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

Webmaster