summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2006-09-21 17:03:34 -0700
committerEric Anholt <eric@anholt.net>2006-09-27 13:30:09 -0700
commit117ff04b504578a24dff70659e2db1b81aaa1177 (patch)
tree467c91e97e15f03d62cd591d6b83809e6a3e7f8a /src
parentdaade50ca271d1cdf236bbe84afade85d4111ac9 (diff)
Attempt to make the ACPI hotkey support a little more modesetting-compatible.
Previously, we watched for the BIOS to have changed the layout, and repaired the resulting configuration. Now, we request that the BIOS make no changes, but leave a note in a register for when the key has been pressed. When we notice this, we reprobe monitors and turn on/off the things we find. This is a temporary solution until we can get the hotkey hooked up as an input key to external applications to control the change using RandR 1.2. It is also untested as neither of my laptops do anything with the hotkey. However, this code does result in many fewer BIOS calls.
Diffstat (limited to 'src')
-rw-r--r--src/i810_reg.h4
-rw-r--r--src/i830.h3
-rw-r--r--src/i830_driver.c517
3 files changed, 71 insertions, 453 deletions
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 275d858c..3a15a464 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -94,6 +94,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define LINEAR_MODE_ENABLE 0x02
#define PAGE_MAPPING_ENABLE 0x01
+#define HOTKEY_VBIOS_SWITCH_BLOCK 0x80
+#define HOTKEY_SWITCH 0x20
+#define HOTKEY_TOGGLE 0x10
+
/* Blitter control, p378
*/
#define BITBLT_CNTL 0x7000c
diff --git a/src/i830.h b/src/i830.h
index 3a939312..4a95441c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -393,10 +393,7 @@ typedef struct _I830Rec {
CARD32 saveSWF4;
Bool checkDevices;
- int monitorSwitch;
int operatingDevices;
- int toggleDevices;
- int lastDevice0, lastDevice1, lastDevice2;
/* These are indexed by the display types */
Bool displayAttached[NumDisplayTypes];
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 75ea480c..c3ae8c30 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -438,116 +438,6 @@ Check5fStatus(ScrnInfoPtr pScrn, int func, int ax)
}
}
-static int
-GetToggleList(ScrnInfoPtr pScrn, int toggle)
-{
- vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
-
- DPRINTF(PFX, "GetToggleList\n");
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x5f64;
- pVbe->pInt10->bx = 0x500;
-
- pVbe->pInt10->bx |= toggle;
-
- xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
- if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Toggle (%d) 0x%x\n", toggle, pVbe->pInt10->cx);
- return pVbe->pInt10->cx & 0xffff;
- }
-
- return 0;
-}
-
-static int
-GetNextDisplayDeviceList(ScrnInfoPtr pScrn, int toggle)
-{
- vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
- int devices = 0;
- int pipe = 0;
- int i;
-
- DPRINTF(PFX, "GetNextDisplayDeviceList\n");
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x5f64;
- pVbe->pInt10->bx = 0xA00;
- pVbe->pInt10->bx |= toggle;
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
-
- xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
- if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
- return 0;
-
- for (i=0; i<(pVbe->pInt10->cx & 0xff); i++) {
- CARD32 VODA = (CARD32)((CARD32*)pVbe->memory)[i];
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Next ACPI _DGS [%d] 0x%lx\n",
- i, (unsigned long) VODA);
-
- /* Check if it's a custom Video Output Device Attribute */
- if (!(VODA & 0x80000000))
- continue;
-
- pipe = (VODA & 0x000000F0) >> 4;
-
- if (pipe != 0 && pipe != 1) {
- pipe = 0;
-#if 0
- ErrorF("PIPE %d\n",pipe);
-#endif
- }
-
- switch ((VODA & 0x00000F00) >> 8) {
- case 0x0:
- case 0x1: /* CRT */
- devices |= PIPE_CRT << (pipe == 1 ? 8 : 0);
- break;
- case 0x2: /* TV/HDTV */
- devices |= PIPE_TV << (pipe == 1 ? 8 : 0);
- break;
- case 0x3: /* DFP */
- devices |= PIPE_DFP << (pipe == 1 ? 8 : 0);
- break;
- case 0x4: /* LFP */
- devices |= PIPE_LFP << (pipe == 1 ? 8 : 0);
- break;
- }
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle devices 0x%x\n", devices);
-
- return devices;
-}
-
-static int
-GetAttachableDisplayDeviceList(ScrnInfoPtr pScrn)
-{
- vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
- int i;
-
- DPRINTF(PFX, "GetAttachableDisplayDeviceList\n");
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x5f64;
- pVbe->pInt10->bx = 0x900;
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
-
- xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
- if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
- return 0;
-
- for (i=0; i<(pVbe->pInt10->cx & 0xff); i++)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Attachable device 0x%lx.\n",
- (unsigned long) ((CARD32*)pVbe->memory)[i]);
-
- return pVbe->pInt10->cx & 0xffff;
-}
-
struct panelid {
short hsize;
short vsize;
@@ -1217,6 +1107,31 @@ I830IsPrimary(ScrnInfoPtr pScrn)
return TRUE;
}
+#define HOTKEY_BIOS_SWITCH 0
+#define HOTKEY_DRIVER_NOTIFY 1
+
+/**
+ * Controls the BIOS's behavior on hotkey switch.
+ *
+ * If the mode is HOTKEY_BIOS_SWITCH, the BIOS will be set to do a mode switch
+ * on its own and update the state in the scratch register.
+ * If the mode is HOTKEY_DRIVER_NOTIFY, the BIOS won't do a mode switch and
+ * will just update the state to represent what it would have been switched to.
+ */
+static void
+i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD8 gr18;
+
+ gr18 = pI830->readControl(pI830, GRX, 0x18);
+ if (mode == HOTKEY_BIOS_SWITCH)
+ gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK;
+ else
+ gr18 |= HOTKEY_VBIOS_SWITCH_BLOCK;
+ pI830->writeControl(pI830, GRX, 0x18, gr18);
+}
+
static Bool
I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
{
@@ -2179,28 +2094,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Maximum frambuffer space: %d kByte\n", pScrn->videoRam);
- /* XXX Move this to a header. */
-#define VIDEO_BIOS_SCRATCH 0x18
-
-#if 1
- /*
- * XXX This should be in ScreenInit/EnterVT. PreInit should not leave the
- * state changed.
- */
- /* Enable hot keys by writing the proper value to GR18 */
- {
- CARD8 gr18;
-
- gr18 = pI830->readControl(pI830, GRX, VIDEO_BIOS_SCRATCH);
- gr18 &= ~0x80; /*
- * Clear Hot key bit so that Video
- * BIOS performs the hot key
- * servicing
- */
- pI830->writeControl(pI830, GRX, VIDEO_BIOS_SCRATCH, gr18);
- }
-#endif
-
/*
* Limit videoram available for mode selection to what the video
* BIOS can see.
@@ -3734,6 +3627,8 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
TimerCancel(pI830->devicesTimer);
pI830->devicesTimer = NULL;
+ i830SetHotkeyControl(pScrn, HOTKEY_BIOS_SWITCH);
+
#ifdef I830_XV
/* Give the video overlay code a chance to shutdown. */
I830VideoSwitchModeBefore(pScrn, NULL);
@@ -3951,9 +3846,6 @@ I830BIOSEnterVT(int scrnIndex, int flags)
pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
#endif
- /* Setup for device monitoring status */
- pI830->monitorSwitch = pI830->toggleDevices = INREG(SWF0) & 0x0000FFFF;
-
if (I830IsPrimary(pScrn))
if (!I830BindAGPMemory(pScrn))
return FALSE;
@@ -4003,6 +3895,13 @@ I830BIOSEnterVT(int scrnIndex, int flags)
}
#endif
+ /* Set the hotkey to just notify us. We can check its results periodically
+ * in the CheckDevicesTimer. Eventually we want the kernel to just hand us
+ * an input event when someone presses the button, but for now we just have
+ * to poll.
+ */
+ i830SetHotkeyControl(pScrn, HOTKEY_DRIVER_NOTIFY);
+
if (pI830->checkDevices)
pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn);
@@ -4367,15 +4266,6 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo)
ErrorF("I830PMEvent: Capability change\n");
- /* ACPI Toggle */
- pI830->toggleDevices = GetNextDisplayDeviceList(pScrn, 1);
- if (xf86IsEntityShared(pScrn->entityList[0])) {
- I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
- pI8302->toggleDevices = pI830->toggleDevices;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle to 0x%x\n",pI830->toggleDevices);
-
I830CheckDevicesTimer(NULL, 0, pScrn);
SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
break;
@@ -4385,27 +4275,16 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo)
return TRUE;
}
-static int CountBits(int a)
-{
- int i;
- int b = 0;
-
- for (i=0;i<8;i++) {
- if (a & (1<<i))
- b+=1;
- }
-
- return b;
-}
-
-static CARD32
-I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
-{
- ScrnInfoPtr pScrn = (ScrnInfoPtr) arg;
- I830Ptr pI830 = I830PTR(pScrn);
- int cloned = 0;
#if 0
+/**
+ * This function is used for testing of the screen detect functions from the
+ * periodic timer.
+ */
+static void
+i830MonitorDetectDebugger(ScrnInfoPtr pScrn)
+{
Bool found_crt;
+ I830Ptr pI830 = I830PTR(pScrn);
int start, finish, i;
if (!pScrn->vtSema)
@@ -4431,303 +4310,41 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Detected SDVO as %s in %dms\n",
found_sdvo ? "connected" : "disconnected", finish - start);
}
+}
#endif
- if (pScrn->vtSema) {
- /* Check for monitor lid being closed/opened and act accordingly */
- CARD32 adjust;
- CARD32 temp = INREG(SWF0) & 0x0000FFFF;
- int fixup = 0;
- I830Ptr pI8301;
- I830Ptr pI8302 = NULL;
-
- if (I830IsPrimary(pScrn))
- pI8301 = pI830;
- else
- pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
-
- if (xf86IsEntityShared(pScrn->entityList[0]))
- pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
-
- /* this avoids several BIOS calls if possible */
- if (pI830->monitorSwitch != temp || pI830->monitorSwitch != pI830->toggleDevices) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Hotkey switch to 0x%lx.\n", (unsigned long) temp);
-
- if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
- (*pI830->AccelInfoRec->Sync)(pScrn);
- pI830->AccelInfoRec->NeedToSync = FALSE;
- if (xf86IsEntityShared(pScrn->entityList[0]))
- pI8302->AccelInfoRec->NeedToSync = FALSE;
- }
-
- GetAttachableDisplayDeviceList(pScrn);
-
- pI8301->lastDevice0 = pI8301->lastDevice1;
- pI8301->lastDevice1 = pI8301->lastDevice2;
- pI8301->lastDevice2 = pI8301->monitorSwitch;
-
- if (temp != pI8301->lastDevice1 &&
- temp != pI8301->lastDevice2) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected three device configs.\n");
- } else
- if (CountBits(temp & 0xff) > 1) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected cloned pipe mode (A).\n");
- if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone)
- temp = pI8301->MonType2 << 8 | pI8301->MonType1;
- } else
- if (CountBits((temp & 0xff00) >> 8) > 1) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected cloned pipe mode (B).\n");
- if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone)
- temp = pI8301->MonType2 << 8 | pI8301->MonType1;
- } else
- if (pI8301->lastDevice1 && pI8301->lastDevice2) {
- if ( ((pI8301->lastDevice1 & 0xFF00) == 0) &&
- ((pI8301->lastDevice2 & 0x00FF) == 0) ) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected last devices (1).\n");
- cloned = 1;
- } else if ( ((pI8301->lastDevice2 & 0xFF00) == 0) &&
- ((pI8301->lastDevice1 & 0x00FF) == 0) ) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected last devices (2).\n");
- cloned = 1;
- } else
- cloned = 0;
- }
-
- if (cloned &&
- ((CountBits(pI8301->lastDevice1 & 0xff) > 1) ||
- ((CountBits((pI8301->lastDevice1 & 0xff00) >> 8) > 1))) ) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected duplicate (1).\n");
- cloned = 0;
- } else
- if (cloned &&
- ((CountBits(pI8301->lastDevice2 & 0xff) > 1) ||
- ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected duplicate (2).\n");
- cloned = 0;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Requested display devices 0x%lx.\n",
- (unsigned long) temp);
-
-
- /* If the BIOS doesn't flip between CRT, LFP and CRT+LFP we fake
- * it here as it seems some just flip between CRT and LFP. Ugh!
- *
- * So this pushes them onto Pipe B and clones the displays, which
- * is what most BIOS' should be doing.
- *
- * Cloned pipe mode should only be done when running single head.
- */
- if (xf86IsEntityShared(pScrn->entityList[0])) {
- cloned = 0;
-
- /* Some BIOS' don't realize we may be in true dual head mode.
- * And only display the primary output on both when switching.
- * We detect this here and cycle back to both pipes.
- */
- if ((pI830->lastDevice0 == temp) &&
- ((CountBits(pI8301->lastDevice2 & 0xff) > 1) ||
- ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected cloned pipe mode when dual head on previous switch. (0x%x -> 0x%x)\n", (int)temp, pI8301->MonType2 << 8 | pI8301->MonType1);
- temp = pI8301->MonType2 << 8 | pI8301->MonType1;
- }
-
- }
-
- if (cloned) {
- if (pI830->Clone)
- temp = pI8301->MonType2 << 8 | pI8301->MonType1;
- else if (pI8301->lastDevice1 & 0xFF)
- temp = pI8301->lastDevice1 << 8 | pI8301->lastDevice2;
- else
- temp = pI8301->lastDevice2 << 8 | pI8301->lastDevice1;
- }
-
- /* Jump to our next mode if we detect we've been here before */
- if (temp == pI8301->lastDevice1 || temp == pI8301->lastDevice2) {
- temp = GetToggleList(pScrn, 1);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected duplicate devices. Toggling (0x%lx)\n",
- (unsigned long) temp);
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Detected display change operation (0x%x, 0x%x, 0x%lx).\n",
- pI8301->lastDevice1, pI8301->lastDevice2,
- (unsigned long) temp);
-
- /* So that if we close on the wrong config, we restore correctly */
- pI830->specifiedMonitor = TRUE;
-
- if (!xf86IsEntityShared(pScrn->entityList[0])) {
- if ((temp & 0xFF00) && (temp & 0x00FF)) {
- pI830->Clone = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n");
- } else {
- pI830->Clone = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clearing Clone mode\n");
- }
- }
-
- {
- /* Turn Cursor off before switching */
- Bool on = pI830->cursorOn;
- if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor)
- pI830->CursorInfoRec->HideCursor(pScrn);
- pI830->cursorOn = on;
- }
-
-#if 0 /* Disable -- I'll need to look at this whole function later. */
- /* double check the display devices are what's configured and try
- * not to do it twice because of dual heads with the code above */
- if (!SetDisplayDevices(pScrn, temp)) {
- if ( cloned &&
- ((CountBits(temp & 0xff) > 1) ||
- (CountBits((temp & 0xff00) >> 8) > 1)) ) {
- temp = pI8301->lastDevice2 | pI8301->lastDevice1;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Cloning failed, "
- "trying dual pipe clone mode (0x%lx)\n",
- (unsigned long) temp);
- if (!SetDisplayDevices(pScrn, temp))
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch "
- "to configured display devices (0x%lx).\n",
- (unsigned long) temp);
- else {
- pI830->Clone = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n");
- }
- }
- }
-#endif
-
- pI8301->monitorSwitch = temp;
- pI8301->operatingDevices = temp;
- pI8301->toggleDevices = temp;
-
- if (xf86IsEntityShared(pScrn->entityList[0])) {
- pI8302->operatingDevices = pI8301->operatingDevices;
- pI8302->monitorSwitch = pI8301->monitorSwitch;
- pI8302->toggleDevices = pI8301->toggleDevices;
- }
+static CARD32
+I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ ScrnInfoPtr pScrn = (ScrnInfoPtr) arg;
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD8 gr18;
- fixup = 1;
+ if (!pScrn->vtSema)
+ return 1000;
#if 0
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "ACPI _DGS queried devices is 0x%x, but probed is 0x%x monitorSwitch=0x%x\n",
- pI830->toggleDevices, INREG(SWF0), pI830->monitorSwitch);
+ i830MonitorDetectDebugger(pScrn);
#endif
- } else {
- int offset = -1;
- if (I830IsPrimary(pScrn))
- offset = pI8301->FrontBuffer.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp);
- else {
- offset = pI8301->FrontBuffer2.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp);
- }
-
- if (pI830->pipe == 0)
- adjust = INREG(DSPABASE);
- else
- adjust = INREG(DSPBBASE);
-
- if (adjust != offset) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Fixing display offsets.\n");
-
- i830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
- }
- }
-
- if (fixup) {
- ScreenPtr pCursorScreen;
- int x = 0, y = 0;
+ /* Check for a hotkey press report from the BIOS. */
+ gr18 = pI830->readControl(pI830, GRX, 0x18);
+ if ((gr18 & (HOTKEY_TOGGLE | HOTKEY_SWITCH)) != 0) {
+ /* The user has pressed the hotkey requesting a toggle or switch.
+ * Re-probe our connected displays and turn on whatever we find.
+ *
+ * In the future, we want the hotkey to dump down to a user app which
+ * implements a sensible policy using RandR-1.2. For now, all we get
+ * is this.
+ */
+ I830ValidateXF86ModeList(pScrn, FALSE);
+ xf86SwitchMode(pScrn->pScreen, pScrn->currentMode);
- pCursorScreen = miPointerCurrentScreen();
- if (pScrn->pScreen == pCursorScreen)
- miPointerPosition(&x, &y);
-
- /* Now, when we're single head, make sure we switch pipes */
- if (!(xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) || cloned) {
- if (temp & 0xFF00)
- pI830->pipe = 1;
- else
- pI830->pipe = 0;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Primary pipe is now %s.\n", pI830->pipe ? "B" : "A");
- }
-
- pI830->currentMode = NULL;
- I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0);
- i830AdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
-
- if (xf86IsEntityShared(pScrn->entityList[0])) {
- ScrnInfoPtr pScrn2;
- I830Ptr pI8302;
-
- if (I830IsPrimary(pScrn)) {
- pScrn2 = pI830->entityPrivate->pScrn_2;
- pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
- } else {
- pScrn2 = pI830->entityPrivate->pScrn_1;
- pI8302 = I830PTR(pI830->entityPrivate->pScrn_1);
- }
-
- if (pScrn2->pScreen == pCursorScreen)
- miPointerPosition(&x, &y);
-
- pI8302->currentMode = NULL;
- I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0);
- i830AdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
-
- (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE);
- (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE);
-
- if (pScrn2->pScreen == pCursorScreen) {
- int sigstate = xf86BlockSIGIO ();
- miPointerWarpCursor(pScrn2->pScreen,x,y);
-
- /* xf86Info.currentScreen = pScrn->pScreen; */
- xf86UnblockSIGIO (sigstate);
- if (pI8302->CursorInfoRec && !pI8302->SWCursor && pI8302->cursorOn) {
- pI8302->CursorInfoRec->HideCursor(pScrn);
- xf86SetCursor(pScrn2->pScreen, pI830->pCurs, x, y);
- pI8302->CursorInfoRec->ShowCursor(pScrn);
- pI8302->cursorOn = TRUE;
- }
- }
- }
-
- (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, FALSE);
- (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, TRUE);
-
- if (pScrn->pScreen == pCursorScreen) {
- int sigstate = xf86BlockSIGIO ();
- miPointerWarpCursor(pScrn->pScreen,x,y);
-
- /* xf86Info.currentScreen = pScrn->pScreen; */
- xf86UnblockSIGIO (sigstate);
- if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
- pI830->CursorInfoRec->HideCursor(pScrn);
- xf86SetCursor(pScrn->pScreen, pI830->pCurs, x, y);
- pI830->CursorInfoRec->ShowCursor(pScrn);
- pI830->cursorOn = TRUE;
- }
- }
- }
+ /* Clear the BIOS's hotkey press flags */
+ gr18 &= ~(HOTKEY_TOGGLE | HOTKEY_SWITCH);
+ pI830->writeControl(pI830, GRX, 0x18, gr18);
}
-
return 1000;
}