Annotation of researchv9/X11/src/X.V11R1/clients/xprop/xprop.c, revision 1.1.1.1

1.1       root        1: #include <X11/Xlib.h>
                      2: #include <X11/Xutil.h>
                      3: #include <string.h>
                      4: #include <stdio.h>
                      5: #include <ctype.h>
                      6: 
                      7: #include <X11/Xatom.h>
                      8: 
                      9: #include "dsimple.h"
                     10: 
                     11: #define MAXSTR 10000
                     12: 
                     13: #define min(a,b)  ((a) < (b) ? (a) : (b))
                     14: 
                     15: /*
                     16:  *
                     17:  * The Thunk Manager - routines to create, add to, and free thunk lists
                     18:  *
                     19:  */
                     20: 
                     21: typedef struct {
                     22:   int thunk_count;
                     23:   long value;
                     24:   char *extra_value;
                     25:   char *format;
                     26:   char *dformat;
                     27: } thunk;
                     28: 
                     29: thunk *Create_Thunk_List()
                     30: {
                     31:   thunk *tptr;
                     32: 
                     33:   tptr = (thunk *) Malloc( sizeof(thunk) );
                     34: 
                     35:   tptr->thunk_count = 0;
                     36: 
                     37:   return(tptr);
                     38: }
                     39: 
                     40: Free_Thunk_List(list)
                     41: thunk *list;
                     42: {
                     43:   free(list);
                     44: }
                     45: 
                     46: thunk *Add_Thunk(list, t)
                     47: thunk *list;
                     48: thunk t;
                     49: {
                     50:   int i;
                     51: 
                     52:   i = list->thunk_count;
                     53: 
                     54:   list = (thunk *) realloc(list, (i+1)*sizeof(thunk) );
                     55:   if (!list)
                     56:     Fatal_Error("Out of memory!");
                     57: 
                     58:   list[i++] = t;
                     59:   list->thunk_count = i;
                     60: 
                     61:   return(list);
                     62: }
                     63: 
                     64: /*
                     65:  * Misc. routines
                     66:  */
                     67: 
                     68: char *Copy_String(string)
                     69:      char *string;
                     70: {
                     71:        char *new;
                     72:        int length;
                     73: 
                     74:        length = strlen(string) + 1;
                     75: 
                     76:        new = (char *) Malloc(length);
                     77:        bcopy(string, new, length);
                     78: 
                     79:        return(new);
                     80: }
                     81: 
                     82: int Read_Char(stream)
                     83:      FILE *stream;
                     84: {
                     85:        int c;
                     86: 
                     87:        c = getc(stream);
                     88:        if (c==EOF)
                     89:          Fatal_Error("Bad format file: Unexpected EOF.");
                     90:        return(c);
                     91: }
                     92: 
                     93: Read_White_Space(stream)
                     94:      FILE *stream;
                     95: {
                     96:        int c;
                     97: 
                     98:        while ((c=getc(stream))==' ' || c=='\n' || c=='\t');
                     99:        ungetc(c, stream);
                    100: }
                    101: 
                    102: static char _large_buffer[MAXSTR+10];
                    103: 
                    104: char *Read_Quoted(stream)
                    105:      FILE *stream;
                    106: {
                    107:        char *ptr;
                    108:        int c, length;
                    109: 
                    110:        Read_White_Space(stream);
                    111:        if (Read_Char(stream)!='\'')
                    112:          Fatal_Error("Bad format file format: missing dformat.");
                    113: 
                    114:        ptr = _large_buffer; length=MAXSTR;
                    115:        for (;;) {
                    116:                if (length<0)
                    117:                  Fatal_Error("Bad format file format: dformat too long.");
                    118:                c = Read_Char(stream);
                    119:                if (c==(int) '\'')
                    120:                  break;
                    121:                ptr++[0]=c; length--;
                    122:                if (c== (int) '\\') {
                    123:                        c=Read_Char(stream);
                    124:                        if (c=='\n') {
                    125:                                ptr--; length++;
                    126:                        } else
                    127:                          ptr++[0]=c; length--;
                    128:                }
                    129:        }
                    130:        ptr++[0]='\0';
                    131: 
                    132:        return(Copy_String(_large_buffer));
                    133: }
                    134: 
                    135: /*
                    136:  *
                    137:  * Atom to format, dformat mapping Manager
                    138:  *
                    139:  */
                    140: 
                    141: #define D_FORMAT "0x"              /* Default format for properties */
                    142: #define D_DFORMAT " = $0+\n";      /* Default display pattern for properties */
                    143: 
                    144: static thunk *_property_formats = 0;   /* Holds mapping */
                    145: 
                    146: Apply_Default_Formats(format, dformat)
                    147:      char **format;
                    148:      char **dformat;
                    149: {
                    150:   if (!*format)
                    151:     *format = D_FORMAT;
                    152:   if (!*dformat)
                    153:     *dformat = D_DFORMAT;
                    154: }
                    155:   
                    156: Lookup_Formats(atom, format, dformat)
                    157:      Atom atom;
                    158:      char **format;
                    159:      char **dformat;
                    160: {
                    161:   int i;
                    162: 
                    163:   if (_property_formats)
                    164:     for (i=_property_formats->thunk_count-1; i>=0; i--)
                    165:       if (_property_formats[i].value==atom) {
                    166:        if (!*format)
                    167:          *format = _property_formats[i].format;
                    168:        if (!*dformat)
                    169:          *dformat = _property_formats[i].dformat;
                    170:        break;
                    171:       }
                    172: }
                    173: 
                    174: Add_Mapping(atom, format, dformat)
                    175:      Atom atom;
                    176:      char *format;
                    177:      char *dformat;
                    178: {
                    179:   thunk t;
                    180: 
                    181:   if (!_property_formats)
                    182:     _property_formats = Create_Thunk_List();
                    183: 
                    184:   t.value=atom;
                    185:   t.format=format;
                    186:   t.dformat=dformat;
                    187: 
                    188:   _property_formats = Add_Thunk(_property_formats, t);
                    189: }
                    190: 
                    191: /*
                    192:  *
                    193:  * Setup_Mapping: Routine to setup default atom to format, dformat mapping:
                    194:  * 
                    195:  */
                    196: 
                    197: typedef struct { Atom atom; char *format; char *dformat } _default_mapping;
                    198: _default_mapping _default_mappings[] = {
                    199: 
                    200:        /*
                    201:         * General types:
                    202:         */
                    203:        { XA_INTEGER, "0i", 0 },
                    204:        { XA_CARDINAL, "0c", 0 },
                    205:        { XA_STRING, "8s", 0 },
                    206:        { XA_ATOM, "32a", 0 },
                    207: 
                    208:        { XA_POINT, "16ii", " = $0, $1\n" },
                    209:        { XA_RECTANGLE, "16iicc", ":\n\t\tupper left corner: $0, $1\n\
                    210: \t\tsize: $2 by $3\n" },
                    211:        { XA_ARC, "16iiccii", ":\n\t\tarc at $0, $1\n\
                    212: \t\tsize: $2 by $3\n\
                    213: \t\tfrom angle $4 to angle $5\n" },
                    214: 
                    215:        { XA_FONT, "32x", ": font id # $0\n" },
                    216:        { XA_DRAWABLE, "32x", ": drawable id # $0\n" },
                    217:        { XA_WINDOW, "32x", ": window id # $0\n" },
                    218:        { XA_PIXMAP, "32x", ": pixmap id # $0\n" },
                    219:        { XA_BITMAP, "32x", ": bitmap id # $0\n" },
                    220:        { XA_VISUALID, "32x", ": visual id # $0\n" },
                    221:        { XA_COLORMAP, "32x", ": colormap id # $0\n" },
                    222:        { XA_CURSOR, "32x", ": cursor id # $0\n" },
                    223: 
                    224:        { XA_RGB_COLOR_MAP, "32xccccccc", ":\n\
                    225: \t\tcolormap id #: $0\n\
                    226: \t\tred-max: $1\n\
                    227: \t\tred-mult: $2\n\
                    228: \t\tgreen-max: $3\n\
                    229: \t\tgreen-mult: $4\n\
                    230: \t\tblue-max: $5\n\
                    231: \t\tblue-mult: $6\n\
                    232: \t\tbase-pixel: $7\n" },
                    233: 
                    234:        /*
                    235:         * Window manager types:
                    236:         */
                    237:        { XA_WM_COMMAND, "8s", " = { $0+ }\n" },
                    238:        { XA_WM_HINTS, "32mbcxxxii", ":\n\
                    239: ?m0(\t\tApplication accepts input\\?: $1\n)\
                    240: ?m1(\t\tInitial state is \
                    241: ?$2=0(Don't Care State)\
                    242: ?$2=1(Normal State)\
                    243: ?$2=2(Zoomed State)\
                    244: ?$2=3(Iconic State)\
                    245: ?$2=4(Inactive State)\
                    246: .\n)\
                    247: ?m2(\t\tpixmap id # to use for icon: $3\n)\
                    248: ?m5(\t\tbitmap id # of mask for icon: $5\n)\
                    249: ?m3(\t\twindow id # to use for icon: $4\n)\
                    250: ?m4(\t\tstarting position for icon: $6, $7\n)" },
                    251:        { XA_WM_SIZE_HINTS, "32mii", ":\n\
                    252: ?m0(\t\tuser specified location: $1, $2\n)\
                    253: ?m2(\t\tprogram specified location: $1, $2\n)\
                    254: ?m1(\t\tuser specified size: $3 by $4\n)\
                    255: ?m3(\t\tprogram specified size: $3 by $4\n)\
                    256: ?m4(\t\tprogram specified minimum size: $5 by $6\n)\
                    257: ?m5(\t\tprogram specified maximum size: $7 by $8\n)\
                    258: ?m6(\t\tprogram specified resize increment: $9 by $10\n)\
                    259: ?m7(\t\tprogram specified minimum ascept ratio: $11/$12\n\
                    260: \t\tprogram specified maximum ascept ratio: $13/$14\n)" },
                    261:        { XA_WM_ICON_SIZE, "32cccccc", ":\n\
                    262: \t\tminimum icon size: $0 by $1\n\
                    263: \t\tmaximum icon size: $2 by $3\n\
                    264: \t\tincremental size change: $4 by $5\n" },
                    265: 
                    266:        /*
                    267:         * Font specific mapping of property names to types:
                    268:         */
                    269:        { XA_MIN_SPACE, "32c", 0 },
                    270:        { XA_NORM_SPACE, "32c", 0 },
                    271:        { XA_MAX_SPACE, "32c", 0 },
                    272:        { XA_END_SPACE, "32c", 0 },
                    273:        { XA_SUPERSCRIPT_X, "32i", 0 },
                    274:        { XA_SUPERSCRIPT_Y, "32i", 0 },
                    275:        { XA_SUBSCRIPT_X, "32i", 0 },
                    276:        { XA_SUBSCRIPT_Y, "32i", 0 },
                    277:        { XA_UNDERLINE_POSITION, "32i", 0 },
                    278:        { XA_UNDERLINE_THICKNESS, "32c", 0 },
                    279:        { XA_STRIKEOUT_ASCENT, "32i", 0 },
                    280:        { XA_STRIKEOUT_DESCENT, "32i", 0 },
                    281:        { XA_ITALIC_ANGLE, "32i", 0 },
                    282:        { XA_X_HEIGHT, "32i", 0 },
                    283:        { XA_QUAD_WIDTH, "32i", 0 },
                    284:        { XA_WEIGHT, "32c", 0 },
                    285:        { XA_POINT_SIZE, "32c", 0 },
                    286:        { XA_RESOLUTION, "32c", 0 },
                    287:        { XA_COPYRIGHT, "32a", 0 },
                    288:        { XA_NOTICE, "32a", 0 },
                    289:        { XA_FONT_NAME, "32a", 0 },
                    290:        { XA_FAMILY_NAME, "32a", 0 },
                    291:        { XA_FULL_NAME, "32a", 0 },
                    292: 
                    293:        { 0, 0, 0 } };
                    294:        
                    295: Setup_Mapping()
                    296: {
                    297:        _default_mapping *dmap = _default_mappings;
                    298: 
                    299:        while (dmap->format) {
                    300:                Add_Mapping( dmap->atom, dmap->format, dmap->dformat );
                    301:                dmap++;
                    302:        }
                    303: }
                    304: 
                    305: /*
                    306:  * Read_Mapping: routine to read in additional mappings from a stream
                    307:  *               already open for reading.
                    308:  */
                    309: 
                    310: Read_Mappings(stream)
                    311:      FILE *stream;
                    312: {
                    313:        char format_buffer[100];
                    314:        char name[1000], *dformat, *format;
                    315:        int count, c;
                    316:        Atom atom, Parse_Atom();
                    317: 
                    318:        while ((count=fscanf(stream," %990s %90s ",name,format_buffer))!=EOF) {
                    319:                if (count != 2)
                    320:                  Fatal_Error("Bad format file format.");
                    321: 
                    322:                atom = Parse_Atom(name, False);
                    323:                format = Copy_String(format_buffer);
                    324: 
                    325:                Read_White_Space(stream);
                    326:                dformat = D_DFORMAT;
                    327:                c = getc(stream);
                    328:                ungetc(c, stream);
                    329:                if (c==(int)'\'')
                    330:                  dformat = Read_Quoted(stream);
                    331: 
                    332:                Add_Mapping(atom, format, dformat);
                    333:        }
                    334: }
                    335: 
                    336: /*
                    337:  *
                    338:  * Formatting Routines: a group of routines to translate from various
                    339:  *                      values to a static read-only string useful for output.
                    340:  *
                    341:  * Routines: Format_Hex, Format_Unsigned, Format_Signed, Format_Atom,
                    342:  *           Format_Mask_Word, Format_Bool, Format_String, Format_Len_String.
                    343:  *
                    344:  * All of the above routines take a long except for Format_String and
                    345:  * Format_Len_String.
                    346:  *
                    347:  */
                    348: static char _formatting_buffer[MAXSTR+100];
                    349: static char _formatting_buffer2[10];
                    350: 
                    351: char *Format_Hex(word)
                    352:      long word;
                    353: {
                    354:   sprintf(_formatting_buffer2, "0x%lx", word);
                    355:   return(_formatting_buffer2);
                    356: }
                    357: 
                    358: char *Format_Unsigned(word)
                    359:      long word;
                    360: {
                    361:   sprintf(_formatting_buffer2, "%lu", word);
                    362:   return(_formatting_buffer2);
                    363: }
                    364: 
                    365: char *Format_Signed(word)
                    366:      long word;
                    367: {
                    368:   sprintf(_formatting_buffer2, "%ld", word);
                    369:   return(_formatting_buffer2);
                    370: }
                    371: 
                    372: char *Format_Atom(atom)
                    373:      Atom atom;
                    374: {
                    375:   char *name;
                    376: 
                    377:   name=XGetAtomName(dpy, atom);
                    378:   if (!name)
                    379:     sprintf(_formatting_buffer, "undefined atom # 0x%lx", atom);
                    380:   else
                    381:     strncpy(_formatting_buffer, name, MAXSTR);
                    382: 
                    383:   return(_formatting_buffer);
                    384: }
                    385: 
                    386: char *Format_Mask_Word(word)
                    387:      long word;
                    388: {
                    389:   long bit_mask, bit;
                    390:   int seen = 0;
                    391: 
                    392:   strcpy(_formatting_buffer, "{MASK: ");
                    393:   for (bit=0, bit_mask=1; bit<=sizeof(long)*8; bit++, bit_mask<<=1) {
                    394:     if (bit_mask & word) {
                    395:       if (seen) {
                    396:        strcat(_formatting_buffer, ", ");
                    397:       }
                    398:       seen=1;
                    399:       strcat(_formatting_buffer, Format_Unsigned(bit));
                    400:     }
                    401:   }
                    402:   strcat(_formatting_buffer, "}");
                    403: 
                    404:   return(_formatting_buffer);
                    405: }
                    406: 
                    407: char *Format_Bool(value)
                    408:      long value;
                    409: {
                    410:   if (!value)
                    411:     return("False");
                    412: 
                    413:   return("True");
                    414: }
                    415: 
                    416: static char *_buf_ptr;
                    417: static int _buf_len;
                    418: 
                    419: _put_char(c)
                    420:      char c;
                    421: {
                    422:        if (--_buf_len<0) {
                    423:                _buf_ptr[0]='\0';
                    424:                return;
                    425:        }
                    426:        _buf_ptr++[0] = c;
                    427: }
                    428: 
                    429: _format_char(c)
                    430:      char c;
                    431: {
                    432:        switch (c) {
                    433:              case '\\':
                    434:              case '\"':
                    435:                _put_char('\\');
                    436:                _put_char(c);
                    437:                break;
                    438:              case '\n':
                    439:                _put_char('\\');
                    440:                _put_char('n');
                    441:                break;
                    442:              case '\t':
                    443:                _put_char('\\');
                    444:                _put_char('t');
                    445:                break;
                    446:              default:
                    447:                if (c<' ') {
                    448:                        _put_char('\\');
                    449:                        sprintf(_buf_ptr, "%o", (int) c);
                    450:                        _buf_ptr += strlen(_buf_ptr);
                    451:                        _buf_len -= strlen(_buf_ptr);
                    452:                } else
                    453:                  _put_char(c);
                    454:        }
                    455: }
                    456: 
                    457: char *Format_String(string)
                    458:      char *string;
                    459: {
                    460:        char c;
                    461: 
                    462:        _buf_ptr = _formatting_buffer;
                    463:        _buf_len = MAXSTR;
                    464:        _put_char('\"');
                    465: 
                    466:        while (c = string++[0])
                    467:          _format_char(c);
                    468: 
                    469:        _buf_len += 3;
                    470:        _put_char('\"');
                    471:        _put_char('\0');
                    472:        return(_formatting_buffer);
                    473: }
                    474: 
                    475: char *Format_Len_String(string, len)
                    476:      char *string;
                    477:      int len;
                    478: {
                    479:   char *data, *result;
                    480: 
                    481:   data = (char *) Malloc(len+1);
                    482: 
                    483:   bcopy(string, data, len);
                    484:   data[len]='\0';
                    485: 
                    486:   result = Format_String(data);
                    487:   free(data);
                    488: 
                    489:   return(result);
                    490: }  
                    491: 
                    492: /*
                    493:  *
                    494:  * Parsing Routines: a group of routines to parse strings into values
                    495:  *
                    496:  * Routines: Parse_Atom, Scan_Long, Skip_Past_Right_Paran, Scan_Octal
                    497:  *
                    498:  * Routines of the form Parse_XXX take a string which is parsed to a value.
                    499:  * Routines of the form Scan_XXX take a string, parse the beginning to a value,
                    500:  * and return the rest of the string.  The value is returned via. the last
                    501:  * parameter.  All numeric values are longs!
                    502:  *
                    503:  */
                    504: 
                    505: char *Skip_Digits(string)
                    506:      char *string;
                    507: {
                    508:        while (isdigit(string[0])) string++;
                    509:        return(string);
                    510: }
                    511: 
                    512: char *Scan_Long(string, value)
                    513:      char *string;
                    514:      long *value;
                    515: {
                    516:        if (!isdigit(*string))
                    517:          Fatal_Error("Bad number: %s.", string);
                    518: 
                    519:        *value = atol(string);
                    520:        return(Skip_Digits(string));
                    521: }
                    522: 
                    523: char *Scan_Octal(string, value)
                    524:      char *string;
                    525:      long *value;
                    526: {
                    527:        if (sscanf(string, "%lo", value)!=1)
                    528:          Fatal_Error("Bad octal number: %s.", string);
                    529:        return(Skip_Digits(string));
                    530: }
                    531: 
                    532: Atom Parse_Atom(name, only_if_exists)
                    533:      char *name;
                    534:      int only_if_exists;
                    535: {
                    536:        Atom atom;
                    537: 
                    538:        if ((atom = XInternAtom(dpy, name, only_if_exists))==None)
                    539:          return(0);
                    540: 
                    541:        return(atom);
                    542: }
                    543: 
                    544: char *Skip_Past_Right_Paran(string)
                    545:      char *string;
                    546: {
                    547:        char c;
                    548:        int nesting=0;
                    549: 
                    550:        while (c=string++[0], c!=')' || nesting)
                    551:          switch (c) {
                    552:                case '\0':
                    553:                  Fatal_Error("Missing ')'.");
                    554:                case '(':
                    555:                  nesting++;
                    556:                  break;
                    557:                case ')':
                    558:                  nesting--;
                    559:                  break;
                    560:                case '\\':
                    561:                  string++;
                    562:                  break;
                    563:          }
                    564:        return(string);
                    565: }
                    566: 
                    567: /*
                    568:  *
                    569:  * The Format Manager: a group of routines to manage "formats"
                    570:  *
                    571:  */
                    572: 
                    573: int Is_A_Format(string)
                    574: char *string;
                    575: {
                    576:        return(isdigit(string[0]));
                    577: }
                    578: 
                    579: int Get_Format_Size(format)
                    580:   char *format;
                    581: {
                    582:   long size;
                    583: 
                    584:   Scan_Long(format, &size);
                    585: 
                    586:   /* Check for legal sizes */
                    587:   if (size != 0 && size != 8 && size != 16 && size != 32)
                    588:     Fatal_Error("bad format: %s", format);
                    589: 
                    590:   return((int) size);
                    591: }
                    592: 
                    593: char Get_Format_Char(format, i)
                    594:      char *format;
                    595:      int i;
                    596: {
                    597:   long size;
                    598: 
                    599:   /* Remove # at front of format */
                    600:   format = Scan_Long(format, &size);
                    601:   if (!*format)
                    602:     Fatal_Error("bad format: %s", format);
                    603: 
                    604:   /* Last character repeats forever... */
                    605:   if (i>=strlen(format))
                    606:     i=strlen(format)-1;
                    607: 
                    608:   return(format[i]);
                    609: }
                    610: 
                    611: char *Format_Thunk(t, format_char)
                    612:      thunk t;
                    613:      char format_char;
                    614: {
                    615:   long value;
                    616:   value = t.value;
                    617: 
                    618:   switch (format_char) {
                    619:   case 's':
                    620:     return(Format_Len_String(t.extra_value, t.value));
                    621:   case 'x':
                    622:     return(Format_Hex(value));
                    623:   case 'c':
                    624:     return(Format_Unsigned(value));
                    625:   case 'i':
                    626:     return(Format_Signed(value));
                    627:   case 'b':
                    628:     return(Format_Bool(value));
                    629:   case 'm':
                    630:     return(Format_Mask_Word(value));
                    631:   case 'a':
                    632:     return(Format_Atom(value));
                    633:   default:
                    634:     Fatal_Error("bad format character: %c", format_char);
                    635:   }
                    636: }
                    637: 
                    638: char *Format_Thunk_I(thunks, format, i)
                    639:      thunk *thunks;
                    640:      char *format;
                    641:      int i;
                    642: {
                    643:   if (i >= thunks->thunk_count)
                    644:     return("<field not available>");
                    645: 
                    646:   return(Format_Thunk(thunks[i], Get_Format_Char(format, i)));
                    647: }
                    648: 
                    649: long Mask_Word(thunks, format)
                    650:      thunk *thunks;
                    651:      char *format;
                    652: {
                    653:        int j;
                    654: 
                    655:        for (j=0; j<strlen(format); j++)
                    656:          if (Get_Format_Char(format, j) == 'm')
                    657:            return(thunks[j].value);
                    658:        return(0L);
                    659: }
                    660: 
                    661: /*
                    662:  *
                    663:  * The Display Format Manager:
                    664:  *
                    665:  */
                    666: 
                    667: int Is_A_DFormat(string)
                    668:      char *string;
                    669: {
                    670:   return( string[0] && string[0]!='-' && !isalpha(string[0]) );
                    671: }
                    672: 
                    673: char *Handle_Backslash(dformat)
                    674:      char *dformat;
                    675: {
                    676:        char c;
                    677:        long i;
                    678: 
                    679:        if (!(c = *(dformat++)))
                    680:          return(dformat);
                    681: 
                    682:        switch (c) {
                    683:              case 'n':
                    684:                putchar('\n');
                    685:                break;
                    686:              case 't':
                    687:                putchar('\t');
                    688:                break;
                    689:              case '0':
                    690:              case '1':
                    691:              case '2':
                    692:              case '3':
                    693:              case '4':
                    694:              case '5':
                    695:              case '6':
                    696:              case '7':
                    697:                dformat = Scan_Octal(dformat, &i);
                    698:                putchar((int) i);
                    699:                break;
                    700:              default:
                    701:                putchar(c);
                    702:                break;
                    703:        }
                    704:        return(dformat);
                    705: }
                    706: 
                    707: char *Handle_Dollar_sign(dformat, thunks, format)
                    708:      char *dformat;
                    709:      thunk *thunks;
                    710:      char *format;
                    711: {
                    712:        long i;
                    713: 
                    714:        dformat = Scan_Long(dformat, &i);
                    715: 
                    716:        if (dformat[0]=='+') {
                    717:                int seen=0;
                    718:                dformat++;
                    719:                for (; i<thunks->thunk_count; i++) {
                    720:                        if (seen)
                    721:                          printf(", ");
                    722:                        seen = 1;
                    723:                        printf("%s", Format_Thunk_I(thunks, format, (int) i));
                    724:                }
                    725:        } else
                    726:          printf("%s", Format_Thunk_I(thunks, format, (int) i));
                    727: 
                    728:        return(dformat);
                    729: }
                    730: 
                    731: int Mask_Bit_I(thunks, format, i)
                    732:      thunk *thunks;
                    733:      char *format;
                    734:      int i;
                    735: {
                    736:        long value;
                    737: 
                    738:        value = Mask_Word(thunks, format);
                    739: 
                    740:        value = value & (1L<<i);
                    741:        if (value)
                    742:          value=1;
                    743:        return(value);
                    744: }
                    745: 
                    746: char *Scan_Term(string, thunks, format, value)
                    747:      thunk *thunks;
                    748:      char *string, *format;
                    749:      long *value;
                    750: {
                    751:        long i;
                    752: 
                    753:        *value=0;
                    754: 
                    755:        if (isdigit(*string))
                    756:          string = Scan_Long(string, value);
                    757:        else if (*string=='$') {
                    758:                string = Scan_Long(++string, &i);
                    759:                if (i>=thunks->thunk_count)
                    760:                  i=thunks->thunk_count;
                    761:                *value = thunks[i].value;
                    762:        } else if (*string=='m') {
                    763:                string = Scan_Long(++string, &i);
                    764:                *value = Mask_Bit_I(thunks, format, (int) i);
                    765:        } else
                    766:          Fatal_Error("Bad term: %s.", string);
                    767: 
                    768:        return(string);
                    769: }
                    770: 
                    771: char *Scan_Exp(string, thunks, format, value)
                    772:      thunk *thunks;
                    773:      char *string, *format;
                    774:      long *value;
                    775: {
                    776:        long temp;
                    777: 
                    778:        if (string[0]=='(') {
                    779:                string = Scan_Exp(++string, thunks, format, value);
                    780:                if (string[0]!=')')
                    781:                  Fatal_Error("Missing ')'");
                    782:                return(++string);
                    783:        }
                    784:        if (string[0]=='!') {
                    785:                string = Scan_Exp(++string, thunks, format, value);
                    786:                *value = !*value;
                    787:                return(string);
                    788:        }
                    789: 
                    790:        string = Scan_Term(string, thunks, format, value);
                    791: 
                    792:        if (string[0]=='=') {
                    793:                string = Scan_Exp(++string, thunks, format, &temp);
                    794:                *value = *value == temp;
                    795:        }
                    796: 
                    797:        return(string);
                    798: }
                    799: 
                    800: char *Handle_Question_Mark(dformat, thunks, format)
                    801:      thunk *thunks;
                    802:      char *dformat, *format;
                    803: {
                    804:        long true;
                    805: 
                    806:        dformat = Scan_Exp(dformat, thunks, format, &true);
                    807: 
                    808:        if (*dformat!='(')
                    809:          Fatal_Error("Bad conditional: '(' expected: %s.", dformat);
                    810:        ++dformat;
                    811: 
                    812:        if (!true)
                    813:          dformat = Skip_Past_Right_Paran(dformat);
                    814: 
                    815:        return(dformat);
                    816: }
                    817: 
                    818: Display_Property(thunks, dformat, format)
                    819:      thunk *thunks;
                    820:      char *dformat, *format;
                    821: {
                    822:   char c;
                    823: 
                    824:   while (c = *(dformat++))
                    825:     switch (c) {
                    826:          case ')':
                    827:            continue;
                    828:          case '\\':
                    829:            dformat = Handle_Backslash(dformat);
                    830:            continue;
                    831:          case '$':
                    832:            dformat = Handle_Dollar_sign(dformat, thunks, format);
                    833:            continue;
                    834:          case '?':
                    835:            dformat = Handle_Question_Mark(dformat, thunks, format);
                    836:            continue;
                    837:          default:
                    838:            putchar(c);
                    839:            continue;
                    840:     }
                    841: }
                    842: 
                    843: /*
                    844:  *
                    845:  * Routines to convert property data to and from thunks
                    846:  *
                    847:  */
                    848: 
                    849: long Extract_Value(pointer, length, size, signedp)
                    850:      char **pointer;
                    851:      int *length;
                    852:      int size;
                    853: {
                    854:        long value, mask;
                    855: 
                    856:        switch (size) {
                    857:              case 8:
                    858:                value = (long) * (char *) *pointer;
                    859:                *pointer += 1;
                    860:                *length -= 1;
                    861:                mask = 0xff;
                    862:                break;
                    863:              case 16:
                    864:                value = (long) * (short *) *pointer;
                    865:                *pointer += 2;
                    866:                *length -= 2;
                    867:                mask = 0xffff;
                    868:                break;
                    869:              default:
                    870:                /* Error */
                    871:              case 32:
                    872:                value = (long) * (long *) *pointer;
                    873:                *pointer += 4;
                    874:                *length -= 4;
                    875:                mask = 0xffffffff;
                    876:                break;
                    877:        }
                    878:        if (!signedp)
                    879:          value &= mask;
                    880:        return(value);
                    881: }
                    882: 
                    883: long Extract_Len_String(pointer, length, size, string)
                    884:      char **pointer;
                    885:      int *length;
                    886:      int size;
                    887:      char **string;
                    888: {
                    889:        int len;
                    890: 
                    891:        if (size!=8)
                    892:         Fatal_Error("can't use format character 's' with any size except 8.");
                    893:        len=0; *string = *pointer;
                    894:        while ((len++, --*length, *((*pointer)++)) && *length>0);
                    895: 
                    896:        return(len);
                    897: }
                    898: 
                    899: thunk *Break_Down_Property(pointer, length, format, size)
                    900:      char *pointer, *format;
                    901:      int length, size;
                    902: {
                    903:        thunk *thunks;
                    904:        thunk t;
                    905:        int i;
                    906:        char format_char;
                    907: 
                    908:        thunks = Create_Thunk_List();
                    909:        i=0;
                    910: 
                    911:        while (length>=(size/8)) {
                    912:            format_char = Get_Format_Char(format, i);
                    913:            if (format_char=='s')
                    914:              t.value=Extract_Len_String(&pointer,&length,size,&t.extra_value);
                    915:            else
                    916:              t.value=Extract_Value(&pointer,&length,size,format_char=='i');
                    917:            thunks = Add_Thunk(thunks, t);
                    918:            i++;
                    919:         }
                    920: 
                    921:        return(thunks);
                    922: }
                    923: 
                    924: /*
                    925:  * 
                    926:  * Routines for parsing command line:
                    927:  *
                    928:  */
                    929: 
                    930: usage()
                    931: {
                    932:        outl("\n%s: usage: %s [<select option>] <option>* <mapping>* <spec>*",
                    933:             program_name, program_name);
                    934:        outl("\n\tselect option ::= -root | -id <id> | -font <font> | -name <name>\
                    935: \n\toption ::= -len <n> | -notype | -spy | {-formats|-fs} <format file>\
                    936: \n\tmapping ::= {-f|-format} <atom> <format> [<dformat>]\
                    937: \n\tspec ::= [<format> [<dformat>]] <atom>\
                    938: \n\tformat ::= {0|8|16|32}{a|b|c|i|m|s|x}*\
                    939: \n\tdformat ::= <unit><unit>*             (can't start with a letter or '-')\
                    940: \n\tunit ::= ?<exp>(<unit>*) | $<n> | <display char>\
                    941: \n\texp ::= <term> | <term>=<exp> | !<exp>\
                    942: \n\tterm ::= <n> | $<n> | m<n>\
                    943: \n\tdisplay char ::= <normal char> | \\<non digit char> | \\<octal number>\
                    944: \n\tnormal char ::= <any char except a digit, $, ?, \\, or )>\
                    945: \n\n");
                    946:        exit(1);
                    947: }
                    948: 
                    949: Parse_Format_Mapping(argc, argv)
                    950:      int *argc;
                    951:      char ***argv;
                    952: #define ARGC (*argc)
                    953: #define ARGV (*argv)
                    954: #define OPTION ARGV[0]
                    955: #define NXTOPT if (++ARGV, --ARGC==0) usage()
                    956: {
                    957:   char *type_name, *format, *dformat;
                    958:   
                    959:   NXTOPT; type_name = OPTION;
                    960: 
                    961:   NXTOPT; format = OPTION;
                    962:   if (!Is_A_Format(format))
                    963:     Fatal_Error("Bad format: %s.", format);
                    964: 
                    965:   dformat=0;
                    966:   if (ARGC>0 && Is_A_DFormat(ARGV[1])) {
                    967:     ARGV++; ARGC--; dformat=OPTION;
                    968:   }
                    969: 
                    970:   Add_Mapping( Parse_Atom(type_name, False), format, dformat);
                    971: }
                    972: 
                    973: /*
                    974:  *
                    975:  * The Main Program:
                    976:  *
                    977:  */
                    978: 
                    979: Window target_win=0;
                    980: int notype=0;
                    981: int spy=0;
                    982: int max_len=MAXSTR;
                    983: XFontStruct *font;
                    984: 
                    985: main(argc, argv)
                    986: int argc;
                    987: char **argv;
                    988: {
                    989:   FILE *stream;
                    990:   char *name, *getenv();
                    991:   thunk *props, *Handle_Prop_Requests();
                    992: 
                    993:   INIT_NAME;
                    994: 
                    995:   /* Handle display name, opening the display */
                    996:   Setup_Display_And_Screen(&argc, argv);
                    997: 
                    998:   /* Handle selecting the window to display properties for */
                    999:   target_win = Select_Window_Args(&argc, argv);
                   1000: 
                   1001:   /* Set up default atom to format, dformat mapping */
                   1002:   Setup_Mapping();
                   1003:   if (name = getenv("XPROPFORMATS")) {
                   1004:          if (!(stream=fopen(name, "r")))
                   1005:            Fatal_Error("unable to open file %s for reading.", name);
                   1006:          Read_Mappings(stream);
                   1007:          fclose(stream);
                   1008:   }
                   1009: 
                   1010:   /* Handle '-' options to setup xprop, select window to work on */
                   1011:   while (argv++, --argc>0 && **argv=='-') {
                   1012:     if (!strcmp(argv[0], "-"))
                   1013:       continue;
                   1014:     if (!strcmp(argv[0], "-notype")) {
                   1015:       notype=1;
                   1016:       continue;
                   1017:     }
                   1018:     if (!strcmp(argv[0], "-spy")) {
                   1019:            spy=1;
                   1020:            continue;
                   1021:     }
                   1022:     if (!strcmp(argv[0], "-len")) {
                   1023:            if (++argv, --argc==0) usage();
                   1024:            max_len = atoi(argv[0]);
                   1025:            continue;
                   1026:     }
                   1027:     if (!strcmp(argv[0], "-formats") || !strcmp(argv[0], "-fs")) {
                   1028:            if (++argv, --argc==0) usage();
                   1029:            if (!(stream=fopen(argv[0], "r")))
                   1030:              Fatal_Error("unable to open file %s for reading.", argv[0]);
                   1031:            Read_Mappings(stream);
                   1032:            fclose(stream);
                   1033:            continue;
                   1034:     }
                   1035:     if (!strcmp(argv[0], "-font")) {
                   1036:            if (++argv, --argc==0) usage();
                   1037:            font = Open_Font(argv[0]);
                   1038:            target_win = -1;
                   1039:            continue;
                   1040:     }
                   1041:     if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "-format")) {
                   1042:       Parse_Format_Mapping(&argc, &argv);
                   1043:       continue;
                   1044:     }
                   1045:     usage();
                   1046:   }
                   1047: 
                   1048:   if (target_win==0)
                   1049:     target_win = Select_Window(dpy);
                   1050: 
                   1051:   props=Handle_Prop_Requests(argc, argv);
                   1052: 
                   1053:   if (spy && target_win != -1) {
                   1054:        XEvent event;
                   1055:         char *format, *dformat;
                   1056:        
                   1057:        XSelectInput(dpy, target_win, PropertyChangeMask);
                   1058:        for (;;) {
                   1059:                XNextEvent(dpy, &event);
                   1060:                format = dformat = NULL;
                   1061:                if (props) {
                   1062:                        int i;
                   1063:                        for (i=0; i<props->thunk_count; i++)
                   1064:                          if (props[i].value == event.xproperty.atom)
                   1065:                            break;
                   1066:                        if (i>=props->thunk_count)
                   1067:                          continue;
                   1068:                        format = props[i].format;
                   1069:                        dformat = props[i].dformat;
                   1070:                }
                   1071:                Show_Prop(format, dformat, Format_Atom(event.xproperty.atom));
                   1072:         }
                   1073:   }
                   1074: }
                   1075: 
                   1076: /*
                   1077:  *
                   1078:  * Other Stuff (temp.):
                   1079:  *
                   1080:  */
                   1081: 
                   1082: thunk *Handle_Prop_Requests(argc, argv)
                   1083:      int argc;
                   1084:      char **argv;
                   1085: {
                   1086:   char *format, *dformat, *prop;
                   1087:   thunk *thunks, t;
                   1088: 
                   1089:   thunks = Create_Thunk_List();
                   1090: 
                   1091:   /* if no prop referenced, by default list all properties for given window */
                   1092:   if (!argc) {
                   1093:     Show_All_Props();
                   1094:     return(NULL);
                   1095:   }
                   1096: 
                   1097:   while (argc>0) {
                   1098:     format = 0;
                   1099:     dformat = 0;
                   1100: 
                   1101:     /* Get overriding formats, if any */
                   1102:     if (Is_A_Format(argv[0])) {
                   1103:       format = argv++[0]; argc--;
                   1104:       if (!argc) usage();
                   1105:     }
                   1106:     if (Is_A_DFormat(argv[0])) {
                   1107:       dformat = argv++[0]; argc--;
                   1108:       if (!argc) usage();
                   1109:     }
                   1110: 
                   1111:     /* Get property name */
                   1112:     prop = argv++[0]; argc--;
                   1113: 
                   1114:     t.value = Parse_Atom(prop, True);
                   1115:     t.format = format;
                   1116:     t.dformat = dformat;
                   1117:     if (t.value)
                   1118:       thunks = Add_Thunk(thunks, t);
                   1119:     Show_Prop(format, dformat, prop);
                   1120:   }
                   1121:   return(thunks);
                   1122: }
                   1123: 
                   1124: Show_All_Props()
                   1125: {
                   1126:   Atom *atoms, atom;
                   1127:   char *name;
                   1128:   int count, i;
                   1129: 
                   1130:   if (target_win!=-1) {
                   1131:          atoms = XListProperties(dpy, target_win, &count);
                   1132:          for (i=0; i<count; i++) {
                   1133:                  name = Format_Atom(atoms[i]);
                   1134:                  Show_Prop(0, 0, name);
                   1135:          }
                   1136:   } else
                   1137:     for (i=0; i<font->n_properties; i++) {
                   1138:            atom = font->properties[i].name;
                   1139:            name = Format_Atom(atom);
                   1140:            Show_Prop(0, 0, name);
                   1141:     }
                   1142: }
                   1143: 
                   1144: Set_Prop(format, dformat, prop, mode, value)
                   1145:      char *format, *dformat, *prop, *value;
                   1146:      char mode;
                   1147: {
                   1148:   outl("Seting prop %s(%s) using %s mode %c to %s",
                   1149:        prop, format, dformat, mode, value);
                   1150: }
                   1151: 
                   1152: static unsigned long _font_prop;
                   1153: 
                   1154: char *Get_Font_Property_Data_And_Type(atom, length, type, size)
                   1155:      Atom atom;
                   1156:      long *length;
                   1157:      Atom *type;
                   1158:      int *size;
                   1159: {
                   1160:        int i;
                   1161:        
                   1162:        *type = 0;
                   1163:        
                   1164:        for (i=0; i<font->n_properties; i++)
                   1165:          if (atom==font->properties[i].name) {
                   1166:                  _font_prop=font->properties[i].card32;
                   1167:                  *length=4;
                   1168:                  *size=32;
                   1169:                  return((char *) &_font_prop);
                   1170:          }
                   1171:        return(0);
                   1172: }
                   1173: 
                   1174: char *Get_Window_Property_Data_And_Type(atom, length, type, size)
                   1175:      Atom atom;
                   1176:      long *length;
                   1177:      Atom *type;
                   1178:      int *size;
                   1179: {
                   1180:        Atom actual_type;
                   1181:        int actual_format;
                   1182:        long nitems;
                   1183:        long bytes_after;
                   1184:        char *prop;
                   1185:        int status;
                   1186:        
                   1187:        status = XGetWindowProperty(dpy, target_win, atom, 0, (max_len+3)/4,
                   1188:                                    False, AnyPropertyType, &actual_type,
                   1189:                                    &actual_format, &nitems, &bytes_after,
                   1190:                                    &prop);
                   1191:        if (status==BadWindow)
                   1192:          Fatal_Error("window id # 0x%lx does not exists!", target_win);
                   1193:        if (status!=Success)
                   1194:          Fatal_Error("XGetWindowProperty failed!");
                   1195:        
                   1196:        *length = min(nitems * actual_format/8, max_len);
                   1197:        *type = actual_type;
                   1198:        *size = actual_format;
                   1199:        return(prop);
                   1200: }
                   1201: 
                   1202: char *Get_Property_Data_And_Type(atom, length, type, size)
                   1203:      Atom atom;
                   1204:      long *length;
                   1205:      Atom *type;
                   1206:      int *size;
                   1207: {
                   1208:        if (target_win == -1)
                   1209:          return(Get_Font_Property_Data_And_Type(atom, length, type, size));
                   1210:        else
                   1211:          return(Get_Window_Property_Data_And_Type(atom, length, type, size));
                   1212: }
                   1213: 
                   1214: Show_Prop(format, dformat, prop)
                   1215:      char *format, *dformat, *prop;
                   1216: {
                   1217:   char *data;
                   1218:   long length;
                   1219:   Atom atom, type;
                   1220:   thunk *thunks;
                   1221:   int size, fsize;
                   1222: 
                   1223:   printf("%s", prop);
                   1224:   if (!(atom = Parse_Atom(prop, True))) {
                   1225:          printf(": not defined.\n");
                   1226:          return;
                   1227:   }
                   1228: 
                   1229:   data = Get_Property_Data_And_Type(atom, &length, &type, &size);
                   1230:   if (!size) {
                   1231:           puts(": not defined.");
                   1232:          return;
                   1233:   }
                   1234: 
                   1235:   if (!notype && type)
                   1236:     printf("(%s)", Format_Atom(type));
                   1237: 
                   1238:   Lookup_Formats(atom, &format, &dformat);
                   1239:   if (type)
                   1240:     Lookup_Formats(type, &format, &dformat);
                   1241:   Apply_Default_Formats(&format, &dformat);
                   1242: 
                   1243:   fsize=Get_Format_Size(format);
                   1244:   if (fsize!=size && fsize!=0) {
                   1245:        printf(": Type mismatch: assumed size %d bits, actual size %d bits.\n",
                   1246:         fsize, size);
                   1247:          return;
                   1248:   }
                   1249: 
                   1250:   thunks = Break_Down_Property(data, length, format, size);
                   1251: 
                   1252:   Display_Property(thunks, dformat, format);
                   1253: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.