| @@ -2,39 +2,29 @@ | | | @@ -2,39 +2,29 @@ |
2 | Copyright (c) 2002 XFree86 Inc | | 2 | Copyright (c) 2002 XFree86 Inc |
3 | */ | | 3 | */ |
4 | | | 4 | |
5 | #ifdef HAVE_CONFIG_H | | 5 | #ifdef HAVE_CONFIG_H |
6 | #include <config.h> | | 6 | #include <config.h> |
7 | #endif | | 7 | #endif |
8 | #include <stdlib.h> | | 8 | #include <stdlib.h> |
9 | #include <X11/Xlibint.h> | | 9 | #include <X11/Xlibint.h> |
10 | #include <X11/Xutil.h> | | 10 | #include <X11/Xutil.h> |
11 | #include <X11/extensions/Xext.h> | | 11 | #include <X11/extensions/Xext.h> |
12 | #include <X11/extensions/extutil.h> | | 12 | #include <X11/extensions/extutil.h> |
13 | #include <X11/extensions/XResproto.h> | | 13 | #include <X11/extensions/XResproto.h> |
14 | #include <X11/extensions/XRes.h> | | 14 | #include <X11/extensions/XRes.h> |
| | | 15 | #include <assert.h> |
15 | #include <limits.h> | | 16 | #include <limits.h> |
16 | | | 17 | |
17 | #ifndef HAVE__XEATDATAWORDS | | | |
18 | static inline void _XEatDataWords(Display *dpy, unsigned long n) | | | |
19 | { | | | |
20 | # ifndef LONG64 | | | |
21 | if (n >= (ULONG_MAX >> 2)) | | | |
22 | _XIOError(dpy); | | | |
23 | # endif | | | |
24 | _XEatData (dpy, n << 2); | | | |
25 | } | | | |
26 | #endif | | | |
27 | | | | |
28 | static XExtensionInfo _xres_ext_info_data; | | 18 | static XExtensionInfo _xres_ext_info_data; |
29 | static XExtensionInfo *xres_ext_info = &_xres_ext_info_data; | | 19 | static XExtensionInfo *xres_ext_info = &_xres_ext_info_data; |
30 | static const char *xres_extension_name = XRES_NAME; | | 20 | static const char *xres_extension_name = XRES_NAME; |
31 | | | 21 | |
32 | #define XResCheckExtension(dpy,i,val) \ | | 22 | #define XResCheckExtension(dpy,i,val) \ |
33 | XextCheckExtension (dpy, i, xres_extension_name, val) | | 23 | XextCheckExtension (dpy, i, xres_extension_name, val) |
34 | | | 24 | |
35 | static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xres_ext_info) | | 25 | static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xres_ext_info) |
36 | | | 26 | |
37 | static XExtensionHooks xres_extension_hooks = { | | 27 | static XExtensionHooks xres_extension_hooks = { |
38 | NULL, /* create_gc */ | | 28 | NULL, /* create_gc */ |
39 | NULL, /* copy_gc */ | | 29 | NULL, /* copy_gc */ |
40 | NULL, /* flush_gc */ | | 30 | NULL, /* flush_gc */ |
| @@ -229,23 +219,247 @@ Status XResQueryClientPixmapBytes ( | | | @@ -229,23 +219,247 @@ Status XResQueryClientPixmapBytes ( |
229 | | | 219 | |
230 | LockDisplay (dpy); | | 220 | LockDisplay (dpy); |
231 | GetReq (XResQueryClientPixmapBytes, req); | | 221 | GetReq (XResQueryClientPixmapBytes, req); |
232 | req->reqType = info->codes->major_opcode; | | 222 | req->reqType = info->codes->major_opcode; |
233 | req->XResReqType = X_XResQueryClientPixmapBytes; | | 223 | req->XResReqType = X_XResQueryClientPixmapBytes; |
234 | req->xid = xid; | | 224 | req->xid = xid; |
235 | if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { | | 225 | if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { |
236 | UnlockDisplay (dpy); | | 226 | UnlockDisplay (dpy); |
237 | SyncHandle (); | | 227 | SyncHandle (); |
238 | return 0; | | 228 | return 0; |
239 | } | | 229 | } |
240 | | | 230 | |
241 | #ifdef LONG64 | | 231 | #ifdef LONG64 |
242 | *bytes = (rep.bytes_overflow * 4294967295) + rep.bytes; | | 232 | *bytes = (rep.bytes_overflow * 4294967296UL) + rep.bytes; |
243 | #else | | 233 | #else |
244 | *bytes = rep.bytes_overflow ? 0xffffffff : rep.bytes; | | 234 | *bytes = rep.bytes_overflow ? 0xffffffff : rep.bytes; |
245 | #endif | | 235 | #endif |
246 | | | 236 | |
247 | UnlockDisplay (dpy); | | 237 | UnlockDisplay (dpy); |
248 | SyncHandle (); | | 238 | SyncHandle (); |
249 | return 1; | | 239 | return 1; |
250 | } | | 240 | } |
251 | | | 241 | |
| | | 242 | static Bool ReadClientValues( |
| | | 243 | Display *dpy, |
| | | 244 | long num_ids, |
| | | 245 | XResClientIdValue *client_ids /* out */ |
| | | 246 | ) |
| | | 247 | { |
| | | 248 | int c; |
| | | 249 | for (c = 0; c < num_ids; ++c) { |
| | | 250 | XResClientIdValue* client = client_ids + c; |
| | | 251 | long int value; |
| | | 252 | _XRead32 (dpy, &value, 4); |
| | | 253 | client->spec.client = value; |
| | | 254 | _XRead32 (dpy, &value, 4); |
| | | 255 | client->spec.mask = value; |
| | | 256 | _XRead32 (dpy, &value, 4); |
| | | 257 | client->length = value; |
| | | 258 | client->value = malloc(client->length); |
| | | 259 | _XRead32 (dpy, client->value, client->length); |
| | | 260 | } |
| | | 261 | return True; |
| | | 262 | } |
| | | 263 | |
| | | 264 | Status XResQueryClientIds ( |
| | | 265 | Display *dpy, |
| | | 266 | long num_specs, |
| | | 267 | XResClientIdSpec *client_specs, /* in */ |
| | | 268 | long *num_ids, /* out */ |
| | | 269 | XResClientIdValue **client_ids /* out */ |
| | | 270 | ) |
| | | 271 | { |
| | | 272 | XExtDisplayInfo *info = find_display (dpy); |
| | | 273 | xXResQueryClientIdsReq *req; |
| | | 274 | xXResQueryClientIdsReply rep; |
| | | 275 | int c; |
| | | 276 | |
| | | 277 | *num_ids = 0; |
| | | 278 | |
| | | 279 | XResCheckExtension (dpy, info, 0); |
| | | 280 | LockDisplay (dpy); |
| | | 281 | GetReq (XResQueryClientIds, req); |
| | | 282 | req->reqType = info->codes->major_opcode; |
| | | 283 | req->XResReqType = X_XResQueryClientIds; |
| | | 284 | req->length += num_specs * 2; /* 2 longs per client id spec */ |
| | | 285 | req->numSpecs = num_specs; |
| | | 286 | |
| | | 287 | for (c = 0; c < num_specs; ++c) { |
| | | 288 | Data32(dpy, &client_specs[c].client, 4); |
| | | 289 | Data32(dpy, &client_specs[c].mask, 4); |
| | | 290 | } |
| | | 291 | |
| | | 292 | if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { |
| | | 293 | goto error; |
| | | 294 | } |
| | | 295 | |
| | | 296 | *client_ids = calloc(rep.numIds, sizeof(**client_ids)); |
| | | 297 | *num_ids = rep.numIds; |
| | | 298 | |
| | | 299 | if (!ReadClientValues(dpy, *num_ids, *client_ids)) { |
| | | 300 | goto error; |
| | | 301 | } |
| | | 302 | |
| | | 303 | UnlockDisplay (dpy); |
| | | 304 | SyncHandle (); |
| | | 305 | return Success; |
| | | 306 | |
| | | 307 | error: |
| | | 308 | XResClientIdsDestroy (*num_ids, *client_ids); |
| | | 309 | *client_ids = NULL; |
| | | 310 | |
| | | 311 | UnlockDisplay (dpy); |
| | | 312 | SyncHandle (); |
| | | 313 | return !Success; |
| | | 314 | } |
| | | 315 | |
| | | 316 | void XResClientIdsDestroy ( |
| | | 317 | long num_ids, |
| | | 318 | XResClientIdValue *client_ids |
| | | 319 | ) |
| | | 320 | { |
| | | 321 | int c; |
| | | 322 | for (c = 0; c < num_ids; ++c) { |
| | | 323 | free(client_ids[c].value); |
| | | 324 | } |
| | | 325 | free(client_ids); |
| | | 326 | } |
| | | 327 | |
| | | 328 | XResClientIdType XResGetClientIdType( |
| | | 329 | XResClientIdValue* value |
| | | 330 | ) |
| | | 331 | { |
| | | 332 | int bit; |
| | | 333 | XResClientIdType idType = 0; |
| | | 334 | Bool found = False; |
| | | 335 | for (bit = 0; bit < XRES_CLIENT_ID_NR; ++bit) { |
| | | 336 | if (value->spec.mask & (1 << bit)) { |
| | | 337 | assert(!found); |
| | | 338 | found = True; |
| | | 339 | idType = bit; |
| | | 340 | } |
| | | 341 | } |
| | | 342 | |
| | | 343 | assert(found); |
| | | 344 | |
| | | 345 | return idType; |
| | | 346 | } |
| | | 347 | |
| | | 348 | pid_t XResGetClientPid( |
| | | 349 | XResClientIdValue* value |
| | | 350 | ) |
| | | 351 | { |
| | | 352 | if (value->spec.mask & XRES_CLIENT_ID_PID_MASK && value->length >= 4) { |
| | | 353 | return (pid_t) * (CARD32*) value->value; |
| | | 354 | } else { |
| | | 355 | return (pid_t) -1; |
| | | 356 | } |
| | | 357 | } |
| | | 358 | |
| | | 359 | static Status ReadResourceSizeSpec( |
| | | 360 | Display *dpy, |
| | | 361 | XResResourceSizeSpec *size |
| | | 362 | ) |
| | | 363 | { |
| | | 364 | long int value; |
| | | 365 | _XRead32(dpy, &value, 4); |
| | | 366 | size->spec.resource = value; |
| | | 367 | _XRead32(dpy, &value, 4); |
| | | 368 | size->spec.type = value; |
| | | 369 | _XRead32(dpy, &value, 4); |
| | | 370 | size->bytes = value; |
| | | 371 | _XRead32(dpy, &value, 4); |
| | | 372 | size->ref_count = value; |
| | | 373 | _XRead32(dpy, &value, 4); |
| | | 374 | size->use_count = value; |
| | | 375 | return 0; |
| | | 376 | } |
| | | 377 | |
| | | 378 | static Status ReadResourceSizeValues( |
| | | 379 | Display *dpy, |
| | | 380 | long num_sizes, |
| | | 381 | XResResourceSizeValue *sizes) |
| | | 382 | { |
| | | 383 | int c; |
| | | 384 | int d; |
| | | 385 | for (c = 0; c < num_sizes; ++c) { |
| | | 386 | long int num; |
| | | 387 | ReadResourceSizeSpec(dpy, &sizes[c].size); |
| | | 388 | _XRead32(dpy, &num, 4); |
| | | 389 | sizes[c].num_cross_references = num; |
| | | 390 | sizes[c].cross_references = num ? calloc(num, sizeof(*sizes[c].cross_references)) : NULL; |
| | | 391 | for (d = 0; d < num; ++d) { |
| | | 392 | ReadResourceSizeSpec(dpy, &sizes[c].cross_references[d]); |
| | | 393 | } |
| | | 394 | } |
| | | 395 | return Success; |
| | | 396 | } |
| | | 397 | |
| | | 398 | Status XResQueryResourceBytes ( |
| | | 399 | Display *dpy, |
| | | 400 | XID client, |
| | | 401 | long num_specs, |
| | | 402 | XResResourceIdSpec *resource_specs, /* in */ |
| | | 403 | long *num_sizes, /* out */ |
| | | 404 | XResResourceSizeValue **sizes /* out */ |
| | | 405 | ) |
| | | 406 | { |
| | | 407 | XExtDisplayInfo *info = find_display (dpy); |
| | | 408 | xXResQueryResourceBytesReq *req; |
| | | 409 | xXResQueryResourceBytesReply rep; |
| | | 410 | int c; |
| | | 411 | |
| | | 412 | *num_sizes = 0; |
| | | 413 | |
| | | 414 | XResCheckExtension (dpy, info, 0); |
| | | 415 | |
| | | 416 | LockDisplay (dpy); |
| | | 417 | GetReq (XResQueryResourceBytes, req); |
| | | 418 | req->reqType = info->codes->major_opcode; |
| | | 419 | req->XResReqType = X_XResQueryResourceBytes; |
| | | 420 | req->length += num_specs * 2; /* 2 longs per client id spec */ |
| | | 421 | req->client = client; |
| | | 422 | req->numSpecs = num_specs; |
| | | 423 | |
| | | 424 | for (c = 0; c < num_specs; ++c) { |
| | | 425 | Data32(dpy, &resource_specs[c].resource, 4); |
| | | 426 | Data32(dpy, &resource_specs[c].type, 4); |
| | | 427 | } |
| | | 428 | |
| | | 429 | *num_sizes = 0; |
| | | 430 | *sizes = NULL; |
| | | 431 | |
| | | 432 | if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { |
| | | 433 | goto error; |
| | | 434 | } |
| | | 435 | |
| | | 436 | *sizes = calloc(rep.numSizes, sizeof(**sizes)); |
| | | 437 | *num_sizes = rep.numSizes; |
| | | 438 | |
| | | 439 | if (ReadResourceSizeValues(dpy, *num_sizes, *sizes) != Success) { |
| | | 440 | goto error; |
| | | 441 | } |
| | | 442 | |
| | | 443 | UnlockDisplay (dpy); |
| | | 444 | SyncHandle (); |
| | | 445 | return Success; |
| | | 446 | |
| | | 447 | error: |
| | | 448 | XResResourceSizeValuesDestroy(*num_sizes, *sizes); |
| | | 449 | |
| | | 450 | UnlockDisplay (dpy); |
| | | 451 | SyncHandle (); |
| | | 452 | return !Success; |
| | | 453 | } |
| | | 454 | |
| | | 455 | void XResResourceSizeValuesDestroy ( |
| | | 456 | long num_sizes, |
| | | 457 | XResResourceSizeValue *sizes |
| | | 458 | ) |
| | | 459 | { |
| | | 460 | int c; |
| | | 461 | for (c = 0; c < num_sizes; ++c) { |
| | | 462 | free(sizes[c].cross_references); |
| | | 463 | } |
| | | 464 | free(sizes); |
| | | 465 | } |