From 824abd1d34428d5ad1d13364f69da4c4d3fe63f3 Mon Sep 17 00:00:00 2001 From: Kaleb Keithley Date: Mon, 17 Nov 2003 19:04:09 +0000 Subject: merge XFree86 4.3.0.1 to -CURRENT --- dsimple.c | 50 +- dsimple.h | 39 +- xprop.c | 2298 ++++++++++++++++++++++++++++++++++--------------------------- xprop.man | 25 +- 4 files changed, 1354 insertions(+), 1058 deletions(-) diff --git a/dsimple.c b/dsimple.c index 210d121..bbdbd93 100644 --- a/dsimple.c +++ b/dsimple.c @@ -26,25 +26,22 @@ other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/programs/xlsfonts/dsimple.c,v 3.6 2001/12/14 20:02:09 dawes Exp $ */ #include #include #include #include #include +#include +#include /* * Other_stuff.h: Definitions of routines in other_stuff. * * Written by Mark Lillibridge. Last updated 7/1/87 */ -unsigned long Resolve_Color(); -Pixmap Bitmap_To_Pixmap(); -Window Select_Window(); -void out(); -void blip(); -Window Window_With_Name(); -void Fatal_Error(); +#include "dsimple.h" /* * Just_display: A group of routines designed to make the writting of simple @@ -58,10 +55,11 @@ void Fatal_Error(); /* This stuff is defined in the calling program by just_display.h */ -extern char *program_name; -extern Display *dpy; -extern int screen; +char *program_name = "unknown_program"; +Display *dpy; +int screen; +static void _bitmap_error(int, char *); /* * Malloc: like malloc but handles out of memory using Fatal_Error. @@ -69,7 +67,7 @@ extern int screen; char *Malloc(size) unsigned size; { - char *data, *malloc(); + char *data; if (!(data = malloc(size))) Fatal_Error("Out of memory!"); @@ -85,7 +83,7 @@ char *Realloc(ptr, size) char *ptr; int size; { - char *new_ptr, *realloc(); + char *new_ptr; if (!ptr) return(Malloc(size)); @@ -326,9 +324,6 @@ Window Select_Window_Args(rargc, argv) * Written by Mark Lillibridge. Last updated 7/1/87 */ -extern Display *dpy; -extern int screen; - /* * Resolve_Color: This routine takes a color name and returns the pixel # * that when used in the window w will be of color name. @@ -402,7 +397,9 @@ Pixmap Bitmap_To_Pixmap(dpy, d, gc, bitmap, width, height) */ void blip() { - outl("blip!"); + fflush(stdout); + fprintf(stderr, "blip!\n"); + fflush(stderr); } @@ -493,13 +490,14 @@ Window Window_With_Name(dpy, top, name) * in code so we can tell where we are. Outl may be invoked like * printf with up to 7 arguments. */ -/* VARARGS1 */ -outl(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6) - char *msg; - char *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; +void +outl(char *msg, ...) { + va_list args; fflush(stdout); - fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); fprintf(stderr, "\n"); fflush(stderr); } @@ -509,15 +507,15 @@ outl(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6) * Standard fatal error routine - call like printf but maximum of 7 arguments. * Does not require dpy or screen defined. */ -/* VARARGS1 */ -void Fatal_Error(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6) -char *msg; -char *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; +void Fatal_Error(char *msg, ...) { + va_list args; fflush(stdout); fflush(stderr); fprintf(stderr, "%s: error: ", program_name); - fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); fprintf(stderr, "\n"); exit(1); } diff --git a/dsimple.h b/dsimple.h index a634848..a11cae7 100644 --- a/dsimple.h +++ b/dsimple.h @@ -26,6 +26,7 @@ other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/programs/xlsfonts/dsimple.h,v 1.8 2002/12/24 17:43:01 tsi Exp $ */ /* * Just_display.h: This file contains the definitions needed to use the @@ -40,16 +41,28 @@ from The Open Group. /* Global variables used by routines in just_display.c */ -char *program_name = "unknown_program"; /* Name of this program */ -Display *dpy; /* The current display */ -int screen; /* The current screen */ +extern char *program_name; /* Name of this program */ +extern Display *dpy; /* The current display */ +extern int screen; /* The current screen */ #define INIT_NAME program_name=argv[0] /* use this in main to setup program_name */ /* Declaritions for functions in just_display.c */ -void Fatal_Error(); +#if NeedFunctionPrototypes +char *Malloc(unsigned); +char *Realloc(char *, int); +char *Get_Display_Name(int *, char **); +Display *Open_Display(char *); +void Setup_Display_And_Screen(int *, char **); +XFontStruct *Open_Font(char *); +void Beep(void); +Pixmap ReadBitmapFile(Drawable, char *, int *, int *, int *, int *); +void WriteBitmapFile(char *, Pixmap, int, int, int, int); +Window Select_Window_Args(int *, char **); +void usage(void); +#else char *Malloc(); char *Realloc(); char *Get_Display_Name(); @@ -60,10 +73,11 @@ void Beep(); Pixmap ReadBitmapFile(); void WriteBitmapFile(); Window Select_Window_Args(); +void usage(); +#endif #define X_USAGE "[host:display]" /* X arguments handled by Get_Display_Name */ -#define SELECT_USAGE "[{-root|-id |-font |-name }]" /* * Other_stuff.h: Definitions of routines in other_stuff. @@ -73,9 +87,22 @@ Window Select_Window_Args(); * Send bugs, etc. to chariot@athena.mit.edu. */ +#if NeedFunctionPrototypes +unsigned long Resolve_Color(Window, char *); +Pixmap Bitmap_To_Pixmap(Display *, Drawable, GC, Pixmap, int, int); +Window Select_Window(Display *); +void blip(void); +Window Window_With_Name(Display *, Window, char *); +#else unsigned long Resolve_Color(); Pixmap Bitmap_To_Pixmap(); Window Select_Window(); -void out(); void blip(); Window Window_With_Name(); +#endif +#ifdef __GNUC__ +void Fatal_Error(char *, ...) __attribute__((__noreturn__)); +#else +void Fatal_Error(char *, ...); +#endif +void outl(char *, ...); diff --git a/xprop.c b/xprop.c index 0d8f32d..fbabda8 100644 --- a/xprop.c +++ b/xprop.c @@ -2,13 +2,14 @@ /* Copyright 1990, 1998 The Open Group +Copyright (c) 2000 The XFree86 Project, Inc. Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -26,29 +27,42 @@ other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/programs/xprop/xprop.c,v 1.12 2002/12/02 22:10:23 tsi Exp $ */ #include #include #include #include +#include #include #include +#ifdef HAS_WCHAR_H +#include +#endif +#ifdef HAS_WCTYPE_H +#include +#endif +#include + +#ifndef HAS_WCTYPE_H +#define iswprint(x) isprint(x) +#endif #include #include #include "dsimple.h" -#ifndef X_NOT_STDC_ENV -#include -#else -char *getenv(); -#endif - #define MAXSTR 10000 +#define MAXELEMENTS 64 +#ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +/* isprint() in "C" locale */ +#define c_isprint(c) ((c) >= 0x20 && (c) < 0x7f) /* * @@ -58,116 +72,188 @@ char *getenv(); typedef struct { int thunk_count; + const char *propname; long value; - char *extra_value; - char *format; - char *dformat; + Atom extra_encoding; + const char *extra_value; + const char *format; + const char *dformat; } thunk; -thunk *Create_Thunk_List() +static thunk * +Create_Thunk_List (void) { - thunk *tptr; + thunk *tptr; - tptr = (thunk *) Malloc( sizeof(thunk) ); + tptr = (thunk *) Malloc(sizeof(thunk)); - tptr->thunk_count = 0; + tptr->thunk_count = 0; - return(tptr); + return tptr; } -Free_Thunk_List(list) -thunk *list; +#ifdef notused +static void +Free_Thunk_List (thunk *list) { - free(list); + free(list); } +#endif -thunk *Add_Thunk(list, t) -thunk *list; -thunk t; +static thunk * +Add_Thunk (thunk *list, thunk t) { - int i; + int i; - i = list->thunk_count; + i = list->thunk_count; - list = (thunk *) realloc(list, (i+1)*sizeof(thunk) ); - if (!list) - Fatal_Error("Out of memory!"); + list = (thunk *) realloc(list, (i+1)*sizeof(thunk)); + if (!list) + Fatal_Error("Out of memory!"); - list[i++] = t; - list->thunk_count = i; + list[i++] = t; + list->thunk_count = i; - return(list); + return list; } /* * Misc. routines */ -char *Copy_String(string) - char *string; +static char * +Copy_String (const char *string) { - char *new; - int length; + char *new; + int length; - length = strlen(string) + 1; + length = strlen(string) + 1; - new = (char *) Malloc(length); - memmove( new, string, length); + new = (char *) Malloc(length); + memcpy(new, string, length); - return(new); + return new; } -int Read_Char(stream) - FILE *stream; +static int +Read_Char (FILE *stream) { - int c; + int c; - c = getc(stream); - if (c==EOF) - Fatal_Error("Bad format file: Unexpected EOF."); - return(c); + c = getc(stream); + if (c == EOF) + Fatal_Error("Bad format file: Unexpected EOF."); + return c; } -Read_White_Space(stream) - FILE *stream; +static void +Read_White_Space (FILE *stream) { - int c; + int c; - while ((c=getc(stream))==' ' || c=='\n' || c=='\t'); - ungetc(c, stream); + while ((c = getc(stream)) == ' ' || c == '\n' || c == '\t'); + ungetc(c, stream); } static char _large_buffer[MAXSTR+10]; -char *Read_Quoted(stream) - FILE *stream; +static char * +Read_Quoted (FILE *stream) { - char *ptr; - int c, length; + char *ptr; + int c, length; + + Read_White_Space(stream); + if (Read_Char(stream)!='\'') + Fatal_Error("Bad format file format: missing dformat."); + + ptr = _large_buffer; length = MAXSTR; + for (;;) { + if (length < 0) + Fatal_Error("Bad format file format: dformat too long."); + c = Read_Char(stream); + if (c == (int) '\'') + break; + ptr++[0] = c; length--; + if (c == (int) '\\') { + c = Read_Char(stream); + if (c == '\n') { + ptr--; length++; + } else + ptr++[0] = c; length--; + } + } + ptr++[0] = '\0'; - Read_White_Space(stream); - if (Read_Char(stream)!='\'') - Fatal_Error("Bad format file format: missing dformat."); + return Copy_String(_large_buffer); +} - ptr = _large_buffer; length=MAXSTR; - for (;;) { - if (length<0) - Fatal_Error("Bad format file format: dformat too long."); - c = Read_Char(stream); - if (c==(int) '\'') - break; - ptr++[0]=c; length--; - if (c== (int) '\\') { - c=Read_Char(stream); - if (c=='\n') { - ptr--; length++; - } else - ptr++[0]=c; length--; - } - } - ptr++[0]='\0'; +/* + * + * Parsing Routines: a group of routines to parse strings into values + * + * Routines: Parse_Atom, Scan_Long, Skip_Past_Right_Paren, Scan_Octal + * + * Routines of the form Parse_XXX take a string which is parsed to a value. + * Routines of the form Scan_XXX take a string, parse the beginning to a value, + * and return the rest of the string. The value is returned via. the last + * parameter. All numeric values are longs! + * + */ - return(Copy_String(_large_buffer)); +static const char * +Skip_Digits (const char *string) +{ + while (isdigit((unsigned char) string[0])) string++; + return string; +} + +static const char * +Scan_Long (const char *string, long *value) +{ + if (!isdigit((unsigned char) *string)) + Fatal_Error("Bad number: %s.", string); + + *value = atol(string); + return Skip_Digits(string); +} + +static const char * +Scan_Octal (const char *string, long *value) +{ + if (sscanf(string, "%lo", value)!=1) + Fatal_Error("Bad octal number: %s.", string); + return Skip_Digits(string); +} + +static Atom +Parse_Atom (const char *name, int only_if_exists) +{ + /* may return None = 0 */ + return XInternAtom(dpy, name, only_if_exists); +} + +static const char * +Skip_Past_Right_Paren (const char *string) +{ + char c; + int nesting = 0; + + while (c = string++[0], c != ')' || nesting) + switch (c) { + case '\0': + Fatal_Error("Missing ')'."); + case '(': + nesting++; + break; + case ')': + nesting--; + break; + case '\\': + string++; + break; + } + return string; } /* @@ -179,51 +265,46 @@ char *Read_Quoted(stream) #define D_FORMAT "0x" /* Default format for properties */ #define D_DFORMAT " = $0+\n" /* Default display pattern for properties */ -static thunk *_property_formats = 0; /* Holds mapping */ +static thunk *_property_formats = NULL; /* Holds mapping */ -Apply_Default_Formats(format, dformat) - char **format; - char **dformat; +static void +Apply_Default_Formats (const char **format, const char **dformat) { - if (!*format) - *format = D_FORMAT; - if (!*dformat) - *dformat = D_DFORMAT; + if (!*format) + *format = D_FORMAT; + if (!*dformat) + *dformat = D_DFORMAT; } - -Lookup_Formats(atom, format, dformat) - Atom atom; - char **format; - char **dformat; + +static void +Lookup_Formats (Atom atom, const char **format, const char **dformat) { - int i; - - if (_property_formats) - for (i=_property_formats->thunk_count-1; i>=0; i--) - if (_property_formats[i].value==atom) { - if (!*format) - *format = _property_formats[i].format; - if (!*dformat) - *dformat = _property_formats[i].dformat; - break; - } + int i; + + if (_property_formats) + for (i = _property_formats->thunk_count-1; i >= 0; i--) + if (_property_formats[i].value == atom) { + if (!*format) + *format = _property_formats[i].format; + if (!*dformat) + *dformat = _property_formats[i].dformat; + break; + } } -Add_Mapping(atom, format, dformat) - Atom atom; - char *format; - char *dformat; +static void +Add_Mapping (Atom atom, const char *format, const char *dformat) { - thunk t; + thunk t; - if (!_property_formats) - _property_formats = Create_Thunk_List(); + if (!_property_formats) + _property_formats = Create_Thunk_List(); - t.value=atom; - t.format=format; - t.dformat=dformat; + t.value = atom; + t.format = format; + t.dformat = dformat; - _property_formats = Add_Thunk(_property_formats, t); + _property_formats = Add_Thunk(_property_formats, t); } /* @@ -233,84 +314,84 @@ Add_Mapping(atom, format, dformat) */ typedef struct _propertyRec { - char * name; - Atom atom; - char * format; - char * dformat; + const char * name; + Atom atom; + const char * format; + const char * dformat; } propertyRec; -#define ARC_DFORMAT ":\n\ -\t\tarc at $0, $1\n\ -\t\tsize: $2 by $3\n\ -\t\tfrom angle $4 to angle $5\n" - -#define RECTANGLE_DFORMAT ":\n\ -\t\tupper left corner: $0, $1\n\ -\t\tsize: $2 by $3\n" - -#define RGB_COLOR_MAP_DFORMAT ":\n\ -\t\tcolormap id #: $0\n\ -\t\tred-max: $1\n\ -\t\tred-mult: $2\n\ -\t\tgreen-max: $3\n\ -\t\tgreen-mult: $4\n\ -\t\tblue-max: $5\n\ -\t\tblue-mult: $6\n\ -\t\tbase-pixel: $7\n\ -\t\tvisual id #: $8\n\ -\t\tkill id #: $9\n" - -#define WM_HINTS_DFORMAT ":\n\ -?m0(\t\tClient accepts input or input focus: $1\n)\ -?m1(\t\tInitial state is \ -?$2=0(Don't Care State)\ -?$2=1(Normal State)\ -?$2=2(Zoomed State)\ -?$2=3(Iconic State)\ -?$2=4(Inactive State)\ -.\n)\ -?m2(\t\tbitmap id # to use for icon: $3\n)\ -?m5(\t\tbitmap id # of mask for icon: $7\n)\ -?m3(\t\twindow id # to use for icon: $4\n)\ -?m4(\t\tstarting position for icon: $5, $6\n)\ -?m6(\t\twindow id # of group leader: $8\n)\ -?m8(\t\tThe visible hint bit is set\n)" - -#define WM_ICON_SIZE_DFORMAT ":\n\ -\t\tminimum icon size: $0 by $1\n\ -\t\tmaximum icon size: $2 by $3\n\ -\t\tincremental size change: $4 by $5\n" - -#define WM_SIZE_HINTS_DFORMAT ":\n\ -?m0(\t\tuser specified location: $1, $2\n)\ -?m2(\t\tprogram specified location: $1, $2\n)\ -?m1(\t\tuser specified size: $3 by $4\n)\ -?m3(\t\tprogram specified size: $3 by $4\n)\ -?m4(\t\tprogram specified minimum size: $5 by $6\n)\ -?m5(\t\tprogram specified maximum size: $7 by $8\n)\ -?m6(\t\tprogram specified resize increment: $9 by $10\n)\ -?m7(\t\tprogram specified minimum aspect ratio: $11/$12\n\ -\t\tprogram specified maximum aspect ratio: $13/$14\n)\ -?m8(\t\tprogram specified base size: $15 by $16\n)\ -?m9(\t\twindow gravity: \ -?$17=0(Forget)\ -?$17=1(NorthWest)\ -?$17=2(North)\ -?$17=3(NorthEast)\ -?$17=4(West)\ -?$17=5(Center)\ -?$17=6(East)\ -?$17=7(SouthWest)\ -?$17=8(South)\ -?$17=9(SouthEast)\ -?$17=10(Static)\ -\n)" - -#define WM_STATE_DFORMAT ":\n\ -\t\twindow state: ?$0=0(Withdrawn)?$0=1(Normal)?$0=3(Iconic)\n\ -\t\ticon window: $1\n" - -propertyRec windowPropTable[] = { +#define ARC_DFORMAT ":\n"\ +"\t\tarc at $0, $1\n"\ +"\t\tsize: $2 by $3\n"\ +"\t\tfrom angle $4 to angle $5\n" + +#define RECTANGLE_DFORMAT ":\n"\ +"\t\tupper left corner: $0, $1\n"\ +"\t\tsize: $2 by $3\n" + +#define RGB_COLOR_MAP_DFORMAT ":\n"\ +"\t\tcolormap id #: $0\n"\ +"\t\tred-max: $1\n"\ +"\t\tred-mult: $2\n"\ +"\t\tgreen-max: $3\n"\ +"\t\tgreen-mult: $4\n"\ +"\t\tblue-max: $5\n"\ +"\t\tblue-mult: $6\n"\ +"\t\tbase-pixel: $7\n"\ +"\t\tvisual id #: $8\n"\ +"\t\tkill id #: $9\n" + +#define WM_HINTS_DFORMAT ":\n"\ +"?m0(\t\tClient accepts input or input focus: $1\n)"\ +"?m1(\t\tInitial state is "\ +"?$2=0(Don't Care State)"\ +"?$2=1(Normal State)"\ +"?$2=2(Zoomed State)"\ +"?$2=3(Iconic State)"\ +"?$2=4(Inactive State)"\ +".\n)"\ +"?m2(\t\tbitmap id # to use for icon: $3\n)"\ +"?m5(\t\tbitmap id # of mask for icon: $7\n)"\ +"?m3(\t\twindow id # to use for icon: $4\n)"\ +"?m4(\t\tstarting position for icon: $5, $6\n)"\ +"?m6(\t\twindow id # of group leader: $8\n)"\ +"?m8(\t\tThe visible hint bit is set\n)" + +#define WM_ICON_SIZE_DFORMAT ":\n"\ +"\t\tminimum icon size: $0 by $1\n"\ +"\t\tmaximum icon size: $2 by $3\n"\ +"\t\tincremental size change: $4 by $5\n" + +#define WM_SIZE_HINTS_DFORMAT ":\n"\ +"?m0(\t\tuser specified location: $1, $2\n)"\ +"?m2(\t\tprogram specified location: $1, $2\n)"\ +"?m1(\t\tuser specified size: $3 by $4\n)"\ +"?m3(\t\tprogram specified size: $3 by $4\n)"\ +"?m4(\t\tprogram specified minimum size: $5 by $6\n)"\ +"?m5(\t\tprogram specified maximum size: $7 by $8\n)"\ +"?m6(\t\tprogram specified resize increment: $9 by $10\n)"\ +"?m7(\t\tprogram specified minimum aspect ratio: $11/$12\n"\ +"\t\tprogram specified maximum aspect ratio: $13/$14\n)"\ +"?m8(\t\tprogram specified base size: $15 by $16\n)"\ +"?m9(\t\twindow gravity: "\ +"?$17=0(Forget)"\ +"?$17=1(NorthWest)"\ +"?$17=2(North)"\ +"?$17=3(NorthEast)"\ +"?$17=4(West)"\ +"?$17=5(Center)"\ +"?$17=6(East)"\ +"?$17=7(SouthWest)"\ +"?$17=8(South)"\ +"?$17=9(SouthEast)"\ +"?$17=10(Static)"\ +"\n)" + +#define WM_STATE_DFORMAT ":\n"\ +"\t\twindow state: ?$0=0(Withdrawn)?$0=1(Normal)?$0=3(Iconic)\n"\ +"\t\ticon window: $1\n" + +static propertyRec windowPropTable[] = { {"ARC", XA_ARC, "16iiccii", ARC_DFORMAT }, {"ATOM", XA_ATOM, "32a", 0 }, {"BITMAP", XA_BITMAP, "32x", ": bitmap id # $0\n" }, @@ -330,7 +411,9 @@ propertyRec windowPropTable[] = { {"WM_COLORMAP_WINDOWS", 0, "32x", ": window id # $0+\n"}, {"WM_COMMAND", XA_WM_COMMAND, "8s", " = { $0+ }\n" }, {"WM_HINTS", XA_WM_HINTS, "32mbcxxiixx", WM_HINTS_DFORMAT }, - {"WM_ICON_SIZE", XA_WM_ICON_SIZE, "32cccccc", WM_ICON_SIZE_DFORMAT}, + {"WM_ICON_NAME", XA_WM_ICON_NAME, "8t", 0 }, + {"WM_ICON_SIZE", XA_WM_ICON_SIZE, "32cccccc", WM_ICON_SIZE_DFORMAT}, + {"WM_NAME", XA_WM_NAME, "8t", 0 }, {"WM_PROTOCOLS", 0, "32a", ": protocols $0+\n"}, {"WM_SIZE_HINTS", XA_WM_SIZE_HINTS,"32mii", WM_SIZE_HINTS_DFORMAT }, {"WM_STATE", 0, "32cx", WM_STATE_DFORMAT} @@ -346,69 +429,70 @@ propertyRec windowPropTable[] = { /* * Font-specific mapping of property names to types: */ -propertyRec fontPropTable[] = { +static propertyRec fontPropTable[] = { /* XLFD name properties */ - "FOUNDRY", 0, "32a", 0, - "FAMILY_NAME", XA_FAMILY_NAME, "32a", 0, - "WEIGHT_NAME", 0, "32a", 0, - "SLANT", 0, "32a", 0, - "SETWIDTH_NAME", 0, "32a", 0, - "ADD_STYLE_NAME", 0, "32a", 0, - "PIXEL_SIZE", 0, "32c", 0, - "POINT_SIZE", XA_POINT_SIZE, "32c", 0, - "RESOLUTION_X", 0, "32c", 0, - "RESOLUTION_Y", 0, "32c", 0, - "SPACING", 0, "32a", 0, - "AVERAGE_WIDTH", 0, "32c", 0, - "CHARSET_REGISTRY", 0, "32a", 0, - "CHARSET_ENCODING", 0, "32a", 0, + { "FOUNDRY", 0, "32a", 0 }, + { "FAMILY_NAME", XA_FAMILY_NAME, "32a", 0 }, + { "WEIGHT_NAME", 0, "32a", 0 }, + { "SLANT", 0, "32a", 0 }, + { "SETWIDTH_NAME", 0, "32a", 0 }, + { "ADD_STYLE_NAME", 0, "32a", 0 }, + { "PIXEL_SIZE", 0, "32c", 0 }, + { "POINT_SIZE", XA_POINT_SIZE, "32c", 0 }, + { "RESOLUTION_X", 0, "32c", 0 }, + { "RESOLUTION_Y", 0, "32c", 0 }, + { "SPACING", 0, "32a", 0 }, + { "AVERAGE_WIDTH", 0, "32c", 0 }, + { "CHARSET_REGISTRY", 0, "32a", 0 }, + { "CHARSET_ENCODING", 0, "32a", 0 }, /* other font properties referenced in the XLFD */ - "QUAD_WIDTH", XA_QUAD_WIDTH, "32i", 0, - "RESOLUTION", XA_RESOLUTION, "32c", 0, - "MIN_SPACE", XA_MIN_SPACE, "32c", 0, - "NORM_SPACE", XA_NORM_SPACE, "32c", 0, - "MAX_SPACE", XA_MAX_SPACE, "32c", 0, - "END_SPACE", XA_END_SPACE, "32c", 0, - "SUPERSCRIPT_X", XA_SUPERSCRIPT_X, "32i", 0, - "SUPERSCRIPT_Y", XA_SUPERSCRIPT_Y, "32i", 0, - "SUBSCRIPT_X", XA_SUBSCRIPT_X, "32i", 0, - "SUBSCRIPT_Y", XA_SUBSCRIPT_Y, "32i", 0, - "UNDERLINE_POSITION", XA_UNDERLINE_POSITION, "32i", 0, - "UNDERLINE_THICKNESS", XA_UNDERLINE_THICKNESS, "32i", 0, - "STRIKEOUT_ASCENT", XA_STRIKEOUT_ASCENT, "32i", 0, - "STRIKEOUT_DESCENT", XA_STRIKEOUT_DESCENT, "32i", 0, - "ITALIC_ANGLE", XA_ITALIC_ANGLE, "32i", 0, - "X_HEIGHT", XA_X_HEIGHT, "32i", 0, - "WEIGHT", XA_WEIGHT, "32i", 0, - "FACE_NAME", 0, "32a", 0, - "COPYRIGHT", XA_COPYRIGHT, "32a", 0, - "AVG_CAPITAL_WIDTH", 0, "32i", 0, - "AVG_LOWERCASE_WIDTH", 0, "32i", 0, - "RELATIVE_SETWIDTH", 0, "32c", 0, - "RELATIVE_WEIGHT", 0, "32c", 0, - "CAP_HEIGHT", XA_CAP_HEIGHT, "32c", 0, - "SUPERSCRIPT_SIZE", 0, "32c", 0, - "FIGURE_WIDTH", 0, "32i", 0, - "SUBSCRIPT_SIZE", 0, "32c", 0, - "SMALL_CAP_SIZE", 0, "32i", 0, - "NOTICE", XA_NOTICE, "32a", 0, - "DESTINATION", 0, "32c", 0, + { "QUAD_WIDTH", XA_QUAD_WIDTH, "32i", 0 }, + { "RESOLUTION", XA_RESOLUTION, "32c", 0 }, + { "MIN_SPACE", XA_MIN_SPACE, "32c", 0 }, + { "NORM_SPACE", XA_NORM_SPACE, "32c", 0 }, + { "MAX_SPACE", XA_MAX_SPACE, "32c", 0 }, + { "END_SPACE", XA_END_SPACE, "32c", 0 }, + { "SUPERSCRIPT_X", XA_SUPERSCRIPT_X, "32i", 0 }, + { "SUPERSCRIPT_Y", XA_SUPERSCRIPT_Y, "32i", 0 }, + { "SUBSCRIPT_X", XA_SUBSCRIPT_X, "32i", 0 }, + { "SUBSCRIPT_Y", XA_SUBSCRIPT_Y, "32i", 0 }, + { "UNDERLINE_POSITION", XA_UNDERLINE_POSITION, "32i", 0 }, + { "UNDERLINE_THICKNESS", XA_UNDERLINE_THICKNESS, "32i", 0 }, + { "STRIKEOUT_ASCENT", XA_STRIKEOUT_ASCENT, "32i", 0 }, + { "STRIKEOUT_DESCENT", XA_STRIKEOUT_DESCENT, "32i", 0 }, + { "ITALIC_ANGLE", XA_ITALIC_ANGLE, "32i", 0 }, + { "X_HEIGHT", XA_X_HEIGHT, "32i", 0 }, + { "WEIGHT", XA_WEIGHT, "32i", 0 }, + { "FACE_NAME", 0, "32a", 0 }, + { "COPYRIGHT", XA_COPYRIGHT, "32a", 0 }, + { "AVG_CAPITAL_WIDTH", 0, "32i", 0 }, + { "AVG_LOWERCASE_WIDTH", 0, "32i", 0 }, + { "RELATIVE_SETWIDTH", 0, "32c", 0 }, + { "RELATIVE_WEIGHT", 0, "32c", 0 }, + { "CAP_HEIGHT", XA_CAP_HEIGHT, "32c", 0 }, + { "SUPERSCRIPT_SIZE", 0, "32c", 0 }, + { "FIGURE_WIDTH", 0, "32i", 0 }, + { "SUBSCRIPT_SIZE", 0, "32c", 0 }, + { "SMALL_CAP_SIZE", 0, "32i", 0 }, + { "NOTICE", XA_NOTICE, "32a", 0 }, + { "DESTINATION", 0, "32c", 0 }, /* other font properties */ - "FONT", XA_FONT, "32a", 0, - "FONT_NAME", XA_FONT_NAME, "32a", 0, + { "FONT", XA_FONT, "32a", 0 }, + { "FONT_NAME", XA_FONT_NAME, "32a", 0 }, }; static int XpropMode; #define XpropWindowProperties 0 #define XpropFontProperties 1 -Setup_Mapping() +static void +Setup_Mapping (void) { int n; propertyRec *p; @@ -430,12 +514,12 @@ Setup_Mapping() } } -char *GetAtomName(atom) - Atom atom; +static const char * +GetAtomName (Atom atom) { int n; propertyRec *p; - + if (XpropMode == XpropWindowProperties) { n = sizeof(windowPropTable) / sizeof(propertyRec); p = windowPropTable; @@ -447,7 +531,7 @@ char *GetAtomName(atom) if (p->atom == atom) return p->name; - return (char *) NULL; + return NULL; } /* @@ -455,30 +539,30 @@ char *GetAtomName(atom) * already open for reading. */ -Read_Mappings(stream) - FILE *stream; +static void +Read_Mappings (FILE *stream) { - char format_buffer[100]; - char name[1000], *dformat, *format; - int count, c; - Atom atom, Parse_Atom(); - - while ((count=fscanf(stream," %990s %90s ",name,format_buffer))!=EOF) { - if (count != 2) - Fatal_Error("Bad format file format."); - - atom = Parse_Atom(name, False); - format = Copy_String(format_buffer); - - Read_White_Space(stream); - dformat = D_DFORMAT; - c = getc(stream); - ungetc(c, stream); - if (c==(int)'\'') - dformat = Read_Quoted(stream); - - Add_Mapping(atom, format, dformat); - } + char format_buffer[100]; + char name[1000], *dformat, *format; + int count, c; + Atom atom; + + while ((count = fscanf(stream," %990s %90s ",name,format_buffer)) != EOF) { + if (count != 2) + Fatal_Error("Bad format file format."); + + atom = Parse_Atom(name, False); + format = Copy_String(format_buffer); + + Read_White_Space(stream); + dformat = D_DFORMAT; + c = getc(stream); + ungetc(c, stream); + if (c == (int) '\'') + dformat = Read_Quoted(stream); + + Add_Mapping(atom, format, dformat); + } } /* @@ -494,239 +578,217 @@ Read_Mappings(stream) * */ static char _formatting_buffer[MAXSTR+100]; -static char _formatting_buffer2[10]; +static char _formatting_buffer2[21]; -char *Format_Hex(wrd) - long wrd; +static const char * +Format_Hex (long wrd) { - sprintf(_formatting_buffer2, "0x%lx", wrd); - return(_formatting_buffer2); + sprintf(_formatting_buffer2, "0x%lx", wrd); + return _formatting_buffer2; } -char *Format_Unsigned(wrd) - long wrd; +static const char * +Format_Unsigned (long wrd) { - sprintf(_formatting_buffer2, "%lu", wrd); - return(_formatting_buffer2); + sprintf(_formatting_buffer2, "%lu", wrd); + return _formatting_buffer2; } -char *Format_Signed(wrd) - long wrd; +static const char * +Format_Signed (long wrd) { - sprintf(_formatting_buffer2, "%ld", wrd); - return(_formatting_buffer2); + sprintf(_formatting_buffer2, "%ld", wrd); + return _formatting_buffer2; } /*ARGSUSED*/ -int ignore_errors (dpy, ev) - Display *dpy; - XErrorEvent *ev; +static int +ignore_errors (Display *dpy, XErrorEvent *ev) { return 0; } -char *Format_Atom(atom) - Atom atom; +static const char * +Format_Atom (Atom atom) { - char *name; - int (*handler)(); - - if ((name = GetAtomName(atom))) { - strncpy(_formatting_buffer, name, MAXSTR); - return(_formatting_buffer); - } - - handler = XSetErrorHandler (ignore_errors); - name=XGetAtomName(dpy, atom); - XSetErrorHandler(handler); - if (! name) - sprintf(_formatting_buffer, "undefined atom # 0x%lx", atom); - else { - strncpy(_formatting_buffer, name, MAXSTR); - XFree(name); - } - return(_formatting_buffer); + const char *found; + char *name; + XErrorHandler handler; + + if ((found = GetAtomName(atom)) != NULL) + return found; + + handler = XSetErrorHandler (ignore_errors); + name = XGetAtomName(dpy, atom); + XSetErrorHandler(handler); + if (! name) + sprintf(_formatting_buffer, "undefined atom # 0x%lx", atom); + else { + int namelen = strlen(name); + if (namelen > MAXSTR) namelen = MAXSTR; + memcpy(_formatting_buffer, name, namelen); + _formatting_buffer[namelen] = '\0'; + XFree(name); + } + return _formatting_buffer; } -char *Format_Mask_Word(wrd) - long wrd; +static const char * +Format_Mask_Word (long wrd) { - long bit_mask, bit; - int seen = 0; - - strcpy(_formatting_buffer, "{MASK: "); - for (bit=0, bit_mask=1; bit<=sizeof(long)*8; bit++, bit_mask<<=1) { - if (bit_mask & wrd) { - if (seen) { - strcat(_formatting_buffer, ", "); - } - seen=1; - strcat(_formatting_buffer, Format_Unsigned(bit)); + long bit_mask, bit; + int seen = 0; + + strcpy(_formatting_buffer, "{MASK: "); + for (bit=0, bit_mask=1; bit <= sizeof(long)*8; bit++, bit_mask<<=1) { + if (bit_mask & wrd) { + if (seen) { + strcat(_formatting_buffer, ", "); + } + seen = 1; + strcat(_formatting_buffer, Format_Unsigned(bit)); + } } - } - strcat(_formatting_buffer, "}"); + strcat(_formatting_buffer, "}"); - return(_formatting_buffer); + return _formatting_buffer; } -char *Format_Bool(value) - long value; +static const char * +Format_Bool (long value) { - if (!value) - return("False"); + if (!value) + return "False"; - return("True"); + return "True"; } static char *_buf_ptr; static int _buf_len; -_put_char(c) - char c; +static void +_put_char (char c) { - if (--_buf_len<0) { - _buf_ptr[0]='\0'; - return; - } - _buf_ptr++[0] = c; + if (--_buf_len < 0) { + _buf_ptr[0] = '\0'; + return; + } + _buf_ptr++[0] = c; } -_format_char(c) - char c; +static void +_format_char (char c) { - switch (c) { - case '\\': - case '\"': - _put_char('\\'); - _put_char(c); - break; - case '\n': - _put_char('\\'); - _put_char('n'); - break; - case '\t': - _put_char('\\'); - _put_char('t'); - break; - default: - if (!isprint (c)) { - _put_char('\\'); - sprintf(_buf_ptr, "%o", (int) c); - _buf_ptr += strlen(_buf_ptr); - _buf_len -= strlen(_buf_ptr); - } else - _put_char(c); - } + switch (c) { + case '\\': + case '\"': + _put_char('\\'); + _put_char(c); + break; + case '\n': + _put_char('\\'); + _put_char('n'); + break; + case '\t': + _put_char('\\'); + _put_char('t'); + break; + default: + if (!c_isprint(c)) { + _put_char('\\'); + sprintf(_buf_ptr, "%03o", (unsigned char) c); + _buf_ptr += 3; + _buf_len -= 3; + } else + _put_char(c); + } } -char *Format_String(string) - char *string; +static const char * +Format_String (const char *string) { - char c; + char c; - _buf_ptr = _formatting_buffer; - _buf_len = MAXSTR; - _put_char('\"'); + _buf_ptr = _formatting_buffer; + _buf_len = MAXSTR; + _put_char('\"'); - while ((c = string++[0])) - _format_char(c); + while ((c = string++[0])) + _format_char(c); - _buf_len += 3; - _put_char('\"'); - _put_char('\0'); - return(_formatting_buffer); + *_buf_ptr++ = '"'; + *_buf_ptr++ = '\0'; + return _formatting_buffer; } -char *Format_Len_String(string, len) - char *string; - int len; +static const char * +Format_Len_String (const char *string, int len) { - char *data, *result; + char *data; + const char *result; - data = (char *) Malloc(len+1); + data = (char *) Malloc(len+1); - memmove( data, string, len); - data[len]='\0'; + memcpy(data, string, len); + data[len] = '\0'; - result = Format_String(data); - free(data); + result = Format_String(data); + free(data); - return(result); + return result; } -/* - * - * Parsing Routines: a group of routines to parse strings into values - * - * Routines: Parse_Atom, Scan_Long, Skip_Past_Right_Paran, Scan_Octal - * - * Routines of the form Parse_XXX take a string which is parsed to a value. - * Routines of the form Scan_XXX take a string, parse the beginning to a value, - * and return the rest of the string. The value is returned via. the last - * parameter. All numeric values are longs! - * - */ - -char *Skip_Digits(string) - char *string; -{ - while (isdigit(string[0])) string++; - return(string); -} - -char *Scan_Long(string, value) - char *string; - long *value; -{ - if (!isdigit(*string)) - Fatal_Error("Bad number: %s.", string); - - *value = atol(string); - return(Skip_Digits(string)); -} - -char *Scan_Octal(string, value) - char *string; - long *value; -{ - if (sscanf(string, "%lo", value)!=1) - Fatal_Error("Bad octal number: %s.", string); - return(Skip_Digits(string)); -} - -Atom Parse_Atom(name, only_if_exists) - char *name; - int only_if_exists; -{ - Atom atom; - - if ((atom = XInternAtom(dpy, name, only_if_exists))==None) - return(0); - - return(atom); -} - -char *Skip_Past_Right_Paran(string) - char *string; +static const char * +Format_Len_Text (const char *string, int len, Atom encoding) { - char c; - int nesting=0; - - while (c=string++[0], c!=')' || nesting) - switch (c) { - case '\0': - Fatal_Error("Missing ')'."); - case '(': - nesting++; - break; - case ')': - nesting--; - break; - case '\\': - string++; - break; - } - return(string); + XTextProperty textprop; + char **list; + int count; + + /* Try to convert to local encoding. */ + textprop.encoding = encoding; + textprop.format = 8; + textprop.value = (unsigned char *) string; + textprop.nitems = len; + if (XmbTextPropertyToTextList(dpy, &textprop, &list, &count) == Success) { + _buf_ptr = _formatting_buffer; + _buf_len = MAXSTR; + *_buf_ptr++ = '"'; + while (count > 0) { + string = *list++; + len = strlen(string); + while (len > 0) { + wchar_t wc; + int n = mbtowc(&wc, string, len); + if (n > 0 && iswprint(wc)) { + if (_buf_len >= n) { + memcpy(_buf_ptr, string, n); + _buf_ptr += n; + _buf_len -= n; + } + string += n; + len -= n; + } else { + _put_char('\\'); + sprintf(_buf_ptr, "%03o", (unsigned char) *string); + _buf_ptr += 3; + _buf_len -= 3; + string++; + len--; + } + } + count--; + if (count > 0) { + sprintf(_buf_ptr, "\\000"); + _buf_ptr += 4; + _buf_len -= 4; + } + } + *_buf_ptr++ = '"'; + *_buf_ptr++ = '\0'; + return _formatting_buffer; + } else + return Format_Len_String(string, len); } /* @@ -735,92 +797,89 @@ char *Skip_Past_Right_Paran(string) * */ -int Is_A_Format(string) -char *string; +static int +Is_A_Format (const char *string) { - return(isdigit(string[0])); + return isdigit((unsigned char) string[0]); } -int Get_Format_Size(format) - char *format; +static int +Get_Format_Size (const char *format) { - long size; + long size; - Scan_Long(format, &size); + Scan_Long(format, &size); - /* Check for legal sizes */ - if (size != 0 && size != 8 && size != 16 && size != 32) - Fatal_Error("bad format: %s", format); + /* Check for legal sizes */ + if (size != 0 && size != 8 && size != 16 && size != 32) + Fatal_Error("bad format: %s", format); - return((int) size); + return (int) size; } -char Get_Format_Char(format, i) - char *format; - int i; +static char +Get_Format_Char (const char *format, int i) { - long size; + long size; - /* Remove # at front of format */ - format = Scan_Long(format, &size); - if (!*format) - Fatal_Error("bad format: %s", format); + /* Remove # at front of format */ + format = Scan_Long(format, &size); + if (!*format) + Fatal_Error("bad format: %s", format); - /* Last character repeats forever... */ - if (i >= (int)strlen(format)) - i=strlen(format)-1; + /* Last character repeats forever... */ + if (i >= (int)strlen(format)) + i = strlen(format)-1; - return(format[i]); + return format[i]; } -char *Format_Thunk(t, format_char) - thunk t; - char format_char; +static const char * +Format_Thunk (thunk t, char format_char) { - long value; - value = t.value; - - switch (format_char) { - case 's': - return(Format_Len_String(t.extra_value, (int)t.value)); - case 'x': - return(Format_Hex(value)); - case 'c': - return(Format_Unsigned(value)); - case 'i': - return(Format_Signed(value)); - case 'b': - return(Format_Bool(value)); - case 'm': - return(Format_Mask_Word(value)); - case 'a': - return(Format_Atom(value)); - default: - Fatal_Error("bad format character: %c", format_char); - } + long value; + value = t.value; + + switch (format_char) { + case 's': + return Format_Len_String(t.extra_value, (int)t.value); + case 't': + return Format_Len_Text(t.extra_value, (int)t.value, t.extra_encoding); + case 'x': + return Format_Hex(value); + case 'c': + return Format_Unsigned(value); + case 'i': + return Format_Signed(value); + case 'b': + return Format_Bool(value); + case 'm': + return Format_Mask_Word(value); + case 'a': + return Format_Atom(value); + default: + Fatal_Error("bad format character: %c", format_char); + } } -char *Format_Thunk_I(thunks, format, i) - thunk *thunks; - char *format; - int i; +static const char * +Format_Thunk_I (thunk *thunks, const char *format, int i) { - if (i >= thunks->thunk_count) - return(""); + if (i >= thunks->thunk_count) + return ""; - return(Format_Thunk(thunks[i], Get_Format_Char(format, i))); + return Format_Thunk(thunks[i], Get_Format_Char(format, i)); } -long Mask_Word(thunks, format) - thunk *thunks; - char *format; +static long +Mask_Word (thunk *thunks, const char *format) { - int j; + int j; - for (j=0; j<(int)strlen(format); j++) - if (Get_Format_Char(format, j) == 'm') - return(thunks[j].value); - return(0L); + for (j = 0; j < (int)strlen(format); j++) + if (Get_Format_Char(format, j) == 'm') + return thunks[j].value; + return 0; } /* @@ -829,166 +888,156 @@ long Mask_Word(thunks, format) * */ -int Is_A_DFormat(string) - char *string; +static int +Is_A_DFormat (const char *string) { - return( string[0] && string[0] != '-' && - !(isalpha(string[0]) || string[0] == '_') ); + return string[0] && string[0] != '-' + && !(isalpha((unsigned char) string[0]) || string[0] == '_'); } -char *Handle_Backslash(dformat) - char *dformat; +static const char * +Handle_Backslash (const char *dformat) { - char c; - long i; + char c; + long i; - if (!(c = *(dformat++))) - return(dformat); + if (!(c = *(dformat++))) + return dformat; - switch (c) { - case 'n': - putchar('\n'); - break; - case 't': - putchar('\t'); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - dformat = Scan_Octal(dformat, &i); - putchar((int) i); - break; - default: - putchar(c); - break; - } - return(dformat); + switch (c) { + case 'n': + putchar('\n'); + break; + case 't': + putchar('\t'); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + dformat = Scan_Octal(dformat, &i); + putchar((int) i); + break; + default: + putchar(c); + break; + } + return dformat; } -char *Handle_Dollar_sign(dformat, thunks, format) - char *dformat; - thunk *thunks; - char *format; +static const char * +Handle_Dollar_sign (const char *dformat, thunk *thunks, const char *format) { - long i; - - dformat = Scan_Long(dformat, &i); - - if (dformat[0]=='+') { - int seen=0; - dformat++; - for (; ithunk_count; i++) { - if (seen) - printf(", "); - seen = 1; - printf("%s", Format_Thunk_I(thunks, format, (int) i)); - } - } else - printf("%s", Format_Thunk_I(thunks, format, (int) i)); + long i; + + dformat = Scan_Long(dformat, &i); + + if (dformat[0] == '+') { + int seen = 0; + dformat++; + for (; i < thunks->thunk_count; i++) { + if (seen) + printf(", "); + seen = 1; + printf("%s", Format_Thunk_I(thunks, format, (int) i)); + } + } else + printf("%s", Format_Thunk_I(thunks, format, (int) i)); - return(dformat); + return dformat; } -int Mask_Bit_I(thunks, format, i) - thunk *thunks; - char *format; - int i; +static int +Mask_Bit_I (thunk *thunks, const char *format, int i) { - long value; + long value; - value = Mask_Word(thunks, format); + value = Mask_Word(thunks, format); - value = value & (1L<=thunks->thunk_count) - i=thunks->thunk_count; - *value = thunks[i].value; - } else if (*string=='m') { - string = Scan_Long(++string, &i); - *value = Mask_Bit_I(thunks, format, (int) i); - } else - Fatal_Error("Bad term: %s.", string); - - return(string); + long i; + + *value = 0; + + if (isdigit((unsigned char) *string)) + string = Scan_Long(string, value); + else if (*string == '$') { + string = Scan_Long(++string, &i); + if (i >= thunks->thunk_count) + i = thunks->thunk_count; + *value = thunks[i].value; + } else if (*string == 'm') { + string = Scan_Long(++string, &i); + *value = Mask_Bit_I(thunks, format, (int) i); + } else + Fatal_Error("Bad term: %s.", string); + + return string; } -char *Scan_Exp(string, thunks, format, value) - thunk *thunks; - char *string, *format; - long *value; +static const char * +Scan_Exp (const char *string, thunk *thunks, const char *format, long *value) { - long temp; + long temp; - if (string[0]=='(') { - string = Scan_Exp(++string, thunks, format, value); - if (string[0]!=')') - Fatal_Error("Missing ')'"); - return(++string); - } - if (string[0]=='!') { - string = Scan_Exp(++string, thunks, format, value); - *value = !*value; - return(string); - } + if (string[0] == '(') { + string = Scan_Exp(++string, thunks, format, value); + if (string[0]!=')') + Fatal_Error("Missing ')'"); + return ++string; + } + if (string[0] == '!') { + string = Scan_Exp(++string, thunks, format, value); + *value = !*value; + return string; + } - string = Scan_Term(string, thunks, format, value); + string = Scan_Term(string, thunks, format, value); - if (string[0]=='=') { - string = Scan_Exp(++string, thunks, format, &temp); - *value = *value == temp; - } + if (string[0] == '=') { + string = Scan_Exp(++string, thunks, format, &temp); + *value = *value == temp; + } - return(string); + return string; } -char *Handle_Question_Mark(dformat, thunks, format) - thunk *thunks; - char *dformat, *format; +static const char * +Handle_Question_Mark (const char *dformat, thunk *thunks, const char *format) { - long true; + long true; - dformat = Scan_Exp(dformat, thunks, format, &true); + dformat = Scan_Exp(dformat, thunks, format, &true); - if (*dformat!='(') - Fatal_Error("Bad conditional: '(' expected: %s.", dformat); - ++dformat; + if (*dformat != '(') + Fatal_Error("Bad conditional: '(' expected: %s.", dformat); + ++dformat; - if (!true) - dformat = Skip_Past_Right_Paran(dformat); + if (!true) + dformat = Skip_Past_Right_Paren(dformat); - return(dformat); + return dformat; } -Display_Property(thunks, dformat, format) - thunk *thunks; - char *dformat, *format; +static void +Display_Property (thunk *thunks, const char *dformat, const char *format) { - char c; + char c; - while ((c = *(dformat++))) - switch (c) { + while ((c = *(dformat++))) + switch (c) { case ')': continue; case '\\': @@ -1003,88 +1052,454 @@ Display_Property(thunks, dformat, format) default: putchar(c); continue; - } + } } /* * - * Routines to convert property data to and from thunks + * Routines to convert property data to thunks * */ -long Extract_Value(pointer, length, size, signedp) - char **pointer; - int *length; - int size; +static long +Extract_Value (const char **pointer, int *length, int size, int signedp) { - long value, mask; + long value; - switch (size) { - case 8: - value = (long) * (char *) *pointer; - *pointer += 1; - *length -= 1; - mask = 0xff; - break; - case 16: - value = (long) * (short *) *pointer; - *pointer += sizeof(short); - *length -= sizeof(short); - mask = 0xffff; - break; - default: - /* Error */ - case 32: - value = (long) * (long *) *pointer; - *pointer += sizeof(long); - *length -= sizeof(long); - mask = 0xffffffff; - break; + switch (size) { + case 8: + if (signedp) + value = * (const signed char *) *pointer; + else + value = * (const unsigned char *) *pointer; + *pointer += 1; + *length -= 1; + break; + case 16: + if (signedp) + value = * (const short *) *pointer; + else + value = * (const unsigned short *) *pointer; + *pointer += sizeof(short); + *length -= sizeof(short); + break; + case 32: + if (signedp) + value = * (const long *) *pointer; + else + value = * (const unsigned long *) *pointer & 0xffffffff; + *pointer += sizeof(long); + *length -= sizeof(long); + break; + default: + abort(); + } + return value; +} + +static long +Extract_Len_String (const char **pointer, int *length, int size, const char **string) +{ + int len; + + if (size != 8) + Fatal_Error("can't use format character 's' with any size except 8."); + len = 0; *string = *pointer; + while ((len++, --*length, *((*pointer)++)) && *length>0); + + return len; +} + +static thunk * +Break_Down_Property (const char *pointer, int length, Atom type, const char *format, int size) +{ + thunk *thunks; + thunk t; + int i; + char format_char; + + thunks = Create_Thunk_List(); + i = 0; + + while (length >= size/8) { + format_char = Get_Format_Char(format, i); + if (format_char == 's') + t.value = Extract_Len_String(&pointer,&length,size,&t.extra_value); + else if (format_char == 't') { + t.extra_encoding = type; + t.value = Extract_Len_String(&pointer,&length,size,&t.extra_value); + } else + t.value = Extract_Value(&pointer,&length,size,format_char=='i'); + thunks = Add_Thunk(thunks, t); + i++; + } + + return thunks; +} + +/* + * Variables set by main() + */ + +static Window target_win = 0; +static int notype = 0; +static int max_len = MAXSTR; +static XFontStruct *font; +static unsigned long _font_prop; + +/* + * + * Other Stuff (temp.): + * + */ + +static const char * +Get_Font_Property_Data_And_Type (Atom atom, + long *length, Atom *type, int *size) +{ + int i; + + *type = None; + + for (i = 0; i < font->n_properties; i++) + if (atom == font->properties[i].name) { + _font_prop = font->properties[i].card32; + *length = sizeof(long); + *size = 32; + return (const char *) &_font_prop; } - if (!signedp) - value &= mask; - return(value); + *size = 0; + return NULL; +} + +static const char * +Get_Window_Property_Data_And_Type (Atom atom, + long *length, Atom *type, int *size) +{ + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long nbytes; + unsigned long bytes_after; + unsigned char *prop; + int status; + + status = XGetWindowProperty(dpy, target_win, atom, 0, (max_len+3)/4, + False, AnyPropertyType, &actual_type, + &actual_format, &nitems, &bytes_after, + &prop); + if (status == BadWindow) + Fatal_Error("window id # 0x%lx does not exists!", target_win); + if (status != Success) + Fatal_Error("XGetWindowProperty failed!"); + + if (actual_format == 32) + nbytes = sizeof(long); + else if (actual_format == 16) + nbytes = sizeof(short); + else if (actual_format == 8) + nbytes = 1; + else + abort(); + *length = min(nitems * nbytes, max_len); + *type = actual_type; + *size = actual_format; + return (const char *)prop; } -long Extract_Len_String(pointer, length, size, string) - char **pointer; - int *length; - int size; - char **string; +static const char * +Get_Property_Data_And_Type (Atom atom, long *length, Atom *type, int *size) { - int len; + if (target_win == -1) + return Get_Font_Property_Data_And_Type(atom, length, type, size); + else + return Get_Window_Property_Data_And_Type(atom, length, type, size); +} + +static void +Show_Prop (const char *format, const char *dformat, const char *prop) +{ + const char *data; + long length; + Atom atom, type; + thunk *thunks; + int size, fsize; + + printf("%s", prop); + atom = Parse_Atom(prop, True); + if (atom == None) { + printf(": no such atom on any window.\n"); + return; + } + + data = Get_Property_Data_And_Type(atom, &length, &type, &size); + if (!size) { + puts(": not found."); + return; + } + + if (!notype && type != None) + printf("(%s)", Format_Atom(type)); + + Lookup_Formats(atom, &format, &dformat); + if (type != None) + Lookup_Formats(type, &format, &dformat); + Apply_Default_Formats(&format, &dformat); + + fsize = Get_Format_Size(format); + if (fsize != size && fsize != 0) { + printf(": Type mismatch: assumed size %d bits, actual size %d bits.\n", + fsize, size); + return; + } + + thunks = Break_Down_Property(data, (int)length, type, format, size); - if (size!=8) - Fatal_Error("can't use format character 's' with any size except 8."); - len=0; *string = *pointer; - while ((len++, --*length, *((*pointer)++)) && *length>0); + Display_Property(thunks, dformat, format); +} - return(len); +static void +Show_All_Props (void) +{ + Atom *atoms, atom; + const char *name; + int count, i; + + if (target_win != -1) { + atoms = XListProperties(dpy, target_win, &count); + for (i = 0; i < count; i++) { + name = Format_Atom(atoms[i]); + Show_Prop(NULL, NULL, name); + } + } else + for (i = 0; i < font->n_properties; i++) { + atom = font->properties[i].name; + name = Format_Atom(atom); + Show_Prop(NULL, NULL, name); + } } -thunk *Break_Down_Property(pointer, length, format, size) - char *pointer, *format; - int length, size; +static thunk * +Handle_Prop_Requests (int argc, char **argv) { - thunk *thunks; - thunk t; - int i; - char format_char; - - thunks = Create_Thunk_List(); - i=0; - - while (length>=(size/8)) { - format_char = Get_Format_Char(format, i); - if (format_char=='s') - t.value=Extract_Len_String(&pointer,&length,size,&t.extra_value); - else - t.value=Extract_Value(&pointer,&length,size,format_char=='i'); + char *format, *dformat, *prop; + thunk *thunks, t; + + thunks = Create_Thunk_List(); + + /* if no prop referenced, by default list all properties for given window */ + if (!argc) { + Show_All_Props(); + return NULL; + } + + while (argc > 0) { + format = NULL; + dformat = NULL; + + /* Get overriding formats, if any */ + if (Is_A_Format(argv[0])) { + format = argv++[0]; argc--; + if (!argc) usage(); + } + if (Is_A_DFormat(argv[0])) { + dformat = argv++[0]; argc--; + if (!argc) usage(); + } + + /* Get property name */ + prop = argv++[0]; argc--; + + t.propname = prop; + t.value = Parse_Atom(prop, True); + t.format = format; + t.dformat = dformat; + if (t.value) thunks = Add_Thunk(thunks, t); - i++; - } + Show_Prop(format, dformat, prop); + } + return thunks; +} + +static void +Remove_Property (Display *dpy, Window w, const char *propname) +{ + Atom id = XInternAtom (dpy, propname, True); - return(thunks); + if (id == None) { + fprintf (stderr, "%s: no such property \"%s\"\n", + program_name, propname); + return; + } + XDeleteProperty (dpy, w, id); +} + +static void +Set_Property (Display *dpy, Window w, const char *propname, const char *value) +{ + Atom atom; + const char *format; + const char *dformat; + int size; + char format_char; + Atom type = 0; + unsigned char *data = NULL; + int nelements = 0; + + atom = Parse_Atom(propname, False); + + format = dformat = NULL; + Lookup_Formats(atom, &format, &dformat); + if (format == NULL) + Fatal_Error("unsupported conversion for %s", propname); + + size = Get_Format_Size(format); + + format_char = Get_Format_Char(format, 0); + switch (format_char) { + case 's': + if (size != 8) + Fatal_Error("can't use format character 's' with any size except 8."); + type = XA_STRING; + data = (unsigned char *) value; + nelements = strlen(value); + break; + case 't': { + XTextProperty textprop; + if (size != 8) + Fatal_Error("can't use format character 't' with any size except 8."); + if (XmbTextListToTextProperty(dpy, (char **) &value, 1, + XStdICCTextStyle, &textprop) != Success) { + fprintf(stderr, "cannot convert %s argument to STRING or COMPOUND_TEXT.\n", propname); + return; + } + type = textprop.encoding; + data = textprop.value; + nelements = textprop.nitems; + break; + } + case 'x': + case 'c': { + static unsigned char data8[MAXELEMENTS]; + static unsigned short data16[MAXELEMENTS]; + static unsigned long data32[MAXELEMENTS]; + unsigned long intvalue; + unsigned char * value2 = strdup(value); + unsigned char * tmp = strtok(value2,","); + nelements = 1; + intvalue = strtoul(tmp, NULL, 0); + switch(size) { + case 8: + data8[0] = intvalue; data = (unsigned char *) data8; break; + case 16: + data16[0] = intvalue; data = (unsigned char *) data16; break; + case 32: + data32[0] = intvalue; data = (unsigned char *) data32; break; + } + tmp = strtok(NULL,","); + while(tmp != NULL){ + intvalue = strtoul(tmp, NULL,0); + switch(size) { + case 8: + data8[nelements] = intvalue; break; + case 16: + data16[nelements] = intvalue; break; + case 32: + data32[nelements] = intvalue; break; + } + nelements++; + if(nelements == MAXELEMENTS){ + fprintf(stderr, "Maximum number of elements reached (%d). List truncated.\n",MAXELEMENTS); + break; + } + tmp = strtok(NULL,","); + } + + type = XA_CARDINAL; + free(value2); + break; + } + case 'i': { + static unsigned char data8[MAXELEMENTS]; + static unsigned short data16[MAXELEMENTS]; + static unsigned long data32[MAXELEMENTS]; + unsigned long intvalue; + unsigned char * value2 = strdup(value); + unsigned char * tmp = strtok(value2,","); + nelements = 1; + intvalue = strtoul(tmp, NULL, 0); + switch(size) { + case 8: + data8[0] = intvalue; data = (unsigned char *) data8; break; + case 16: + data16[0] = intvalue; data = (unsigned char *) data16; break; + case 32: + data32[0] = intvalue; data = (unsigned char *) data32; break; + } + tmp = strtok(NULL,","); + while(tmp != NULL){ + intvalue = strtoul(tmp, NULL,0); + switch(size) { + case 8: + data8[nelements] = intvalue; break; + case 16: + data16[nelements] = intvalue; break; + case 32: + data32[nelements] = intvalue; break; + } + nelements++; + if(nelements == MAXELEMENTS){ + fprintf(stderr, "Maximum number of elements reached (%d). List truncated.\n",MAXELEMENTS); + break; + } + tmp = strtok(NULL,","); + } + + type = XA_INTEGER; + free(value2); + break; + } + case 'b': { + unsigned long boolvalue; + static unsigned char data8; + static unsigned short data16; + static unsigned long data32; + if (!strcmp(value, "True")) + boolvalue = 1; + else if (!strcmp(value, "False")) + boolvalue = 0; + else { + fprintf(stderr, "cannot convert %s argument to Bool\n", propname); + return; + } + type = XA_INTEGER; + switch (size) { + case 8: + data8 = boolvalue; data = (unsigned char *) &data8; break; + case 16: + data16 = boolvalue; data = (unsigned char *) &data16; break; + case 32: default: + data32 = boolvalue; data = (unsigned char *) &data32; break; + } + nelements = 1; + break; + } + case 'a': { + static Atom avalue; + avalue = Parse_Atom(value, False); + type = XA_ATOM; + data = (unsigned char *) &avalue; + nelements = 1; + break; + } + case 'm': + /* NYI */ + default: + Fatal_Error("bad format character: %c", format_char); + } + + XChangeProperty(dpy, target_win, atom, type, size, PropModeReplace, + data, nelements); } /* @@ -1093,7 +1508,8 @@ thunk *Break_Down_Property(pointer, length, format, size) * */ -usage() +void +usage (void) { char **cpp; static char *help_message[] = { @@ -1103,7 +1519,8 @@ usage() " -id id resource id of window to examine", " -name name name of window to examine", " -font name name of font to examine", -" -remove propname name of property to remove", +" -remove propname remove a property", +" -set propname value set a property to a given value", " -root examine the root window", " -len n display at most n bytes of any property", " -notype do not display the type field", @@ -1114,7 +1531,8 @@ usage() NULL}; fflush (stdout); - fprintf (stderr, "usage: %s [-options ...] [[format [dformat]] atom]\n\n", + fprintf (stderr, + "usage: %s [-options ...] [[format [dformat]] atom] ...\n\n", program_name); for (cpp = help_message; *cpp; cpp++) { fprintf (stderr, "%s\n", *cpp); @@ -1123,17 +1541,20 @@ NULL}; exit (1); } -grammar () +static void +grammar (void) { - printf ("Grammar for xprop:\n\n"); - printf("\t%s [] []