static void resume(pmEvent event, Bool undo) { int i; InputInfoPtr pInfo; xf86AccessEnter(); for (i = 0; i < xf86NumScreens; i++) { if (xf86Screens[i]->PMEvent) xf86Screens[i]->PMEvent(xf86Screens[i], event, undo); else { xf86Screens[i]->vtSema = TRUE; xf86Screens[i]->EnterVT(xf86Screens[i]); } } OsReleaseSIGIO(); for (i = 0; i < xf86NumScreens; i++) { if (xf86Screens[i]->EnableDisableFBAccess) (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE); } dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); pInfo = xf86InputDevs; while (pInfo) { EnableDevice(pInfo->dev, TRUE); pInfo = pInfo->next; } }
static void xf86ReleaseKeys(DeviceIntPtr pDev) { KeyClassPtr keyc; int i; if (!pDev || !pDev->key) return; keyc = pDev->key; /* * Hmm... here is the biggest hack of every time ! * It may be possible that a switch-vt procedure has finished BEFORE * you released all keys neccessary to do this. That peculiar behavior * can fool the X-server pretty much, cause it assumes that some keys * were not released. TWM may stuck alsmost completly.... * OK, what we are doing here is after returning from the vt-switch * exeplicitely unrelease all keyboard keys before the input-devices * are reenabled. */ for (i = keyc->xkbInfo->desc->min_key_code; i < keyc->xkbInfo->desc->max_key_code; i++) { if (key_is_down(pDev, i, KEY_POSTED)) { OsBlockSIGIO(); QueueKeyboardEvents(pDev, KeyRelease, i, NULL); OsReleaseSIGIO(); } } }
static void ephyrWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { OsBlockSIGIO(); ephyrCursorScreen = pScreen; miPointerWarpCursor(inputInfo.pointer, pScreen, x, y); OsReleaseSIGIO(); }
/* ARGSUSED */ void xf86Wakeup(pointer blockData, int err, pointer pReadmask) { fd_set *LastSelectMask = (fd_set *) pReadmask; fd_set devicesWithInput; InputInfoPtr pInfo; if (err >= 0) { XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices); if (XFD_ANYSET(&devicesWithInput)) { pInfo = xf86InputDevs; while (pInfo) { if (pInfo->read_input && pInfo->fd >= 0 && (FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) { OsBlockSIGIO(); /* * Remove the descriptior from the set because more than one * device may share the same file descriptor. */ FD_CLR(pInfo->fd, &devicesWithInput); pInfo->read_input(pInfo); OsReleaseSIGIO(); } pInfo = pInfo->next; } } } if (err >= 0) { /* we don't want the handlers called if select() */ IHPtr ih; /* returned with an error condition, do we? */ for (ih = InputHandlers; ih; ih = ih->next) { if (ih->enabled && ih->fd >= 0 && ih->ihproc && (FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) { ih->ihproc(ih->fd, ih->data); } } } if (xf86VTSwitchPending()) xf86VTSwitch(); }
static void DoApmEvent(pmEvent event, Bool undo) { int i; switch (event) { #if 0 case XF86_APM_SYS_STANDBY: case XF86_APM_USER_STANDBY: #endif case XF86_APM_SYS_SUSPEND: case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend? */ case XF86_APM_USER_SUSPEND: /* should we do this ? */ if (!undo && !suspended) { suspend(event, undo); suspended = TRUE; } else if (undo && suspended) { resume(event, undo); suspended = FALSE; } break; #if 0 case XF86_APM_STANDBY_RESUME: #endif case XF86_APM_NORMAL_RESUME: case XF86_APM_CRITICAL_RESUME: if (suspended) { resume(event, undo); suspended = FALSE; } break; default: OsBlockSIGIO(); for (i = 0; i < xf86NumScreens; i++) { if (xf86Screens[i]->PMEvent) { xf86Screens[i]->PMEvent(xf86Screens[i], event, undo); } } OsReleaseSIGIO(); break; } }
static void block_sigio_test(void) { #ifdef SIG_BLOCK sigset_t current; sigemptyset(¤t); assert(!sig_is_blocked(SIGIO)); /* block once */ OsBlockSIGIO(); assert(sig_is_blocked(SIGIO)); OsReleaseSIGIO(); assert(!sig_is_blocked(SIGIO)); /* block twice, nested */ OsBlockSIGIO(); assert(sig_is_blocked(SIGIO)); OsBlockSIGIO(); assert(sig_is_blocked(SIGIO)); OsReleaseSIGIO(); assert(sig_is_blocked(SIGIO)); OsReleaseSIGIO(); assert(!sig_is_blocked(SIGIO)); /* block all */ OsBlockSignals(); assert(sig_is_blocked(SIGIO)); OsReleaseSignals(); assert(!sig_is_blocked(SIGIO)); /* block all nested */ OsBlockSignals(); assert(sig_is_blocked(SIGIO)); OsBlockSignals(); assert(sig_is_blocked(SIGIO)); OsReleaseSignals(); assert(sig_is_blocked(SIGIO)); OsReleaseSignals(); assert(!sig_is_blocked(SIGIO)); /* mix the two */ /* ABBA */ OsBlockSignals(); assert(sig_is_blocked(SIGIO)); OsBlockSIGIO(); assert(sig_is_blocked(SIGIO)); OsReleaseSIGIO(); assert(sig_is_blocked(SIGIO)); OsReleaseSignals(); assert(!sig_is_blocked(SIGIO)); /* ABAB */ OsBlockSignals(); assert(sig_is_blocked(SIGIO)); OsBlockSIGIO(); assert(sig_is_blocked(SIGIO)); OsReleaseSignals(); assert(sig_is_blocked(SIGIO)); OsReleaseSIGIO(); assert(!sig_is_blocked(SIGIO)); /* BAAB */ OsBlockSIGIO(); assert(sig_is_blocked(SIGIO)); OsBlockSignals(); assert(sig_is_blocked(SIGIO)); OsReleaseSignals(); assert(sig_is_blocked(SIGIO)); OsReleaseSIGIO(); assert(!sig_is_blocked(SIGIO)); /* BABA */ OsBlockSIGIO(); assert(sig_is_blocked(SIGIO)); OsBlockSignals(); assert(sig_is_blocked(SIGIO)); OsReleaseSIGIO(); assert(sig_is_blocked(SIGIO)); OsReleaseSignals(); assert(!sig_is_blocked(SIGIO)); #endif }
void xf86UnblockSIGIO(int wasset) { OsReleaseSIGIO(); }
int xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure) { struct sigaction sa; struct sigaction osa; int i; int installed = FALSE; if (!xf86Info.useSIGIO) return 0; for (i = 0; i < MAX_FUNCS; i++) { if (!xf86SigIOFuncs[i].f) { if (xf86IsPipe(fd)) return 0; OsBlockSIGIO(); #ifdef O_ASYNC if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_ASYNC) == -1) { xf86Msg(X_WARNING, "fcntl(%d, O_ASYNC): %s\n", fd, strerror(errno)); } else { if (fcntl(fd, F_SETOWN, getpid()) == -1) { xf86Msg(X_WARNING, "fcntl(%d, F_SETOWN): %s\n", fd, strerror(errno)); } else { installed = TRUE; } } #endif #ifdef I_SETSIG /* System V Streams - used on Solaris for input devices */ if (!installed && isastream(fd)) { if (ioctl(fd, I_SETSIG, S_INPUT | S_ERROR | S_HANGUP) == -1) { xf86Msg(X_WARNING, "fcntl(%d, I_SETSIG): %s\n", fd, strerror(errno)); } else { installed = TRUE; } } #endif if (!installed) { OsReleaseSIGIO(); return 0; } sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sa.sa_flags = 0; sa.sa_handler = xf86SIGIO; sigaction(SIGIO, &sa, &osa); xf86SigIOFuncs[i].fd = fd; xf86SigIOFuncs[i].closure = closure; xf86SigIOFuncs[i].f = f; if (i >= xf86SigIOMax) xf86SigIOMax = i + 1; if (fd >= xf86SigIOMaxFd) xf86SigIOMaxFd = fd + 1; FD_SET(fd, &xf86SigIOMask); OsReleaseSIGIO(); return 1; } /* Allow overwriting of the closure and callback */ else if (xf86SigIOFuncs[i].fd == fd) { xf86SigIOFuncs[i].closure = closure; xf86SigIOFuncs[i].f = f; return 1; } } return 0; }
/* * xf86VTSwitch -- * Handle requests for switching the vt. */ static void xf86VTSwitch(void) { int i; static int prevSIGIO; InputInfoPtr pInfo; IHPtr ih; DebugF("xf86VTSwitch()\n"); #ifdef XFreeXDGA if (!DGAVTSwitch()) return; #endif /* * Since all screens are currently all in the same state it is sufficient * check the first. This might change in future. */ if (xf86Screens[0]->vtSema) { DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n", BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE)); #ifdef DPMSExtension if (DPMSPowerLevel != DPMSModeOn) DPMSSet(serverClient, DPMSModeOn); #endif for (i = 0; i < xf86NumScreens; i++) { if (!(dispatchException & DE_TERMINATE)) if (xf86Screens[i]->EnableDisableFBAccess) (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], FALSE); } /* * Keep the order: Disable Device > LeaveVT * EnterVT > EnableDevice */ for (ih = InputHandlers; ih; ih = ih->next) xf86DisableInputHandler(ih); for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) { if (pInfo->dev) { if (!pInfo->dev->enabled) pInfo->flags |= XI86_DEVICE_DISABLED; xf86ReleaseKeys(pInfo->dev); ProcessInputEvents(); DisableDevice(pInfo->dev, TRUE); } } OsBlockSIGIO(); for (i = 0; i < xf86NumScreens; i++) xf86Screens[i]->LeaveVT(xf86Screens[i]); for (i = 0; i < xf86NumGPUScreens; i++) xf86GPUScreens[i]->LeaveVT(xf86GPUScreens[i]); xf86AccessLeave(); /* We need this here, otherwise */ if (!xf86VTSwitchAway()) { /* * switch failed */ DebugF("xf86VTSwitch: Leave failed\n"); xf86AccessEnter(); for (i = 0; i < xf86NumScreens; i++) { if (!xf86Screens[i]->EnterVT(xf86Screens[i])) FatalError("EnterVT failed for screen %d\n", i); } for (i = 0; i < xf86NumGPUScreens; i++) { if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i])) FatalError("EnterVT failed for gpu screen %d\n", i); } if (!(dispatchException & DE_TERMINATE)) { for (i = 0; i < xf86NumScreens; i++) { if (xf86Screens[i]->EnableDisableFBAccess) (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE); } } dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); pInfo = xf86InputDevs; while (pInfo) { if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0) EnableDevice(pInfo->dev, TRUE); pInfo->flags &= ~XI86_DEVICE_DISABLED; pInfo = pInfo->next; } for (ih = InputHandlers; ih; ih = ih->next) xf86EnableInputHandler(ih); OsReleaseSIGIO(); } else { #ifdef XF86PM if (xf86OSPMClose) xf86OSPMClose(); xf86OSPMClose = NULL; #endif for (i = 0; i < xf86NumScreens; i++) { /* * zero all access functions to * trap calls when switched away. */ xf86Screens[i]->vtSema = FALSE; } if (xorgHWAccess) xf86DisableIO(); } } else { DebugF("xf86VTSwitch: Entering\n"); if (!xf86VTSwitchTo()) return; #ifdef XF86PM xf86OSPMClose = xf86OSPMOpen(); #endif if (xorgHWAccess) xf86EnableIO(); xf86AccessEnter(); for (i = 0; i < xf86NumScreens; i++) { xf86Screens[i]->vtSema = TRUE; if (!xf86Screens[i]->EnterVT(xf86Screens[i])) FatalError("EnterVT failed for screen %d\n", i); } for (i = 0; i < xf86NumGPUScreens; i++) { xf86GPUScreens[i]->vtSema = TRUE; if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i])) FatalError("EnterVT failed for gpu screen %d\n", i); } for (i = 0; i < xf86NumScreens; i++) { if (xf86Screens[i]->EnableDisableFBAccess) (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE); } /* Turn screen saver off when switching back */ dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); pInfo = xf86InputDevs; while (pInfo) { if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0) EnableDevice(pInfo->dev, TRUE); pInfo->flags &= ~XI86_DEVICE_DISABLED; pInfo = pInfo->next; } for (ih = InputHandlers; ih; ih = ih->next) xf86EnableInputHandler(ih); OsReleaseSIGIO(); } }