Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!mailrus!purdue!decwrl!hplabs!hp-pcd!hpcvlx!fred From: fred@hpcvlx.HP.COM (Fred Taft) Newsgroups: comp.windows.x Subject: Re: HP's Xtk Fixes (as Context Diffs) Message-ID: <1610053@hpcvlx.HP.COM> Date: 19 Aug 88 19:53:22 GMT References: <1610043@hpcvlx.HP.COM> Organization: Hewlett-Packard Co., Corvallis, OR, USA Lines: 177 ### bug number: 402 ### area: Xt ### severity: medium ### comments: VERSION: Xtk release 2 SYNOPSIS: XtGetValues() returns bogus information on 68000 architecture machines, if the application queries a short or char value, and it also specifies within the arglist a pointer to a short or char variable, into which the result is to be placed. DESCRIPTION: Several months ago, I reported a discrepancy in how XtGetValues() worked, versus how it was documented. I received a message that the problem was being fixed, yet I notice that it is still present in the R2 toolkit, to a degree anyways. According to the documentation, when you issue a GetValue request, you pass in an arglist composed of an argument name/address pair; the address indicates where the return value should be placed. If I don't supply a pointer (i.e. I pass in a NULL address), when I query a Boolean value, the value is always returned in the arglist; I noticed that CopyToArg() specifically tested for this case; I can live with this, since it allows old clients to continue to run. However, if I do pass in an address, then the returned boolean value was always 0 (FALSE). After further investigation, I believe the problem lies in the following line of code which had been added to CopyToArg() to fix the original problem: if (*dst != NULL) dst = *(XtArgVal **)dst; The above statement treats everything as a pointer to a long variable; XtArgVal is typedef'ed to a long. In the days where the values were always returned in the arglist, treating the destination as a long was fine since the value field really was a long. However, since the value now pointed to by dst can be a char, a short, a long, etc, this assumption is no longer valid. For instance, assume the following: dst ----> arglist value entry ----> a boolean variable ("---->" denotes 'pointing to') When the buggy statement shown above is executed, the picture now looks like the following: dst ----> a boolean variable Since the argument being queried is a char, the following is used to copy the value into the specified destinatioin: *dst = (XtArgVal) *((char *) src); Since the value pointed to by dst is assumed to be a long, the following four bytes are copied into the location we specified: 0x00, 0x00, 0x00, 0x01 Unfortunately, at least for those of us using 68000 architecture, the first 0x00 is copied into our destination, instead of the 0x01. REPEAT-BY: Boolean flag; Arg arg[1]; XtSetArg (arg[0], XtNsensitive, &flag); XtGetValues (w, arg, XtNumber(arg)); FIX: *** Resources.c Fri Aug 19 12:28:34 1988 --- Resources.new. Fri Aug 19 12:28:20 1988 *************** *** 62,67 XtArgVal src, *dst; register unsigned int size; { /* ||| Old semantics are yucky, but keep as long as NULL value */ if (*dst != NULL) dst = *(XtArgVal **)dst; --- 62,69 ----- XtArgVal src, *dst; register unsigned int size; { + Boolean addrGiven = False; + /* ||| Old semantics are yucky, but keep as long as NULL value */ if (*dst != NULL) { *************** *** 64,69 { /* ||| Old semantics are yucky, but keep as long as NULL value */ if (*dst != NULL) dst = *(XtArgVal **)dst; if (size == sizeof(XtArgVal)) --- 66,72 ----- /* ||| Old semantics are yucky, but keep as long as NULL value */ if (*dst != NULL) + { dst = *(XtArgVal **)dst; addrGiven = True; } *************** *** 65,70 /* ||| Old semantics are yucky, but keep as long as NULL value */ if (*dst != NULL) dst = *(XtArgVal **)dst; if (size == sizeof(XtArgVal)) *dst = *(XtArgVal *)src; --- 68,75 ----- if (*dst != NULL) { dst = *(XtArgVal **)dst; + addrGiven = True; + } if (size == sizeof(XtArgVal)) *dst = *(XtArgVal *)src; *************** *** 69,75 if (size == sizeof(XtArgVal)) *dst = *(XtArgVal *)src; else if (size == sizeof(short)) ! *dst = (XtArgVal) *((short *) src); else if (size == sizeof(char)) *dst = (XtArgVal) *((char *) src); else if (size < sizeof(XtArgVal)) --- 74,85 ----- if (size == sizeof(XtArgVal)) *dst = *(XtArgVal *)src; else if (size == sizeof(short)) ! { ! if (addrGiven) ! *((short *)dst) = (short)*((short *) src); ! else ! *dst = (XtArgVal) *((short *) src); ! } else if (size == sizeof(char)) { if (addrGiven) *************** *** 71,77 else if (size == sizeof(short)) *dst = (XtArgVal) *((short *) src); else if (size == sizeof(char)) ! *dst = (XtArgVal) *((char *) src); else if (size < sizeof(XtArgVal)) bcopy((char *) src, (char *) dst, (int) size); else --- 81,92 ----- *dst = (XtArgVal) *((short *) src); } else if (size == sizeof(char)) ! { ! if (addrGiven) ! *((char *)dst) = (char)*((char *) src); ! else ! *dst = (XtArgVal) *((char *) src); ! } else if (size < sizeof(XtArgVal)) bcopy((char *) src, (char *) dst, (int) size); else