1/* 2 * 3 * Copyright © 2000 SuSE, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of SuSE not be used in advertising or 10 * publicity pertaining to distribution of the software without specific, 11 * written prior permission. SuSE makes no representations about the 12 * suitability of this software for any purpose. It is provided "as is" 13 * without express or implied warranty. 14 * 15 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Author: Keith Packard, SuSE, Inc. 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include <config.h> 27#endif 28#include "Xrenderint.h" 29 30GlyphSet 31XRenderCreateGlyphSet (Display *dpy, _Xconst XRenderPictFormat *format) 32{ 33 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 34 GlyphSet gsid; 35 xRenderCreateGlyphSetReq *req; 36 37 RenderCheckExtension (dpy, info, 0); 38 LockDisplay(dpy); 39 GetReq(RenderCreateGlyphSet, req); 40 req->reqType = (CARD8) info->codes->major_opcode; 41 req->renderReqType = X_RenderCreateGlyphSet; 42 req->gsid = (CARD32) (gsid = XAllocID(dpy)); 43 req->format = (CARD32) format->id; 44 UnlockDisplay(dpy); 45 SyncHandle(); 46 return gsid; 47} 48 49GlyphSet 50XRenderReferenceGlyphSet (Display *dpy, GlyphSet existing) 51{ 52 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 53 GlyphSet gsid; 54 xRenderReferenceGlyphSetReq *req; 55 56 RenderCheckExtension (dpy, info, 0); 57 LockDisplay(dpy); 58 GetReq(RenderReferenceGlyphSet, req); 59 req->reqType = (CARD8) info->codes->major_opcode; 60 req->renderReqType = X_RenderReferenceGlyphSet; 61 req->gsid = (CARD32) (gsid = XAllocID(dpy)); 62 req->existing = (CARD32) existing; 63 UnlockDisplay(dpy); 64 SyncHandle(); 65 return gsid; 66} 67 68void 69XRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset) 70{ 71 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 72 xRenderFreeGlyphSetReq *req; 73 74 RenderSimpleCheckExtension (dpy, info); 75 LockDisplay(dpy); 76 GetReq(RenderFreeGlyphSet, req); 77 req->reqType = (CARD8) info->codes->major_opcode; 78 req->renderReqType = X_RenderFreeGlyphSet; 79 req->glyphset = (CARD32) glyphset; 80 UnlockDisplay(dpy); 81 SyncHandle(); 82} 83 84void 85XRenderAddGlyphs (Display *dpy, 86 GlyphSet glyphset, 87 _Xconst Glyph *gids, 88 _Xconst XGlyphInfo *glyphs, 89 int nglyphs, 90 _Xconst char *images, 91 int nbyte_images) 92{ 93 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 94 xRenderAddGlyphsReq *req; 95 long len; 96 97 if (nbyte_images & 3) 98 nbyte_images += 4 - (nbyte_images & 3); 99 RenderSimpleCheckExtension (dpy, info); 100 LockDisplay(dpy); 101 GetReq(RenderAddGlyphs, req); 102 req->reqType = (CARD8) info->codes->major_opcode; 103 req->renderReqType = X_RenderAddGlyphs; 104 req->glyphset = (CARD32) glyphset; 105 req->nglyphs = (CARD32) nglyphs; 106 len = (nglyphs * (SIZEOF (xGlyphInfo) + 4) + nbyte_images) >> 2; 107 SetReqLen(req, len, len); 108 Data32 (dpy, (_Xconst long *) gids, nglyphs * 4); 109 Data16 (dpy, (_Xconst short *) glyphs, nglyphs * SIZEOF (xGlyphInfo)); 110 Data (dpy, images, nbyte_images); 111 UnlockDisplay(dpy); 112 SyncHandle(); 113} 114 115void 116XRenderFreeGlyphs (Display *dpy, 117 GlyphSet glyphset, 118 _Xconst Glyph *gids, 119 int nglyphs) 120{ 121 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 122 xRenderFreeGlyphsReq *req; 123 long len; 124 125 RenderSimpleCheckExtension (dpy, info); 126 LockDisplay(dpy); 127 GetReq(RenderFreeGlyphs, req); 128 req->reqType = (CARD8) info->codes->major_opcode; 129 req->renderReqType = X_RenderFreeGlyphs; 130 req->glyphset = (CARD32) glyphset; 131 len = nglyphs; 132 SetReqLen(req, len, len); 133 len <<= 2; 134 Data32 (dpy, (_Xconst long *) gids, len); 135 UnlockDisplay(dpy); 136 SyncHandle(); 137} 138 139void 140XRenderCompositeString8 (Display *dpy, 141 int op, 142 Picture src, 143 Picture dst, 144 _Xconst XRenderPictFormat *maskFormat, 145 GlyphSet glyphset, 146 int xSrc, 147 int ySrc, 148 int xDst, 149 int yDst, 150 _Xconst char *string, 151 int nchar) 152{ 153 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 154 xRenderCompositeGlyphs8Req *req; 155 long len; 156 xGlyphElt *elt; 157 int nbytes; 158 159 if (!nchar) 160 return; 161 162 RenderSimpleCheckExtension (dpy, info); 163 LockDisplay(dpy); 164 165 GetReq(RenderCompositeGlyphs8, req); 166 req->reqType = (CARD8) info->codes->major_opcode; 167 req->renderReqType = X_RenderCompositeGlyphs8; 168 req->op = (CARD8) op; 169 req->src = (CARD32) src; 170 req->dst = (CARD32) dst; 171 req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None); 172 req->glyphset = (CARD32) glyphset; 173 req->xSrc = (INT16) xSrc; 174 req->ySrc = (INT16) ySrc; 175 176 /* 177 * xGlyphElt must be aligned on a 32-bit boundary; this is 178 * easily done by filling no more than 252 glyphs in each 179 * bucket 180 */ 181 182#define MAX_8 252 183 184 len = SIZEOF(xGlyphElt) * ((nchar + MAX_8-1) / MAX_8) + nchar; 185 186 req->length = (CARD16) (req->length + ((len + 3)>>2)); /* convert to number of 32-bit words */ 187 188 /* 189 * If the entire request does not fit into the remaining space in the 190 * buffer, flush the buffer first. 191 */ 192 193 if (dpy->bufptr + len > dpy->bufmax) 194 _XFlush (dpy); 195 196 while(nchar > MAX_8) 197 { 198 nbytes = MAX_8 + SIZEOF(xGlyphElt); 199 BufAlloc (xGlyphElt *, elt, nbytes); 200 elt->len = MAX_8; 201 elt->deltax = (INT16) xDst; 202 elt->deltay = (INT16) yDst; 203 xDst = 0; 204 yDst = 0; 205 memcpy ((char *) (elt + 1), string, MAX_8); 206 nchar = nchar - MAX_8; 207 string += MAX_8; 208 } 209 210 if (nchar) 211 { 212 nbytes = (nchar + SIZEOF(xGlyphElt) + 3) & ~3; 213 BufAlloc (xGlyphElt *, elt, nbytes); 214 elt->len = (CARD8) nchar; 215 elt->deltax = (INT16) xDst; 216 elt->deltay = (INT16) yDst; 217 memcpy ((char *) (elt + 1), string, (size_t) nchar); 218 } 219#undef MAX_8 220 221 UnlockDisplay(dpy); 222 SyncHandle(); 223} 224void 225XRenderCompositeString16 (Display *dpy, 226 int op, 227 Picture src, 228 Picture dst, 229 _Xconst XRenderPictFormat *maskFormat, 230 GlyphSet glyphset, 231 int xSrc, 232 int ySrc, 233 int xDst, 234 int yDst, 235 _Xconst unsigned short *string, 236 int nchar) 237{ 238 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 239 xRenderCompositeGlyphs8Req *req; 240 long len; 241 xGlyphElt *elt; 242 int nbytes; 243 244 if (!nchar) 245 return; 246 247 RenderSimpleCheckExtension (dpy, info); 248 LockDisplay(dpy); 249 250 GetReq(RenderCompositeGlyphs16, req); 251 req->reqType = (CARD8) info->codes->major_opcode; 252 req->renderReqType = X_RenderCompositeGlyphs16; 253 req->op = (CARD8) op; 254 req->src = (CARD32) src; 255 req->dst = (CARD32) dst; 256 req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None); 257 req->glyphset = (CARD32) glyphset; 258 req->xSrc = (INT16) xSrc; 259 req->ySrc = (INT16) ySrc; 260 261#define MAX_16 254 262 263 len = SIZEOF(xGlyphElt) * ((nchar + MAX_16-1) / MAX_16) + nchar * 2; 264 265 req->length = (CARD16) (req->length + ((len + 3)>>2)); /* convert to number of 32-bit words */ 266 267 /* 268 * If the entire request does not fit into the remaining space in the 269 * buffer, flush the buffer first. 270 */ 271 272 if (dpy->bufptr + len > dpy->bufmax) 273 _XFlush (dpy); 274 275 while(nchar > MAX_16) 276 { 277 nbytes = MAX_16 * 2 + SIZEOF(xGlyphElt); 278 BufAlloc (xGlyphElt *, elt, nbytes); 279 elt->len = MAX_16; 280 elt->deltax = (INT16) xDst; 281 elt->deltay = (INT16) yDst; 282 xDst = 0; 283 yDst = 0; 284 memcpy ((char *) (elt + 1), (_Xconst char *) string, MAX_16 * 2); 285 nchar = nchar - MAX_16; 286 string += MAX_16; 287 } 288 289 if (nchar) 290 { 291 nbytes = (nchar * 2 + SIZEOF(xGlyphElt) + 3) & ~3; 292 BufAlloc (xGlyphElt *, elt, nbytes); 293 elt->len = (CARD8) nchar; 294 elt->deltax = (INT16) xDst; 295 elt->deltay = (INT16) yDst; 296 memcpy ((char *) (elt + 1), (_Xconst char *) string, (size_t) (nchar * 2)); 297 } 298#undef MAX_16 299 300 UnlockDisplay(dpy); 301 SyncHandle(); 302} 303 304void 305XRenderCompositeString32 (Display *dpy, 306 int op, 307 Picture src, 308 Picture dst, 309 _Xconst XRenderPictFormat *maskFormat, 310 GlyphSet glyphset, 311 int xSrc, 312 int ySrc, 313 int xDst, 314 int yDst, 315 _Xconst unsigned int *string, 316 int nchar) 317{ 318 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 319 xRenderCompositeGlyphs8Req *req; 320 long len; 321 xGlyphElt *elt; 322 int nbytes; 323 324 if (!nchar) 325 return; 326 327 RenderSimpleCheckExtension (dpy, info); 328 LockDisplay(dpy); 329 330 GetReq(RenderCompositeGlyphs32, req); 331 req->reqType = (CARD8) info->codes->major_opcode; 332 req->renderReqType = X_RenderCompositeGlyphs32; 333 req->op = (CARD8) op; 334 req->src = (CARD32) src; 335 req->dst = (CARD32) dst; 336 req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None); 337 req->glyphset = (CARD32) glyphset; 338 req->xSrc = (INT16) xSrc; 339 req->ySrc = (INT16) ySrc; 340 341#define MAX_32 254 342 343 len = SIZEOF(xGlyphElt) * ((nchar + MAX_32-1) / MAX_32) + nchar * 4; 344 345 req->length = (CARD16) (req->length + ((len + 3)>>2)); /* convert to number of 32-bit words */ 346 347 /* 348 * If the entire request does not fit into the remaining space in the 349 * buffer, flush the buffer first. 350 */ 351 352 if (dpy->bufptr + len > dpy->bufmax) 353 _XFlush (dpy); 354 355 while(nchar > MAX_32) 356 { 357 nbytes = MAX_32 * 4 + SIZEOF(xGlyphElt); 358 BufAlloc (xGlyphElt *, elt, nbytes); 359 elt->len = MAX_32; 360 elt->deltax = (INT16) xDst; 361 elt->deltay = (INT16) yDst; 362 xDst = 0; 363 yDst = 0; 364 memcpy ((char *) (elt + 1), (_Xconst char *) string, MAX_32 * 4); 365 nchar = nchar - MAX_32; 366 string += MAX_32; 367 } 368 369 if (nchar) 370 { 371 nbytes = nchar * 4 + SIZEOF(xGlyphElt); 372 BufAlloc (xGlyphElt *, elt, nbytes); 373 elt->len = (CARD8) nchar; 374 elt->deltax = (INT16) xDst; 375 elt->deltay = (INT16) yDst; 376 memcpy ((char *) (elt + 1), (_Xconst char *) string, (size_t) (nchar * 4)); 377 } 378#undef MAX_32 379 380 UnlockDisplay(dpy); 381 SyncHandle(); 382} 383 384void 385XRenderCompositeText8 (Display *dpy, 386 int op, 387 Picture src, 388 Picture dst, 389 _Xconst XRenderPictFormat *maskFormat, 390 int xSrc, 391 int ySrc, 392 int xDst, 393 int yDst, 394 _Xconst XGlyphElt8 *elts, 395 int nelt) 396{ 397 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 398 xRenderCompositeGlyphs8Req *req; 399 GlyphSet glyphset; 400 long len; 401 int i; 402 403 if (!nelt) 404 return; 405 406 RenderSimpleCheckExtension (dpy, info); 407 LockDisplay(dpy); 408 409 GetReq(RenderCompositeGlyphs8, req); 410 req->reqType = (CARD8) info->codes->major_opcode; 411 req->renderReqType = X_RenderCompositeGlyphs8; 412 req->op = (CARD8) op; 413 req->src = (CARD32) src; 414 req->dst = (CARD32) dst; 415 req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None); 416 req->glyphset = (CARD32) elts[0].glyphset; 417 req->xSrc = (INT16) xSrc; 418 req->ySrc = (INT16) ySrc; 419 420 /* 421 * Compute the space necessary 422 */ 423 len = 0; 424 425#define MAX_8 252 426 427 glyphset = elts[0].glyphset; 428 for (i = 0; i < nelt; i++) 429 { 430 long elen; 431 int nchars; 432 433 /* 434 * Check for glyphset change 435 */ 436 if (elts[i].glyphset != glyphset) 437 { 438 glyphset = elts[i].glyphset; 439 len += (SIZEOF (xGlyphElt) + 4) >> 2; 440 } 441 nchars = elts[i].nchars; 442 /* 443 * xGlyphElt must be aligned on a 32-bit boundary; this is 444 * easily done by filling no more than 252 glyphs in each 445 * bucket 446 */ 447 elen = SIZEOF(xGlyphElt) * ((nchars + MAX_8-1) / MAX_8) + nchars; 448 len += (elen + 3) >> 2; 449 } 450 451 req->length = (CARD16) (req->length + len); 452 453 /* 454 * Send the glyphs 455 */ 456 glyphset = elts[0].glyphset; 457 for (i = 0; i < nelt; i++) 458 { 459 xGlyphElt *elt; 460 _Xconst char *chars; 461 int nchars; 462 463 /* 464 * Switch glyphsets 465 */ 466 if (elts[i].glyphset != glyphset) 467 { 468 glyphset = elts[i].glyphset; 469 BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); 470 elt->len = 0xff; 471 elt->deltax = 0; 472 elt->deltay = 0; 473 Data32(dpy, &glyphset, 4); 474 } 475 nchars = elts[i].nchars; 476 xDst = elts[i].xOff; 477 yDst = elts[i].yOff; 478 chars = elts[i].chars; 479 while (nchars) 480 { 481 int this_chars = nchars > MAX_8 ? MAX_8 : nchars; 482 483 BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); 484 elt->len = (CARD8) this_chars; 485 elt->deltax = (INT16) xDst; 486 elt->deltay = (INT16) yDst; 487 xDst = 0; 488 yDst = 0; 489 Data (dpy, chars, this_chars); 490 nchars -= this_chars; 491 chars += this_chars; 492 } 493 } 494#undef MAX_8 495 496 UnlockDisplay(dpy); 497 SyncHandle(); 498} 499 500void 501XRenderCompositeText16 (Display *dpy, 502 int op, 503 Picture src, 504 Picture dst, 505 _Xconst XRenderPictFormat *maskFormat, 506 int xSrc, 507 int ySrc, 508 int xDst, 509 int yDst, 510 _Xconst XGlyphElt16 *elts, 511 int nelt) 512{ 513 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 514 xRenderCompositeGlyphs16Req *req; 515 GlyphSet glyphset; 516 long len; 517 int i; 518 519 if (!nelt) 520 return; 521 522 RenderSimpleCheckExtension (dpy, info); 523 LockDisplay(dpy); 524 525 GetReq(RenderCompositeGlyphs16, req); 526 req->reqType = (CARD8) info->codes->major_opcode; 527 req->renderReqType = X_RenderCompositeGlyphs16; 528 req->op = (CARD8) op; 529 req->src = (CARD32) src; 530 req->dst = (CARD32) dst; 531 req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None); 532 req->glyphset = (CARD32) elts[0].glyphset; 533 req->xSrc = (INT16) xSrc; 534 req->ySrc = (INT16) ySrc; 535 536 /* 537 * Compute the space necessary 538 */ 539 len = 0; 540 541#define MAX_16 254 542 543 glyphset = elts[0].glyphset; 544 for (i = 0; i < nelt; i++) 545 { 546 int nchars; 547 long elen; 548 549 /* 550 * Check for glyphset change 551 */ 552 if (elts[i].glyphset != glyphset) 553 { 554 glyphset = elts[i].glyphset; 555 len += (SIZEOF (xGlyphElt) + 4) >> 2; 556 } 557 nchars = elts[i].nchars; 558 /* 559 * xGlyphElt must be aligned on a 32-bit boundary; this is 560 * easily done by filling no more than 254 glyphs in each 561 * bucket 562 */ 563 elen = SIZEOF(xGlyphElt) * ((nchars + MAX_16-1) / MAX_16) + nchars * 2; 564 len += (elen + 3) >> 2; 565 } 566 567 req->length = (CARD16) (req->length + len); 568 569 glyphset = elts[0].glyphset; 570 for (i = 0; i < nelt; i++) 571 { 572 xGlyphElt *elt; 573 _Xconst unsigned short *chars; 574 int nchars; 575 576 /* 577 * Switch glyphsets 578 */ 579 if (elts[i].glyphset != glyphset) 580 { 581 glyphset = elts[i].glyphset; 582 BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); 583 elt->len = 0xff; 584 elt->deltax = 0; 585 elt->deltay = 0; 586 Data32(dpy, &glyphset, 4); 587 } 588 nchars = elts[i].nchars; 589 xDst = elts[i].xOff; 590 yDst = elts[i].yOff; 591 chars = elts[i].chars; 592 while (nchars) 593 { 594 int this_chars = nchars > MAX_16 ? MAX_16 : nchars; 595 int this_bytes = this_chars * 2; 596 597 BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); 598 elt->len = (CARD8) this_chars; 599 elt->deltax = (INT16) xDst; 600 elt->deltay = (INT16) yDst; 601 xDst = 0; 602 yDst = 0; 603 Data16 (dpy, chars, this_bytes); 604 nchars -= this_chars; 605 chars += this_chars; 606 } 607 } 608#undef MAX_16 609 610 UnlockDisplay(dpy); 611 SyncHandle(); 612} 613 614void 615XRenderCompositeText32 (Display *dpy, 616 int op, 617 Picture src, 618 Picture dst, 619 _Xconst XRenderPictFormat *maskFormat, 620 int xSrc, 621 int ySrc, 622 int xDst, 623 int yDst, 624 _Xconst XGlyphElt32 *elts, 625 int nelt) 626{ 627 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 628 xRenderCompositeGlyphs32Req *req; 629 GlyphSet glyphset; 630 long len; 631 int i; 632 633 if (!nelt) 634 return; 635 636 RenderSimpleCheckExtension (dpy, info); 637 LockDisplay(dpy); 638 639 640 GetReq(RenderCompositeGlyphs32, req); 641 req->reqType = (CARD8) info->codes->major_opcode; 642 req->renderReqType = X_RenderCompositeGlyphs32; 643 req->op = (CARD8) op; 644 req->src = (CARD32) src; 645 req->dst = (CARD32) dst; 646 req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None); 647 req->glyphset = (CARD32) elts[0].glyphset; 648 req->xSrc = (INT16) xSrc; 649 req->ySrc = (INT16) ySrc; 650 651 /* 652 * Compute the space necessary 653 */ 654 len = 0; 655 656#define MAX_32 254 657 658 glyphset = elts[0].glyphset; 659 for (i = 0; i < nelt; i++) 660 { 661 int nchars; 662 long elen; 663 664 /* 665 * Check for glyphset change 666 */ 667 if (elts[i].glyphset != glyphset) 668 { 669 glyphset = elts[i].glyphset; 670 len += (SIZEOF (xGlyphElt) + 4) >> 2; 671 } 672 nchars = elts[i].nchars; 673 elen = SIZEOF(xGlyphElt) * ((nchars + MAX_32-1) / MAX_32) + nchars *4; 674 len += (elen + 3) >> 2; 675 } 676 677 req->length = (CARD16) (req->length + len); 678 679 glyphset = elts[0].glyphset; 680 for (i = 0; i < nelt; i++) 681 { 682 xGlyphElt *elt; 683 _Xconst unsigned int *chars; 684 int nchars; 685 686 /* 687 * Switch glyphsets 688 */ 689 if (elts[i].glyphset != glyphset) 690 { 691 glyphset = elts[i].glyphset; 692 BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); 693 elt->len = 0xff; 694 elt->deltax = 0; 695 elt->deltay = 0; 696 Data32(dpy, &glyphset, 4); 697 } 698 nchars = elts[i].nchars; 699 xDst = elts[i].xOff; 700 yDst = elts[i].yOff; 701 chars = elts[i].chars; 702 while (nchars) 703 { 704 int this_chars = nchars > MAX_32 ? MAX_32 : nchars; 705 int this_bytes = this_chars * 4; 706 BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); 707 elt->len = (CARD8) this_chars; 708 elt->deltax = (INT16) xDst; 709 elt->deltay = (INT16) yDst; 710 xDst = 0; 711 yDst = 0; 712 DataInt32 (dpy, chars, this_bytes); 713 nchars -= this_chars; 714 chars += this_chars; 715 } 716 } 717#undef MAX_32 718 719 UnlockDisplay(dpy); 720 SyncHandle(); 721} 722