comparison src/select-x.c @ 3833:2b1e7cb9ae2c

[xemacs-hg @ 2007-02-17 15:55:21 by stephent] Fix 64-bit issues in X property handling. <87d548dgqz.fsf@uwakimon.sk.tsukuba.ac.jp>
author stephent
date Sat, 17 Feb 2007 15:55:22 +0000
parents 140bb0f4da00
children 304aebb79cd3
comparison
equal deleted inserted replaced
3832:21b3a0f9cbfd 3833:2b1e7cb9ae2c
1046 *data_ret = 0; 1046 *data_ret = 0;
1047 *bytes_ret = 0; 1047 *bytes_ret = 0;
1048 return; 1048 return;
1049 } 1049 }
1050 1050
1051 total_size = bytes_remaining + 1; 1051 /* The manpage for XGetWindowProperty from X.org X11.7.2 sez:
1052 nitems_return [[ our actual_size_ret ]]
1053 Returns the actual number of 8-bit, 16-bit, or 32-bit items
1054 stored in the prop_return data.
1055 prop_return [[ our tmp_data ]]
1056 Returns the data in the specified format. If the returned
1057 format is 8, the returned data is represented as a char
1058 array. If the returned format is 16, the returned data is
1059 represented as a array of short int type and should be cast
1060 to that type to obtain the elements. If the returned format
1061 is 32, the property data will be stored as an array of longs
1062 (which in a 64-bit application will be 64-bit values that are
1063 padded in the upper 4 bytes).
1064 bytes_after_return [[ our bytes_remaining ]]
1065 Returns the number of bytes remaining to be read in the prop-
1066 erty if a partial read was performed.
1067
1068 AFAIK XEmacs does not support any platforms where the char type is other
1069 than 8 bits (Cray?), or where the short type is other than 16 bits.
1070 There is no such agreement on the size of long, and 64-bit platforms
1071 generally make long be a 64-bit quantity while while it's 32 bits on
1072 32-bit platforms.
1073
1074 This means that on all platforms the wire item is the same size as our
1075 buffer unit when format == 8 or format == 16 or format == wordsize == 32,
1076 and the buffer size can be taken as bytes_remaining plus padding.
1077 However, when format == 32 and wordsize == 64, the buffer unit is twice
1078 the size of the wire item. Obviously this code below is not 128-bit
1079 safe. (We could replace the factor 2 with (sizeof(long)*8/32.)
1080
1081 We can hope it doesn't much matter on versions of X11 earlier than R7.
1082 */
1083 if (sizeof(long) == 8 && *actual_format_ret == 32)
1084 total_size = 2 * bytes_remaining + 1;
1085 else
1086 total_size = bytes_remaining + 1;
1052 *data_ret = xnew_rawbytes (total_size); 1087 *data_ret = xnew_rawbytes (total_size);
1053 1088
1054 /* Now read, until we've gotten it all. */ 1089 /* Now read, until we've gotten it all. */
1055 while (bytes_remaining) 1090 while (bytes_remaining)
1056 { 1091 {
1070 /* If this doesn't return Success at this point, it means that 1105 /* If this doesn't return Success at this point, it means that
1071 some clod deleted the selection while we were in the midst of 1106 some clod deleted the selection while we were in the midst of
1072 reading it. Deal with that, I guess.... 1107 reading it. Deal with that, I guess....
1073 */ 1108 */
1074 if (result != Success) break; 1109 if (result != Success) break;
1075 *actual_size_ret *= *actual_format_ret / 8; 1110 /* Again we need to compute the number of bytes in our buffer, not
1111 the number of bytes transferred for the property. */
1112 if (sizeof(long) == 8 && *actual_format_ret == 32)
1113 *actual_size_ret *= 8;
1114 else
1115 *actual_size_ret *= *actual_format_ret / 8;
1076 memcpy ((*data_ret) + offset, tmp_data, *actual_size_ret); 1116 memcpy ((*data_ret) + offset, tmp_data, *actual_size_ret);
1077 offset += *actual_size_ret; 1117 offset += *actual_size_ret;
1078 XFree ((char *) tmp_data); 1118 XFree ((char *) tmp_data);
1079 } 1119 }
1080 *bytes_ret = offset; 1120 *bytes_ret = offset;