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

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

Webmaster