From a4a2e814d5d0e6152307a301eda1d6fc1c555aaa Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Sun, 13 Feb 2011 21:36:02 -0800 Subject: [PATCH 01/35] xkb: Use snprintf to measure string lengths instead of manual strlen math Signed-off-by: Alan Coopersmith Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- xkb/ddxLoad.c | 21 +++++++++++---------- xkb/maprules.c | 3 +-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c index 51b577725..9686ea85d 100644 --- a/xkb/ddxLoad.c +++ b/xkb/ddxLoad.c @@ -303,15 +303,16 @@ FILE * file; &&(!isalpha(xkm_output_dir[0]) || xkm_output_dir[1]!=':') #endif ) { - if (strlen(XkbBaseDirectory)+strlen(xkm_output_dir) - +strlen(mapName)+6 <= PATH_MAX) - { - sprintf(buf,"%s/%s%s.xkm",XkbBaseDirectory, - xkm_output_dir,mapName); - } + if (snprintf(buf, PATH_MAX, "%s/%s%s.xkm", XkbBaseDirectory, + xkm_output_dir, mapName) >= PATH_MAX) + buf[0] = '\0'; + } + else + { + if (snprintf(buf, PATH_MAX, "%s%s.xkm", xkm_output_dir, mapName) + >= PATH_MAX) + buf[0] = '\0'; } - else if (strlen(xkm_output_dir)+strlen(mapName)+5 <= PATH_MAX) - sprintf(buf,"%s%s.xkm",xkm_output_dir,mapName); if (buf[0] != '\0') file= fopen(buf,"rb"); else file= NULL; @@ -388,11 +389,11 @@ XkbRF_RulesPtr rules; if (!rules_name) return FALSE; - if (strlen(XkbBaseDirectory) + strlen(rules_name) + 8 > PATH_MAX) { + if (snprintf(buf, PATH_MAX, "%s/rules/%s", XkbBaseDirectory, rules_name) + >= PATH_MAX) { LogMessage(X_ERROR, "XKB: Rules name is too long\n"); return FALSE; } - sprintf(buf,"%s/rules/%s", XkbBaseDirectory, rules_name); file = fopen(buf, "r"); if (!file) { diff --git a/xkb/maprules.c b/xkb/maprules.c index c683c0d4f..0c91cdc20 100644 --- a/xkb/maprules.c +++ b/xkb/maprules.c @@ -945,9 +945,8 @@ Bool ok; if ((!base)||(!rules)) return FALSE; if (locale) { - if (strlen(base)+strlen(locale)+2 > PATH_MAX) + if (snprintf(buf, PATH_MAX, "%s-%s", base, locale) >= PATH_MAX) return FALSE; - sprintf(buf,"%s-%s", base, locale); } else { if (strlen(base)+1 > PATH_MAX) From aac1b435664819008989ed19f73e9c89920602c5 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Sun, 13 Feb 2011 21:36:03 -0800 Subject: [PATCH 02/35] Replace _XkbDupString with Xstrdup The two functions have identical semantics, including safely returning NULL when NULL is passed in (which POSIX strdup does not guarantee). Some callers could probably be adjusted to call libc strdup directly, when we know the input is non-NULL. Signed-off-by: Alan Coopersmith Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- include/xkbsrv.h | 4 ---- xkb/maprules.c | 30 +++++++++++++++--------------- xkb/xkb.c | 8 ++++---- xkb/xkbInit.c | 20 ++++++++++---------- xkb/xkbfmisc.c | 10 +++++----- xkb/xkmread.c | 21 ++++----------------- 6 files changed, 38 insertions(+), 55 deletions(-) diff --git a/include/xkbsrv.h b/include/xkbsrv.h index 9f1507e8e..422bae014 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -846,10 +846,6 @@ extern _X_EXPORT XkbGeometryPtr XkbLookupNamedGeometry( Bool * /* shouldFree */ ); -extern _X_EXPORT char * _XkbDupString( - const char * /* str */ -); - extern _X_EXPORT void XkbConvertCase( KeySym /* sym */, KeySym * /* lower */, diff --git a/xkb/maprules.c b/xkb/maprules.c index 0c91cdc20..f94089982 100644 --- a/xkb/maprules.c +++ b/xkb/maprules.c @@ -391,8 +391,8 @@ Bool append = FALSE; } if (*words == '\0') return FALSE; - group->name = _XkbDupString(gname); - group->words = _XkbDupString(words); + group->name = Xstrdup(gname); + group->words = Xstrdup(words); for (i = 1, words = group->words; *words; words++) { if ( *words == ' ') { *words++ = '\0'; @@ -443,16 +443,16 @@ Bool append = FALSE; rule->flags|= XkbRF_Append; else rule->flags|= XkbRF_Normal; - rule->model= _XkbDupString(tmp.name[MODEL]); - rule->layout= _XkbDupString(tmp.name[LAYOUT]); - rule->variant= _XkbDupString(tmp.name[VARIANT]); - rule->option= _XkbDupString(tmp.name[OPTION]); + rule->model= Xstrdup(tmp.name[MODEL]); + rule->layout= Xstrdup(tmp.name[LAYOUT]); + rule->variant= Xstrdup(tmp.name[VARIANT]); + rule->option= Xstrdup(tmp.name[OPTION]); - rule->keycodes= _XkbDupString(tmp.name[KEYCODES]); - rule->symbols= _XkbDupString(tmp.name[SYMBOLS]); - rule->types= _XkbDupString(tmp.name[TYPES]); - rule->compat= _XkbDupString(tmp.name[COMPAT]); - rule->geometry= _XkbDupString(tmp.name[GEOMETRY]); + rule->keycodes= Xstrdup(tmp.name[KEYCODES]); + rule->symbols= Xstrdup(tmp.name[SYMBOLS]); + rule->types= Xstrdup(tmp.name[TYPES]); + rule->compat= Xstrdup(tmp.name[COMPAT]); + rule->geometry= Xstrdup(tmp.name[GEOMETRY]); rule->layout_num = rule->variant_num = 0; for (i = 0; i < nread; i++) { @@ -497,7 +497,7 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs) memset((char *)mdefs, 0, sizeof(XkbRF_MultiDefsRec)); mdefs->model = defs->model; - mdefs->options = _XkbDupString(defs->options); + mdefs->options = Xstrdup(defs->options); if (mdefs->options) squeeze_spaces(mdefs->options); if (defs->layout) { @@ -506,7 +506,7 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs) } else { char *p; int i; - mdefs->layout[1] = _XkbDupString(defs->layout); + mdefs->layout[1] = Xstrdup(defs->layout); if (mdefs->layout[1] == NULL) return FALSE; squeeze_spaces(mdefs->layout[1]); @@ -530,7 +530,7 @@ MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs) } else { char *p; int i; - mdefs->variant[1] = _XkbDupString(defs->variant); + mdefs->variant[1] = Xstrdup(defs->variant); if (mdefs->variant[1] == NULL) return FALSE; squeeze_spaces(mdefs->variant[1]); @@ -566,7 +566,7 @@ Apply(char *src, char **dst) *dst= _Concat(*dst, src); } else { if (*dst == NULL) - *dst= _XkbDupString(src); + *dst= Xstrdup(src); } } } diff --git a/xkb/xkb.c b/xkb/xkb.c index 6fd66c5e5..d98e35296 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -5619,17 +5619,17 @@ ProcXkbGetKbdByName(ClientPtr client) else fwant= stuff->want|stuff->need; if ((!names.compat)&& (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) { - names.compat= _XkbDupString("%"); + names.compat= Xstrdup("%"); } if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) { - names.types= _XkbDupString("%"); + names.types= Xstrdup("%"); } if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) { - names.symbols= _XkbDupString("%"); + names.symbols= Xstrdup("%"); } geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0)); if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) { - names.geometry= _XkbDupString("%"); + names.geometry= Xstrdup("%"); geom_changed= FALSE; } diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c index fbf8f14b8..3d3febb4f 100644 --- a/xkb/xkbInit.c +++ b/xkb/xkbInit.c @@ -221,15 +221,15 @@ static void XkbSetRulesUsed(XkbRMLVOSet *rmlvo) { free(XkbRulesUsed); - XkbRulesUsed= (rmlvo->rules?_XkbDupString(rmlvo->rules):NULL); + XkbRulesUsed= (rmlvo->rules?Xstrdup(rmlvo->rules):NULL); free(XkbModelUsed); - XkbModelUsed= (rmlvo->model?_XkbDupString(rmlvo->model):NULL); + XkbModelUsed= (rmlvo->model?Xstrdup(rmlvo->model):NULL); free(XkbLayoutUsed); - XkbLayoutUsed= (rmlvo->layout?_XkbDupString(rmlvo->layout):NULL); + XkbLayoutUsed= (rmlvo->layout?Xstrdup(rmlvo->layout):NULL); free(XkbVariantUsed); - XkbVariantUsed= (rmlvo->variant?_XkbDupString(rmlvo->variant):NULL); + XkbVariantUsed= (rmlvo->variant?Xstrdup(rmlvo->variant):NULL); free(XkbOptionsUsed); - XkbOptionsUsed= (rmlvo->options?_XkbDupString(rmlvo->options):NULL); + XkbOptionsUsed= (rmlvo->options?Xstrdup(rmlvo->options):NULL); if (XkbWantRulesProp) QueueWorkProc(XkbWriteRulesProp,NULL,NULL); return; @@ -240,23 +240,23 @@ XkbSetRulesDflts(XkbRMLVOSet *rmlvo) { if (rmlvo->rules) { free(XkbRulesDflt); - XkbRulesDflt= _XkbDupString(rmlvo->rules); + XkbRulesDflt= Xstrdup(rmlvo->rules); } if (rmlvo->model) { free(XkbModelDflt); - XkbModelDflt= _XkbDupString(rmlvo->model); + XkbModelDflt= Xstrdup(rmlvo->model); } if (rmlvo->layout) { free(XkbLayoutDflt); - XkbLayoutDflt= _XkbDupString(rmlvo->layout); + XkbLayoutDflt= Xstrdup(rmlvo->layout); } if (rmlvo->variant) { free(XkbVariantDflt); - XkbVariantDflt= _XkbDupString(rmlvo->variant); + XkbVariantDflt= Xstrdup(rmlvo->variant); } if (rmlvo->options) { free(XkbOptionsDflt); - XkbOptionsDflt= _XkbDupString(rmlvo->options); + XkbOptionsDflt= Xstrdup(rmlvo->options); } return; } diff --git a/xkb/xkbfmisc.c b/xkb/xkbfmisc.c index 7aa9863f2..dea347335 100644 --- a/xkb/xkbfmisc.c +++ b/xkb/xkbfmisc.c @@ -241,7 +241,7 @@ unsigned wantNames,wantConfig,wantDflts; if (wantNames&XkmTypesMask) { if (old_names->types!=None) { tmp= NameForAtom(old_names->types); - names->types= _XkbDupString(tmp); + names->types= Xstrdup(tmp); } else { wantDflts|= XkmTypesMask; @@ -251,7 +251,7 @@ unsigned wantNames,wantConfig,wantDflts; if (wantNames&XkmCompatMapMask) { if (old_names->compat!=None) { tmp= NameForAtom(old_names->compat); - names->compat= _XkbDupString(tmp); + names->compat= Xstrdup(tmp); } else wantDflts|= XkmCompatMapMask; complete|= XkmCompatMapMask; @@ -260,13 +260,13 @@ unsigned wantNames,wantConfig,wantDflts; if (old_names->symbols==None) return FALSE; tmp= NameForAtom(old_names->symbols); - names->symbols= _XkbDupString(tmp); + names->symbols= Xstrdup(tmp); complete|= XkmSymbolsMask; } if (wantNames&XkmKeyNamesMask) { if (old_names->keycodes!=None) { tmp= NameForAtom(old_names->keycodes); - names->keycodes= _XkbDupString(tmp); + names->keycodes= Xstrdup(tmp); } else wantDflts|= XkmKeyNamesMask; complete|= XkmKeyNamesMask; @@ -275,7 +275,7 @@ unsigned wantNames,wantConfig,wantDflts; if (old_names->geometry==None) return FALSE; tmp= NameForAtom(old_names->geometry); - names->geometry= _XkbDupString(tmp); + names->geometry= Xstrdup(tmp); complete|= XkmGeometryMask; wantNames&= ~XkmGeometryMask; } diff --git a/xkb/xkmread.c b/xkb/xkmread.c index b564195bc..e8b97dcda 100644 --- a/xkb/xkmread.c +++ b/xkb/xkmread.c @@ -51,19 +51,6 @@ XkbInternAtom(char *str,Bool only_if_exists) return MakeAtom(str,strlen(str),!only_if_exists); } -char * -_XkbDupString(const char *str) -{ -char *new; - - if (str==NULL) - return NULL; - new= calloc(strlen(str)+1,sizeof(char)); - if (new) - strcpy(new,str); - return new; -} - /***====================================================================***/ static void * @@ -845,9 +832,9 @@ int nRead=0; doodad->text.height= doodadWire.text.height; doodad->text.color_ndx= doodadWire.text.color_ndx; nRead+= XkmGetCountedString(file,buf,100); - doodad->text.text= _XkbDupString(buf); + doodad->text.text= Xstrdup(buf); nRead+= XkmGetCountedString(file,buf,100); - doodad->text.font= _XkbDupString(buf); + doodad->text.font= Xstrdup(buf); break; case XkbIndicatorDoodad: doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx; @@ -859,7 +846,7 @@ int nRead=0; doodad->logo.color_ndx= doodadWire.logo.color_ndx; doodad->logo.shape_ndx= doodadWire.logo.shape_ndx; nRead+= XkmGetCountedString(file,buf,100); - doodad->logo.logo_name= _XkbDupString(buf); + doodad->logo.logo_name= Xstrdup(buf); break; default: /* report error? */ @@ -1021,7 +1008,7 @@ XkbGeometrySizesRec sizes; geom->width_mm= wireGeom.width_mm; geom->height_mm= wireGeom.height_mm; nRead+= XkmGetCountedString(file,buf,100); - geom->label_font= _XkbDupString(buf); + geom->label_font= Xstrdup(buf); if (wireGeom.num_properties>0) { char val[1024]; for (i=0;i Date: Sun, 13 Feb 2011 21:36:04 -0800 Subject: [PATCH 03/35] XkbAddGeomProperty: Fix checks for malloc failure Check the variable we just tried to malloc, not the string we're copying and already checked for NULL at the beginning of the function. Signed-off-by: Alan Coopersmith Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- xkb/XKBGAlloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xkb/XKBGAlloc.c b/xkb/XKBGAlloc.c index 3ec9edab8..f49aead02 100644 --- a/xkb/XKBGAlloc.c +++ b/xkb/XKBGAlloc.c @@ -659,11 +659,11 @@ register XkbPropertyPtr prop; } prop= &geom->properties[geom->num_properties]; prop->name= malloc(strlen(name)+1); - if (!name) + if (!prop->name) return NULL; strcpy(prop->name,name); prop->value= malloc(strlen(value)+1); - if (!value) { + if (!prop->value) { free(prop->name); prop->name= NULL; return NULL; From 0f9c6f2f822ff53b9d12ff4fa0b26cbeb7394ba5 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Sun, 13 Feb 2011 21:36:05 -0800 Subject: [PATCH 04/35] xkb: Replace malloc(strlen) + strcpy with strdup Signed-off-by: Alan Coopersmith Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- xkb/XKBGAlloc.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/xkb/XKBGAlloc.c b/xkb/XKBGAlloc.c index f49aead02..65f92fdba 100644 --- a/xkb/XKBGAlloc.c +++ b/xkb/XKBGAlloc.c @@ -647,9 +647,7 @@ register XkbPropertyPtr prop; for (i=0,prop=geom->properties;inum_properties;i++,prop++) { if ((prop->name)&&(strcmp(name,prop->name)==0)) { free(prop->value); - prop->value= malloc(strlen(value)+1); - if (prop->value) - strcpy(prop->value,value); + prop->value= strdup(value); return prop; } } @@ -658,17 +656,15 @@ register XkbPropertyPtr prop; return NULL; } prop= &geom->properties[geom->num_properties]; - prop->name= malloc(strlen(name)+1); + prop->name= strdup(name); if (!prop->name) return NULL; - strcpy(prop->name,name); - prop->value= malloc(strlen(value)+1); + prop->value= strdup(value); if (!prop->value) { free(prop->name); prop->name= NULL; return NULL; } - strcpy(prop->value,value); geom->num_properties++; return prop; } @@ -720,10 +716,9 @@ register XkbColorPtr color; } color= &geom->colors[geom->num_colors]; color->pixel= pixel; - color->spec= malloc(strlen(spec)+1); + color->spec= strdup(spec); if (!color->spec) return NULL; - strcpy(color->spec,spec); geom->num_colors++; return color; } From da39d57a20d4281fc4099e356645fef980290030 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 15 Feb 2011 11:27:57 +0000 Subject: [PATCH 05/35] Input: Store passive-activating key in CheckDeviceGrabs CheckDeviceGrabs will activate a passive grab for KeyPress and ButtonPress events. GrabInfoRec::activatingKey contains the keycode which activated the passive grab, so we can deactivate it later in ProcessOtherEvents. Previously, CheckDeviceGrabs relied on its callers to set activatingKey, which not all callers were doing (I'm looking at you, ComputeFreezes). Just set it in CheckDeviceGrabs instead. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- Xi/exevents.c | 4 +--- dix/events.c | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 327873e29..513116782 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1047,10 +1047,8 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) switch(event->type) { case ET_KeyPress: - if (!grab && CheckDeviceGrabs(device, event, 0)) { - device->deviceGrab.activatingKey = key; + if (!grab && CheckDeviceGrabs(device, event, 0)) return; - } break; case ET_KeyRelease: if (grab && device->deviceGrab.fromPassiveGrab && diff --git a/dix/events.c b/dix/events.c index 07f8b05ea..5e8166d43 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3582,6 +3582,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) WindowPtr pWin = NULL; FocusClassPtr focus = IsPointerEvent((InternalEvent*)event) ? NULL : device->focus; BOOL sendCore = (IsMaster(device) && device->coreEvents); + Bool ret = FALSE; if (event->type != ET_ButtonPress && event->type != ET_KeyPress) @@ -3601,7 +3602,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) if (device->spriteInfo->sprite->spriteTrace[i++] == ancestor) break; if (i == device->spriteInfo->sprite->spriteTraceGood) - return FALSE; + goto out; } if (focus) @@ -3610,23 +3611,32 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) { pWin = focus->trace[i]; if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE)) - return TRUE; + { + ret = TRUE; + goto out; + } } if ((focus->win == NoneWin) || (i >= device->spriteInfo->sprite->spriteTraceGood) || (pWin && pWin != device->spriteInfo->sprite->spriteTrace[i-1])) - return FALSE; + goto out; } for (; i < device->spriteInfo->sprite->spriteTraceGood; i++) { pWin = device->spriteInfo->sprite->spriteTrace[i]; if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE)) - return TRUE; + { + ret = TRUE; + goto out; + } } - return FALSE; +out: + if (ret == TRUE && event->type == ET_KeyPress) + device->deviceGrab.activatingKey = event->detail.key; + return ret; } /** From 737562257e8ee30b1c438e5160a61fbb26ca609e Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 15 Feb 2011 11:27:59 +0000 Subject: [PATCH 06/35] Input: Actually send Xi 1.x DeviceStateNotify events When a client has selected for Xi 1.x DeviceStateNotify events, they should receive them when a DeviceFocusIn event is generated. The code to do this was there, but an incorrect test meant they were never being sent. The "type" passed in is the XI2 type, the XI1 type is in event.type. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- Xi/exevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 513116782..cf38967ba 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1278,7 +1278,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, DeviceFocusChangeMask, NullGrab); - if ((type == DeviceFocusIn) && + if ((event.type == DeviceFocusIn) && (wOtherInputMasks(pWin)) && (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) { From 8a0241656cecb6ab2fb377f02b14238d18e65fc1 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 15 Feb 2011 11:28:00 +0000 Subject: [PATCH 07/35] Input: Rename EventIsDeliverable return masks Rename the return mask values for EventIsDeliverable: * CORE_MASK -> EVENT_CORE_MASK * XI_MASK -> EVENT_XI1_MASK * XI2_MASK -> EVENT_XI2_MASK * DONT_PROPAGATE_MASK -> EVENT_DONT_PROPAGATE_MASK And don't undef them in dix/events.c, since they're supposed to be global. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- dix/events.c | 26 +++++++++++--------------- include/input.h | 11 ++++++----- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/dix/events.c b/dix/events.c index 5e8166d43..66c11b490 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2287,8 +2287,8 @@ FixUpEventFromWindow( * @param[in] event The event that is to be sent. * @param[in] win The current event window. * - * @return Bitmask of ::XI2_MASK, ::XI_MASK, ::CORE_MASK, and - * ::DONT_PROPAGATE_MASK. + * @return Bitmask of ::EVENT_XI2_MASK, ::EVENT_XI1_MASK, ::EVENT_CORE_MASK, and + * ::EVENT_DONT_PROPAGATE_MASK. */ int EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win) @@ -2309,7 +2309,7 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win) ((inputMasks->xi2mask[XIAllDevices][type/8] & filter) || ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && IsMaster(dev)) || (inputMasks->xi2mask[dev->id][type/8] & filter))) - rc |= XI2_MASK; + rc |= EVENT_XI2_MASK; type = GetXIType(event); ev.u.u.type = type; @@ -2319,22 +2319,22 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win) if (type && inputMasks && (inputMasks->deliverableEvents[dev->id] & filter) && (inputMasks->inputEvents[dev->id] & filter)) - rc |= XI_MASK; + rc |= EVENT_XI1_MASK; /* Check for XI DontPropagate mask */ if (type && inputMasks && (inputMasks->dontPropagateMask[dev->id] & filter)) - rc |= DONT_PROPAGATE_MASK; + rc |= EVENT_DONT_PROPAGATE_MASK; /* Check for core mask */ type = GetCoreType(event); if (type && (win->deliverableEvents & filter) && ((wOtherEventMasks(win) | win->eventMask) & filter)) - rc |= CORE_MASK; + rc |= EVENT_CORE_MASK; /* Check for core DontPropagate mask */ if (type && (filter & wDontPropagateMask(win))) - rc |= DONT_PROPAGATE_MASK; + rc |= EVENT_DONT_PROPAGATE_MASK; return rc; } @@ -2377,7 +2377,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, if ((mask = EventIsDeliverable(dev, event, pWin))) { /* XI2 events first */ - if (mask & XI2_MASK) + if (mask & EVENT_XI2_MASK) { xEvent *xi2 = NULL; rc = EventToXI2(event, &xi2); @@ -2397,7 +2397,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, } /* XI events */ - if (mask & XI_MASK) + if (mask & EVENT_XI1_MASK) { rc = EventToXI(event, &xE, &count); if (rc == Success) { @@ -2415,7 +2415,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, } /* Core event */ - if ((mask & CORE_MASK) && IsMaster(dev) && dev->coreEvents) + if ((mask & EVENT_CORE_MASK) && IsMaster(dev) && dev->coreEvents) { rc = EventToCore(event, &core); if (rc == Success) { @@ -2433,7 +2433,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, } if ((deliveries < 0) || (pWin == stopAt) || - (mask & DONT_PROPAGATE_MASK)) + (mask & EVENT_DONT_PROPAGATE_MASK)) { deliveries = 0; goto unwind; @@ -2449,10 +2449,6 @@ unwind: return deliveries; } -#undef XI_MASK -#undef CORE_MASK -#undef DONT_PROPAGATE_MASK - /** * Deliver event to a window and it's immediate parent. Used for most window * events (CreateNotify, ConfigureNotify, etc.). Not useful for events that diff --git a/include/input.h b/include/input.h index f96a0a988..0dc725a37 100644 --- a/include/input.h +++ b/include/input.h @@ -538,14 +538,15 @@ extern WindowPtr XYToWindow(SpritePtr pSprite, int x, int y); extern int EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win); /** - * Return masks for EventIsDeliverable. + * Masks specifying the type of event to deliver for an InternalEvent; used + * by EventIsDeliverable. * @defgroup EventIsDeliverable return flags * @{ */ -#define XI_MASK (1 << 0) /**< XI mask set on window */ -#define CORE_MASK (1 << 1) /**< Core mask set on window */ -#define DONT_PROPAGATE_MASK (1 << 2) /**< DontPropagate mask set on window */ -#define XI2_MASK (1 << 3) /**< XI2 mask set on window */ +#define EVENT_XI1_MASK (1 << 0) /**< XI1.x event */ +#define EVENT_CORE_MASK (1 << 1) /**< Core event */ +#define EVENT_DONT_PROPAGATE_MASK (1 << 2) /**< DontPropagate mask set */ +#define EVENT_XI2_MASK (1 << 3) /**< XI2 mask set on window */ /* @} */ /* Implemented by the DDX. */ From ea71495adabca52df44241c0eba39e6bceb58202 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 15 Feb 2011 11:28:01 +0000 Subject: [PATCH 08/35] Input: Reduce use of filter in DeliverEvents Instead of switching on the event filter to determine delivery, use the event type instead. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- dix/events.c | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/dix/events.c b/dix/events.c index 66c11b490..d547e57d6 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2466,9 +2466,8 @@ int DeliverEvents(WindowPtr pWin, xEvent *xE, int count, WindowPtr otherParent) { - Mask filter; - int deliveries; DeviceIntRec dummy; + int deliveries; #ifdef PANORAMIX if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) @@ -2479,11 +2478,42 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count, return 0; dummy.id = XIAllDevices; - filter = GetEventFilter(&dummy, xE); - if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify)) - xE->u.destroyNotify.event = pWin->drawable.id; - if (filter != StructureAndSubMask) - return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, NullGrab); + + switch (xE->u.u.type) + { + case DestroyNotify: + case UnmapNotify: + case MapNotify: + case MapRequest: + case ReparentNotify: + case ConfigureNotify: + case ConfigureRequest: + case GravityNotify: + case CirculateNotify: + case CirculateRequest: + xE->u.destroyNotify.event = pWin->drawable.id; + break; + } + + switch (xE->u.u.type) + { + case DestroyNotify: + case UnmapNotify: + case MapNotify: + case ReparentNotify: + case ConfigureNotify: + case GravityNotify: + case CirculateNotify: + break; + default: + { + Mask filter; + filter = GetEventFilter(&dummy, xE); + return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, + NullGrab); + } + } + deliveries = DeliverEventsToWindow(&dummy, pWin, xE, count, StructureNotifyMask, NullGrab); if (pWin->parent) From 46b49796015762fd131bec96eff6caaa890bfd5f Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 15 Feb 2011 11:28:02 +0000 Subject: [PATCH 09/35] Input: Allow EventToCore to return multiple events Some event types (notably Expose and GraphicsExpose) require multiple events, a la XI 1.x. Bring the EventToCore API in line with EventToXI's and allow it to generate multiple events. Signed-off-by: Daniel Stone Signed-off-by: Peter Hutterer --- dix/eventconvert.c | 37 ++++++++++++++++++----- dix/events.c | 57 +++++++++++++++++------------------ include/eventconvert.h | 2 +- record/record.c | 9 ++++-- test/input.c | 68 ++++++++++++++++++++++++------------------ 5 files changed, 102 insertions(+), 71 deletions(-) diff --git a/dix/eventconvert.c b/dix/eventconvert.c index 7b894f016..897691946 100644 --- a/dix/eventconvert.c +++ b/dix/eventconvert.c @@ -97,8 +97,12 @@ EventIsKeyRepeat(xEvent *event) * @return Success or the matching error code. */ int -EventToCore(InternalEvent *event, xEvent *core) +EventToCore(InternalEvent *event, xEvent **core_out, int *count_out) { + xEvent *core = NULL; + int count = 0; + int ret = BadImplementation; + switch(event->any.type) { case ET_Motion: @@ -108,7 +112,10 @@ EventToCore(InternalEvent *event, xEvent *core) * present */ if (!BitIsOn(e->valuators.mask, 0) && !BitIsOn(e->valuators.mask, 1)) - return BadMatch; + { + ret = BadMatch; + goto out; + } } /* fallthrough */ case ET_ButtonPress: @@ -119,9 +126,15 @@ EventToCore(InternalEvent *event, xEvent *core) DeviceEvent *e = &event->device_event; if (e->detail.key > 0xFF) - return BadMatch; + { + ret = BadMatch; + goto out; + } - memset(core, 0, sizeof(xEvent)); + core = calloc(1, sizeof(*core)); + if (!core) + return BadAlloc; + count = 1; core->u.u.type = e->type - ET_KeyPress + KeyPress; core->u.u.detail = e->detail.key & 0xFF; core->u.keyButtonPointer.time = e->time; @@ -129,7 +142,10 @@ EventToCore(InternalEvent *event, xEvent *core) core->u.keyButtonPointer.rootY = e->root_y; core->u.keyButtonPointer.state = e->corestate; core->u.keyButtonPointer.root = e->root; - EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat)); + EventSetKeyRepeatFlag(core, + (e->type == ET_KeyPress && + e->key_repeat)); + ret = Success; } break; case ET_ProximityIn: @@ -139,13 +155,18 @@ EventToCore(InternalEvent *event, xEvent *core) case ET_RawButtonPress: case ET_RawButtonRelease: case ET_RawMotion: - return BadMatch; + ret = BadMatch; + goto out; default: /* XXX: */ ErrorF("[dix] EventToCore: Not implemented yet \n"); - return BadImplementation; + ret = BadImplementation; } - return Success; + +out: + *core_out = core; + *count_out = count; + return ret; } /** diff --git a/dix/events.c b/dix/events.c index d547e57d6..2723f5374 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2366,8 +2366,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, Window child = None; Mask filter; int deliveries = 0; - xEvent core; - xEvent *xE = NULL; + xEvent *xE = NULL, *core = NULL; int rc, mask, count = 0; CHECKEVENT(event); @@ -2417,13 +2416,13 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, /* Core event */ if ((mask & EVENT_CORE_MASK) && IsMaster(dev) && dev->coreEvents) { - rc = EventToCore(event, &core); + rc = EventToCore(event, &core, &count); if (rc == Success) { - if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success) { - filter = GetEventFilter(dev, &core); - FixUpEventFromWindow(pSprite, &core, pWin, child, FALSE); - deliveries = DeliverEventsToWindow(dev, pWin, &core, 1, - filter, grab); + if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, core, count) == Success) { + filter = GetEventFilter(dev, core); + FixUpEventFromWindow(pSprite, core, pWin, child, FALSE); + deliveries = DeliverEventsToWindow(dev, pWin, core, + count, filter, grab); if (deliveries > 0) goto unwind; } @@ -2445,6 +2444,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, } unwind: + free(core); free(xE); return deliveries; } @@ -3460,7 +3460,6 @@ CheckPassiveGrabsOnWindow( { int rc, count = 0; xEvent *xE = NULL; - xEvent core; event->corestate &= 0x1f00; event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00); @@ -3512,7 +3511,7 @@ CheckPassiveGrabsOnWindow( if (match & CORE_MATCH) { - rc = EventToCore((InternalEvent*)event, &core); + rc = EventToCore((InternalEvent*)event, &xE, &count); if (rc != Success) { if (rc != BadMatch) @@ -3520,8 +3519,6 @@ CheckPassiveGrabsOnWindow( "(%d, %d).\n", device->name, event->type, rc); continue; } - xE = &core; - count = 1; } else if (match & XI2_MATCH) { rc = EventToXI2((InternalEvent*)event, &xE); @@ -3551,6 +3548,7 @@ CheckPassiveGrabsOnWindow( { FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE); + /* XXX: XACE? */ TryClientEvents(rClient(grab), device, xE, count, GetEventFilter(device, xE), GetEventFilter(device, xE), grab); @@ -3564,8 +3562,7 @@ CheckPassiveGrabsOnWindow( grabinfo->sync.state = FROZEN_WITH_EVENT; } - if (match & (XI_MATCH | XI2_MATCH)) - free(xE); /* on core match xE == &core */ + free(xE); return grab; } } @@ -3682,8 +3679,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window) DeviceIntPtr ptr; WindowPtr focus = keybd->focus->win; BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents); - xEvent core; - xEvent *xE = NULL, *xi2 = NULL; + xEvent *core = NULL, *xE = NULL, *xi2 = NULL; int count, rc; int deliveries = 0; @@ -3737,13 +3733,13 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window) if (sendCore) { - rc = EventToCore(event, &core); + rc = EventToCore(event, &core, &count); if (rc == Success) { - if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, &core, 1) == Success) { - FixUpEventFromWindow(keybd->spriteInfo->sprite, &core, focus, + if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, core, count) == Success) { + FixUpEventFromWindow(keybd->spriteInfo->sprite, core, focus, None, FALSE); - deliveries = DeliverEventsToWindow(keybd, focus, &core, 1, - GetEventFilter(keybd, &core), + deliveries = DeliverEventsToWindow(keybd, focus, core, count, + GetEventFilter(keybd, core), NullGrab); } } else if (rc != BadMatch) @@ -3752,6 +3748,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window) } unwind: + free(core); free(xE); free(xi2); return; @@ -3777,6 +3774,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, int rc, count = 0; xEvent *xi = NULL; xEvent *xi2 = NULL; + xEvent *core = NULL; grabinfo = &thisDev->deviceGrab; grab = grabinfo->grab; @@ -3826,22 +3824,20 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, /* try core event */ if (sendCore && grab->grabtype == GRABTYPE_CORE) { - xEvent core; - - rc = EventToCore(event, &core); + rc = EventToCore(event, &core, &count); if (rc == Success) { - FixUpEventFromWindow(pSprite, &core, grab->window, None, TRUE); + FixUpEventFromWindow(pSprite, core, grab->window, None, TRUE); if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, - grab->window, &core, 1) || + grab->window, core, count) || XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), - grab->window, &core, 1)) + grab->window, core, count)) deliveries = 1; /* don't send, but pretend we did */ - else if (!IsInterferingGrab(rClient(grab), thisDev, &core)) + else if (!IsInterferingGrab(rClient(grab), thisDev, core)) { deliveries = TryClientEvents(rClient(grab), thisDev, - &core, 1, mask, - GetEventFilter(thisDev, &core), + core, count, mask, + GetEventFilter(thisDev, core), grab); } } else if (rc != BadMatch) @@ -3931,6 +3927,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, } } + free(core); free(xi); free(xi2); } diff --git a/include/eventconvert.h b/include/eventconvert.h index b1196a00e..b000abc4b 100644 --- a/include/eventconvert.h +++ b/include/eventconvert.h @@ -30,7 +30,7 @@ #define FP1616(integral, frac) ((integral) * (1 << 16) + (frac) * (1 << 16)) -_X_EXPORT int EventToCore(InternalEvent *event, xEvent *core); +_X_EXPORT int EventToCore(InternalEvent *event, xEvent **core, int *count); _X_EXPORT int EventToXI(InternalEvent *ev, xEvent **xi, int *count); _X_EXPORT int EventToXI2(InternalEvent *ev, xEvent **xi); _X_INTERNAL int GetCoreType(InternalEvent* ev); diff --git a/record/record.c b/record/record.c index 6a93d7a5c..1168c43ac 100644 --- a/record/record.c +++ b/record/record.c @@ -804,6 +804,7 @@ RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata) RecordContextPtr pContext; RecordClientsAndProtocolPtr pRCAP; int eci; /* enabled context index */ + int count; for (eci = 0; eci < numEnabledContexts; eci++) { @@ -818,9 +819,11 @@ RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata) /* TODO check return values */ if (IsMaster(pei->device)) { - xEvent xE; - EventToCore(pei->event, &xE); - RecordSendProtocolEvents(pRCAP, pContext, &xE, 1); + xEvent *core_events; + EventToCore(pei->event, &core_events, &count); + RecordSendProtocolEvents(pRCAP, pContext, core_events, + count); + free(core_events); } EventToXI(pei->event, &xi_events, &count); diff --git a/test/input.c b/test/input.c index 879e14f2f..e7300a102 100644 --- a/test/input.c +++ b/test/input.c @@ -148,29 +148,32 @@ static void dix_check_grab_values(void) static void dix_event_to_core(int type) { DeviceEvent ev; - xEvent core; + xEvent *core; int time; int x, y; int rc; int state; int detail; + int count; const int ROOT_WINDOW_ID = 0x100; /* EventToCore memsets the event to 0 */ #define test_event() \ g_assert(rc == Success); \ - g_assert(core.u.u.type == type); \ - g_assert(core.u.u.detail == detail); \ - g_assert(core.u.keyButtonPointer.time == time); \ - g_assert(core.u.keyButtonPointer.rootX == x); \ - g_assert(core.u.keyButtonPointer.rootY == y); \ - g_assert(core.u.keyButtonPointer.state == state); \ - g_assert(core.u.keyButtonPointer.eventX == 0); \ - g_assert(core.u.keyButtonPointer.eventY == 0); \ - g_assert(core.u.keyButtonPointer.root == ROOT_WINDOW_ID); \ - g_assert(core.u.keyButtonPointer.event == 0); \ - g_assert(core.u.keyButtonPointer.child == 0); \ - g_assert(core.u.keyButtonPointer.sameScreen == FALSE); + g_assert(core); \ + g_assert(count == 1); \ + g_assert(core->u.u.type == type); \ + g_assert(core->u.u.detail == detail); \ + g_assert(core->u.keyButtonPointer.time == time); \ + g_assert(core->u.keyButtonPointer.rootX == x); \ + g_assert(core->u.keyButtonPointer.rootY == y); \ + g_assert(core->u.keyButtonPointer.state == state); \ + g_assert(core->u.keyButtonPointer.eventX == 0); \ + g_assert(core->u.keyButtonPointer.eventY == 0); \ + g_assert(core->u.keyButtonPointer.root == ROOT_WINDOW_ID); \ + g_assert(core->u.keyButtonPointer.event == 0); \ + g_assert(core->u.keyButtonPointer.child == 0); \ + g_assert(core->u.keyButtonPointer.sameScreen == FALSE); x = 0; y = 0; @@ -191,30 +194,33 @@ static void dix_event_to_core(int type) ev.type = type; ev.detail.key = 0; - rc = EventToCore((InternalEvent*)&ev, &core); + rc = EventToCore((InternalEvent*)&ev, &core, &count); test_event(); x = 1; y = 2; ev.root_x = x; ev.root_y = y; - rc = EventToCore((InternalEvent*)&ev, &core); + rc = EventToCore((InternalEvent*)&ev, &core, &count); test_event(); x = 0x7FFF; y = 0x7FFF; ev.root_x = x; ev.root_y = y; - rc = EventToCore((InternalEvent*)&ev, &core); + rc = EventToCore((InternalEvent*)&ev, &core, &count); test_event(); x = 0x8000; /* too high */ y = 0x8000; /* too high */ ev.root_x = x; ev.root_y = y; - rc = EventToCore((InternalEvent*)&ev, &core); - g_assert(core.u.keyButtonPointer.rootX != x); - g_assert(core.u.keyButtonPointer.rootY != y); + rc = EventToCore((InternalEvent*)&ev, &core, &count); + g_assert(rc == Success); + g_assert(core); + g_assert(count == 1); + g_assert(core->u.keyButtonPointer.rootX != x); + g_assert(core->u.keyButtonPointer.rootY != y); x = 0x7FFF; y = 0x7FFF; @@ -222,36 +228,39 @@ static void dix_event_to_core(int type) ev.root_y = y; time = 0; ev.time = time; - rc = EventToCore((InternalEvent*)&ev, &core); + rc = EventToCore((InternalEvent*)&ev, &core, &count); test_event(); detail = 1; ev.detail.key = detail; - rc = EventToCore((InternalEvent*)&ev, &core); + rc = EventToCore((InternalEvent*)&ev, &core, &count); test_event(); detail = 0xFF; /* highest value */ ev.detail.key = detail; - rc = EventToCore((InternalEvent*)&ev, &core); + rc = EventToCore((InternalEvent*)&ev, &core, &count); test_event(); detail = 0xFFF; /* too big */ ev.detail.key = detail; - rc = EventToCore((InternalEvent*)&ev, &core); + rc = EventToCore((InternalEvent*)&ev, &core, &count); g_assert(rc == BadMatch); detail = 0xFF; /* too big */ ev.detail.key = detail; state = 0xFFFF; /* highest value */ ev.corestate = state; - rc = EventToCore((InternalEvent*)&ev, &core); + rc = EventToCore((InternalEvent*)&ev, &core, &count); test_event(); state = 0x10000; /* too big */ ev.corestate = state; - rc = EventToCore((InternalEvent*)&ev, &core); - g_assert(core.u.keyButtonPointer.state != state); - g_assert(core.u.keyButtonPointer.state == (state & 0xFFFF)); + rc = EventToCore((InternalEvent*)&ev, &core, &count); + g_assert(rc == Success); + g_assert(core); + g_assert(count == 1); + g_assert(core->u.keyButtonPointer.state != state); + g_assert(core->u.keyButtonPointer.state == (state & 0xFFFF)); #undef test_event } @@ -259,14 +268,15 @@ static void dix_event_to_core(int type) static void dix_event_to_core_fail(int evtype, int expected_rc) { DeviceEvent ev; - xEvent core; + xEvent *core; int rc; + int count; ev.header = 0xFF; ev.length = sizeof(DeviceEvent); ev.type = evtype; - rc = EventToCore((InternalEvent*)&ev, &core); + rc = EventToCore((InternalEvent*)&ev, &core, &count); g_assert(rc == expected_rc); } From 2fbccc881bfab4bdc5b97f74a7e5bcec7fdeae20 Mon Sep 17 00:00:00 2001 From: Simon Thum Date: Sun, 6 Feb 2011 19:07:19 +0100 Subject: [PATCH 10/35] fix percent options parsing Signed-off-by: Simon Thum Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- hw/xfree86/common/xf86Option.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c index 16c27e5ee..455cafa87 100644 --- a/hw/xfree86/common/xf86Option.c +++ b/hw/xfree86/common/xf86Option.c @@ -212,7 +212,7 @@ LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed) return deflt; } -static int +static double LookupPercentOption(pointer optlist, const char *name, double deflt, Bool markUsed) { OptionInfoRec o; From 38ffeec0c89e83afc62579dec221c325d667cc1e Mon Sep 17 00:00:00 2001 From: Simon Thum Date: Sun, 6 Feb 2011 19:13:00 +0100 Subject: [PATCH 11/35] xfree86: allow to check for options without warnings in the log This allows set_percent_option in synaptics to work as described, and should generally enable to check option syntax without log spam. Signed-off-by: Simon Thum Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- hw/xfree86/common/xf86Option.c | 75 ++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c index 455cafa87..480f38694 100644 --- a/hw/xfree86/common/xf86Option.c +++ b/hw/xfree86/common/xf86Option.c @@ -496,27 +496,33 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, switch (p->type) { case OPTV_INTEGER: if (*s == '\0') { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires an integer value\n", - p->name); + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires an integer value\n", + p->name); + } p->found = FALSE; } else { p->value.num = strtoul(s, &end, 0); if (*end == '\0') { p->found = TRUE; } else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires an integer value\n", - p->name); + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires an integer value\n", + p->name); + } p->found = FALSE; } } break; case OPTV_STRING: if (*s == '\0') { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires an string value\n", - p->name); + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires an string value\n", + p->name); + } p->found = FALSE; } else { p->value.str = s; @@ -529,18 +535,22 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, break; case OPTV_REAL: if (*s == '\0') { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a floating point value\n", - p->name); + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a floating point " + "value\n", p->name); + } p->found = FALSE; } else { p->value.realnum = strtod(s, &end); if (*end == '\0') { p->found = TRUE; } else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a floating point value\n", - p->name); + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a floating point " + "value\n", p->name); + } p->found = FALSE; } } @@ -549,8 +559,11 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, if (GetBoolValue(p, s)) { p->found = TRUE; } else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a boolean value\n", p->name); + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a boolean value\n", + p->name); + } p->found = FALSE; } break; @@ -561,8 +574,10 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, * hence 100 looks the same as 100% to the caller of sccanf */ if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') { - xf86DrvMsg(scrnIndex, X_WARNING, + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a percent value\n", p->name); + } p->found = FALSE; } else { p->found = TRUE; @@ -571,9 +586,11 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, break; case OPTV_FREQ: if (*s == '\0') { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a frequency value\n", - p->name); + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + } p->found = FALSE; } else { double freq = strtod(s, &end); @@ -590,17 +607,21 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p, !xf86NameCmp(end, "M")) units = 1000000; else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a frequency value\n", - p->name); + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + } p->found = FALSE; } if (p->found) freq *= (double)units; } else { - xf86DrvMsg(scrnIndex, X_WARNING, - "Option \"%s\" requires a frequency value\n", - p->name); + if (markUsed) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + } p->found = FALSE; } if (p->found) { From 006157f203f8493bb3d18e333a3fd3d6cb10f8ea Mon Sep 17 00:00:00 2001 From: Simon Thum Date: Sat, 4 Sep 2010 16:31:24 +0200 Subject: [PATCH 12/35] dix: refactor scheme init This makes it possible to init a scheme in one init call, so we get rid of the tightly coupled two-phase init used before. Signed-off-by: Simon Thum Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- dix/devices.c | 55 ++++++++++++++-------------------------------- dix/ptrveloc.c | 38 +++++++++++++++++++++++++------- include/input.h | 5 +++++ include/inputstr.h | 1 + include/ptrveloc.h | 10 ++++----- 5 files changed, 57 insertions(+), 52 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index 6c0dc42a4..3065319d0 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -1279,10 +1279,11 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, /* global list of acceleration schemes */ ValuatorAccelerationRec pointerAccelerationScheme[] = { - {PtrAccelNoOp, NULL, NULL, NULL}, - {PtrAccelPredictable, acceleratePointerPredictable, NULL, AccelerationDefaultCleanup}, - {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL}, - {-1, NULL, NULL, NULL} /* terminator */ + {PtrAccelNoOp, NULL, NULL, NULL, NULL}, + {PtrAccelPredictable, acceleratePointerPredictable, NULL, + InitPredictableAccelerationScheme, AccelerationDefaultCleanup}, + {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL}, + {-1, NULL, NULL, NULL, NULL} /* terminator */ }; /** @@ -1294,59 +1295,37 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme) { int x, i = -1; - void* data = NULL; ValuatorClassPtr val; val = dev->valuator; - if(!val) - return FALSE; - - if(IsMaster(dev) && scheme != PtrAccelNoOp) + if (!val) return FALSE; - for(x = 0; pointerAccelerationScheme[x].number >= 0; x++) { + if (IsMaster(dev) && scheme != PtrAccelNoOp) + return FALSE; + + for (x = 0; pointerAccelerationScheme[x].number >= 0; x++) { if(pointerAccelerationScheme[x].number == scheme){ i = x; break; } } - if(-1 == i) + if (-1 == i) return FALSE; if (val->accelScheme.AccelCleanupProc) val->accelScheme.AccelCleanupProc(dev); - /* init scheme-specific data */ - switch(scheme){ - case PtrAccelPredictable: - { - DeviceVelocityPtr s; - s = malloc(sizeof(DeviceVelocityRec)); - if(!s) - return FALSE; - InitVelocityData(s); - data = s; - break; + if (pointerAccelerationScheme[i].AccelInitProc) { + if (!pointerAccelerationScheme[i].AccelInitProc(dev, + &pointerAccelerationScheme[i])) { + return FALSE; } - default: - break; + } else { + val->accelScheme = pointerAccelerationScheme[i]; } - - val->accelScheme = pointerAccelerationScheme[i]; - val->accelScheme.accelData = data; - - /* post-init scheme */ - switch(scheme){ - case PtrAccelPredictable: - InitializePredictableAccelerationProperties(dev); - break; - - default: - break; - } - return TRUE; } diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c index 8f0332161..1b9c81b8c 100644 --- a/dix/ptrveloc.c +++ b/dix/ptrveloc.c @@ -67,6 +67,10 @@ SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, float velocity, float threshold, float acc); static PointerAccelerationProfileFunc GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); +static BOOL +InitializePredictableAccelerationProperties(DeviceIntPtr dev); +static BOOL +DeletePredictableAccelerationProperties(DeviceIntPtr dev); /*#define PTRACCEL_DEBUGGING*/ @@ -85,7 +89,7 @@ GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); /** - * Init struct so it should match the average case + * Init DeviceVelocity struct so it should match the average case */ void InitVelocityData(DeviceVelocityPtr vel) @@ -107,7 +111,7 @@ InitVelocityData(DeviceVelocityPtr vel) /** - * Clean up + * Clean up DeviceVelocityRec */ void FreeVelocityData(DeviceVelocityPtr vel){ @@ -116,8 +120,28 @@ FreeVelocityData(DeviceVelocityPtr vel){ } -/* - * dix uninit helper, called through scheme +/** + * Init predictable scheme + */ +Bool +InitPredictableAccelerationScheme(DeviceIntPtr dev, + ValuatorAccelerationPtr protoScheme) { + DeviceVelocityPtr vel; + ValuatorAccelerationRec scheme; + scheme = *protoScheme; + vel = calloc(1, sizeof(DeviceVelocityRec)); + if (!vel) + return FALSE; + InitVelocityData(vel); + scheme.accelData = vel; + dev->valuator->accelScheme = scheme; + InitializePredictableAccelerationProperties(dev); + return TRUE; +} + + +/** + * Uninit scheme */ void AccelerationDefaultCleanup(DeviceIntPtr dev) @@ -1024,12 +1048,10 @@ acceleratePointerPredictable( int *valuators, int evtime) { - float mult = 0.0; + float fdx, fdy, tmp, mult; /* no need to init */ int dx = 0, dy = 0; int *px = NULL, *py = NULL; - DeviceVelocityPtr velocitydata = - (DeviceVelocityPtr) dev->valuator->accelScheme.accelData; - float fdx, fdy, tmp; /* no need to init */ + DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev); Bool soften = TRUE; if (!num_valuators || !valuators || !velocitydata) diff --git a/include/input.h b/include/input.h index 0dc725a37..643866f98 100644 --- a/include/input.h +++ b/include/input.h @@ -150,6 +150,11 @@ typedef void (*PointerAccelSchemeProc)( typedef void (*DeviceCallbackProc)( DeviceIntPtr /*pDev*/); +struct _ValuatorAccelerationRec; +typedef Bool (*PointerAccelSchemeInitProc)( + DeviceIntPtr /*dev*/, + struct _ValuatorAccelerationRec* /*protoScheme*/); + typedef struct _DeviceRec { pointer devicePrivate; ProcessInputProc processInputProc; /* current */ diff --git a/include/inputstr.h b/include/inputstr.h index b74ee0454..65b9ef9f4 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -266,6 +266,7 @@ typedef struct _ValuatorAccelerationRec { int number; PointerAccelSchemeProc AccelSchemeProc; void *accelData; /* at disposal of AccelScheme */ + PointerAccelSchemeInitProc AccelInitProc; DeviceCallbackProc AccelCleanupProc; } ValuatorAccelerationRec, *ValuatorAccelerationPtr; diff --git a/include/ptrveloc.h b/include/ptrveloc.h index 6f999a88f..8c59c0361 100644 --- a/include/ptrveloc.h +++ b/include/ptrveloc.h @@ -110,12 +110,6 @@ BasicComputeAcceleration(DeviceIntPtr dev, DeviceVelocityPtr vel, extern _X_EXPORT void FreeVelocityData(DeviceVelocityPtr vel); -extern _X_INTERNAL BOOL -InitializePredictableAccelerationProperties(DeviceIntPtr dev); - -extern _X_INTERNAL BOOL -DeletePredictableAccelerationProperties(DeviceIntPtr dev); - extern _X_EXPORT int SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); @@ -129,6 +123,10 @@ SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel, extern _X_INTERNAL void AccelerationDefaultCleanup(DeviceIntPtr dev); +extern _X_INTERNAL Bool +InitPredictableAccelerationScheme(DeviceIntPtr dev, + struct _ValuatorAccelerationRec* protoScheme); + extern _X_INTERNAL void acceleratePointerPredictable(DeviceIntPtr dev, int first_valuator, int num_valuators, int *valuators, int evtime); From 31ddb7ef4f5bac2c13c199e74a0716e43b8dc38e Mon Sep 17 00:00:00 2001 From: Simon Thum Date: Wed, 2 Feb 2011 00:03:44 +0100 Subject: [PATCH 13/35] dix: avoid FP promotion during pointer acceleration Signed-off-by: Simon Thum Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- dix/ptrveloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c index 1b9c81b8c..e6ac2ed14 100644 --- a/dix/ptrveloc.c +++ b/dix/ptrveloc.c @@ -1084,11 +1084,11 @@ acceleratePointerPredictable( (float)dev->ptrfeed->ctrl.num / (float)dev->ptrfeed->ctrl.den); - if(mult != 1.0 || velocitydata->const_acceleration != 1.0) { + if(mult != 1.0f || velocitydata->const_acceleration != 1.0f) { ApplySofteningAndConstantDeceleration( velocitydata, dx, dy, &fdx, &fdy, - (mult > 1.0) && soften); + (mult > 1.0f) && soften); if (dx) { tmp = mult * fdx + dev->last.remainder[0]; From 649269d40667cfb387cb5286dd3519dd68f7dd80 Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Wed, 16 Feb 2011 16:55:57 -0800 Subject: [PATCH 14/35] Check for OOM condition in XISendDeviceHierarchyEvent When system is out of memory, calloc can fail returning a NULL pointer. Check for this before dereferencing it, and bail out if it fails. Ref.: https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/720445 Signed-off-by: Bryce Harrington Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- Xi/xichangehierarchy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c index b9cdedf77..21c74ed7a 100644 --- a/Xi/xichangehierarchy.c +++ b/Xi/xichangehierarchy.c @@ -70,6 +70,8 @@ void XISendDeviceHierarchyEvent(int flags[MAXDEVICES]) ev = calloc(1, sizeof(xXIHierarchyEvent) + MAXDEVICES * sizeof(xXIHierarchyInfo)); + if (!ev) + return; ev->type = GenericEvent; ev->extension = IReqCode; ev->evtype = XI_HierarchyChanged; From 15fe86e69fc256342881112cd07565527e32435b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 11:01:19 +1000 Subject: [PATCH 15/35] mi: remove static GenerateEvent variable. Push into the respective devices. This should have no functional changes since we never warp more than one device at a time. In the glorious future with true multithreading, still the better thing to do. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- mi/mipointer.c | 9 +++++---- mi/mipointrst.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mi/mipointer.c b/mi/mipointer.c index 554397a3b..5ee456c71 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -220,15 +220,15 @@ miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, *pTopLeftBox = *pHotBox; } -static Bool GenerateEvent; - static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, Bool generateEvent) { SetupScreen (pScreen); + miPointerPtr pPointer = MIPOINTER(pDev); + + pPointer->generateEvent = generateEvent; - GenerateEvent = generateEvent; /* device dependent - must pend signal and call miPointerWarpCursor */ (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y); if (!generateEvent) @@ -261,6 +261,7 @@ miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) pPointer->confined = FALSE; pPointer->x = 0; pPointer->y = 0; + pPointer->generateEvent = FALSE; if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen))) { @@ -306,7 +307,7 @@ miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) changedScreen = TRUE; } - if (GenerateEvent) + if (pPointer->generateEvent) miPointerMove (pDev, pScreen, x, y); else miPointerMoveNoEvent(pDev, pScreen, x, y); diff --git a/mi/mipointrst.h b/mi/mipointrst.h index bd9c24a00..c912a17da 100644 --- a/mi/mipointrst.h +++ b/mi/mipointrst.h @@ -44,6 +44,7 @@ typedef struct { Bool confined; /* pointer can't change screens */ int x, y; /* hot spot location */ int devx, devy; /* sprite position */ + Bool generateEvent; /* generate an event during warping? */ } miPointerRec, *miPointerPtr; typedef struct { From d9987c8c45236bc9cfcaf716f4bfcac2a9d0e7e6 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 11:22:45 +1000 Subject: [PATCH 16/35] mi: Add a few comments explaining various cursor move functions. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- mi/mipointer.c | 153 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 138 insertions(+), 15 deletions(-) diff --git a/mi/mipointer.c b/mi/mipointer.c index 5ee456c71..a3c26d030 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -23,6 +23,29 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ +/** + * @file + * This file contains functions to move the pointer on the screen and/or + * restrict its movement. These functions are divided into two sets: + * Screen-specific functions that are used as function pointers from other + * parts of the server (and end up heavily wrapped by e.g. animcur and + * xfixes): + * miPointerConstrainCursor + * miPointerCursorLimits + * miPointerDisplayCursor + * miPointerRealizeCursor + * miPointerUnrealizeCursor + * miPointerSetCursorPosition + * miRecolorCursor + * miPointerDeviceInitialize + * miPointerDeviceCleanup + * If wrapped, these are the last element in the wrapping chain. They may + * call into sprite-specific code through further function pointers though. + * + * The second type of functions are those that are directly called by the + * DIX, DDX and some drivers. + */ + #ifdef HAVE_DIX_CONFIG_H #include #endif @@ -126,6 +149,12 @@ miPointerInitialize (ScreenPtr pScreen, return TRUE; } +/** + * Destroy screen-specific information. + * + * @param index Screen index of the screen in screenInfo.screens[] + * @param pScreen The actual screen pointer + */ static Bool miPointerCloseScreen (int index, ScreenPtr pScreen) { @@ -201,6 +230,15 @@ miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) return TRUE; } +/** + * Set up the constraints for the given device. This function does not + * actually constrain the cursor but merely copies the given box to the + * internal constraint storage. + * + * @param pDev The device to constrain to the box + * @param pBox The rectangle to constrain the cursor to + * @param pScreen Used for copying screen confinement + */ static void miPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox) { @@ -212,7 +250,17 @@ miPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox) pPointer->confined = PointerConfinedToScreen(pDev); } -/*ARGSUSED*/ +/** + * Should calculate the box for the given cursor, based on screen and the + * confinement given. But we assume that whatever box is passed in is valid + * anyway. + * + * @param pDev The device to calculate the cursor limits for + * @param pScreen The screen the confinement happens on + * @param pCursor The screen the confinement happens on + * @param pHotBox The confinement box for the cursor + * @param[out] pTopLeftBox The new confinement box, always *pHotBox. + */ static void miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox) @@ -220,6 +268,27 @@ miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, *pTopLeftBox = *pHotBox; } +/** + * Set the device's cursor position to the x/y position on the given screen. + * Generates and event if required. + * + * This function is called from: + * - sprite init code to place onto initial position + * - the various WarpPointer implementations (core, XI, Xinerama, dmx,…) + * - during the cursor update path in CheckMotion + * - in the Xinerama part of NewCurrentScreen + * - when a RandR/RandR1.2 mode was applied (it may have moved the pointer, so + * it's set back to the original pos) + * + * @param pDev The device to move + * @param pScreen The screen the device is on + * @param x The x coordinate in per-screen coordinates + * @param y The y coordinate in per-screen coordinates + * @param generateEvent True if the pointer movement should generate an + * event. + * + * @return TRUE in all cases + */ static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, Bool generateEvent) @@ -236,9 +305,13 @@ miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, return TRUE; } -/* Set up sprite information for the device. - This function will be called once for each device after it is initialized - in the DIX. +/** + * Set up sprite information for the device. + * This function will be called once for each device after it is initialized + * in the DIX. + * + * @param pDev The newly created device + * @param pScreen The initial sprite scree. */ static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) @@ -273,8 +346,12 @@ miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) return TRUE; } -/* Clean up after device. - This function will be called once before the device is freed in the DIX +/** + * Clean up after device. + * This function will be called once before the device is freed in the DIX + * + * @param pDev The device to be removed from the server + * @param pScreen Current screen of the device */ static void miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) @@ -290,7 +367,17 @@ miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) } -/* Once signals are ignored, the WarpCursor function can call this */ +/** + * Warp the pointer to the given position on the given screen. May generate + * an event, depending on whether we're coming from miPointerSetPosition. + * + * Once signals are ignored, the WarpCursor function can call this + * + * @param pDev The device to warp + * @param pScreen Screen to warp on + * @param x The x coordinate in per-screen coordinates + * @param y The y coordinate in per-screen coordinates + */ void miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) @@ -323,16 +410,11 @@ miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) UpdateSpriteForScreen (pDev, pScreen) ; } -/* - * Pointer/CursorDisplay interface routines - */ - -/* - * miPointerUpdateSprite +/** + * Syncronize the sprite with the cursor. * - * Syncronize the sprite with the cursor - called from ProcessInputEvents + * @param pDev The device to sync */ - void miPointerUpdateSprite (DeviceIntPtr pDev) { @@ -409,6 +491,14 @@ miPointerUpdateSprite (DeviceIntPtr pDev) } } +/** + * Set the device to the coordinates on the given screen. + * + * @param pDev The device to move + * @param screen_no Index of the screen to move to + * @param x The x coordinate in per-screen coordinates + * @param y The y coordinate in per-screen coordinates + */ void miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y) { @@ -427,12 +517,18 @@ miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y) pPointer->limits.y2 = pScreen->height; } +/** + * @return The current screen of the VCP + */ ScreenPtr miPointerCurrentScreen (void) { return miPointerGetScreen(inputInfo.pointer); } +/** + * @return The current screen of the given device or NULL. + */ ScreenPtr miPointerGetScreen(DeviceIntPtr pDev) { @@ -484,6 +580,18 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, pPointer->pScreen = pScreen; } +/** + * Set the devices' cursor position to the given x/y position. + * + * This function is called during the pointer update path in + * GetPointerEvents and friends (and the same in the xwin DDX). + * + * @param pDev The device to move + * @param[in,out] x The x coordiante in screen coordinates (in regards to total + * desktop size) + * @param[in,out] y The y coordiante in screen coordinates (in regards to total + * desktop size) + */ void miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y) { @@ -537,6 +645,12 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y) miPointerMoveNoEvent(pDev, pScreen, *x, *y); } +/** + * Get the current position of the device in desktop coordinates. + * + * @param x Return value for the current x coordinate in desktop coordiates. + * @param y Return value for the current y coordinate in desktop coordiates. + */ void miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y) { @@ -550,6 +664,15 @@ void darwinEvents_lock(void); void darwinEvents_unlock(void); #endif +/** + * Move the device's pointer to the x/y coordinates on the given screen. + * This function generates and enqueues pointer events. + * + * @param pDev The device to move + * @param pScreen The screen the device is on + * @param x The x coordinate in per-screen coordinates + * @param y The y coordinate in per-screen coordinates + */ void miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { From 3a6160b408447ce620140849f962683a5d139cb9 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 11:40:01 +1000 Subject: [PATCH 17/35] mi: remove if 0 code. Note sure why this is in if 0 but it's been that way since 2007. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- mi/mipointer.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/mi/mipointer.c b/mi/mipointer.c index a3c26d030..124f9de4d 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -158,33 +158,8 @@ miPointerInitialize (ScreenPtr pScreen, static Bool miPointerCloseScreen (int index, ScreenPtr pScreen) { -#if 0 - miPointerPtr pPointer; - DeviceIntPtr pDev; -#endif - SetupScreen(pScreen); -#if 0 - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { - pPointer = MIPOINTER(pDev); - - if (pScreen == pPointer->pScreen) - pPointer->pScreen = 0; - if (pScreen == pPointer->pSpriteScreen) - pPointer->pSpriteScreen = 0; - } - } - - if (MIPOINTER(inputInfo.pointer)->pScreen == pScreen) - MIPOINTER(inputInfo.pointer)->pScreen = 0; - if (MIPOINTER(inputInfo.pointer)->pSpriteScreen == pScreen) - MIPOINTER(inputInfo.pointer)->pSpriteScreen = 0; -#endif - pScreen->CloseScreen = pScreenPriv->CloseScreen; free((pointer) pScreenPriv); FreeEventList(events, GetMaximumEventsNum()); From c2a9e0a96983f22f721196513e75a53ea0b86d7e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 11:41:47 +1000 Subject: [PATCH 18/35] mi: simplify a "check for keyboard" condition Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- mi/mipointer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mi/mipointer.c b/mi/mipointer.c index 124f9de4d..aa0ca6d78 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -193,8 +193,7 @@ miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) miPointerPtr pPointer; /* return for keyboards */ - if ((IsMaster(pDev) && !DevHasCursor(pDev)) || - (!IsMaster(pDev) && pDev->u.master && !DevHasCursor(pDev->u.master))) + if (!IsPointerDevice(pDev)) return FALSE; pPointer = MIPOINTER(pDev); From d63c979c7fe0f2b114b27e73ebe0a706be8840ae Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 15:21:31 +1000 Subject: [PATCH 19/35] dix: replace direct master access with GetMaster and temp. device. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- dix/getevents.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dix/getevents.c b/dix/getevents.c index 794df420b..60282a826 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -866,10 +866,11 @@ positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac, miPointerSetPosition(dev, screenx, screeny); if (dev->u.master) { - dev->u.master->last.valuators[0] = *screenx; - dev->u.master->last.valuators[1] = *screeny; - dev->u.master->last.remainder[0] = *screenx_frac; - dev->u.master->last.remainder[1] = *screeny_frac; + DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); + master->last.valuators[0] = *screenx; + master->last.valuators[1] = *screeny; + master->last.remainder[0] = *screenx_frac; + master->last.remainder[1] = *screeny_frac; } if (dev->valuator) From dc32a23890776edf575bf18b3f3c079da6214340 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 15:21:51 +1000 Subject: [PATCH 20/35] Fix two incorrect checks for master devices. These two were sideeffects of lastSlave being in the same field as the master. For devices generated by the master device directly, lastSlave was 0 and the device would (with the old checks) be interpreted as floating. Add the required checks to safeguard against master devices. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- Xi/exevents.c | 3 +++ mi/mieq.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 327873e29..b39e202ff 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -710,6 +710,9 @@ ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) if (rc != Success) return; /* Device has disappeared */ + if (IsMaster(slave)) + return; + if (!slave->u.master) return; /* set floating since the event */ diff --git a/mi/mieq.c b/mi/mieq.c index 01da52a6c..c0020c3c3 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -325,7 +325,7 @@ CopyGetMasterEvent(DeviceIntPtr sdev, CHECKEVENT(original); /* ET_XQuartz has sdev == NULL */ - if (!sdev || !sdev->u.master) + if (!sdev || IsMaster(sdev) || !sdev->u.master) return NULL; #if XFreeXDGA From 77af45ebc3eda32dc534968cab8d5adfb01bd9e3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 12:48:30 +1000 Subject: [PATCH 21/35] dix: Simplify retrieving the master device. GetMaster() returns NULL for floating slaves. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- dix/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/events.c b/dix/events.c index 07f8b05ea..4826781d7 100644 --- a/dix/events.c +++ b/dix/events.c @@ -4277,7 +4277,7 @@ DeviceEnterLeaveEvent( if (BitIsOn(mouse->button->down, i)) SetBit(&event[1], i); - kbd = (IsMaster(mouse) || mouse->u.master) ? GetPairedDevice(mouse) : NULL; + kbd = GetMaster(mouse, MASTER_KEYBOARD); if (kbd && kbd->key) { event->mods.base_mods = kbd->key->xkbInfo->state.base_mods; From 703baece7ebd128a6742d0523d5b3ebe65126fa5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 12:19:26 +1000 Subject: [PATCH 22/35] dix: Add IsFloating(device) wrapper. Simplifies check for floating devices. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- dix/events.c | 7 +++++++ include/dix.h | 1 + 2 files changed, 8 insertions(+) diff --git a/dix/events.c b/dix/events.c index 4826781d7..f6d92cf6a 100644 --- a/dix/events.c +++ b/dix/events.c @@ -328,6 +328,13 @@ IsMaster(DeviceIntPtr dev) return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD; } +Bool +IsFloating(DeviceIntPtr dev) +{ + return GetMaster(dev, MASTER_KEYBOARD) == NULL; +} + + /** * Max event opcode. */ diff --git a/include/dix.h b/include/dix.h index 12e4b5977..3f99098a2 100644 --- a/include/dix.h +++ b/include/dix.h @@ -570,6 +570,7 @@ extern Bool _X_EXPORT IsPointerDevice( DeviceIntPtr dev); extern Bool _X_EXPORT IsKeyboardDevice(DeviceIntPtr dev); extern Bool IsPointerEvent(InternalEvent *event); extern _X_EXPORT Bool IsMaster(DeviceIntPtr dev); +extern _X_EXPORT Bool IsFloating(DeviceIntPtr dev); extern _X_HIDDEN void CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master); extern _X_HIDDEN int CorePointerProc(DeviceIntPtr dev, int what); From e48bf3b6403dde33586ca0e421db61e402525453 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 11:11:57 +1000 Subject: [PATCH 23/35] xfree86: replace two inputInfo.pointer uses with device loops. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- hw/xfree86/common/xf86RandR.c | 37 +++++++++++++++++++++++++++------- hw/xfree86/modes/xf86RandR12.c | 36 ++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/hw/xfree86/common/xf86RandR.c b/hw/xfree86/common/xf86RandR.c index d7ffff4ca..4663d0366 100644 --- a/hw/xfree86/common/xf86RandR.c +++ b/hw/xfree86/common/xf86RandR.c @@ -242,11 +242,20 @@ xf86RandRSetConfig (ScreenPtr pScreen, ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); DisplayModePtr mode; - int px, py; + int pos[MAXDEVICES][2]; Bool useVirtual = FALSE; Rotation oldRotation = randrp->rotation; + DeviceIntPtr dev; + Bool view_adjusted = FALSE; + + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (!IsMaster(dev) && !IsFloating(dev)) + continue; + + miPointerGetPosition(dev, &pos[dev->id][0], &pos[dev->id][1]); + } - miPointerGetPosition(inputInfo.pointer, &px, &py); for (mode = scrp->modes; ; mode = mode->next) { if (mode->HDisplay == pSize->width && @@ -303,17 +312,31 @@ xf86RandRSetConfig (ScreenPtr pScreen, } return FALSE; } + /* * Move the cursor back where it belongs; SwitchMode repositions it + * FIXME: duplicated code, see modes/xf86RandR12.c */ - if (pScreen == miPointerCurrentScreen ()) + for (dev = inputInfo.devices; dev; dev = dev->next) { - px = (px >= pScreen->width ? (pScreen->width - 1) : px); - py = (py >= pScreen->height ? (pScreen->height - 1) : py); + if (!IsMaster(dev) && !IsFloating(dev)) + continue; - xf86SetViewport(pScreen, px, py); + if (pScreen == miPointerGetScreen(dev)) { + int px = pos[dev->id][0]; + int py = pos[dev->id][1]; - (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE); + px = (px >= pScreen->width ? (pScreen->width - 1) : px); + py = (py >= pScreen->height ? (pScreen->height - 1) : py); + + /* Setting the viewpoint makes only sense on one device */ + if (!view_adjusted && IsMaster(dev)) { + xf86SetViewport(pScreen, px, py); + view_adjusted = TRUE; + } + + (*pScreen->SetCursorPosition) (dev, pScreen, px, py, FALSE); + } } return TRUE; diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 407bf3567..82d180bb0 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -584,10 +584,12 @@ xf86RandR12SetConfig (ScreenPtr pScreen, ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); DisplayModePtr mode; - int px, py; + int pos[MAXDEVICES][2]; Bool useVirtual = FALSE; int maxX = 0, maxY = 0; Rotation oldRotation = randrp->rotation; + DeviceIntPtr dev; + Bool view_adjusted = FALSE; randrp->rotation = rotation; @@ -597,7 +599,14 @@ xf86RandR12SetConfig (ScreenPtr pScreen, randrp->virtualY = scrp->virtualY; } - miPointerGetPosition (inputInfo.pointer, &px, &py); + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (!IsMaster(dev) && !IsFloating(dev)) + continue; + + miPointerGetPosition(dev, &pos[dev->id][0], &pos[dev->id][1]); + } + for (mode = scrp->modes; ; mode = mode->next) { if (randrp->maxX == 0 || randrp->maxY == 0) @@ -643,15 +652,28 @@ xf86RandR12SetConfig (ScreenPtr pScreen, /* * Move the cursor back where it belongs; SwitchMode repositions it + * FIXME: duplicated code, see modes/xf86RandR12.c */ - if (pScreen == miPointerGetScreen(inputInfo.pointer)) + for (dev = inputInfo.devices; dev; dev = dev->next) { - px = (px >= pScreen->width ? (pScreen->width - 1) : px); - py = (py >= pScreen->height ? (pScreen->height - 1) : py); + if (!IsMaster(dev) && !IsFloating(dev)) + continue; - xf86SetViewport(pScreen, px, py); + if (pScreen == miPointerGetScreen(dev)) { + int px = pos[dev->id][0]; + int py = pos[dev->id][1]; - (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE); + px = (px >= pScreen->width ? (pScreen->width - 1) : px); + py = (py >= pScreen->height ? (pScreen->height - 1) : py); + + /* Setting the viewpoint makes only sense on one device */ + if (!view_adjusted && IsMaster(dev)) { + xf86SetViewport(pScreen, px, py); + view_adjusted = TRUE; + } + + (*pScreen->SetCursorPosition) (dev, pScreen, px, py, FALSE); + } } return TRUE; From dc57f89959e549403f8488eb9f23425bd7118b22 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 11 Feb 2011 12:47:37 +1000 Subject: [PATCH 24/35] Switch to use IsFloating() This is not a straightforward search/replacement due to a long-standing issue. dev->u.master is the same field as dev->u.lastSlave. Thus, if dev is a master device, a check for dev->u.master may give us false positives and false negatives. The switch to IsFloating() spells out these cases and modifies the conditions accordingly to cover both cases. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- Xi/exevents.c | 6 +++--- Xi/xipassivegrab.c | 10 ++-------- Xi/xiquerydevice.c | 2 +- Xi/xiquerypointer.c | 2 +- Xi/xiwarppointer.c | 2 +- dix/devices.c | 8 ++++---- dix/events.c | 6 +++--- dix/getevents.c | 6 +++--- dix/inpututils.c | 2 +- mi/mieq.c | 6 +++--- mi/mipointer.c | 4 ++-- mi/misprite.c | 16 ++++++++-------- xkb/xkb.c | 2 +- xkb/xkbAccessX.c | 2 +- xkb/xkbActions.c | 6 +++--- 15 files changed, 37 insertions(+), 43 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index b39e202ff..ea9daa905 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -713,7 +713,7 @@ ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) if (IsMaster(slave)) return; - if (!slave->u.master) + if (IsFloating(slave)) return; /* set floating since the event */ if (slave->u.master->id != dce->masterid) @@ -1009,7 +1009,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) b = device->button; k = device->key; - if (IsMaster(device) || !device->u.master) + if (IsMaster(device) || IsFloating(device)) CheckMotion(event, device); switch (event->type) @@ -1226,7 +1226,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, DeviceIntPtr mouse; int btlen, len, i; - mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev; + mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER); /* XI 2 event */ btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c index e99b6e554..8663d12a1 100644 --- a/Xi/xipassivegrab.c +++ b/Xi/xipassivegrab.c @@ -162,10 +162,7 @@ ProcXIPassiveGrabDevice(ClientPtr client) if (!modifiers_failed) return BadAlloc; - if (!IsMaster(dev) && dev->u.master) - mod_dev = GetMaster(dev, MASTER_KEYBOARD); - else - mod_dev = dev; + mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD); for (i = 0; i < stuff->num_modifiers; i++, modifiers++) { @@ -280,10 +277,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client) if (rc != Success) return rc; - if (!IsMaster(dev) && dev->u.master) - mod_dev = GetMaster(dev, MASTER_KEYBOARD); - else - mod_dev = dev; + mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD); tempGrab.resource = client->clientAsMask; tempGrab.device = dev; diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c index fdd2c051d..3cad8d7f1 100644 --- a/Xi/xiquerydevice.c +++ b/Xi/xiquerydevice.c @@ -383,7 +383,7 @@ int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment) DeviceIntPtr paired = GetPairedDevice(dev); use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard; *attachment = (paired ? paired->id : 0); - } else if (master) + } else if (!IsFloating(dev)) { use = IsPointerDevice(master) ? XISlavePointer : XISlaveKeyboard; *attachment = master->id; diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c index 8df958ea2..51317994b 100644 --- a/Xi/xiquerypointer.c +++ b/Xi/xiquerypointer.c @@ -93,7 +93,7 @@ ProcXIQueryPointer(ClientPtr client) } if (pDev->valuator == NULL || IsKeyboardDevice(pDev) || - (!IsMaster(pDev) && pDev->u.master)) /* no attached devices */ + (!IsMaster(pDev) && !IsFloating(pDev))) /* no attached devices */ { client->errorValue = stuff->deviceid; return BadDevice; diff --git a/Xi/xiwarppointer.c b/Xi/xiwarppointer.c index c01b115f3..a463ab94d 100644 --- a/Xi/xiwarppointer.c +++ b/Xi/xiwarppointer.c @@ -97,7 +97,7 @@ ProcXIWarpPointer(ClientPtr client) return rc; } - if ((!IsMaster(pDev) && pDev->u.master) || + if ((!IsMaster(pDev) && !IsFloating(pDev)) || (IsMaster(pDev) && !IsPointerDevice(pDev))) { client->errorValue = stuff->deviceid; diff --git a/dix/devices.c b/dix/devices.c index 6c0dc42a4..a3367f7b8 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -987,7 +987,7 @@ CloseDownDevices(void) */ for (dev = inputInfo.devices; dev; dev = dev->next) { - if (!IsMaster(dev) && dev->u.master) + if (!IsMaster(dev) && !IsFloating(dev)) dev->u.master = NULL; } @@ -2397,11 +2397,11 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) return BadDevice; /* set from floating to floating? */ - if (!dev->u.master && !master && dev->enabled) + if (IsFloating(dev) && !master && dev->enabled) return Success; /* free the existing sprite. */ - if (!dev->u.master && dev->spriteInfo->paired == dev) + if (IsFloating(dev) && dev->spriteInfo->paired == dev) { screen = miPointerGetScreen(dev); screen->DeviceCursorCleanup(dev, screen); @@ -2459,7 +2459,7 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) DeviceIntPtr GetPairedDevice(DeviceIntPtr dev) { - if (!IsMaster(dev) && dev->u.master) + if (!IsMaster(dev) && !IsFloating(dev)) dev = dev->u.master; return dev->spriteInfo->paired; diff --git a/dix/events.c b/dix/events.c index f6d92cf6a..b0e52f1c4 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1404,7 +1404,7 @@ CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode) static void DetachFromMaster(DeviceIntPtr dev) { - if (!dev->u.master) + if (!IsFloating(dev)) return; dev->saved_master_id = dev->u.master->id; @@ -2806,7 +2806,7 @@ WindowsRestructured(void) DeviceIntPtr pDev = inputInfo.devices; while(pDev) { - if (IsMaster(pDev) || !pDev->u.master) + if (IsMaster(pDev) || IsFloating(pDev)) CheckMotion(NULL, pDev); pDev = pDev->next; } @@ -3401,7 +3401,7 @@ CheckPassiveGrabsOnWindow( * attached master keyboard. Since the slave may have been * reattached after the grab, the modifier device may not be the * same. */ - if (!IsMaster(grab->device) && device->u.master) + if (!IsMaster(grab->device) && !IsFloating(device)) gdev = GetMaster(device, MASTER_KEYBOARD); } diff --git a/dix/getevents.c b/dix/getevents.c index 60282a826..5b8e3798d 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -767,7 +767,7 @@ moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask) /* if attached, clip both x and y to the defined limits (usually * co-ord space limit). If it is attached, we need x/y to go over the * limits to be able to change screens. */ - if(dev->u.master && dev->valuator) { + if(dev->valuator && IsMaster(dev) || !IsFloating(dev)) { if (valuator_get_mode(dev, 0) == Absolute) clipAxis(dev, 0, x); if (valuator_get_mode(dev, 1) == Absolute) @@ -865,7 +865,7 @@ positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac, * to the current screen. */ miPointerSetPosition(dev, screenx, screeny); - if (dev->u.master) { + if(!IsMaster(dev) || !IsFloating(dev)) { DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); master->last.valuators[0] = *screenx; master->last.valuators[1] = *screeny; @@ -912,7 +912,7 @@ updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms) return; updateMotionHistory(dev, ms, mask, dev->last.valuators); - if (dev->u.master) + if(!IsMaster(dev) || !IsFloating(dev)) { DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); updateMotionHistory(master, ms, mask, dev->last.valuators); diff --git a/dix/inpututils.c b/dix/inpututils.c index ef3142c84..8b7b03523 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -273,7 +273,7 @@ change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap, do_modmap_change(client, tmp, modmap); } } - else if (dev->u.master && dev->u.master->u.lastSlave == dev) { + else if (!IsFloating(dev) && dev->u.master->u.lastSlave == dev) { /* If this fails, expect the results to be weird. */ if (check_modmap_change(client, dev->u.master, modmap)) do_modmap_change(client, dev->u.master, modmap); diff --git a/mi/mieq.c b/mi/mieq.c index c0020c3c3..6853103a5 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -325,7 +325,7 @@ CopyGetMasterEvent(DeviceIntPtr sdev, CHECKEVENT(original); /* ET_XQuartz has sdev == NULL */ - if (!sdev || IsMaster(sdev) || !sdev->u.master) + if (!sdev || IsMaster(sdev) || IsFloating(sdev)) return NULL; #if XFreeXDGA @@ -410,7 +410,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev, handler(screenNum, event, dev); /* Check for the SD's master in case the device got detached * during event processing */ - if (master && dev->u.master) + if (master && !IsFloating(dev)) handler(screenNum, &mevent, master); } else { @@ -419,7 +419,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev, /* Check for the SD's master in case the device got detached * during event processing */ - if (master && dev->u.master) + if (master && !IsFloating(dev)) master->public.processInputProc(&mevent, master); } } diff --git a/mi/mipointer.c b/mi/mipointer.c index aa0ca6d78..5b8297880 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -73,7 +73,7 @@ DevPrivateKeyRec miPointerScreenKeyRec; DevPrivateKeyRec miPointerPrivKeyRec; #define MIPOINTER(dev) \ - ((!IsMaster(dev) && !dev->u.master) ? \ + (IsFloating(dev) ? \ (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \ (miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey)) @@ -332,7 +332,7 @@ miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) { SetupScreen(pScreen); - if (!IsMaster(pDev) && pDev->u.master) + if (!IsMaster(pDev) && !IsFloating(pDev)) return; (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen); diff --git a/mi/misprite.c b/mi/misprite.c index 770951e8f..b0290af29 100644 --- a/mi/misprite.c +++ b/mi/misprite.c @@ -143,7 +143,7 @@ typedef struct { #endif #define MISPRITE(dev) \ - ((!IsMaster(dev) && !dev->u.master) ? \ + (IsFloating(dev) ? \ (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \ (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey)) @@ -766,7 +766,7 @@ miSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { miCursorInfoPtr pCursorInfo; - if (!IsMaster(pDev) && !pDev->u.master) + if (IsFloating(pDev)) return FALSE; pCursorInfo = MISPRITE(pDev); @@ -790,7 +790,7 @@ miSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, miCursorInfoPtr pPointer; miSpriteScreenPtr pScreenPriv; - if (!IsMaster(pDev) && !pDev->u.master) + if (IsFloating(pDev)) return; pPointer = MISPRITE(pDev); @@ -848,7 +848,7 @@ miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { CursorPtr pCursor; - if (!IsMaster(pDev) && !pDev->u.master) + if (IsFloating(pDev)) return; pCursor = MISPRITE(pDev)->pCursor; @@ -905,7 +905,7 @@ miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen) miCursorInfoPtr pCursorInfo; - if (!IsMaster(pDev) && !pDev->u.master) + if (IsFloating(pDev)) return; DamageDrawInternal (pScreen, TRUE); @@ -944,7 +944,7 @@ miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) CursorPtr pCursor; miCursorInfoPtr pCursorInfo; - if (!IsMaster(pDev) && !pDev->u.master) + if (IsFloating(pDev)) return; DamageDrawInternal (pScreen, TRUE); @@ -985,7 +985,7 @@ miSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen) CursorPtr pCursor; miCursorInfoPtr pCursorInfo; - if (!IsMaster(pDev) && !pDev->u.master) + if (IsFloating(pDev)) return; DamageDrawInternal (pScreen, TRUE); @@ -1025,7 +1025,7 @@ miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen) CursorPtr pCursor; miCursorInfoPtr pCursorInfo; - if (!IsMaster(pDev) && !pDev->u.master) + if (IsFloating(pDev)) return; pCursorInfo = MISPRITE(pDev); diff --git a/xkb/xkb.c b/xkb/xkb.c index a57139f35..4557350bf 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -5883,7 +5883,7 @@ ProcXkbGetKbdByName(ClientPtr client) nkn.changed|= XkbNKN_GeometryMask; XkbSendNewKeyboardNotify(dev,&nkn); - if (!IsMaster(dev) && dev->u.master) + if (!IsMaster(dev) && !IsFloating(dev)) { DeviceIntPtr master = dev->u.master; if (master->u.lastSlave == dev) diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c index 10c38ca47..12fe2a1f5 100644 --- a/xkb/xkbAccessX.c +++ b/xkb/xkbAccessX.c @@ -694,7 +694,7 @@ ProcessInputProc backupproc; xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(mouse); DeviceEvent *event = &ev->device_event; - dev = (IsMaster(mouse) || mouse->u.master) ? GetMaster(mouse, MASTER_KEYBOARD) : mouse; + dev = IsFloating(mouse) ? mouse : GetMaster(mouse, MASTER_KEYBOARD); if (dev && dev->key) { diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index 8d7c124e8..eda409c07 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -1367,7 +1367,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, Valuat mpointer = GetMaster(dev, MASTER_POINTER); lastSlave = mpointer->u.lastSlave; ptr = GetXTestDevice(mpointer); - } else if (!dev->u.master) + } else if (IsFloating(dev)) ptr = dev; else return; @@ -1397,7 +1397,7 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) int gpe_flags = 0; /* ignore attached SDs */ - if (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) != NULL) + if (!IsMaster(dev) && !IsFloating(dev)) return; if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) @@ -1427,7 +1427,7 @@ XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) if (IsMaster(dev)) { DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER); ptr = GetXTestDevice(mpointer); - } else if (!dev->u.master) + } else if (IsFloating(dev)) ptr = dev; else return; From df6559237a2d641b2fc38d14975beab9bae0d971 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 11:30:10 +1000 Subject: [PATCH 25/35] dix: add MASTER_ATTACHED as allowed type for GetMaster(). In some cases, we don't know/care whether we want the master pointer or keyboard for a device. Add a new type MASTER_ATTACHED to return the master this device is attached to. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- dix/devices.c | 7 +++++-- include/inputstr.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index a3367f7b8..8be1903eb 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -2473,7 +2473,10 @@ GetPairedDevice(DeviceIntPtr dev) * returned master is either the device itself or the paired master device. * If dev is a floating slave device, NULL is returned. * - * @type ::MASTER_KEYBOARD or ::MASTER_POINTER + * @type ::MASTER_KEYBOARD or ::MASTER_POINTER or ::MASTER_ATTACHED + * @return The requested master device. In the case of MASTER_ATTACHED, this + * is the directly attached master to this device, regardless of the type. + * Otherwise, it is either the master keyboard or pointer for this device. */ DeviceIntPtr GetMaster(DeviceIntPtr dev, int which) @@ -2485,7 +2488,7 @@ GetMaster(DeviceIntPtr dev, int which) else master = dev->u.master; - if (master) + if (master && which != MASTER_ATTACHED) { if (which == MASTER_KEYBOARD) { diff --git a/include/inputstr.h b/include/inputstr.h index b74ee0454..58d318fd6 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -493,6 +493,7 @@ typedef struct _SpriteInfoRec { #define MASTER_POINTER 1 #define MASTER_KEYBOARD 2 #define SLAVE 3 +#define MASTER_ATTACHED 4 /* special type for GetMaster */ typedef struct _DeviceIntRec { DeviceRec public; From febce8cb814df46018f6ae1e6a9daea019b8ad0a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 11:32:28 +1000 Subject: [PATCH 26/35] Xi: replace a direct master access with GetMaster() Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- Xi/exevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index ea9daa905..0df65791a 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -869,7 +869,7 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) * event being delivered through the slave first */ for (sd = inputInfo.devices; sd; sd = sd->next) { - if (IsMaster(sd) || sd->u.master != device) + if (IsMaster(sd) || GetMaster(sd, MASTER_POINTER) != device) continue; if (!sd->button) continue; From e1ac704185dee31b427a46cd41a00ef7a28b4129 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 11:42:09 +1000 Subject: [PATCH 27/35] dix: fix up a master check in ChangeKeyboardMapping handling. We don't just care about the directly attached master, we care about the master keyboard. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- dix/devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/devices.c b/dix/devices.c index 8be1903eb..f7018d0d1 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -1664,7 +1664,7 @@ ProcChangeKeyboardMapping(ClientPtr client) stuff->keyCodes, NULL, client); for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { - if (IsMaster(tmp) || tmp->u.master != pDev) + if (IsMaster(tmp) || GetMaster(tmp, MASTER_KEYBOARD) != pDev) continue; if (!tmp->key) continue; From ce7f79efd588899f01c74f95c2f58d6dd6d816cd Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 11:53:06 +1000 Subject: [PATCH 28/35] dix: fix a master device access in change_modmap. We need to check if our master keyboard is the given device since we may be a pointer with keys and thus need to change the modmap too. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- dix/inpututils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dix/inpututils.c b/dix/inpututils.c index 8b7b03523..abeabf229 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -268,12 +268,12 @@ change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap, /* Change any attached masters/slaves. */ if (IsMaster(dev)) { for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { - if (!IsMaster(tmp) && tmp->u.master == dev) + if (!IsMaster(tmp) && GetMaster(tmp, MASTER_KEYBOARD) == dev) if (check_modmap_change_slave(client, dev, tmp, modmap)) do_modmap_change(client, tmp, modmap); } } - else if (!IsFloating(dev) && dev->u.master->u.lastSlave == dev) { + else if (!IsFloating(dev) && GetMaster(dev, MASTER_KEYBOARD)->u.lastSlave == dev) { /* If this fails, expect the results to be weird. */ if (check_modmap_change(client, dev->u.master, modmap)) do_modmap_change(client, dev->u.master, modmap); From d270f12a3e44f4ea01f176a86783e8cd4c59ddf7 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 11:55:51 +1000 Subject: [PATCH 29/35] xfree86: update GetMaster check for the VCP. Same result, but now also triggers on slave keyboards that send pointer events. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- hw/xfree86/ramdac/xf86Cursor.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c index ec781aad8..24c91cc37 100644 --- a/hw/xfree86/ramdac/xf86Cursor.c +++ b/hw/xfree86/ramdac/xf86Cursor.c @@ -317,8 +317,7 @@ 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 || - (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer)) + if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) { pCurs->refcnt++; if (ScreenPriv->CurrentCursor) @@ -386,8 +385,7 @@ xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) /* only update coordinate state for first sprite, otherwise we get jumps when removing a sprite. The second sprite is never HW rendered anyway */ - if (pDev == inputInfo.pointer || - (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer)) + if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) { ScreenPriv->x = x; ScreenPriv->y = y; From 52c13896ce9a1e178d4eeed15f68020947cc20ed Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 11:57:06 +1000 Subject: [PATCH 30/35] mi: update macro to search for MASTER_POINTER Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- mi/midispcur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mi/midispcur.c b/mi/midispcur.c index 48feb8823..9b3e87a57 100644 --- a/mi/midispcur.c +++ b/mi/midispcur.c @@ -76,7 +76,7 @@ typedef struct { #define miGetDCDevice(dev, screen) \ ((DevHasCursor(dev)) ? \ (miDCBufferPtr)dixLookupScreenPrivate(&dev->devPrivates, miDCDeviceKey, screen) : \ - (miDCBufferPtr)dixLookupScreenPrivate(&dev->u.master->devPrivates, miDCDeviceKey, screen)) + (miDCBufferPtr)dixLookupScreenPrivate(&GetMaster(dev, MASTER_POINTER)->devPrivates, miDCDeviceKey, screen)) /* * The core pointer buffer will point to the index of the virtual core pointer From 0ba526deeb4d54ee1a75400291ee7a3673ed4d96 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 12:04:46 +1000 Subject: [PATCH 31/35] mi: check for MASTER_POINTER instead of manual checks. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- mi/mipointer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mi/mipointer.c b/mi/mipointer.c index 5b8297880..209ea06be 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -540,7 +540,7 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, * VCP, as this may cause a non-HW rendered cursor to be rendered during * SIGIO. This again leads to allocs during SIGIO which leads to SIGABRT. */ - if ((pDev == inputInfo.pointer || (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer)) + if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer && !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) { pPointer->devx = x; From 2936635698619271a790004480a14285149277cb Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 12:06:56 +1000 Subject: [PATCH 32/35] xkb: Fix a check for MASTER_KEYBOARD And copy into the master keyboard, not just the directly attached device. Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone Reviewed-by: Benjamin Tissoires --- xkb/xkb.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/xkb/xkb.c b/xkb/xkb.c index 4557350bf..22417533e 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -5883,12 +5883,10 @@ ProcXkbGetKbdByName(ClientPtr client) nkn.changed|= XkbNKN_GeometryMask; XkbSendNewKeyboardNotify(dev,&nkn); - if (!IsMaster(dev) && !IsFloating(dev)) - { - DeviceIntPtr master = dev->u.master; - if (master->u.lastSlave == dev) - { - XkbCopyDeviceKeymap(dev->u.master, dev); + if (!IsMaster(dev)) { + DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD); + if (master && master->u.lastSlave == dev) { + XkbCopyDeviceKeymap(master, dev); XkbSendNewKeyboardNotify(dev,&nkn); } } From 77113dd3eef03dd65b556b672d976817b3f4542e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 11:45:29 +1000 Subject: [PATCH 33/35] input: Change a bunch of direct dev->u.master accesses to use GetMaster() Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- Xi/exevents.c | 2 +- Xi/xichangehierarchy.c | 4 ++-- Xi/xiquerydevice.c | 2 +- dix/devices.c | 10 +++++----- dix/events.c | 4 ++-- mi/mieq.c | 10 ++++++---- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 0df65791a..736896092 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -716,7 +716,7 @@ ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) if (IsFloating(slave)) return; /* set floating since the event */ - if (slave->u.master->id != dce->masterid) + if (GetMaster(slave, MASTER_ATTACHED)->id != dce->masterid) return; /* not our slave anymore, don't care */ /* FIXME: we probably need to send a DCE for the new slave now */ diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c index b9cdedf77..6683f6a5c 100644 --- a/Xi/xichangehierarchy.c +++ b/Xi/xichangehierarchy.c @@ -282,12 +282,12 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo *r, for (attached = inputInfo.devices; attached; attached = attached->next) { if (!IsMaster(attached)) { - if (attached->u.master == ptr) + if (GetMaster(attached, MASTER_ATTACHED) == ptr) { AttachDevice(client, attached, newptr); flags[attached->id] |= XISlaveAttached; } - if (attached->u.master == keybd) + if (GetMaster(attached, MASTER_ATTACHED) == keybd) { AttachDevice(client, attached, newkeybd); flags[attached->id] |= XISlaveAttached; diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c index 3cad8d7f1..8b5421130 100644 --- a/Xi/xiquerydevice.c +++ b/Xi/xiquerydevice.c @@ -375,7 +375,7 @@ SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info) int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment) { - DeviceIntPtr master = dev->u.master; + DeviceIntPtr master = GetMaster(dev, MASTER_ATTACHED); int use; if (IsMaster(dev)) diff --git a/dix/devices.c b/dix/devices.c index f7018d0d1..058f32b05 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -446,7 +446,7 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) { for (other = inputInfo.devices; other; other = other->next) { - if (other->u.master == dev) + if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) { AttachDevice(NULL, other, NULL); flags[other->id] |= XISlaveDetached; @@ -2327,7 +2327,7 @@ RecalculateMasterButtons(DeviceIntPtr slave) for (dev = inputInfo.devices; dev; dev = dev->next) { if (IsMaster(dev) || - dev->u.master != master || + GetMaster(dev, MASTER_ATTACHED) != master || !dev->button) continue; @@ -2408,8 +2408,8 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) free(dev->spriteInfo->sprite); } - oldmaster = dev->u.master; - dev->u.master = master; + oldmaster = GetMaster(dev, MASTER_ATTACHED); + dev->master = master; /* If device is set to floating, we need to create a sprite for it, * otherwise things go bad. However, we don't want to render the cursor, @@ -2460,7 +2460,7 @@ DeviceIntPtr GetPairedDevice(DeviceIntPtr dev) { if (!IsMaster(dev) && !IsFloating(dev)) - dev = dev->u.master; + dev = GetMaster(dev, MASTER_ATTACHED); return dev->spriteInfo->paired; } diff --git a/dix/events.c b/dix/events.c index b0e52f1c4..8b3bfb791 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1407,7 +1407,7 @@ DetachFromMaster(DeviceIntPtr dev) if (!IsFloating(dev)) return; - dev->saved_master_id = dev->u.master->id; + dev->saved_master_id = GetMaster(dev, MASTER_ATTACHED)->id; AttachDevice(NULL, dev, NULL); } @@ -3237,7 +3237,7 @@ ProcWarpPointer(ClientPtr client) dev = PickPointer(client); for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { - if ((tmp == dev) || (!IsMaster(tmp) && tmp->u.master == dev)) { + if (GetMaster(tmp, MASTER_ATTACHED) == dev) { rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess); if (rc != Success) return rc; diff --git a/mi/mieq.c b/mi/mieq.c index 6853103a5..a3e60855d 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -321,6 +321,7 @@ CopyGetMasterEvent(DeviceIntPtr sdev, DeviceIntPtr mdev; int len = original->any.length; int type = original->any.type; + int mtype; /* which master type? */ CHECKEVENT(original); @@ -337,20 +338,21 @@ CopyGetMasterEvent(DeviceIntPtr sdev, { case ET_KeyPress: case ET_KeyRelease: - mdev = GetMaster(sdev, MASTER_KEYBOARD); + mtype = MASTER_KEYBOARD; break; case ET_ButtonPress: case ET_ButtonRelease: case ET_Motion: case ET_ProximityIn: case ET_ProximityOut: - mdev = GetMaster(sdev, MASTER_POINTER); + mtype = MASTER_POINTER; break; default: - mdev = sdev->u.master; + mtype = MASTER_ATTACHED; break; } + mdev = GetMaster(sdev, mtype); memcpy(copy, original, len); ChangeDeviceID(mdev, copy); FixUpEventForMaster(mdev, sdev, original, copy); @@ -466,7 +468,7 @@ mieqProcessInputEvents(void) pthread_mutex_unlock(&miEventQueueMutex); #endif - master = (dev && !IsMaster(dev) && dev->u.master) ? dev->u.master : NULL; + master = (dev) ? GetMaster(dev, MASTER_ATTACHED) : NULL; if (screenIsSaved == SCREEN_SAVER_ON) dixSaveScreens (serverClient, SCREEN_SAVER_OFF, ScreenSaverReset); From 17265ccb027e3f956bf7409106174f44621d1cb8 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 18 Feb 2011 12:28:43 +1000 Subject: [PATCH 34/35] Move master/lastSlave out of the union into separate fields. The removal of the double-use will cause some suble bugs as some conditions to check for the dev->u.master case were broken and also evaluated as true if lastSlave was set (instead of master). Also breaks the input ABI. Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- dix/devices.c | 12 ++++++------ dix/events.c | 4 ++-- dix/inpututils.c | 6 +++--- include/inputstr.h | 6 ++---- mi/mieq.c | 2 +- test/xi2/protocol-xiquerypointer.c | 2 +- test/xi2/protocol-xiwarppointer.c | 2 +- xkb/xkb.c | 2 +- xkb/xkbActions.c | 2 +- 9 files changed, 18 insertions(+), 20 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index 058f32b05..8fb06bbfa 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -457,8 +457,8 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) { for (other = inputInfo.devices; other; other = other->next) { - if (IsMaster(other) && other->u.lastSlave == dev) - other->u.lastSlave = NULL; + if (IsMaster(other) && other->lastSlave == dev) + other->lastSlave = NULL; } } @@ -988,7 +988,7 @@ CloseDownDevices(void) for (dev = inputInfo.devices; dev; dev = dev->next) { if (!IsMaster(dev) && !IsFloating(dev)) - dev->u.master = NULL; + dev->master = NULL; } CloseDeviceList(&inputInfo.devices); @@ -2486,7 +2486,7 @@ GetMaster(DeviceIntPtr dev, int which) if (IsMaster(dev)) master = dev; else - master = dev->u.master; + master = dev->master; if (master && which != MASTER_ATTACHED) { @@ -2541,7 +2541,7 @@ AllocDevicePair (ClientPtr client, char* name, pointer->coreEvents = TRUE; pointer->spriteInfo->spriteOwner = TRUE; - pointer->u.lastSlave = NULL; + pointer->lastSlave = NULL; pointer->last.slave = NULL; pointer->type = (master) ? MASTER_POINTER : SLAVE; @@ -2567,7 +2567,7 @@ AllocDevicePair (ClientPtr client, char* name, keyboard->coreEvents = TRUE; keyboard->spriteInfo->spriteOwner = FALSE; - keyboard->u.lastSlave = NULL; + keyboard->lastSlave = NULL; keyboard->last.slave = NULL; keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE; diff --git a/dix/events.c b/dix/events.c index 8b3bfb791..f39d8a90b 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3244,8 +3244,8 @@ ProcWarpPointer(ClientPtr client) } } - if (dev->u.lastSlave) - dev = dev->u.lastSlave; + if (dev->lastSlave) + dev = dev->lastSlave; pSprite = dev->spriteInfo->sprite; #ifdef PANORAMIX diff --git a/dix/inpututils.c b/dix/inpututils.c index abeabf229..077ffce01 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -273,10 +273,10 @@ change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap, do_modmap_change(client, tmp, modmap); } } - else if (!IsFloating(dev) && GetMaster(dev, MASTER_KEYBOARD)->u.lastSlave == dev) { + else if (!IsFloating(dev) && GetMaster(dev, MASTER_KEYBOARD)->lastSlave == dev) { /* If this fails, expect the results to be weird. */ - if (check_modmap_change(client, dev->u.master, modmap)) - do_modmap_change(client, dev->u.master, modmap); + if (check_modmap_change(client, dev->master, modmap)) + do_modmap_change(client, dev->master, modmap); } return Success; diff --git a/include/inputstr.h b/include/inputstr.h index 58d318fd6..4c67e3dea 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -530,10 +530,8 @@ typedef struct _DeviceIntRec { PrivateRec *devPrivates; DeviceUnwrapProc unwrapProc; SpriteInfoPtr spriteInfo; - union { - DeviceIntPtr master; /* master device */ - DeviceIntPtr lastSlave; /* last slave device used */ - } u; + DeviceIntPtr master; /* master device */ + DeviceIntPtr lastSlave; /* last slave device used */ /* last valuator values recorded, not posted to client; * for slave devices, valuators is in device coordinates diff --git a/mi/mieq.c b/mi/mieq.c index a3e60855d..08a0c8758 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -402,7 +402,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev, master = CopyGetMasterEvent(dev, event, &mevent); if (master) - master->u.lastSlave = dev; + master->lastSlave = dev; /* If someone's registered a custom event handler, let them * steal it. */ diff --git a/test/xi2/protocol-xiquerypointer.c b/test/xi2/protocol-xiquerypointer.c index 810c61575..a42d59515 100644 --- a/test/xi2/protocol-xiquerypointer.c +++ b/test/xi2/protocol-xiquerypointer.c @@ -185,7 +185,7 @@ static void test_XIQueryPointer(void) request_XIQueryPointer(&client_request, &request, BadDevice); test_data.dev = devices.mouse; - devices.mouse->u.master = NULL; /* Float, kind-of */ + devices.mouse->master = NULL; /* Float, kind-of */ request.deviceid = devices.mouse->id; request_XIQueryPointer(&client_request, &request, Success); diff --git a/test/xi2/protocol-xiwarppointer.c b/test/xi2/protocol-xiwarppointer.c index 4f8860ea0..75b7617a0 100644 --- a/test/xi2/protocol-xiwarppointer.c +++ b/test/xi2/protocol-xiwarppointer.c @@ -145,7 +145,7 @@ static void test_XIWarpPointer(void) request.deviceid = devices.kbd->id; request_XIWarpPointer(&client_request, &request, BadDevice); - devices.mouse->u.master = NULL; /* Float, kind-of */ + devices.mouse->master = NULL; /* Float, kind-of */ request.deviceid = devices.mouse->id; request_XIWarpPointer(&client_request, &request, Success); diff --git a/xkb/xkb.c b/xkb/xkb.c index 22417533e..15831591d 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -5885,7 +5885,7 @@ ProcXkbGetKbdByName(ClientPtr client) if (!IsMaster(dev)) { DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD); - if (master && master->u.lastSlave == dev) { + if (master && master->lastSlave == dev) { XkbCopyDeviceKeymap(master, dev); XkbSendNewKeyboardNotify(dev,&nkn); } diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index eda409c07..65c678af8 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -1365,7 +1365,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, Valuat if (IsMaster(dev)) { mpointer = GetMaster(dev, MASTER_POINTER); - lastSlave = mpointer->u.lastSlave; + lastSlave = mpointer->lastSlave; ptr = GetXTestDevice(mpointer); } else if (IsFloating(dev)) ptr = dev; From b636893137da1695e235e3a9354bfd9243fdddc2 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 22 Feb 2011 13:43:28 +0000 Subject: [PATCH 35/35] Input: Don't freeze unrelated devices in DeliverGrabbedEvent When delivering an event to a device grabbed with SyncBoth, DeliverGrabbedEvent walks the device tree looking for associated devices to freeze them. Unfortunately, it froze all devices instead of just the paired device, and the previous fix in 4fbadc8b17237f3c would still break if the same client had a non-SyncBoth grab on another unrelated master device. Fix this by completely ignoring devices that aren't our paired device. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- dix/events.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dix/events.c b/dix/events.c index 2723f5374..de803f652 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3904,16 +3904,15 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, switch (grabinfo->sync.state) { case FREEZE_BOTH_NEXT_EVENT: - for (dev = inputInfo.devices; dev; dev = dev->next) + dev = GetPairedDevice(thisDev); + if (dev) { - if (dev == thisDev) - continue; FreezeThaw(dev, TRUE); if ((dev->deviceGrab.sync.state == FREEZE_BOTH_NEXT_EVENT) && (CLIENT_BITS(grab->resource) == CLIENT_BITS(dev->deviceGrab.grab->resource))) dev->deviceGrab.sync.state = FROZEN_NO_EVENT; - else if (GetPairedDevice(thisDev) == dev) + else dev->deviceGrab.sync.other = grab; } /* fall through */