1 /*
2 * Type Printing for X11 protocol
3 *
4 * James Peterson, 1988
5 *
6 * Copyright (C) 1988 MCC
7 *
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of MCC not be used in
13 * advertising or publicity pertaining to distribution of the software without
14 * specific, written prior permission. MCC makes no
15 * representations about the suitability of this software for any purpose. It
16 * is provided "as is" without express or implied warranty.
17 *
18 * MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20 * EVENT SHALL MCC BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
24 * PERFORMANCE OF THIS SOFTWARE.
25 *
26 */
27 /*
28 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
29 *
30 * Permission is hereby granted, free of charge, to any person obtaining a
31 * copy of this software and associated documentation files (the "Software"),
32 * to deal in the Software without restriction, including without limitation
33 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34 * and/or sell copies of the Software, and to permit persons to whom the
35 * Software is furnished to do so, subject to the following conditions:
36 *
37 * The above copyright notice and this permission notice (including the next
38 * paragraph) shall be included in all copies or substantial portions of the
39 * Software.
40 *
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
46 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
47 * DEALINGS IN THE SOFTWARE.
48 *
49 */
50
51 #include "scope.h"
52 #include "x11.h"
53
54 /*
55 For each of the types we need a way to print that type.
56 Types are of varieties:
57
58 (1) BUILTIN -- we have a separate routine to interpret and print
59 each built-in type.
60 (2) ENUMERATED, SET -- we have one routine which prints, given the
61 data and the list of values.
62 (3) RECORDS -- a separate routine for each to print each field.
63
64 */
65
66 /* ************************************************************ */
67 /* */
68 /* */
69 /* ************************************************************ */
70
71 /* print representation of a character for debugging */
72 static const char *
printrep(unsigned short c)73 printrep(unsigned short c)
74 {
75 static char pr[8];
76
77 if (c < 32) {
78 /* control characters */
79 pr[0] = '^';
80 pr[1] = c + 64;
81 pr[2] = '\0';
82 }
83 else if (c < 127) {
84 /* printing characters */
85 pr[0] = (char) c;
86 pr[1] = '\0';
87 }
88 else if (c == 127)
89 return ("<del>");
90 else if (c <= 0377) {
91 /* upper 128 codes from 128 to 255; print as \ooo - octal */
92 pr[0] = '\\';
93 pr[3] = '0' + (c & 7);
94 c = c >> 3;
95 pr[2] = '0' + (c & 7);
96 c = c >> 3;
97 pr[1] = '0' + (c & 3);
98 pr[4] = '\0';
99 }
100 else {
101 /* very large number -- print as 0xffff - 4 digit hex */
102 snprintf(pr, sizeof(pr), "0x%04x", c);
103 }
104 return (pr);
105 }
106
107 /* ************************************************************ */
108 /* */
109 /* */
110 /* ************************************************************ */
111
112 /*
113 we use indentation for two purposes:
114
115 (1) To show substructure of records inside records ...
116 (2) To separate the bytes from the client (on the left) from
117 those from the server (on the right).
118
119 Each indention level is one tab (8 spaces).
120 */
121
122 #define MaxIndent 10
123 char Leader[MaxIndent + 1];
124 static short CurrentLevel = 0;
125
126 void
SetIndentLevel(short which)127 SetIndentLevel(short which)
128 {
129 short i;
130
131 if (which > MaxIndent)
132 which = MaxIndent;
133 if (which < 0)
134 which = 0;
135 if (which == CurrentLevel)
136 return;
137
138 /* set the indent level to <which> */
139 /* -> set the Print Leader to <which> tabs */
140 for (i = 0; i < which; i++)
141 Leader[i] = '\t';
142 Leader[which] = '\0';
143 CurrentLevel = which;
144 }
145
146 static void
ModifyIndentLevel(short amount)147 ModifyIndentLevel(short amount)
148 {
149 SetIndentLevel(CurrentLevel + amount);
150 }
151
152 static short
SizeofLeader(void)153 SizeofLeader(void)
154 {
155 return (CurrentLevel * 8);
156 }
157
158 /* ************************************************************ */
159 /* */
160 /* */
161 /* ************************************************************ */
162
163 /* if we want verbose enough output, we will dump the buffer in hex */
164
165 void
DumpItem(const char * name,FD fd,const unsigned char * buf,long n)166 DumpItem(const char *name, FD fd, const unsigned char *buf, long n)
167 {
168 if (n == 0)
169 return;
170
171 fprintf(stdout, "%s%20s (fd %d): ", Leader, name, fd);
172
173 DumpHexBuffer(buf, n);
174 fprintf(stdout, "\n");
175 }
176
177 /* ************************************************************ */
178 /* */
179 /* */
180 /* ************************************************************ */
181
182 int
PrintINT8(const unsigned char * buf)183 PrintINT8(const unsigned char *buf)
184 {
185 /* print a INT8 -- 8-bit signed integer */
186 short n = IByte(buf);
187
188 if (n > 127)
189 n = 256 - n;
190 fprintf(stdout, "%d", n);
191 return 1;
192 }
193
194 int
PrintINT16(const unsigned char * buf)195 PrintINT16(const unsigned char *buf)
196 {
197 /* print a INT16 -- 16-bit signed integer */
198 long n = IShort(buf);
199
200 if (n > 32767)
201 n = 65536 - n;
202 fprintf(stdout, "%ld", n);
203 return 2;
204 }
205
206 int
PrintINT32(const unsigned char * buf)207 PrintINT32(const unsigned char *buf)
208 {
209 /* print a INT32 -- 32-bit signed integer */
210 long n = ILong(buf);
211
212 fprintf(stdout, "%ld", n);
213 return 4;
214 }
215
216 /* ************************************************************ */
217
218 int
PrintCARD8(const unsigned char * buf)219 PrintCARD8(const unsigned char *buf)
220 {
221 /* print a CARD8 -- 8-bit unsigned integer */
222 unsigned short n = IByte(buf);
223
224 fprintf(stdout, "%02x", (unsigned) (n & 0xff));
225 return 1;
226 }
227
228 int
PrintCARD16(const unsigned char * buf)229 PrintCARD16(const unsigned char *buf)
230 {
231 /* print a CARD16 -- 16-bit unsigned integer */
232 unsigned long n = IShort(buf);
233
234 fprintf(stdout, "%04x", (unsigned) (n & 0xffff));
235 return 1;
236 }
237
238 int
PrintCARD32(const unsigned char * buf)239 PrintCARD32(const unsigned char *buf)
240 {
241 /* print a CARD32 -- 32-bit unsigned integer */
242 unsigned long n = ILong(buf);
243
244 fprintf(stdout, "%08lx", n);
245 return (4);
246 }
247
248 /* ************************************************************ */
249
250 int
PrintBYTE(const unsigned char * buf)251 PrintBYTE(const unsigned char *buf)
252 {
253 /* print a BYTE -- 8-bit value */
254 short n = IByte(buf);
255
256 fprintf(stdout, "%02x", n);
257 return (1);
258 }
259
260 int
PrintCHAR8(const unsigned char * buf)261 PrintCHAR8(const unsigned char *buf)
262 {
263 /* print a CHAR8 -- 8-bit character */
264 unsigned short n = IByte(buf);
265
266 fprintf(stdout, "%s", printrep(n));
267 return (1);
268 }
269
270 int
PrintSTRING16(const unsigned char * buf)271 PrintSTRING16(const unsigned char *buf)
272 {
273 /* print a CHAR2B -- 16-bit character which is never byte-swapped */
274 unsigned short n = IChar2B(buf);
275
276 fprintf(stdout, "%s", printrep(n));
277 return 2 + n;
278 }
279
280 int
PrintSTR(const unsigned char * buf)281 PrintSTR(const unsigned char *buf)
282 {
283 /* STR have the length (1 byte) then a string of CHAR8 */
284 short n;
285
286 short i;
287
288 n = IByte(buf++);
289 for (i = 0; i < n; i++)
290 fprintf(stdout, "%s", printrep(buf[i]));
291 return (n + 1);
292 }
293
294 /* ************************************************************ */
295
296 int
PrintWINDOW(const unsigned char * buf)297 PrintWINDOW(const unsigned char *buf)
298 {
299 /* print a WINDOW -- CARD32 plus 0 = None */
300 long n = ILong(buf);
301
302 if (n == 0)
303 fprintf(stdout, "None");
304 else
305 fprintf(stdout, "WIN %08lx", n);
306 return (4);
307 }
308
309 int
PrintWINDOWD(const unsigned char * buf)310 PrintWINDOWD(const unsigned char *buf)
311 {
312 /* print a WINDOWD -- CARD32 plus 0 = PointerWindow, 1 = InputFocus */
313 long n = ILong(buf);
314
315 if (n == 0)
316 fprintf(stdout, "PointerWindow");
317 else if (n == 1)
318 fprintf(stdout, "InputFocus");
319 else
320 (void) PrintWINDOW(buf);
321 return 4;
322 }
323
324 int
PrintWINDOWNR(const unsigned char * buf)325 PrintWINDOWNR(const unsigned char *buf)
326 {
327 /* print a WINDOWNR -- CARD32 plus 0 = None, 1 = PointerRoot */
328 long n = ILong(buf);
329
330 if (n == 0)
331 fprintf(stdout, "None");
332 else if (n == 1)
333 fprintf(stdout, "PointerRoot");
334 else
335 (void) PrintWINDOW(buf);
336 return 4;
337 }
338
339 int
PrintPIXMAP(const unsigned char * buf)340 PrintPIXMAP(const unsigned char *buf)
341 {
342 /* print a PIXMAP -- CARD32 plus 0 = None */
343 long n = ILong(buf);
344
345 if (n == 0)
346 fprintf(stdout, "None");
347 else
348 fprintf(stdout, "PXM %08lx", n);
349 return 4;
350 }
351
352 int
PrintPIXMAPNPR(const unsigned char * buf)353 PrintPIXMAPNPR(const unsigned char *buf)
354 {
355 /* print a PIXMAPNPR -- CARD32 plus 0 = None, 1 = ParentRelative */
356 long n = ILong(buf);
357
358 if (n == 0)
359 fprintf(stdout, "None");
360 else if (n == 1)
361 fprintf(stdout, "ParentRelative");
362 else
363 PrintPIXMAP(buf);
364 return 4;
365 }
366
367 int
PrintPIXMAPC(const unsigned char * buf)368 PrintPIXMAPC(const unsigned char *buf)
369 {
370 /* print a PIXMAPC -- CARD32 plus 0 = CopyFromParent */
371 long n = ILong(buf);
372
373 if (n == 0)
374 fprintf(stdout, "CopyFromParent");
375 else
376 PrintPIXMAP(buf);
377 return 4;
378 }
379
380 int
PrintCURSOR(const unsigned char * buf)381 PrintCURSOR(const unsigned char *buf)
382 {
383 /* print a CURSOR -- CARD32 plus 0 = None */
384 long n = ILong(buf);
385
386 if (n == 0)
387 fprintf(stdout, "None");
388 else
389 fprintf(stdout, "CUR %08lx", n);
390 return 4;
391 }
392
393 int
PrintFONT(const unsigned char * buf)394 PrintFONT(const unsigned char *buf)
395 {
396 /* print a FONT -- CARD32 plus 0 = None */
397 long n = ILong(buf);
398
399 if (n == 0)
400 fprintf(stdout, "None");
401 else
402 fprintf(stdout, "FNT %08lx", n);
403 return 4;
404 }
405
406 int
PrintGCONTEXT(const unsigned char * buf)407 PrintGCONTEXT(const unsigned char *buf)
408 {
409 /* print a GCONTEXT -- CARD32 */
410 long n = ILong(buf);
411
412 fprintf(stdout, "GXC %08lx", n);
413 return 4;
414 }
415
416 int
PrintCOLORMAP(const unsigned char * buf)417 PrintCOLORMAP(const unsigned char *buf)
418 {
419 /* print a COLORMAP -- CARD32 plus 0 = None */
420 long n = ILong(buf);
421
422 if (n == 0)
423 fprintf(stdout, "None");
424 else
425 fprintf(stdout, "CMP %08lx", n);
426 return (4);
427 }
428
429 int
PrintCOLORMAPC(const unsigned char * buf)430 PrintCOLORMAPC(const unsigned char *buf)
431 {
432 /* print a COLORMAPC -- CARD32 plus 0 = CopyFromParent */
433 long n = ILong(buf);
434
435 if (n == 0)
436 fprintf(stdout, "CopyFromParent");
437 else
438 (void) PrintCOLORMAP(buf);
439 return 4;
440 }
441
442 int
PrintDRAWABLE(const unsigned char * buf)443 PrintDRAWABLE(const unsigned char *buf)
444 {
445 /* print a DRAWABLE -- CARD32 */
446 long n = ILong(buf);
447
448 fprintf(stdout, "DWB %08lx", n);
449 return 4;
450 }
451
452 int
PrintFONTABLE(const unsigned char * buf)453 PrintFONTABLE(const unsigned char *buf)
454 {
455 /* print a FONTABLE -- CARD32 */
456 long n = ILong(buf);
457
458 fprintf(stdout, "FTB %08lx", n);
459 return 4;
460 }
461
462 /* ************************************************************ */
463
464 /* for atoms, we print the built-in atoms, as well as any user defined
465 ones we've captured during this session. */
466
467 int
PrintATOM(const unsigned char * buf)468 PrintATOM(const unsigned char *buf)
469 {
470 /* print a ATOM -- CARD32 plus 0 = None */
471 long n = ILong(buf);
472 const char *name = FindAtomName(n);
473
474 if (name != NULL) {
475 if (Verbose > 1)
476 fprintf(stdout, "ATM %08lx <%s>", n, name);
477 else
478 fprintf(stdout, "<%s>", name);
479 }
480 else
481 fprintf(stdout, "ATM %08lx", n);
482 return (4);
483 }
484
485 int
PrintATOMT(const unsigned char * buf)486 PrintATOMT(const unsigned char *buf)
487 {
488 /* print a ATOMT -- CARD32 plus 0 = AnyPropertyType */
489 long n = ILong(buf);
490
491 if (n == 0)
492 fprintf(stdout, "AnyPropertyType");
493 else
494 (void) PrintATOM(buf);
495 return 4;
496 }
497
498 int
PrintVISUALID(const unsigned char * buf)499 PrintVISUALID(const unsigned char *buf)
500 {
501 /* print a VISUALID -- CARD32 plus 0 = None */
502 long n = ILong(buf);
503
504 if (n == 0)
505 fprintf(stdout, "None");
506 else
507 fprintf(stdout, "VIS %08lx", n);
508 return 4;
509 }
510
511 int
PrintVISUALIDC(const unsigned char * buf)512 PrintVISUALIDC(const unsigned char *buf)
513 {
514 /* print a VISUALIDC -- CARD32 plus 0 = CopyFromParent */
515 long n = ILong(buf);
516
517 if (n == 0)
518 fprintf(stdout, "CopyFromParent");
519 else
520 PrintVISUALID(buf);
521 return 4;
522 }
523
524 int
PrintTIMESTAMP(const unsigned char * buf)525 PrintTIMESTAMP(const unsigned char *buf)
526 {
527 /* print a TIMESTAMP -- CARD32 plus 0 as the current time */
528 long n = ILong(buf);
529
530 if (n == 0)
531 fprintf(stdout, "CurrentTime");
532 else
533 fprintf(stdout, "TIM %08lx", n);
534 return 4;
535 }
536
537 int
PrintRESOURCEID(const unsigned char * buf)538 PrintRESOURCEID(const unsigned char *buf)
539 {
540 /* print a RESOURCEID -- CARD32 plus 0 = AllTemporary */
541 long n = ILong(buf);
542
543 if (n == 0)
544 fprintf(stdout, "AllTemporary");
545 else
546 fprintf(stdout, "RID %08lx", n);
547 return 4;
548 }
549
550 int
PrintKEYSYM(const unsigned char * buf)551 PrintKEYSYM(const unsigned char *buf)
552 {
553 /* print a KEYSYM -- CARD32 */
554 long n = ILong(buf);
555
556 fprintf(stdout, "KYS %08lx", n);
557 return (4);
558 }
559
560 int
PrintKEYCODE(const unsigned char * buf)561 PrintKEYCODE(const unsigned char *buf)
562 {
563 /* print a KEYCODE -- CARD8 */
564 unsigned short n = IByte(buf);
565
566 fprintf(stdout, "%d (%s)", n, printrep(n));
567 return (1);
568 }
569
570 int
PrintKEYCODEA(const unsigned char * buf)571 PrintKEYCODEA(const unsigned char *buf)
572 {
573 /* print a KEYCODEA -- CARD8 plus 0 = AnyKey */
574 long n = IByte(buf);
575
576 if (n == 0)
577 fprintf(stdout, "AnyKey");
578 else
579 (void) PrintKEYCODE(buf);
580 return 1;
581 }
582
583 int
PrintBUTTON(const unsigned char * buf)584 PrintBUTTON(const unsigned char *buf)
585 {
586 /* print a BUTTON -- CARD8 */
587 unsigned short n = IByte(buf);
588
589 fprintf(stdout, "%d (%s)", n, printrep(n));
590 return 1;
591 }
592
593 int
PrintBUTTONA(const unsigned char * buf)594 PrintBUTTONA(const unsigned char *buf)
595 {
596 /* print a BUTTONA -- CARD8 plus 0 = AnyButton */
597 long n = IByte(buf);
598
599 if (n == 0)
600 fprintf(stdout, "AnyButton");
601 else
602 PrintBUTTON(buf);
603 return 1;
604 }
605
606 /* this is an interesting cheat -- we call DecodeEvent to print an event */
607 /* should work, but its never been tried */
608 int
PrintEVENTFORM(const unsigned char * buf)609 PrintEVENTFORM(const unsigned char *buf)
610 {
611 /* print an EVENT_FORM -- event format */
612 DecodeEvent(-1, buf, (long) -1);
613 return 32;
614 }
615
616 int
PrintEVENT(const unsigned char * buf)617 PrintEVENT(const unsigned char *buf)
618 {
619 uint8_t n = IByte(buf);
620 long e = (long) (n & 0x7f);
621 struct ValueListEntry *p;
622
623 p = TD[EVENT].ValueList;
624 while (p != NULL && p->Value != e)
625 p = p->Next;
626
627 if (p != NULL)
628 fprintf(stdout, "%s", p->Name);
629 else
630 fprintf(stdout, "**INVALID** (%d)", n);
631
632 if (n & 0x80)
633 fprintf(stdout, "\n%s%20s: %s", Leader, "source", "SendEvent");
634
635 return 1;
636 }
637
638 /* ************************************************************ */
639
640 int
PrintENUMERATED(const unsigned char * buf,short length,struct ValueListEntry * ValueList)641 PrintENUMERATED(const unsigned char *buf,
642 short length, struct ValueListEntry *ValueList)
643 {
644 long n;
645 struct ValueListEntry *p;
646
647 if (length == 1)
648 n = IByte(buf);
649 else if (length == 2)
650 n = IShort(buf);
651 else
652 n = ILong(buf);
653
654 p = ValueList;
655 while (p != NULL && p->Value != n)
656 p = p->Next;
657
658 if (p != NULL)
659 fprintf(stdout, "%s", p->Name);
660 else
661 fprintf(stdout, "**INVALID** (%ld)", n);
662
663 return length;
664 }
665
666 /* ************************************************************ */
667
668 int
PrintSET(const unsigned char * buf,short length,struct ValueListEntry * ValueList)669 PrintSET(const unsigned char *buf,
670 short length, struct ValueListEntry *ValueList)
671 {
672 unsigned long n;
673 struct ValueListEntry *p;
674 Boolean MatchesAll = false;
675 Boolean FoundOne = false;
676
677 if (length == 1)
678 n = IByte(buf);
679 else if (length == 2)
680 n = IShort(buf);
681 else
682 n = ILong(buf);
683
684 if (n != 0) {
685 /* first check if the value matches ALL of the bits. */
686 MatchesAll = true;
687 for (p = ValueList; MatchesAll && (p != NULL); p = p->Next) {
688 if ((p->Value & n) == 0)
689 MatchesAll = false;
690 }
691
692 if (!MatchesAll)
693 /* if it matches some, but not all, print only those it matches */
694 for (p = ValueList; p != NULL; p = p->Next) {
695 if ((p->Value & n) != 0) {
696 if (FoundOne)
697 fprintf(stdout, " | ");
698 fprintf(stdout, "%s", p->Name);
699 FoundOne = true;
700 }
701 }
702 }
703
704 if (MatchesAll)
705 fprintf(stdout, "<ALL>");
706 else if (!FoundOne)
707 fprintf(stdout, "0");
708
709 return length;
710 }
711
712 /* ************************************************************ */
713 /* */
714 /* */
715 /* ************************************************************ */
716
717 void
PrintField(const unsigned char * buf,short start,short length,short FieldType,const char * name)718 PrintField(const unsigned char *buf,
719 short start, short length, short FieldType, const char *name)
720 {
721 if (Verbose == 0)
722 return;
723
724 if (length == 0)
725 return;
726
727 fprintf(stdout, "%s%20s: ", Leader, name);
728
729 if (debuglevel & 8)
730 DumpHexBuffer(&(buf[start]), (long) length);
731
732 switch (TD[FieldType].Type) {
733 case BUILTIN:
734 (*TD[FieldType].PrintProc) (&buf[start]);
735 break;
736
737 case ENUMERATED:
738 PrintENUMERATED(&buf[start], length, TD[FieldType].ValueList);
739 break;
740
741 case SET:
742 PrintSET(&buf[start], length, TD[FieldType].ValueList);
743 break;
744
745 case RECORD:
746 ModifyIndentLevel(1);
747 fprintf(stdout, "\n");
748 if (Verbose < 3)
749 return;
750 (*TD[FieldType].PrintProc) (&buf[start]);
751 ModifyIndentLevel(-1);
752 break;
753 }
754 fprintf(stdout, "\n");
755 fflush(stdout);
756 }
757
758 /* ************************************************************ */
759 /* */
760 /* */
761 /* ************************************************************ */
762
763 /* print a list of things. The things are of type <ListType>.
764 They start at <buf>. There are <number> things in the list */
765
766 long
PrintList(const unsigned char * buf,long number,short ListType,const char * name)767 PrintList(const unsigned char *buf,
768 long number, short ListType, const char *name)
769 {
770 long n;
771 long i;
772 long sum;
773
774 if (Verbose == 0)
775 return (0);
776
777 if (number == 0)
778 return (0);
779
780 fprintf(stdout, "%s%20s: (%ld)\n", Leader, name, number);
781 if (Verbose < 2)
782 return (0);
783
784 ModifyIndentLevel(1);
785 sum = 0;
786 for (i = 0; i < number; i++) {
787 switch (TD[ListType].Type) {
788 case BUILTIN:
789 n = (*TD[ListType].PrintProc) (buf);
790 break;
791 case RECORD:
792 n = (*TD[ListType].PrintProc) (buf);
793 break;
794 default:
795 fprintf(stdout, "**INVALID**");
796 n = 0;
797 break;
798 }
799 buf = buf + n;
800 sum = sum + n;
801 fprintf(stdout, "%s---\n", Leader);
802 }
803
804 ModifyIndentLevel(-1);
805 return (sum);
806 }
807
808 /* ************************************************************ */
809 /* */
810 /* */
811 /* ************************************************************ */
812
813 /* print a list of STRs. Similar to PrintList
814 They start at <buf>. There are <number> things in the list */
815
816 long
PrintListSTR(const unsigned char * buf,long number,const char * name)817 PrintListSTR(const unsigned char *buf, long number, const char *name)
818 {
819 long n;
820 long i;
821 long sum;
822
823 if (number == 0)
824 return (0);
825
826 fprintf(stdout, "%s%20s: (%ld)\n", Leader, name, number);
827 if (Verbose < 2)
828 return (0);
829
830 ModifyIndentLevel(1);
831 sum = 0;
832 for (i = 0; i < number; i++) {
833 fprintf(stdout, "%s", Leader);
834 n = PrintSTR(buf);
835 buf = buf + n;
836 sum = sum + n;
837 fprintf(stdout, "\n");
838 }
839
840 ModifyIndentLevel(-1);
841 return (sum);
842 }
843
844
845 /* ************************************************************ */
846 /* */
847 /* */
848 /* ************************************************************ */
849
850
851 int
PrintBytes(const unsigned char * buf,long number,const char * name)852 PrintBytes(const unsigned char *buf, long number, const char *name)
853 {
854 /* print a list of BYTE -- 8-bit character */
855 long i;
856 short column;
857
858 if (number == 0)
859 return (0);
860
861 fprintf(stdout, "%s%20s: ", Leader, name);
862 column = SizeofLeader() + 25;
863 for (i = 0; i < number; i++) {
864 if (column > 80) {
865 if (Verbose < 2)
866 break;
867 fprintf(stdout, "\n%s%20s: ", Leader, "");
868 column = SizeofLeader() + 25;
869 }
870 fprintf(stdout, "%02x ", ((unsigned int) buf[i]));
871 column += 3;
872 }
873 fprintf(stdout, "\n");
874
875 return (number);
876 }
877
878
879 /* ************************************************************ */
880 /* */
881 /* */
882 /* ************************************************************ */
883
884
885 /* print a String of CHAR8 -- 8-bit characters */
886
887 int
PrintString8(const unsigned char * buf,int number,const char * name)888 PrintString8(const unsigned char *buf, int number, const char *name)
889 {
890 short i;
891
892 if (number == 0)
893 return (0);
894
895 fprintf(stdout, "%s%20s: \"", Leader, name);
896 for (i = 0; i < number; i++)
897 fprintf(stdout, "%s", printrep(buf[i]));
898 fprintf(stdout, "\"\n");
899
900 return (number);
901 }
902
903 /* print a String of CHAR16 -- 16-bit characters */
904
905 int
PrintString16(const unsigned char * buf,int number,const char * name)906 PrintString16(const unsigned char *buf, int number, const char *name)
907 {
908 long i;
909 unsigned short c;
910
911 if (number == 0)
912 return (0);
913
914 fprintf(stdout, "%s%20s: \"", Leader, name);
915 for (i = 0; i < number * 2; i += 2) {
916 c = IChar2B(&buf[i]);
917 fprintf(stdout, "%s", printrep(c));
918 }
919 fprintf(stdout, "\"\n");
920
921 return (number);
922 }
923
924 void
PrintTString8(const unsigned char * buf,long number,const char * name)925 PrintTString8(const unsigned char *buf, long number, const char *name)
926 {
927 long i;
928 int off;
929
930 if (number == 0)
931 return;
932
933 off = 0;
934 if (TranslateText)
935 off = 0x20;
936 fprintf(stdout, "%s%20s: \"", Leader, name);
937 for (i = 0; i < number; i++)
938 fprintf(stdout, "%s", printrep(buf[i] + off));
939 fprintf(stdout, "\"\n");
940 }
941
942 /* print a String of CHAR2B -- 16-bit characters */
943 void
PrintTString16(const unsigned char * buf,long number,const char * name)944 PrintTString16(const unsigned char *buf, long number, const char *name)
945 {
946 long i;
947 unsigned short c;
948 int off;
949
950 if (number == 0)
951 return;
952
953 off = 0;
954 if (TranslateText)
955 off = 0x20;
956 fprintf(stdout, "%s%20s: \"", Leader, name);
957 for (i = 0; i < number * 2; i += 2) {
958 c = IChar2B(&buf[i]);
959 fprintf(stdout, "%s", printrep(c + off));
960 }
961 fprintf(stdout, "\"\n");
962 }
963
964
965 /* ************************************************************ */
966 /* */
967 /* */
968 /* ************************************************************ */
969
970 /*
971 A Value List is two things:
972
973 (1) A controlling bitmask. For each one bit in the control,
974 a value is in the list.
975 (2) A list of values.
976 */
977
978 void
PrintValues(const unsigned char * control,int clength,int ctype,const unsigned char * values,const char * name)979 PrintValues(const unsigned char *control,
980 int clength,
981 int ctype, const unsigned char *values, const char *name)
982 {
983 long cmask;
984 struct ValueListEntry *p;
985
986 /* first get the control mask */
987 if (clength == 1)
988 cmask = IByte(control);
989 else if (clength == 2)
990 cmask = IShort(control);
991 else
992 cmask = ILong(control);
993
994 /* now if it is zero, ignore and return */
995 if (cmask == 0)
996 return;
997
998 /* there are bits in the controlling bitmask, figure out which */
999 /* the ctype is a set type, so this code is similar to PrintSET */
1000 fprintf(stdout, "%s%20s:\n", Leader, name);
1001 ModifyIndentLevel(1);
1002 for (p = TD[ctype].ValueList; p != NULL; p = p->Next) {
1003 if ((p->Value & cmask) != 0) {
1004 short m;
1005
1006 if (littleEndian)
1007 m = 0;
1008 else
1009 m = 4 - p->Length;
1010 PrintField(values, m, p->Length, p->Type, p->Name);
1011 values += 4;
1012 }
1013 }
1014 ModifyIndentLevel(-1);
1015 }
1016
1017 /* ************************************************************ */
1018 /* */
1019 /* */
1020 /* ************************************************************ */
1021
1022 /* PolyText8 and PolyText16 take lists of characters with possible
1023 font changes in them. */
1024
1025 void
PrintTextList8(const unsigned char * buf,int length,const char * name)1026 PrintTextList8(const unsigned char *buf, int length, const char *name)
1027 {
1028 short n;
1029
1030 fprintf(stdout, "%s%20s:\n", Leader, name);
1031 while (length > 1) {
1032 n = IByte(&buf[0]);
1033 if (n != 255) {
1034 PrintField(buf, 1, 1, INT8, "delta");
1035 PrintTString8(&buf[2], (long) n, "text item 8 string");
1036 buf += n + 2;
1037 length -= n + 2;
1038 }
1039 else {
1040 PrintField(buf, 1, 4, FONT, "font-shift-id");
1041 buf += 4;
1042 length -= 4;
1043 }
1044 }
1045 }
1046
1047 void
PrintTextList16(const unsigned char * buf,int length,const char * name)1048 PrintTextList16(const unsigned char *buf, int length, const char *name)
1049 {
1050 short n;
1051
1052 fprintf(stdout, "%s%20s:\n", Leader, name);
1053 while (length > 1) {
1054 n = IByte(&buf[0]);
1055 if (n != 255) {
1056 PrintField(buf, 1, 1, INT8, "delta");
1057 PrintTString16(&buf[2], (long) n, "text item 16 string");
1058 buf += n + 2;
1059 length -= n + 2;
1060 }
1061 else {
1062 PrintField(buf, 1, 4, FONT, "font-shift-id");
1063 buf += 4;
1064 length -= 4;
1065 }
1066 }
1067 }
1068
1069 /* ************************************************************ */
1070 /* */
1071 /* */
1072 /* ************************************************************ */
1073
1074 /* Several extensions have grown property requests mimicing the
1075 core protocol Window properties, and share this code for printing
1076 lists of property values */
1077 int
PrintPropertyValues(const unsigned char * buf,uint32_t type,uint8_t unit,uint32_t num,const char * name)1078 PrintPropertyValues(const unsigned char *buf, uint32_t type /* atom */,
1079 uint8_t unit, uint32_t num, const char *name)
1080 {
1081 short fieldType = 0;
1082
1083 switch (type) {
1084 case 4: /* XA_ATOM */
1085 fieldType = ATOM;
1086 break;
1087 case 6: /* XA_CARDINAL */
1088 switch (unit) {
1089 case 4: fieldType = CARD32; break;
1090 case 2: fieldType = CARD16; break;
1091 case 1: fieldType = CARD8; break;
1092 default:
1093 goto rawbytes;
1094 }
1095 break;
1096 case 19: /* XA_INTEGER */
1097 switch (unit) {
1098 case 4: fieldType = INT32; break;
1099 case 2: fieldType = INT16; break;
1100 case 1: fieldType = INT8; break;
1101 default:
1102 goto rawbytes;
1103 }
1104 break;
1105 case 31: /* XA_STRING */
1106 return PrintString8(buf, num * unit, name);
1107 case 33: /* XA_WINDOW */
1108 fieldType = WINDOW;
1109 break;
1110 default:
1111 /* Fall through to check for known non-builtin types below */
1112 break;
1113 }
1114
1115 if (fieldType != 0) {
1116 if (num == 1) {
1117 PrintField(buf, 0, unit, fieldType, name);
1118 return unit;
1119 }
1120 else
1121 return PrintList(buf, num, fieldType, name);
1122 }
1123 else {
1124 const char *typename = FindAtomName(type);
1125
1126 if (typename) {
1127 if (strcmp(typename, "UTF8_STRING") == 0) {
1128 if (IsUTF8locale)
1129 return PrintString8(buf, num * unit, name);
1130 else
1131 goto rawbytes;
1132 }
1133 }
1134 }
1135
1136 rawbytes:
1137 /* When all else fails, print raw bytes */
1138 return PrintBytes(buf, num * unit, name);
1139 }
1140
1141 /* ************************************************************ */
1142 /* */
1143 /* */
1144 /* ************************************************************ */
1145
1146 #define MAXline 78
1147
1148 void
DumpHexBuffer(const unsigned char * buf,long n)1149 DumpHexBuffer(const unsigned char *buf, long n)
1150 {
1151 long i;
1152 short column;
1153 char h[6]; /* one hex or octal character */
1154
1155 column = 27 + SizeofLeader();
1156 for (i = 0; i < n; i++) {
1157 /* get the hex representations */
1158 snprintf(h, sizeof(h), "%02x", (0xff & buf[i]));
1159
1160 /* check if these characters will fit on this line */
1161 if ((column + strlen(h) + 1) > MAXline) {
1162 /* line will be too long -- print it */
1163 fprintf(stdout, "\n");
1164 column = 0;
1165 }
1166 fprintf(stdout, "%s ", h);
1167 column += 3;
1168 }
1169 }
1170
1171 void
PrintValueRec(uint32_t key,uint32_t cmask,short ctype)1172 PrintValueRec(uint32_t key, uint32_t cmask, short ctype)
1173 {
1174 unsigned char *values;
1175 struct ValueListEntry *p;
1176 ValuePtr value;
1177
1178 value = GetValueRec(key);
1179 if (!value)
1180 return;
1181 values = (unsigned char *) value->values;
1182
1183 /* now if it is zero, ignore and return */
1184 if (cmask == 0)
1185 return;
1186
1187 /* there are bits in the controlling bitmask, figure out which */
1188 /* the ctype is a set type, so this code is similar to PrintSET */
1189 ModifyIndentLevel(1);
1190 for (p = TD[ctype].ValueList; p != NULL; p = p->Next) {
1191 if ((p->Value & cmask) != 0) {
1192 short m;
1193
1194 if (littleEndian)
1195 m = 0;
1196 else
1197 m = 4 - p->Length;
1198 PrintField(values, m, p->Length, p->Type, p->Name);
1199 }
1200 values += 4;
1201 }
1202 ModifyIndentLevel(-1);
1203 }
1204