Annotation of researchv9/X11/src/X.V11R1/clients/xprop/xprop.c, revision 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.