diff --git a/Xext/sync.c b/Xext/sync.c index 63f6fa2aa..1b3736644 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2533,7 +2533,7 @@ SyncInitServerTime(void) * IDLETIME implementation */ -static pointer IdleTimeCounter; +static SyncCounter *IdleTimeCounter; static XSyncValue *pIdleTimeValueLess; static XSyncValue *pIdleTimeValueGreater; @@ -2545,38 +2545,69 @@ IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return) } static void -IdleTimeBlockHandler (pointer env, - struct timeval **wt, - pointer LastSelectMask) +IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) { - XSyncValue idle; + XSyncValue idle, old_idle; + SyncTriggerList *list = IdleTimeCounter->pTriglist; + SyncTrigger *trig; if (!pIdleTimeValueLess && !pIdleTimeValueGreater) return; + old_idle = IdleTimeCounter->value; IdleTimeQueryValue (NULL, &idle); + IdleTimeCounter->value = idle; /* push, so CheckTrigger works */ if (pIdleTimeValueLess && XSyncValueLessOrEqual (idle, *pIdleTimeValueLess)) { - AdjustWaitForDelay (wt, 0); + /* + * We've been idle for less than the threshold value, and someone + * wants to know about that, but now we need to know whether they + * want level or edge trigger. Check the trigger list against the + * current idle time, and if any succeed, bomb out of select() + * immediately so we can reschedule. + */ + + for (list = IdleTimeCounter->pTriglist; list; list = list->next) { + trig = list->pTrigger; + if (trig->CheckTrigger(trig, old_idle)) { + AdjustWaitForDelay(wt, 0); + break; + } + } } else if (pIdleTimeValueGreater) { - unsigned long timeout = 0; + /* + * There's a threshold in the positive direction. If we've been + * idle less than it, schedule a wakeup for sometime in the future. + * If we've been idle more than it, and someone wants to know about + * that level-triggered, schedule an immediate wakeup. + */ + unsigned long timeout = -1; - if (XSyncValueLessThan (idle, *pIdleTimeValueGreater)) - { + if (XSyncValueLessThan (idle, *pIdleTimeValueGreater)) { XSyncValue value; Bool overflow; XSyncValueSubtract (&value, *pIdleTimeValueGreater, idle, &overflow); - timeout = XSyncValueLow32 (value); + timeout = min(timeout, XSyncValueLow32 (value)); + } else { + for (list = IdleTimeCounter->pTriglist; list; list = list->next) { + trig = list->pTrigger; + if (trig->CheckTrigger(trig, old_idle)) { + timeout = min(timeout, 0); + break; + } + } } AdjustWaitForDelay (wt, timeout); } + + IdleTimeCounter->value = old_idle; /* pop */ } static void diff --git a/Xi/exevents.c b/Xi/exevents.c index a976802a2..6141f5edd 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -781,12 +781,14 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count) } /* Update device axis */ - for (i = 1; i < count; i++) { + /* Don't update valuators for the VCP, it never sends XI events anyway */ + for (i = 1; !device->isMaster && i < count; i++) { if ((++xV)->type == DeviceValuator) { int *axisvals; int first = xV->first_valuator; BOOL change = FALSE; + if (xV->num_valuators && (!v || (xV->num_valuators && (first + xV->num_valuators > v->numAxes)))) @@ -802,8 +804,8 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count) * dev = event * event = delta */ - axisvals = v->axisVal; int delta; + axisvals = v->axisVal; if (v->mode == Relative) /* device reports relative */ change = TRUE; @@ -1009,7 +1011,9 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count) } /* Valuator event handling */ - for (i = 1; i < count; i++) { + /* Don't care about valuators for the VCP, it never sends XI events */ + + for (i = 1; !device->isMaster && i < count; i++) { if ((++xV)->type == DeviceValuator) { int first = xV->first_valuator; if (xV->num_valuators diff --git a/acinclude.m4 b/acinclude.m4 index efece2aab..c3e36f8b1 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -157,7 +157,7 @@ for arg in "$[]@"; do case "$arg" in --mode=compile) modeok=true ;; --tag=CC|--tag=CXX) tagok=true ;; - *) args+=("$arg") + *) args@<:@${#args[@]}@:>@="$arg" ;; esac done if $modeok && $tagok ; then diff --git a/glx/dispatch.h b/glx/dispatch.h index 712315608..f019aa6aa 100644 --- a/glx/dispatch.h +++ b/glx/dispatch.h @@ -28,6 +28,8 @@ #if !defined( _DISPATCH_H_ ) # define _DISPATCH_H_ + +#include "glapitable.h" /** * \file dispatch.h * Macros for handling GL dispatch tables. diff --git a/glx/glapi.h b/glx/glapi.h index ddfb1cffb..8f2cf6621 100644 --- a/glx/glapi.h +++ b/glx/glapi.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -44,12 +44,17 @@ #ifndef _GLAPI_H #define _GLAPI_H +#define GL_GLEXT_PROTOTYPES #include "GL/gl.h" -#include "glapitable.h" +#include "GL/glext.h" #include "glthread.h" +struct _glapi_table; + +typedef void (*_glapi_proc)(void); /* generic function pointer */ + typedef void (*_glapi_warning_func)(void *ctx, const char *str, ...); @@ -63,6 +68,12 @@ typedef void (*_glapi_warning_func)(void *ctx, const char *str, ...); #endif +/* + * Number of extension functions which we can dynamically add at runtime. + */ +#define MAX_EXTENSION_FUNCS 300 + + /** ** Define the GET_CURRENT_CONTEXT() macro. ** \param C local variable which will hold the current context. diff --git a/glx/glapitable.h b/glx/glapitable.h index 48941f559..5d9d40a8a 100644 --- a/glx/glapitable.h +++ b/glx/glapitable.h @@ -37,7 +37,6 @@ # define GLAPIENTRYP GLAPIENTRY * #endif -typedef void (*_glapi_proc)(void); /* generic function pointer */ struct _glapi_table { diff --git a/glx/glthread.c b/glx/glthread.c index 813d6f9db..b818f4e26 100644 --- a/glx/glthread.c +++ b/glx/glthread.c @@ -34,6 +34,7 @@ #endif #include +#include #include "glthread.h" diff --git a/glx/indirect_dispatch.c b/glx/indirect_dispatch.c index 2afd3eb22..6547f5d96 100644 --- a/glx/indirect_dispatch.c +++ b/glx/indirect_dispatch.c @@ -36,8 +36,8 @@ #include "glxbyteorder.h" #include "indirect_util.h" #include "singlesize.h" -#include "glapitable.h" #include "glapi.h" +#include "glapitable.h" #include "glthread.h" #include "dispatch.h" @@ -2972,8 +2972,7 @@ void __glXDisp_PrioritizeTextures(GLbyte * pc) void __glXDisp_TexSubImage1D(GLbyte * pc) { - const CARD32 ptr_is_null = *(CARD32 *)(pc + 52); - const GLvoid * const pixels = (const GLvoid *) (ptr_is_null != 0) ? NULL : (pc + 56); + const GLvoid * const pixels = (const GLvoid *) (pc + 56); __GLXpixelHeader * const hdr = (__GLXpixelHeader *)(pc); CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, hdr->swapBytes) ); @@ -2996,8 +2995,7 @@ void __glXDisp_TexSubImage1D(GLbyte * pc) void __glXDisp_TexSubImage2D(GLbyte * pc) { - const CARD32 ptr_is_null = *(CARD32 *)(pc + 52); - const GLvoid * const pixels = (const GLvoid *) (ptr_is_null != 0) ? NULL : (pc + 56); + const GLvoid * const pixels = (const GLvoid *) (pc + 56); __GLXpixelHeader * const hdr = (__GLXpixelHeader *)(pc); CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, hdr->swapBytes) ); @@ -3773,8 +3771,7 @@ void __glXDisp_TexImage3D(GLbyte * pc) void __glXDisp_TexSubImage3D(GLbyte * pc) { - const CARD32 ptr_is_null = *(CARD32 *)(pc + 84); - const GLvoid * const pixels = (const GLvoid *) (ptr_is_null != 0) ? NULL : (pc + 88); + const GLvoid * const pixels = (const GLvoid *) (pc + 88); __GLXpixel3DHeader * const hdr = (__GLXpixel3DHeader *)(pc); CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, hdr->swapBytes) ); diff --git a/glx/indirect_dispatch_swap.c b/glx/indirect_dispatch_swap.c index f137cbe98..0b8c27cac 100644 --- a/glx/indirect_dispatch_swap.c +++ b/glx/indirect_dispatch_swap.c @@ -36,8 +36,8 @@ #include "glxbyteorder.h" #include "indirect_util.h" #include "singlesize.h" -#include "glapitable.h" #include "glapi.h" +#include "glapitable.h" #include "glthread.h" #include "dispatch.h" @@ -3092,8 +3092,7 @@ void __glXDispSwap_PrioritizeTextures(GLbyte * pc) void __glXDispSwap_TexSubImage1D(GLbyte * pc) { - const CARD32 ptr_is_null = *(CARD32 *)(pc + 52); - const GLvoid * const pixels = (const GLvoid *) (ptr_is_null != 0) ? NULL : (pc + 56); + const GLvoid * const pixels = (const GLvoid *) (pc + 56); __GLXpixelHeader * const hdr = (__GLXpixelHeader *)(pc); CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, hdr->swapBytes) ); @@ -3116,8 +3115,7 @@ void __glXDispSwap_TexSubImage1D(GLbyte * pc) void __glXDispSwap_TexSubImage2D(GLbyte * pc) { - const CARD32 ptr_is_null = *(CARD32 *)(pc + 52); - const GLvoid * const pixels = (const GLvoid *) (ptr_is_null != 0) ? NULL : (pc + 56); + const GLvoid * const pixels = (const GLvoid *) (pc + 56); __GLXpixelHeader * const hdr = (__GLXpixelHeader *)(pc); CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, hdr->swapBytes) ); @@ -3909,8 +3907,7 @@ void __glXDispSwap_TexImage3D(GLbyte * pc) void __glXDispSwap_TexSubImage3D(GLbyte * pc) { - const CARD32 ptr_is_null = *(CARD32 *)(pc + 84); - const GLvoid * const pixels = (const GLvoid *) (ptr_is_null != 0) ? NULL : (pc + 88); + const GLvoid * const pixels = (const GLvoid *) (pc + 88); __GLXpixel3DHeader * const hdr = (__GLXpixel3DHeader *)(pc); CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, hdr->swapBytes) ); diff --git a/glx/indirect_reqsize.c b/glx/indirect_reqsize.c index 954eecd97..c47f01ee9 100644 --- a/glx/indirect_reqsize.c +++ b/glx/indirect_reqsize.c @@ -572,6 +572,9 @@ __glXTexImage3DReqSize(const GLbyte *pc, Bool swap) type = bswap_32(type); } + if (*(CARD32 *) (pc + 76)) + return 0; + return __glXImageSize(format, type, target, width, height, depth, image_height, row_length, skip_images, skip_rows, alignment); diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 9558b7742..94185da6c 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -650,8 +650,8 @@ _X_EXPORT void DeleteInputDeviceRequest(DeviceIntPtr pDev) { LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate; - InputDriverPtr drv; - IDevRec *idev; + InputDriverPtr drv = NULL; + IDevRec *idev = NULL; IDevPtr *it; Bool isMaster = pDev->isMaster; diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 97176200e..b9729746d 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -244,8 +244,6 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati RRTransformPtr transform, int x, int y) { ScrnInfoPtr scrn = crtc->scrn; - /* During ScreenInit() scrn->pScreen is still NULL */ - ScreenPtr pScreen = screenInfo.screens[scrn->scrnIndex]; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int i; Bool ret = FALSE; @@ -295,11 +293,6 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati } else crtc->transformPresent = FALSE; - /* xf86CrtcFitsScreen() relies on these values being correct. */ - /* This should ensure the values are always set at modeset time. */ - pScreen->width = scrn->virtualX; - pScreen->height = scrn->virtualY; - /* Shift offsets that move us out of virtual size */ if (x + mode->HDisplay > xf86_config->maxWidth || y + mode->VDisplay > xf86_config->maxHeight) @@ -983,7 +976,7 @@ xf86PickCrtcs (ScrnInfoPtr scrn, * see if they can be cloned */ if (xf86ModesEqual (modes[o], modes[n]) && - config->output[0]->initial_rotation == config->output[n]->initial_rotation && + config->output[o]->initial_rotation == config->output[n]->initial_rotation && config->output[o]->initial_x == config->output[n]->initial_x && config->output[o]->initial_y == config->output[n]->initial_y) { @@ -2684,6 +2677,7 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) { crtc->funcs->dpms(crtc, DPMSModeOff); memset(&crtc->mode, 0, sizeof(crtc->mode)); + xf86RotateDestroy(crtc); } } if (pScrn->pScreen) diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index 5e47e6f2b..a2ea2ec11 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -703,6 +703,13 @@ xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y); Bool xf86CrtcRotate (xf86CrtcPtr crtc); +/* + * Clean up any rotation data, used when a crtc is turned off + * as well as when rotation is disabled. + */ +void +xf86RotateDestroy (xf86CrtcPtr crtc); + /* * free shadow memory allocated for all crtcs */ diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index d7f7b3b78..65a553e85 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -294,7 +294,7 @@ xf86RotateBlockHandler(int screenNum, pointer blockData, } } -static void +void xf86RotateDestroy (xf86CrtcPtr crtc) { ScrnInfoPtr pScrn = crtc->scrn; @@ -364,12 +364,14 @@ static Bool xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb) { ScrnInfoPtr pScrn = crtc->scrn; - /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */ - ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; BoxRec b; - if (!pScreen) + /* When called before PreInit, the driver is + * presumably doing load detect + */ + if (pScrn->virtualX == 0 || pScrn->virtualY == 0) return TRUE; + b.x1 = 0; b.y1 = 0; b.x2 = crtc->mode.HDisplay; @@ -383,8 +385,8 @@ xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb) b.y2 += crtc->y; } - return (0 <= b.x1 && b.x2 <= pScreen->width && - 0 <= b.y1 && b.y2 <= pScreen->height); + return (0 <= b.x1 && b.x2 <= pScrn->virtualX && + 0 <= b.y1 && b.y2 <= pScrn->virtualY); } _X_EXPORT Bool diff --git a/hw/xfree86/os-support/bsd/bsd_init.c b/hw/xfree86/os-support/bsd/bsd_init.c index cbb9e4810..7698084ee 100644 --- a/hw/xfree86/os-support/bsd/bsd_init.c +++ b/hw/xfree86/os-support/bsd/bsd_init.c @@ -45,6 +45,7 @@ static int devConsoleFd = -1; #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) static int VTnum = -1; static int initialVT = -1; +static Bool ShareVTs = FALSE; #endif #ifdef PCCONS_SUPPORT @@ -269,44 +270,48 @@ xf86OpenConsole() } #endif acquire_vt: - /* - * now get the VT - */ - SYSCALL(result = - ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno)); - if (result != 0) - { - xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); - } - SYSCALL(result = + if (!ShareVTs) { + /* + * now get the VT + */ + SYSCALL(result = + ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno)); + if (result != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); + } + SYSCALL(result = ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno)); - if (result != 0) - { - xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); - } + if (result != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); + } - signal(SIGUSR1, xf86VTRequest); + signal(SIGUSR1, xf86VTRequest); - vtmode.mode = VT_PROCESS; - vtmode.relsig = SIGUSR1; - vtmode.acqsig = SIGUSR1; - vtmode.frsig = SIGUSR1; - if (ioctl(xf86Info.consoleFd, VT_SETMODE, &vtmode) < 0) - { - FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed"); - } -#if !defined(USE_DEV_IO) && !defined(USE_I386_IOPL) - if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0) - { - FatalError("xf86OpenConsole: KDENABIO failed (%s)", - strerror(errno)); - } -#endif - if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) - { - FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed"); - } - break; + vtmode.mode = VT_PROCESS; + vtmode.relsig = SIGUSR1; + vtmode.acqsig = SIGUSR1; + vtmode.frsig = SIGUSR1; + if (ioctl(xf86Info.consoleFd, VT_SETMODE, &vtmode) < 0) + { + FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed"); + } + #if !defined(USE_DEV_IO) && !defined(USE_I386_IOPL) + if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0) + { + FatalError("xf86OpenConsole: KDENABIO failed (%s)", + strerror(errno)); + } + #endif + if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) + { + FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed"); + } + } else { /* ShareVTs */ + close(xf86Info.consoleFd); + } + break; #endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ #ifdef WSCONS_SUPPORT case WSCONS: @@ -319,7 +324,7 @@ acquire_vt: { /* serverGeneration != 1 */ #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) - if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT) + if (!ShareVTs) if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT) { if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) { @@ -392,6 +397,9 @@ xf86OpenSyscons() if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0) initialVT = -1; #endif + if (ShareVTs) + xf86Info.vtno = initialVT; + if (xf86Info.vtno == -1) { /* @@ -651,6 +659,8 @@ xf86CloseConsole() struct vt_mode VT; #endif + if (ShareVTs) return; + switch (xf86Info.consType) { #ifdef PCCONS_SUPPORT @@ -717,6 +727,11 @@ xf86ProcessArgument(int argc, char *argv[], int i) return(1); } #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + if (!strcmp(argv[i], "-sharevts")) + { + ShareVTs = TRUE; + return(1); + } if ((argv[i][0] == 'v') && (argv[i][1] == 't')) { if (sscanf(argv[i], "vt%2d", &VTnum) == 0 || @@ -737,6 +752,7 @@ xf86UseMsg() { #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) ErrorF("vtXX use the specified VT number (1-12)\n"); + ErrorF("-sharevts share VTs with another X server\n"); #endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ ErrorF("-keeptty "); ErrorF("don't detach controlling tty (for debugging only)\n"); diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c index f51131c6b..92bdd2988 100644 --- a/hw/xfree86/os-support/shared/sigio.c +++ b/hw/xfree86/os-support/shared/sigio.c @@ -229,7 +229,7 @@ xf86RemoveSIGIOHandler(int fd) sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; + sa.sa_handler = SIG_IGN; sigaction(SIGIO, &sa, &osa); } } diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c index aea1d3337..2b73b1698 100644 --- a/hw/xfree86/ramdac/xf86Cursor.c +++ b/hw/xfree86/ramdac/xf86Cursor.c @@ -314,7 +314,8 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, /* only update for VCP, otherwise we get cursor jumps when removing a sprite. The second cursor is never HW rendered anyway. */ - if (pDev == inputInfo.pointer) + if (pDev == inputInfo.pointer || + (!pDev->isMaster && pDev->u.master == inputInfo.pointer)) { ScreenPriv->CurrentCursor = pCurs; ScreenPriv->x = x; diff --git a/randr/randr.c b/randr/randr.c index 230d816a3..2e482f038 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -438,6 +438,9 @@ RRFirstOutput (ScreenPtr pScreen) RROutputPtr output; int i, j; + if (pScrPriv->primaryOutput) + return pScrPriv->primaryOutput; + for (i = 0; i < pScrPriv->numCrtcs; i++) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; diff --git a/randr/randrstr.h b/randr/randrstr.h index f6aa5c7ec..b5cebdc7e 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -2,6 +2,7 @@ * Copyright © 2000 Compaq Computer Corporation * Copyright © 2002 Hewlett-Packard Company * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -272,6 +273,7 @@ typedef struct _rrScrPriv { int numOutputs; RROutputPtr *outputs; + RROutputPtr primaryOutput; int numCrtcs; RRCrtcPtr *crtcs; @@ -822,6 +824,12 @@ RROutputDestroy (RROutputPtr output); int ProcRRGetOutputInfo (ClientPtr client); +extern int +ProcRRSetOutputPrimary (ClientPtr client); + +extern int +ProcRRGetOutputPrimary (ClientPtr client); + /* * Initialize output type */ diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index 0cc0bca98..5a2ea715f 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -217,5 +217,7 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { ProcRRGetCrtcTransform, /* 27 */ ProcRRGetPanning, /* 28 */ ProcRRSetPanning, /* 29 */ + ProcRRSetOutputPrimary, /* 30 */ + ProcRRGetOutputPrimary, /* 31 */ }; diff --git a/randr/rroutput.c b/randr/rroutput.c index 1ecde31a2..82c2530fe 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -1,5 +1,6 @@ /* * Copyright © 2006 Keith Packard + * Copyright © 2008 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -379,6 +380,9 @@ RROutputDestroyResource (pointer value, XID pid) { rrScrPriv(pScreen); int i; + + if (pScrPriv->primaryOutput == output) + pScrPriv->primaryOutput = NULL; for (i = 0; i < pScrPriv->numOutputs; i++) { @@ -426,7 +430,7 @@ RROutputInit (void) } #define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32) - + int ProcRRGetOutputInfo (ClientPtr client) { @@ -533,3 +537,109 @@ ProcRRGetOutputInfo (ClientPtr client) return client->noClientException; } + +void +RRSetPrimaryOutput(ScreenPtr pScreen, rrScrPrivPtr pScrPriv, + RROutputPtr output) +{ + if (pScrPriv->primaryOutput == output) + return; + + /* clear the old primary */ + if (pScrPriv->primaryOutput) { + RROutputChanged(pScrPriv->primaryOutput, 0); + pScrPriv->primaryOutput = NULL; + } + + /* set the new primary */ + if (output) { + pScrPriv->primaryOutput = output; + RROutputChanged(output, 0); + } + + pScrPriv->layoutChanged = TRUE; + + RRTellChanged(pScreen); +} + +int +ProcRRSetOutputPrimary(ClientPtr client) +{ + REQUEST(xRRSetOutputPrimaryReq); + RROutputPtr output = NULL; + WindowPtr pWin; + rrScrPrivPtr pScrPriv; + + REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); + + pWin = SecurityLookupIDByType(client, stuff->window, RT_WINDOW, + DixReadAccess); + + if (!pWin) { + client->errorValue = stuff->window; + return BadWindow; + } + + if (stuff->output) { + output = LookupOutput(client, stuff->output, DixReadAccess); + + if (!output) { + client->errorValue = stuff->output; + return RRErrorBase + BadRROutput; + } + + if (output->crtc) { + client->errorValue = stuff->output; + return BadMatch; + } + + if (output->pScreen != pWin->drawable.pScreen) { + client->errorValue = stuff->window; + return BadMatch; + } + } + + pScrPriv = rrGetScrPriv(pWin->drawable.pScreen); + RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output); + + return client->noClientException; +} + +int +ProcRRGetOutputPrimary(ClientPtr client) +{ + REQUEST(xRRGetOutputPrimaryReq); + WindowPtr pWin; + rrScrPrivPtr pScrPriv; + xRRGetOutputPrimaryReply rep; + RROutputPtr primary = NULL; + + REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq); + + pWin = SecurityLookupIDByType(client, stuff->window, RT_WINDOW, + DixReadAccess); + + if (!pWin) { + client->errorValue = stuff->window; + return BadWindow; + } + + pScrPriv = rrGetScrPriv(pWin->drawable.pScreen); + if (pScrPriv) + primary = pScrPriv->primaryOutput; + + memset(&rep, 0, sizeof(rep)); + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.output = primary ? primary->id : None; + + if (client->swapped) { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.output, n); + } + + WriteToClient(client, sizeof(xRRGetOutputPrimaryReply), &rep); + + return client->noClientException; +} diff --git a/randr/rrscreen.c b/randr/rrscreen.c index 7a8f2ebc7..9b1024e11 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -324,7 +324,7 @@ rrGetScreenResources(ClientPtr client, Bool query) rrScrPrivPtr pScrPriv; CARD8 *extra; unsigned long extraLen; - int i, n, rc; + int i, n, rc, has_primary; RRCrtc *crtcs; RROutput *outputs; xRRModeInfo *modeinfos; @@ -401,12 +401,23 @@ rrGetScreenResources(ClientPtr client, Bool query) outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); names = (CARD8 *) (modeinfos + num_modes); + + has_primary = (pScrPriv->primaryOutput != NULL); + if (pScrPriv->primaryOutput) + { + crtcs[0] = pScrPriv->primaryOutput->id; + if (client->swapped) + swapl (&crtcs[0], n); + } for (i = 0; i < pScrPriv->numCrtcs; i++) { - crtcs[i] = pScrPriv->crtcs[i]->id; + if (pScrPriv->primaryOutput && + pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i]) + continue; + crtcs[i + has_primary] = pScrPriv->crtcs[i]->id; if (client->swapped) - swapl (&crtcs[i], n); + swapl (&crtcs[i + has_primary], n); } for (i = 0; i < pScrPriv->numOutputs; i++) diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c index 3ff9f3f85..9fbf8f0f5 100644 --- a/randr/rrsdispatch.c +++ b/randr/rrsdispatch.c @@ -436,6 +436,31 @@ SProcRRSetPanning (ClientPtr client) return (*ProcRandrVector[stuff->randrReqType]) (client); } +static int +SProcRRSetOutputPrimary (ClientPtr client) +{ + int n; + REQUEST(xRRSetOutputPrimaryReq); + + REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swapl(&stuff->output, n); + return ProcRandrVector[stuff->randrReqType](client); +} + +static int +SProcRRGetOutputPrimary (ClientPtr client) +{ + int n; + REQUEST(xRRSetOutputPrimaryReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return ProcRandrVector[stuff->randrReqType](client); +} + int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { SProcRRQueryVersion, /* 0 */ /* we skip 1 to make old clients fail pretty immediately */ @@ -472,5 +497,7 @@ int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { SProcRRGetCrtcTransform, /* 27 */ SProcRRGetPanning, /* 28 */ SProcRRSetPanning, /* 29 */ + SProcRRSetOutputPrimary, /* 30 */ + SProcRRGetOutputPrimary, /* 31 */ }; diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c index 544666ff1..ad40a1e36 100644 --- a/randr/rrxinerama.c +++ b/randr/rrxinerama.c @@ -260,6 +260,30 @@ ProcRRXineramaIsActive(ClientPtr client) return client->noClientException; } +static void +RRXineramaWriteCrtc(ClientPtr client, RRCrtcPtr crtc) +{ + xXineramaScreenInfo scratch; + + if (RRXineramaCrtcActive (crtc)) + { + int width, height; + RRCrtcGetScanoutSize (crtc, &width, &height); + scratch.x_org = crtc->x; + scratch.y_org = crtc->y; + scratch.width = width; + scratch.height = height; + if(client->swapped) { + register int n; + swaps(&scratch.x_org, n); + swaps(&scratch.y_org, n); + swaps(&scratch.width, n); + swaps(&scratch.height, n); + } + WriteToClient(client, sz_XineramaScreenInfo, &scratch); + } +} + int ProcRRXineramaQueryScreens(ClientPtr client) { @@ -291,26 +315,16 @@ ProcRRXineramaQueryScreens(ClientPtr client) rrScrPriv(pScreen); xXineramaScreenInfo scratch; int i; + int has_primary = (pScrPriv->primaryOutput != NULL); + + if (has_primary) { + RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc); + } for(i = 0; i < pScrPriv->numCrtcs; i++) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; - if (RRXineramaCrtcActive (crtc)) - { - int width, height; - RRCrtcGetScanoutSize (crtc, &width, &height); - scratch.x_org = crtc->x; - scratch.y_org = crtc->y; - scratch.width = width; - scratch.height = height; - if(client->swapped) { - register int n; - swaps(&scratch.x_org, n); - swaps(&scratch.y_org, n); - swaps(&scratch.width, n); - swaps(&scratch.height, n); - } - WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch); - } + if (!has_primary || (crtc != pScrPriv->primaryOutput->crtc)) + RRXineramaWriteCrtc(client, crtc); } } diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c index 0b93e87d9..3a0e375e8 100644 --- a/xkb/xkbInit.c +++ b/xkb/xkbInit.c @@ -93,7 +93,7 @@ typedef struct _SrvXkmInfo { #define XKB_BIN_DIRECTORY XKB_BASE_DIRECTORY #endif #ifndef XKB_DFLT_RULES_FILE -#define XKB_DFLT_RULES_FILE "rules" +#define XKB_DFLT_RULES_FILE "base" #endif #ifndef XKB_DFLT_KB_LAYOUT #define XKB_DFLT_KB_LAYOUT "us" @@ -240,14 +240,33 @@ XkbSetRulesUsed(XkbRF_VarDefsPtr defs) return; } +/** + * Set the default RMLVO for the next device to be initialised. + * If a parameter is NULL, the previous setting will be used. Use empty + * strings if you want to delete a previous setting. + * + * If @rulesFile is NULL and no previous @rulesFile has been set, the + * built-in default is chosen as default. + */ _X_EXPORT void XkbSetRulesDflts(char *rulesFile,char *model,char *layout, char *variant,char *options) { - if (XkbRulesFile) - _XkbFree(XkbRulesFile); - XkbRulesFile= _XkbDupString(rulesFile); - rulesDefined= True; + if (!rulesFile && !XkbRulesFile) + { + LogMessage(X_WARNING, "[xkb] No rule given, and no previous rule " + "defined. Defaulting to '%s'.\n", + XKB_DFLT_RULES_FILE); + rulesFile = XKB_DFLT_RULES_FILE; + } + + if (rulesFile) { + if (XkbRulesFile) + _XkbFree(XkbRulesFile); + XkbRulesFile= _XkbDupString(rulesFile); + rulesDefined= True; + } + if (model) { if (XkbModelDflt) _XkbFree(XkbModelDflt);