diff --git a/Xext/saver.c b/Xext/saver.c index 159153c23..61fc044d7 100644 --- a/Xext/saver.c +++ b/Xext/saver.c @@ -46,6 +46,7 @@ in this Software without prior written authorization from the X Consortium. #include "cursorstr.h" #include "colormapst.h" #include "xace.h" +#include "inputstr.h" #ifdef PANORAMIX #include "panoramiX.h" #include "panoramiXsrv.h" @@ -388,8 +389,10 @@ ScreenSaverFreeSuspend(pointer value, XID id) if (screenIsSaved != SCREEN_SAVER_ON) #endif { + DeviceIntPtr dev; UpdateCurrentTimeIf(); - lastDeviceEventTime = currentTime; + nt_list_for_each_entry(dev, inputInfo.devices, next) + lastDeviceEventTime[dev->id] = currentTime; SetScreenSaverTimer(); } } @@ -672,7 +675,7 @@ ProcScreenSaverQueryInfo(ClientPtr client) pPriv = GetScreenPrivate(pDraw->pScreen); UpdateCurrentTime(); - lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds; + lastInput = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds; rep.type = X_Reply; rep.length = 0; diff --git a/Xext/sync.c b/Xext/sync.c index f2bcd2512..91968e498 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -69,6 +69,7 @@ PERFORMANCE OF THIS SOFTWARE. #include "syncsrv.h" #include "syncsdk.h" #include "protocol-versions.h" +#include "inputstr.h" #include #if !defined(WIN32) @@ -87,8 +88,7 @@ static RESTYPE RTAwait; static RESTYPE RTAlarm; static RESTYPE RTAlarmClient; static RESTYPE RTFence; -static int SyncNumSystemCounters = 0; -static SyncCounter **SysCounterList = NULL; +static struct xorg_list SysCounterList; static int SyncNumInvalidCounterWarnings = 0; #define MAX_INVALID_COUNTER_WARNINGS 5 @@ -114,6 +114,14 @@ static void SyncInitServerTime(void); static void SyncInitIdleTime(void); +static inline void* +SysCounterGetPrivate(SyncCounter *counter) +{ + BUG_WARN(!IsSystemCounter(counter)); + + return counter->pSysCounterInfo ? counter->pSysCounterInfo->private : NULL; +} + static Bool SyncCheckWarnIsCounter(const SyncObject * pSync, const char *warning) { @@ -932,12 +940,6 @@ SyncCreateSystemCounter(const char *name, { SyncCounter *pCounter; - SysCounterList = realloc(SysCounterList, - (SyncNumSystemCounters + - 1) * sizeof(SyncCounter *)); - if (!SysCounterList) - return NULL; - /* this function may be called before SYNC has been initialized, so we * have to make sure RTCounter is created. */ @@ -959,14 +961,16 @@ SyncCreateSystemCounter(const char *name, return pCounter; } pCounter->pSysCounterInfo = psci; - psci->name = name; + psci->pCounter = pCounter; + psci->name = strdup(name); psci->resolution = resolution; psci->counterType = counterType; psci->QueryValue = QueryValue; psci->BracketValues = BracketValues; + psci->private = NULL; XSyncMaxValue(&psci->bracket_greater); XSyncMinValue(&psci->bracket_less); - SysCounterList[SyncNumSystemCounters++] = pCounter; + xorg_list_add(&psci->entry, &SysCounterList); } return pCounter; } @@ -1111,26 +1115,10 @@ FreeCounter(void *env, XID id) free(ptl); /* destroy the trigger list as we go */ } if (IsSystemCounter(pCounter)) { - int i, found = 0; - + xorg_list_del(&pCounter->pSysCounterInfo->entry); + free(pCounter->pSysCounterInfo->name); + free(pCounter->pSysCounterInfo->private); free(pCounter->pSysCounterInfo); - - /* find the counter in the list of system counters and remove it */ - - if (SysCounterList) { - for (i = 0; i < SyncNumSystemCounters; i++) { - if (SysCounterList[i] == pCounter) { - found = i; - break; - } - } - if (found < (SyncNumSystemCounters - 1)) { - for (i = found; i < SyncNumSystemCounters - 1; i++) { - SysCounterList[i] = SysCounterList[i + 1]; - } - } - } - SyncNumSystemCounters--; } free(pCounter); return Success; @@ -1221,20 +1209,20 @@ static int ProcSyncListSystemCounters(ClientPtr client) { xSyncListSystemCountersReply rep; - int i, len; + SysCounterInfo *psci; + int len = 0; xSyncSystemCounter *list = NULL, *walklist = NULL; REQUEST_SIZE_MATCH(xSyncListSystemCountersReq); rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.nCounters = SyncNumSystemCounters; - - for (i = len = 0; i < SyncNumSystemCounters; i++) { - const char *name = SysCounterList[i]->pSysCounterInfo->name; + rep.nCounters = 0; + xorg_list_for_each_entry(psci, &SysCounterList, entry) { /* pad to 4 byte boundary */ - len += pad_to_int32(sz_xSyncSystemCounter + strlen(name)); + len += pad_to_int32(sz_xSyncSystemCounter + strlen(psci->name)); + ++rep.nCounters; } if (len) { @@ -1251,12 +1239,11 @@ ProcSyncListSystemCounters(ClientPtr client) swapl(&rep.nCounters); } - for (i = 0; i < SyncNumSystemCounters; i++) { + xorg_list_for_each_entry(psci, &SysCounterList, entry) { int namelen; char *pname_in_reply; - SysCounterInfo *psci = SysCounterList[i]->pSysCounterInfo; - walklist->counter = SysCounterList[i]->sync.id; + walklist->counter = psci->pCounter->sync.id; walklist->resolution_hi = XSyncValueHigh32(psci->resolution); walklist->resolution_lo = XSyncValueLow32(psci->resolution); namelen = strlen(psci->name); @@ -2441,8 +2428,6 @@ SAlarmNotifyEvent(xSyncAlarmNotifyEvent * from, xSyncAlarmNotifyEvent * to) static void SyncResetProc(ExtensionEntry * extEntry) { - free(SysCounterList); - SysCounterList = NULL; RTCounter = 0; } @@ -2455,6 +2440,8 @@ SyncExtensionInit(void) ExtensionEntry *extEntry; int s; + xorg_list_init(&SysCounterList); + for (s = 0; s < screenInfo.numScreens; s++) miSyncSetup(screenInfo.screens[s]); @@ -2605,33 +2592,48 @@ SyncInitServerTime(void) * IDLETIME implementation */ -static SyncCounter *IdleTimeCounter; -static XSyncValue *pIdleTimeValueLess; -static XSyncValue *pIdleTimeValueGreater; +typedef struct { + XSyncValue *value_less; + XSyncValue *value_greater; + int deviceid; +} IdleCounterPriv; static void IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return) { - CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds; + int deviceid; + CARD32 idle; + if (pCounter) { + SyncCounter *counter = pCounter; + IdleCounterPriv *priv = SysCounterGetPrivate(counter); + deviceid = priv->deviceid; + } + else + deviceid = XIAllDevices; + idle = GetTimeInMillis() - lastDeviceEventTime[deviceid].milliseconds; XSyncIntsToValue(pValue_return, idle, 0); } static void -IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) +IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMask) { + SyncCounter *counter = pCounter; + IdleCounterPriv *priv = SysCounterGetPrivate(counter); + XSyncValue *less = priv->value_less, + *greater = priv->value_greater; XSyncValue idle, old_idle; - SyncTriggerList *list = IdleTimeCounter->sync.pTriglist; + SyncTriggerList *list = counter->sync.pTriglist; SyncTrigger *trig; - if (!pIdleTimeValueLess && !pIdleTimeValueGreater) + if (!less && !greater) return; - old_idle = IdleTimeCounter->value; + old_idle = counter->value; IdleTimeQueryValue(NULL, &idle); - IdleTimeCounter->value = idle; /* push, so CheckTrigger works */ + counter->value = idle; /* push, so CheckTrigger works */ - if (pIdleTimeValueLess && XSyncValueLessOrEqual(idle, *pIdleTimeValueLess)) { + if (less && XSyncValueLessOrEqual(idle, *less)) { /* * 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 @@ -2640,7 +2642,7 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) * immediately so we can reschedule. */ - for (list = IdleTimeCounter->sync.pTriglist; list; list = list->next) { + for (list = counter->sync.pTriglist; list; list = list->next) { trig = list->pTrigger; if (trig->CheckTrigger(trig, old_idle)) { AdjustWaitForDelay(wt, 0); @@ -2653,10 +2655,10 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) * idle time greater than this. Schedule a wakeup for the next * millisecond so we won't miss a transition. */ - if (XSyncValueEqual(idle, *pIdleTimeValueLess)) + if (XSyncValueEqual(idle, *less)) AdjustWaitForDelay(wt, 1); } - else if (pIdleTimeValueGreater) { + else if (greater) { /* * There's a threshold in the positive direction. If we've been * idle less than it, schedule a wakeup for sometime in the future. @@ -2665,15 +2667,15 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) */ unsigned long timeout = -1; - if (XSyncValueLessThan(idle, *pIdleTimeValueGreater)) { + if (XSyncValueLessThan(idle, *greater)) { XSyncValue value; Bool overflow; - XSyncValueSubtract(&value, *pIdleTimeValueGreater, idle, &overflow); + XSyncValueSubtract(&value, *greater, idle, &overflow); timeout = min(timeout, XSyncValueLow32(value)); } else { - for (list = IdleTimeCounter->sync.pTriglist; list; + for (list = counter->sync.pTriglist; list; list = list->next) { trig = list->pTrigger; if (trig->CheckTrigger(trig, old_idle)) { @@ -2686,24 +2688,26 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) AdjustWaitForDelay(wt, timeout); } - IdleTimeCounter->value = old_idle; /* pop */ + counter->value = old_idle; /* pop */ } static void -IdleTimeWakeupHandler(pointer env, int rc, pointer LastSelectMask) +IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask) { + SyncCounter *counter = pCounter; + IdleCounterPriv *priv = SysCounterGetPrivate(counter); + XSyncValue *less = priv->value_less, + *greater = priv->value_greater; XSyncValue idle; - if (!pIdleTimeValueLess && !pIdleTimeValueGreater) + if (!less && !greater) return; - IdleTimeQueryValue(NULL, &idle); + IdleTimeQueryValue(pCounter, &idle); - if ((pIdleTimeValueGreater && - XSyncValueGreaterOrEqual(idle, *pIdleTimeValueGreater)) || - (pIdleTimeValueLess && - XSyncValueLessOrEqual(idle, *pIdleTimeValueLess))) { - SyncChangeCounter(IdleTimeCounter, idle); + if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) || + (less && XSyncValueLessOrEqual(idle, *less))) { + SyncChangeCounter(counter, idle); } } @@ -2711,34 +2715,69 @@ static void IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less, CARD64 * pbracket_greater) { - Bool registered = (pIdleTimeValueLess || pIdleTimeValueGreater); + SyncCounter *counter = pCounter; + IdleCounterPriv *priv = SysCounterGetPrivate(counter); + XSyncValue *less = priv->value_less, + *greater = priv->value_greater; + Bool registered = (less || greater); if (registered && !pbracket_less && !pbracket_greater) { RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler, - IdleTimeWakeupHandler, NULL); + IdleTimeWakeupHandler, pCounter); } else if (!registered && (pbracket_less || pbracket_greater)) { RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler, - IdleTimeWakeupHandler, NULL); + IdleTimeWakeupHandler, pCounter); } - pIdleTimeValueGreater = pbracket_greater; - pIdleTimeValueLess = pbracket_less; + priv->value_greater = pbracket_greater; + priv->value_less = pbracket_less; +} + +static SyncCounter* +init_system_idle_counter(const char *name, int deviceid) +{ + CARD64 resolution; + XSyncValue idle; + IdleCounterPriv *priv = malloc(sizeof(IdleCounterPriv)); + SyncCounter *idle_time_counter; + + IdleTimeQueryValue(NULL, &idle); + XSyncIntToValue(&resolution, 4); + + idle_time_counter = SyncCreateSystemCounter(name, idle, resolution, + XSyncCounterUnrestricted, + IdleTimeQueryValue, + IdleTimeBracketValues); + + priv->deviceid = deviceid; + priv->value_less = priv->value_greater = NULL; + + idle_time_counter->pSysCounterInfo->private = priv; + + return idle_time_counter; } static void SyncInitIdleTime(void) { - CARD64 resolution; - XSyncValue idle; - - IdleTimeQueryValue(NULL, &idle); - XSyncIntToValue(&resolution, 4); - - IdleTimeCounter = SyncCreateSystemCounter("IDLETIME", idle, resolution, - XSyncCounterUnrestricted, - IdleTimeQueryValue, - IdleTimeBracketValues); - - pIdleTimeValueLess = pIdleTimeValueGreater = NULL; + init_system_idle_counter("IDLETIME", XIAllDevices); +} + +SyncCounter* +SyncInitDeviceIdleTime(DeviceIntPtr dev) +{ + char timer_name[64]; + sprintf(timer_name, "DEVICEIDLETIME %d", dev->id); + + return init_system_idle_counter(timer_name, dev->id); +} + +void SyncRemoveDeviceIdleTime(SyncCounter *counter) +{ + /* FreeAllResources() frees all system counters before the devices are + shut down, check if there are any left before freeing the device's + counter */ + if (!xorg_list_is_empty(&SysCounterList)) + xorg_list_del(&counter->pSysCounterInfo->entry); } diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 1e59dedfe..dbed476f2 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -51,6 +51,7 @@ PERFORMANCE OF THIS SOFTWARE. #ifndef _SYNCSRV_H_ #define _SYNCSRV_H_ +#include "list.h" #include "misync.h" #include "misyncstr.h" @@ -74,13 +75,16 @@ typedef void (*SyncSystemCounterBracketValues)(pointer counter, ); typedef struct _SysCounterInfo { - const char *name; + SyncCounter *pCounter; + char *name; CARD64 resolution; CARD64 bracket_greater; CARD64 bracket_less; SyncCounterType counterType; /* how can this counter change */ SyncSystemCounterQueryValue QueryValue; SyncSystemCounterBracketValues BracketValues; + void *private; + struct xorg_list entry; } SysCounterInfo; typedef struct _SyncAlarmClientList { @@ -131,4 +135,7 @@ extern void SyncChangeCounter(SyncCounter *pCounter, extern void SyncDestroySystemCounter(pointer pCounter); extern void SyncExtensionInit(void); + +extern SyncCounter *SyncInitDeviceIdleTime(DeviceIntPtr dev); +extern void SyncRemoveDeviceIdleTime(SyncCounter *counter); #endif /* _SYNCSRV_H_ */ diff --git a/Xi/exevents.c b/Xi/exevents.c index f681a8b6f..ff2224094 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1598,7 +1598,7 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device) GetSpritePosition(device, &rootX, &rootY); event->root_x = rootX; event->root_y = rootY; - NoticeEventTime((InternalEvent *) event); + NoticeEventTime((InternalEvent *) event, device); event->corestate = corestate; key = event->detail.key; break; diff --git a/dix/devices.c b/dix/devices.c index 012550443..600f8b738 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -84,6 +84,7 @@ SOFTWARE. #include "enterleave.h" /* for EnterWindow() */ #include "xserver-properties.h" #include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */ +#include "syncsrv.h" /** @file * This file handles input device-related stuff. @@ -406,9 +407,13 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) RecalculateMasterButtons(dev); + /* initialise an idle timer for this device*/ + dev->idle_counter = SyncInitDeviceIdleTime(dev); + return TRUE; } + /** * Switch a device off through the driver and push it onto the off_devices * list. A device will not send events while disabled. All clients are @@ -432,6 +437,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) if (*prev != dev) return FALSE; + SyncRemoveDeviceIdleTime(dev->idle_counter); + dev->idle_counter = NULL; + /* float attached devices */ if (IsMaster(dev)) { for (other = inputInfo.devices; other; other = other->next) { diff --git a/dix/events.c b/dix/events.c index f7b9456ea..447094757 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1055,19 +1055,20 @@ MonthChangedOrBadTime(InternalEvent *ev) } static void -NoticeTime(InternalEvent *ev) +NoticeTime(InternalEvent *ev, DeviceIntPtr dev) { if (ev->any.time < currentTime.milliseconds) MonthChangedOrBadTime(ev); currentTime.milliseconds = ev->any.time; - lastDeviceEventTime = currentTime; + lastDeviceEventTime[XIAllDevices] = currentTime; + lastDeviceEventTime[dev->id] = currentTime; } void -NoticeEventTime(InternalEvent *ev) +NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev) { if (!syncEvents.playingEvents) - NoticeTime(ev); + NoticeTime(ev, dev); } /************************************************************************** @@ -1091,7 +1092,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device) if (!xorg_list_is_empty(&syncEvents.pending)) tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next); - NoticeTime((InternalEvent *) event); + NoticeTime((InternalEvent *)event, device); /* Fix for key repeating bug. */ if (device->key != NULL && device->key->xkbInfo != NULL && @@ -5163,6 +5164,7 @@ InitEvents(void) for (i = 0; i < MAXDEVICES; i++) { memcpy(&event_filters[i], default_filter, sizeof(default_filter)); + lastDeviceEventTime[i] = currentTime; } syncEvents.replayDev = (DeviceIntPtr) NULL; @@ -5176,7 +5178,6 @@ InitEvents(void) syncEvents.time.milliseconds = 0; /* hardly matters */ currentTime.months = 0; currentTime.milliseconds = GetTimeInMillis(); - lastDeviceEventTime = currentTime; for (i = 0; i < DNPMCOUNT; i++) { DontPropagateMasks[i] = 0; DontPropagateRefCnts[i] = 0; diff --git a/dix/globals.c b/dix/globals.c index c0cae159a..a564575f3 100644 --- a/dix/globals.c +++ b/dix/globals.c @@ -122,7 +122,7 @@ Bool party_like_its_1989 = FALSE; Bool whiteRoot = FALSE; TimeStamp currentTime; -TimeStamp lastDeviceEventTime; +TimeStamp lastDeviceEventTime[MAXDEVICES]; int defaultColorVisualClass = -1; int monitorResolution = 0; diff --git a/dix/window.c b/dix/window.c index a31e78fad..98f5604c9 100644 --- a/dix/window.c +++ b/dix/window.c @@ -3134,8 +3134,10 @@ dixSaveScreens(ClientPtr client, int on, int mode) screenIsSaved = what; if (mode == ScreenSaverReset) { if (on == SCREEN_SAVER_FORCER) { + DeviceIntPtr dev; UpdateCurrentTimeIf(); - lastDeviceEventTime = currentTime; + nt_list_for_each_entry(dev, inputInfo.devices, next) + lastDeviceEventTime[dev->id] = currentTime; } SetScreenSaverTimer(); } diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 692e511a8..e16fe78f2 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -340,7 +340,8 @@ KdEnableInput(void) /* reset screen saver */ ev.any.time = GetTimeInMillis(); - NoticeEventTime(&ev); + NoticeEventTime(&ev, pi->dixdev); + NoticeEventTime(&ev, ki->dixdev); KdUnblockSigio(); } diff --git a/include/dix.h b/include/dix.h index d604e0676..5dc2ac568 100644 --- a/include/dix.h +++ b/include/dix.h @@ -313,7 +313,8 @@ extern _X_EXPORT WindowPtr GetSpriteWindow(DeviceIntPtr pDev); extern _X_EXPORT void -NoticeEventTime(InternalEvent *ev); +NoticeEventTime(InternalEvent *ev, + DeviceIntPtr dev); extern void EnqueueEvent(InternalEvent * /* ev */ , diff --git a/include/dixstruct.h b/include/dixstruct.h index 75685a2dc..b2a168aa8 100644 --- a/include/dixstruct.h +++ b/include/dixstruct.h @@ -156,7 +156,7 @@ typedef struct _WorkQueue { } WorkQueueRec; extern _X_EXPORT TimeStamp currentTime; -extern _X_EXPORT TimeStamp lastDeviceEventTime; +extern _X_EXPORT TimeStamp lastDeviceEventTime[MAXDEVICES]; extern _X_EXPORT int CompareTimeStamps(TimeStamp /*a */ , diff --git a/include/inputstr.h b/include/inputstr.h index 841e8052b..5a38924de 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -591,6 +591,8 @@ typedef struct _DeviceIntRec { /* XTest related master device id */ int xtest_master_id; + + struct _SyncCounter *idle_counter; } DeviceIntRec; typedef struct { diff --git a/os/WaitFor.c b/os/WaitFor.c index 4c3be343b..95e64ba45 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -547,7 +547,7 @@ NextDPMSTimeout(INT32 timeout) static CARD32 ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg) { - INT32 timeout = now - lastDeviceEventTime.milliseconds; + INT32 timeout = now - lastDeviceEventTime[XIAllDevices].milliseconds; CARD32 nextTimeout = 0; #ifdef DPMSExtension diff --git a/os/xdmcp.c b/os/xdmcp.c index 8d0fbb5a9..87f04b455 100644 --- a/os/xdmcp.c +++ b/os/xdmcp.c @@ -1391,7 +1391,7 @@ recv_alive_msg(unsigned length) if (SessionRunning && AliveSessionID == SessionID) { /* backoff dormancy period */ state = XDM_RUN_SESSION; - if ((GetTimeInMillis() - lastDeviceEventTime.milliseconds) > + if ((GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds) > keepaliveDormancy * 1000) { keepaliveDormancy <<= 1; if (keepaliveDormancy > XDM_MAX_DORMANCY)