void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask) { /* * Zero timeout. */ static struct timeval zero; /* * Current timestamp. */ static int now; /* * Pending bytes to write to the * network. */ static int flushable; /* * Set if we need to synchronize * any drawable. */ static int synchronize; #ifdef BLOCKS fprintf(stderr, "[Begin block]\n"); #endif now = GetTimeInMillis(); #ifdef NX_DEBUG_INPUT if (nxagentDebugInputDevices == 1 && now - nxagentLastInputDevicesDumpTime > 5000) { nxagentLastInputDevicesDumpTime = now; nxagentDumpInputDevicesState(); } #endif if (nxagentNeedConnectionChange() == 1) { #ifdef TEST fprintf(stderr, "nxagentBlockHandler: Calling nxagentHandleConnectionChanges " "with ioError [%d] sigHup [%d].\n", nxagentException.ioError, nxagentException.sigHup); #endif nxagentHandleConnectionChanges(); } if (nxagentOption(Rootless) && nxagentLastWindowDestroyed && nxagentRootlessDialogPid == 0 && now > nxagentLastWindowDestroyedTime + 30 * 1000 && !nxagentOption(NoRootlessExit)) { #ifdef WARNING fprintf(stderr, "nxagentBlockHandler: No application running. Closing the session.\n"); #endif nxagentTerminateSession(); } #ifdef TEST if (nxagentLastWindowDestroyed == 1) { fprintf(stderr, "nxagentBlockHandler: Elapsed time [%lu].\n", now - nxagentLastWindowDestroyedTime); } #endif /* * Slow down the agent if the session is * not connected to a valid display. */ if (NXDisplayError(nxagentDisplay) == 1 && nxagentShadowCounter == 0) { usleep(LOOP_DELAY_IF_DOWN * 1000); now = GetTimeInMillis(); } /* * Update the shadow display. This is * only for test purposes. */ #ifdef DUMP nxagentPixmapOnShadowDisplay(NULL); nxagentFbOnShadowDisplay(); #endif /* * We need this here because some window * configuration changes can be generated * by the X server outside the control of * the DIX. */ nxagentFlushConfigureWindow(); /* * Check whether there is any drawable to * synchronize. */ #ifdef TEST fprintf(stderr, "nxagentBlockHandler: Checking synchronization at %s with " "[%d][%d][%d].\n", GetTimeInMillisAsString(), nxagentCorruptedWindows, nxagentCorruptedBackgrounds, nxagentCorruptedPixmaps); #endif synchronize = (nxagentCorruptedWindows > 0 || nxagentCorruptedBackgrounds > 0 || nxagentCorruptedPixmaps > 0); /* * The synchronization function requires a mask as * parameter: * * EVENT_BREAK Breaks if an user input, like * a key press or a mouse move, * is detected. * * CONGESTION_BREAK Breaks if the congestion beco- * mes greater than 4. * * BLOCKING_BREAK Breaks if the display descript- * or becomes blocked for write * during the loop. * * ALWAYS_BREAK Any of the previous conditions * is met. * * NEVER_BREAK The loop continues until all * the drawables are synchronized. */ if (synchronize == 1) { /* * We should not enter the synchronization * loop if there is any user input pending, * i.e. if we are in the middle of a scroll * operation. */ if (nxagentForceSynchronization == 1) { #ifdef TEST fprintf(stderr, "nxagentBlockHandler: Going to force a synchronization at %s.\n", GetTimeInMillisAsString()); #endif nxagentSynchronizationLoop(NEVER_BREAK); nxagentForceSynchronization = 0; } else if (nxagentUserInput(NULL) == 0 && nxagentBlocking == 0 && nxagentCongestion <= 4) { #ifdef TEST fprintf(stderr, "nxagentBlockHandler: Going to synchronize at %s.\n", GetTimeInMillisAsString()); #endif nxagentSynchronizationLoop(ALWAYS_BREAK); } #ifdef TEST else { fprintf(stderr, "nxagentBlockHandler: Not synchronizing with [%d][%d].\n", nxagentBlocking, nxagentCongestion); } #endif /* * Check if we have more corrupted resources * and whether the conditions are satisfied * to continue with the synchronization. */ synchronize = (nxagentCongestion <= 4 && (nxagentCorruptedWindows > 0 || nxagentCorruptedBackgrounds > 0 || nxagentCorruptedPixmaps > 0)); if (nxagentSkipImage == 0 && synchronize == 1) { #ifdef TEST fprintf(stderr, "nxagentBlockHandler: Setting a zero timeout with [%d][%d][%d] and " "congestion [%d].\n", nxagentCorruptedWindows, nxagentCorruptedBackgrounds, nxagentCorruptedPixmaps, nxagentCongestion); #endif zero.tv_sec = 0; zero.tv_usec = 0; *timeout = &zero; } #ifdef TEST else { if (nxagentCorruptedWindows == 0 && nxagentCorruptedBackgrounds == 0 && nxagentCorruptedPixmaps == 0) { fprintf(stderr, "nxagentBlockHandler: Nothing more to synchronize at %s.\n", GetTimeInMillisAsString()); } else { fprintf(stderr, "nxagentBlockHandler: Delaying synchronization with [%d][%d][%d] and " "congestion [%d].\n", nxagentCorruptedWindows, nxagentCorruptedBackgrounds, nxagentCorruptedPixmaps, nxagentCongestion); } } #endif } /* * If the remote X server is blocking, reduce the * amount of data sent in a single display update * by reducing the size of the display buffer. */ #ifdef DYNAMIC_DISPLAY_BUFFER if (nxagentBlocking == 1 && nxagentBuffer > MINIMUM_DISPLAY_BUFFER) { nxagentBuffer >>= 1; if (nxagentBuffer < MINIMUM_DISPLAY_BUFFER) { nxagentBuffer = MINIMUM_DISPLAY_BUFFER; } #ifdef TEST fprintf(stderr, "nxagentDispatchHandler: Reducing the display buffer to [%d] bytes.\n", nxagentBuffer); #endif NXSetDisplayBuffer(nxagentDisplay, nxagentBuffer); }
int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result) { KeySym sym; int index = 0; *result = doNothing; /* * I don't know how much hard work is doing this operation. * Do we need a cache ? */ sym = XKeycodeToKeysym(nxagentDisplay, X -> keycode, index); if (sym == XK_VoidSymbol || sym == NoSymbol) { return 0; } #ifdef TEST fprintf(stderr, "nxagentCheckSpecialKeystroke: got code %x - state %x - sym %lx\n", X -> keycode, X -> state, sym); #endif /* * Check special keys. */ /* * FIXME: We should use the keysym instead that the keycode * here. */ if (X -> keycode == 130 && nxagentIpaq) { *result = doStartKbd; return 1; } if ((X -> state & nxagentAltMetaMask) && ((X -> state & (ControlMask | ShiftMask)) == ControlMask)) { switch (sym) { #ifdef DEBUG_TREE case XK_q: case XK_Q: { *result = doDebugTree; break; } #endif /* DEBUG_TREE */ case XK_t: case XK_T: { *result = doCloseSession; break; } case XK_f: case XK_F: { if (nxagentOption(Rootless) == False) { *result = doSwitchAllScreens; } break; } case XK_m: case XK_M: { if (nxagentOption(Rootless) == False) { *result = doMinimize; } break; } case XK_Left: case XK_KP_Left: { if (nxagentOption(Rootless) == False && nxagentOption(DesktopResize) == False) { *result = doViewportLeft; } break; } case XK_Up: case XK_KP_Up: { if (nxagentOption(Rootless) == False && nxagentOption(DesktopResize) == False) { *result = doViewportUp; } break; } case XK_Right: case XK_KP_Right: { if (nxagentOption(Rootless) == False && nxagentOption(DesktopResize) == False) { *result = doViewportRight; } break; } case XK_Down: case XK_KP_Down: { if (nxagentOption(Rootless) == 0 && nxagentOption(DesktopResize) == 0) { *result = doViewportDown; } break; } case XK_R: case XK_r: { if (nxagentOption(Rootless) == 0) { *result = doSwitchResizeMode; } break; } case XK_E: case XK_e: { *result = doSwitchDeferMode; break; } case XK_BackSpace: case XK_Terminate_Server: { /* * Discard Ctrl-Alt-BackSpace key. */ return 1; break; } case XK_J: case XK_j: { nxagentForceSynchronization = 1; return 1; } #ifdef DUMP case XK_A: case XK_a: { /* * Used to test the lazy encoding. */ nxagentRegionsOnScreen(); return 1; } #endif #ifdef NX_DEBUG_INPUT case XK_X: case XK_x: { /* * Used to test the input devices state. */ if (X -> type == KeyPress) { if (nxagentDebugInputDevices == 0) { fprintf(stderr, "Info: Turning input devices debug ON.\n"); nxagentDebugInputDevices = 1; } else { fprintf(stderr, "Info: Turning input devices debug OFF.\n"); nxagentDebugInputDevices = 0; nxagentLastInputDevicesDumpTime = 0; } } return 1; } case XK_Y: case XK_y: { /* * Used to deactivate input devices grab. */ if (X -> type == KeyPress) { nxagentDeactivateInputDevicesGrabs(); } return 1; } #endif } } else if ((X -> state & nxagentAltMetaMask) && ((X -> state & (ControlMask | ShiftMask)) == (ControlMask | ShiftMask))) { switch (sym) { case XK_f: case XK_F: { if (nxagentOption(Rootless) == 0) { *result = doSwitchFullscreen; } break; } case XK_Left: case XK_KP_Left: { if (nxagentOption(Rootless) == 0 && nxagentOption(DesktopResize) == 0) { *result = doViewportMoveLeft; } break; } case XK_Up: case XK_KP_Up: { if (nxagentOption(Rootless) == 0 && nxagentOption(DesktopResize) == 0) { *result = doViewportMoveUp; } break; } case XK_Right: case XK_KP_Right: { if (nxagentOption(Rootless) == 0 && nxagentOption(DesktopResize) == 0) { *result = doViewportMoveRight; } break; } case XK_Down: case XK_KP_Down: { if (nxagentOption(Rootless) == 0 && nxagentOption(DesktopResize) == 0) { *result = doViewportMoveDown; } break; } } } return (*result == doNothing) ? 0 : 1; }