|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 4: ! 5: All Rights Reserved ! 6: ! 7: Permission to use, copy, modify, and distribute this software and its ! 8: documentation for any purpose and without fee is hereby granted, ! 9: provided that the above copyright notice appear in all copies and that ! 10: both that copyright notice and this permission notice appear in ! 11: supporting documentation, and that the names of Digital or MIT not be ! 12: used in advertising or publicity pertaining to distribution of the ! 13: software without specific, written prior permission. ! 14: ! 15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 21: SOFTWARE. ! 22: ! 23: ******************************************************************/ ! 24: ! 25: /***************************************************************** ! 26: * OS Depedent input routines: ! 27: * ! 28: * WaitForSomething, GetEvent ! 29: * ! 30: *****************************************************************/ ! 31: ! 32: #include "Xos.h" /* for strings, fcntl, time */ ! 33: ! 34: #include <errno.h> ! 35: #include <stdio.h> ! 36: #include "X.h" ! 37: #include "misc.h" ! 38: ! 39: #include <sys/param.h> ! 40: #include <signal.h> ! 41: #include "osdep.h" ! 42: #include "dixstruct.h" ! 43: ! 44: ! 45: extern long AllSockets[]; ! 46: extern long AllClients[]; ! 47: extern long LastSelectMask[]; ! 48: extern long WellKnownConnections; ! 49: extern long EnabledDevices; ! 50: extern long ClientsWithInput[]; ! 51: extern long ClientsWriteBlocked[]; ! 52: extern long OutputPending[]; ! 53: ! 54: extern long ScreenSaverTime; /* milliseconds */ ! 55: extern long ScreenSaverInterval; /* milliseconds */ ! 56: extern ClientPtr ConnectionTranslation[]; ! 57: ! 58: extern Bool clientsDoomed; ! 59: extern Bool NewOutputPending; ! 60: extern Bool AnyClientsWriteBlocked; ! 61: ! 62: extern void CheckConnections(); ! 63: extern void EstablishNewConnections(); ! 64: ! 65: extern int errno; ! 66: ! 67: int isItTimeToYield = 1; ! 68: ! 69: #ifdef MULTI_X_HACK ! 70: extern int XMulti; ! 71: extern int sigwindow_handler(); ! 72: #endif MULTI_X_HACK ! 73: ! 74: #ifdef XTESTEXT1 ! 75: /* ! 76: * defined in xtestext1dd.c ! 77: */ ! 78: extern int playback_on; ! 79: #endif /* XTESTEXT1 */ ! 80: ! 81: /***************** ! 82: * WaitForSomething: ! 83: * Make the server suspend until there is ! 84: * 1. data from clients or ! 85: * 2. input events available or ! 86: * 3. ddx notices something of interest (graphics ! 87: * queue ready, etc.) or ! 88: * 4. clients that have buffered replies/events are ready ! 89: * ! 90: * If the time between INPUT events is ! 91: * greater than ScreenSaverTime, the display is turned off (or ! 92: * saved, depending on the hardware). So, WaitForSomething() ! 93: * has to handle this also (that's why the select() has a timeout. ! 94: * For more info on ClientsWithInput, see ReadRequestFromClient(). ! 95: * pClientsReady is a mask, the bits set are ! 96: * indices into the o.s. depedent table of available clients. ! 97: * (In this case, there is no table -- the index is the socket ! 98: * file descriptor.) ! 99: *****************/ ! 100: ! 101: #ifdef ISOCONN ! 102: /* ! 103: * cannot use select in TSAP stuff, so...see TNetAccept ! 104: * (which calls xselect, which calls select...) ! 105: */ ! 106: ! 107: #include <isode/tsap.h> ! 108: #endif /* ISOCONN */ ! 109: ! 110: static long timeTilFrob = 0; /* while screen saving */ ! 111: ! 112: #if (mskcnt>4) ! 113: /* ! 114: * This is a macro if mskcnt <= 4 ! 115: */ ! 116: ANYSET(src) ! 117: long *src; ! 118: { ! 119: int i; ! 120: ! 121: for (i=0; i<mskcnt; i++) ! 122: if (src[ i ]) ! 123: return (TRUE); ! 124: return (FALSE); ! 125: } ! 126: #endif ! 127: ! 128: WaitForSomething(pClientsReady, nready, pNewClients, nnew) ! 129: ClientPtr *pClientsReady; ! 130: int *nready; ! 131: ClientPtr *pNewClients; ! 132: int *nnew; ! 133: { ! 134: int i; ! 135: struct timeval waittime, *wt; ! 136: long timeout; ! 137: long clientsReadable[mskcnt]; ! 138: long clientsWritable[mskcnt]; ! 139: long curclient; ! 140: int selecterr; ! 141: #ifdef ISOCONN ! 142: int vecp; ! 143: char *vec[4]; ! 144: struct TSAPdisconnect tds; ! 145: struct TSAPdisconnect *td = &tds; ! 146: #endif /* ISOCONN */ ! 147: ! 148: #ifdef hpux ! 149: long ready_inputs; /* to tell HIL drivers about input */ ! 150: #endif hpux ! 151: ! 152: *nready = 0; ! 153: *nnew = 0; ! 154: CLEARBITS(clientsReadable); ! 155: if (! (ANYSET(ClientsWithInput))) ! 156: { ! 157: /* We need a while loop here to handle ! 158: crashed connections and the screen saver timeout */ ! 159: while (1) ! 160: { ! 161: if (ScreenSaverTime) ! 162: { ! 163: timeout = ScreenSaverTime - TimeSinceLastInputEvent(); ! 164: if (timeout <= 0) /* may be forced by AutoResetServer() */ ! 165: { ! 166: long timeSinceSave; ! 167: ! 168: if (clientsDoomed) ! 169: { ! 170: *nnew = *nready = 0; ! 171: break; ! 172: } ! 173: ! 174: timeSinceSave = -timeout; ! 175: if ((timeSinceSave >= timeTilFrob) && (timeTilFrob >= 0)) ! 176: { ! 177: SaveScreens(SCREEN_SAVER_ON, ScreenSaverActive); ! 178: if (ScreenSaverInterval) ! 179: /* round up to the next ScreenSaverInterval */ ! 180: timeTilFrob = ScreenSaverInterval * ! 181: ((timeSinceSave + ScreenSaverInterval) / ! 182: ScreenSaverInterval); ! 183: else ! 184: timeTilFrob = -1; ! 185: } ! 186: timeout = timeTilFrob - timeSinceSave; ! 187: } ! 188: else ! 189: { ! 190: if (timeout > ScreenSaverTime) ! 191: timeout = ScreenSaverTime; ! 192: timeTilFrob = 0; ! 193: } ! 194: if (timeTilFrob >= 0) ! 195: { ! 196: waittime.tv_sec = timeout / MILLI_PER_SECOND; ! 197: waittime.tv_usec = (timeout % MILLI_PER_SECOND) * ! 198: (1000000 / MILLI_PER_SECOND); ! 199: wt = &waittime; ! 200: } ! 201: else ! 202: { ! 203: wt = NULL; ! 204: } ! 205: } ! 206: else ! 207: wt = NULL; ! 208: #ifdef MULTI_X_HACK ! 209: if (XMulti) { ! 210: ipc_block_handler(); ! 211: signal(SIGWINDOW,sigwindow_handler); ! 212: } ! 213: #endif MULTI_X_HACK ! 214: COPYBITS(AllSockets, LastSelectMask); ! 215: BlockHandler(&wt, LastSelectMask); ! 216: if (NewOutputPending) ! 217: FlushAllOutput(); ! 218: #ifdef XTESTEXT1 ! 219: /* XXX how does this interact with new write block handling? */ ! 220: if (playback_on) { ! 221: wt = &waittime; ! 222: XTestComputeWaitTime (&waittime); ! 223: } ! 224: #endif /* XTESTEXT1 */ ! 225: ! 226: #ifndef ISOCONN ! 227: if (AnyClientsWriteBlocked) ! 228: { ! 229: COPYBITS(ClientsWriteBlocked, clientsWritable); ! 230: i = select (MAXSOCKS, LastSelectMask, clientsWritable, ! 231: (int *) NULL, wt); ! 232: } ! 233: else ! 234: { ! 235: i = select (MAXSOCKS, LastSelectMask, ! 236: (int *) NULL, (int *) NULL, wt); ! 237: } ! 238: selecterr = errno; ! 239: #else /* IS ISOCONN */ ! 240: if (AnyClientsWriteBlocked) ! 241: { ! 242: int secs = wt->tv_sec; ! 243: if (secs == 0 && wt->tv_usec != 0) ! 244: secs = 1; ! 245: COPYBITS(ClientsWriteBlocked, clientsWritable); ! 246: i = TNetAccept(&vecp, vec, MAXSOCKS, LastSelectMask, ! 247: clientsWritable, (int *)NULL, wt->tv_sec, td); ! 248: } ! 249: else ! 250: { ! 251: int secs = wt->tv_sec; ! 252: if (secs == 0 && wt->tv_usec != 0) ! 253: secs = 1; ! 254: i = TNetAccept(&vecp, vec, MAXSOCKS, LastSelectMask, ! 255: (int *)NULL, (int *)NULL, secs, td); ! 256: } ! 257: /* map errors */ ! 258: if (i < 0) { ! 259: if (!DR_FATAL(td->td_reason)) ! 260: errno = EWOULDBLOCK; ! 261: } ! 262: selecterr = errno; ! 263: #endif /* ISOCONN */ ! 264: WakeupHandler(i, LastSelectMask); ! 265: #ifdef XTESTEXT1 ! 266: if (playback_on) { ! 267: i = XTestProcessInputAction (i, &waittime); ! 268: } ! 269: #endif /* XTESTEXT1 */ ! 270: if (i <= 0) /* An error or timeout occurred */ ! 271: { ! 272: #ifdef ISODEBUG ! 273: if (isodexbug) ! 274: fprintf(stderr, "WF: TO or ERR %d\n", i); ! 275: #endif ! 276: CLEARBITS(clientsWritable); ! 277: if (i < 0) ! 278: if (selecterr == EBADF) /* Some client disconnected */ ! 279: { ! 280: CheckConnections (); ! 281: if (! ANYSET (AllClients)) ! 282: return; ! 283: } ! 284: else if (selecterr != EINTR) ! 285: ErrorF("WaitForSomething(): select: errno=%d\n", ! 286: selecterr); ! 287: } ! 288: else ! 289: { ! 290: if (AnyClientsWriteBlocked && ANYSET (clientsWritable)) ! 291: { ! 292: #ifdef ISODEBUG ! 293: if (isodexbug) ! 294: fprintf(stderr, "WF: write\n"); ! 295: #endif ! 296: NewOutputPending = TRUE; ! 297: ORBITS(OutputPending, clientsWritable, OutputPending); ! 298: UNSETBITS(ClientsWriteBlocked, clientsWritable); ! 299: if (! ANYSET(ClientsWriteBlocked)) ! 300: AnyClientsWriteBlocked = FALSE; ! 301: } ! 302: ! 303: #ifdef hpux ! 304: ready_inputs = (LastSelectMask[0] & EnabledDevices); ! 305: ! 306: if (ready_inputs > 0) store_inputs (ready_inputs); ! 307: /* call the HIL driver to gather inputs. */ ! 308: #endif hpux ! 309: ! 310: MASKANDSETBITS(clientsReadable, LastSelectMask, AllClients); ! 311: #ifdef ISOCONN ! 312: /* ! 313: * ISODE version says new connections pending accept if vecp > 0 !! ! 314: */ ! 315: if (vecp > 0) { ! 316: #ifdef ISODEBUG ! 317: if (isodexbug) ! 318: fprintf(stderr, "WF: CX pending\n"); ! 319: #endif ! 320: EstablishNewConnections(pNewClients, nnew, vecp, vec); ! 321: } ! 322: #else /* ISOCONN */ ! 323: if (LastSelectMask[0] & WellKnownConnections) ! 324: EstablishNewConnections(pNewClients, nnew); ! 325: #endif /* ISOCONN */ ! 326: if (*nnew || (LastSelectMask[0] & EnabledDevices) ! 327: || (ANYSET (clientsReadable))) ! 328: break; ! 329: } ! 330: } ! 331: } ! 332: else ! 333: { ! 334: COPYBITS(ClientsWithInput, clientsReadable); ! 335: } ! 336: ! 337: if (ANYSET(clientsReadable)) ! 338: { ! 339: #ifdef ISODEBUG ! 340: if (isodexbug) ! 341: fprintf(stderr, "WF: readable\n"); ! 342: #endif ! 343: for (i=0; i<mskcnt; i++) ! 344: { ! 345: while (clientsReadable[i]) ! 346: { ! 347: curclient = ffs (clientsReadable[i]) - 1; ! 348: pClientsReady[(*nready)++] = ! 349: ConnectionTranslation[curclient + (32 * i)]; ! 350: clientsReadable[i] &= ~(1 << curclient); ! 351: } ! 352: } ! 353: } ! 354: } ! 355: ! 356: ! 357:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.