diff options
author | Roland Mainz <roland.mainz@nrubsig.org> | 2005-01-03 01:06:35 +0000 |
---|---|---|
committer | Roland Mainz <roland.mainz@nrubsig.org> | 2005-01-03 01:06:35 +0000 |
commit | 3865cb4a0fbfaab9839f496b0466596872c6be5e (patch) | |
tree | 3783d601b3bbe6c7c011fc5cf37f2ab26aa9c09d | |
parent | 715f625d68e0403b7024b7dcc61bf6bcf73cc0ac (diff) |
xc/lib/XprintAppUtil/xpapputil.csco_port_update-baseXORG-6_8_99_903XORG-6_8_99_902XORG-6_8_99_901XORG-6_8_99_900XORG-6_8_99_9XORG-6_8_99_8XORG-6_8_99_7XORG-6_8_99_6XORG-6_8_99_5XORG-6_8_99_4XORG-6_8_99_3XORG-6_8_99_2XORG-6_8_99_16XORG-6_8_99_15XORG-6_8_99_14XORG-6_8_99_13XORG-6_8_99_12XORG-6_8_99_11XORG-6_8_99_10XORG-6_8_99_1
xc/lib/XprintAppUtil/xpapputil.h
xc/lib/XprintUtil/xprintutil.c
xc/lib/XprintUtil/xprintutil.h
xc/programs/glxgears/glxgears.c
xc/programs/xdbedizzy/xdbedizzy.c
xc/programs/xedit/Xedit-xprint.ad
xc/programs/xedit/commands.c
xc/programs/xlogo/print.c
xc/programs/xlsfonts/xlsfonts.c
xc/programs/xlsfonts/xlsfonts.man
xc/programs/xlsfonts/xlsfonts.sgml
xc/programs/xman/Xman-xprint.ad
xc/programs/xman/handler.c
xc/programs/xman/print.c
xc/programs/xman/print.h
xc/programs/xmore/XMore.ad
xc/programs/xmore/print.c
xc/programs/xmore/print.h
xc/programs/xmore/printdialog.c
xc/programs/xmore/printdialog.h
xc/programs/xmore/printdialogprivates.h
xc/programs/xmore/xmore.c
xc/programs/xphelloworld/xpawhelloworld/xpawhelloworld.c
xc/programs/xphelloworld/xphelloworld/xphelloworld.c
xc/programs/xphelloworld/xpsimplehelloworld/xpsimplehelloworld.c
xc/programs/xphelloworld/xpxmhelloworld/xpxmhelloworld.c
xc/programs/xphelloworld/xpxthelloworld/xpxthelloworld.c
xc/programs/xplsprinters/xplsprinters.c
//bugs.freedesktop.org/show_bug.cgi?id=1706) attachment #1615
(https://bugs.freedesktop.org/attachment.cgi?id=1615): XprintUtils
2004/Q3 update. This adds various new features to the XprintUtils
library including support for page resolutions where
X_resolution!=Y_resolution, listfonts-mode control and initial
framework for the COLORSPACE extension. Patch by Roland Mainz
<roland.mainz@nrubsig.org> and Julien Lafon <julien.lafon@gmail.com>.
-rw-r--r-- | include/X11/XprintUtil/xprintutil.h | 43 | ||||
-rw-r--r-- | src/xprintutil.c | 527 |
2 files changed, 517 insertions, 53 deletions
diff --git a/include/X11/XprintUtil/xprintutil.h b/include/X11/XprintUtil/xprintutil.h index 60dad3b..e4cc7c6 100644 --- a/include/X11/XprintUtil/xprintutil.h +++ b/include/X11/XprintUtil/xprintutil.h @@ -31,7 +31,6 @@ ****************************************************************************** *****************************************************************************/ - /* Force ANSI C prototypes from X11 headers */ #ifndef FUNCPROTO #define FUNCPROTO 15 @@ -88,11 +87,12 @@ typedef struct { /* * Struct for XpuGetResolutionList(), XpuFreeResolutionList(), * XpuGetResolution(), XpuSetPageResolution(), XpuSetDocResolution(), - * XpuFindResolution() + * XpuFindResolutionByName() */ typedef struct { - long dpi; - /* ToDo: Support for Xdpi != Ydpi */ + const char *name; + long x_dpi; + long y_dpi; } XpuResolutionRec, *XpuResolutionList; /* @@ -112,6 +112,14 @@ typedef struct { const char *plex; } XpuPlexRec, *XpuPlexList; +/* + * Struct for XpuGetColorspaceList(), XpuFreeColorspaceList() + */ +typedef struct +{ + const char *name; + XVisualInfo visualinfo; +} XpuColorspaceRec, *XpuColorspaceList; /* XPUATTRIBUTESUPPORTED_*: * Flags which indicate whether it is allowed to set/change a specific attribute @@ -129,6 +137,7 @@ typedef long XpuSupportedFlags; #define XPUATTRIBUTESUPPORTED_DEFAULT_INPUT_TRAY (1L<<7) #define XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM (1L<<8) #define XPUATTRIBUTESUPPORTED_PLEX (1L<<9) +#define XPUATTRIBUTESUPPORTED_LISTFONTS_MODES (1L<<10) /* prototypes */ _XFUNCPROTOBEGIN @@ -136,6 +145,7 @@ _XFUNCPROTOBEGIN int XpuCheckExtension( Display *pdpy ); /* Create/destroy connection to printer */ +Bool XpuXprintServersAvailable( void ); int XpuGetPrinter( const char *printername, Display **pdpyptr, XPContext *pcontextptr ); void XpuClosePrinterDisplay(Display *pdpy, XPContext pcontext); @@ -177,10 +187,10 @@ XpuFindMediumSourceSizeByName( XpuMediumSourceSizeList mlist, int mlist_count, /* Get/Set resolution */ XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); void XpuFreeResolutionList( XpuResolutionList list ); -Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi ); +Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *x_dpi, long *y_dpi ); Bool XpuSetPageResolution( Display *pdpy, XPContext pcontext, XpuResolutionRec * ); Bool XpuSetDocResolution( Display *pdpy, XPContext pcontext, XpuResolutionRec * ); -XpuResolutionRec *XpuFindResolution( XpuResolutionList list, int list_count, long min_dpi, long max_dpi ); +XpuResolutionRec *XpuFindResolutionByName( XpuResolutionList list, int list_count, const char *resolution_name); /* Get/Set orientation */ XpuOrientationList XpuGetOrientationList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); @@ -197,6 +207,15 @@ XpuPlexRec *XpuFindPlexByName( XpuPlexList list, int list_count, const char *ple int XpuSetDocPlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ); int XpuSetPagePlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ); +/* Set/get usage of fonts */ +Bool XpuGetEnableFontDownload( Display *pdpy, XPContext pcontext ); +int XpuSetEnableFontDownload( Display *pdpy, XPContext pcontext, Bool enableFontDownload ); + +/* Get per-printer colorspace information */ +XpuColorspaceList XpuGetColorspaceList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ); +void XpuFreeColorspaceList( XpuColorspaceList list ); +XpuColorspaceRec *XpuFindColorspaceByName( XpuColorspaceList list, int list_count, const char *colorspace ); + /* Start job to printer (spooler) or file */ void XpuStartJobToSpooler(Display *pdpy); void *XpuStartJobToFile( Display *pdpy, XPContext pcontext, const char *filename ); @@ -207,6 +226,18 @@ XpuSupportedFlags XpuGetSupportedJobAttributes(Display *pdpy, XPContext pcontext XpuSupportedFlags XpuGetSupportedDocAttributes(Display *pdpy, XPContext pcontext); XpuSupportedFlags XpuGetSupportedPageAttributes(Display *pdpy, XPContext pcontext); +/* Encode/decode resource strings */ +char *XpuResourceEncode( const char *str ); +char *XpuResourceDecode( const char *str ); +void XpuResourceFreeString( char *s ); + +/* COMPOUND_TEXT <----> local encoding string converters */ +const char *XpuXmbToCompoundText(Display *dpy, const char *xmbtext); +void XpuFreeCompundTextString( const char *s ); +const char *XpuCompoundTextToXmb(Display *dpy, const char *ct); +void XpuFreeXmbString( const char *s ); + + _XFUNCPROTOEND #define XpuGetJobAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPJobAttr ) diff --git a/src/xprintutil.c b/src/xprintutil.c index 43bff69..58fe138 100644 --- a/src/xprintutil.c +++ b/src/xprintutil.c @@ -42,9 +42,9 @@ #include "plstr.h" #undef strtok_r #define strtok_r(s1, s2, x) PL_strtok_r((s1), (s2), (x)) -#endif /* USE_MOZILLA_TYPES */ +#endif /* XPU_USE_NSPR */ -/* List of tokens which can be used to seperate entries in the +/* List of tokens which can be used to separate entries in the * $XPSERVERLIST env var */ static const char XPServerListSeparators[] = " \t\v\n\r\f"; @@ -134,6 +134,35 @@ const char *XpuGetXpServerList( void ) } +Bool XpuXprintServersAvailable( void ) +{ + const char *s; + int c = 0; + /* BUGs/ToDo: + * - XpServerList resource needs to be sourced, too... + * (see comment for |XpuGetXpServerList|, too) + * - There should be some validation whether the server entries + * are + * a) valid (easy :) + * and + * b) available (hard to implement when XOpenDisplay() should be avoided) + */ + s = getenv("XPSERVERLIST"); + /* Check if serverlist is non-empty */ + if (s) + { + while( *s++ ) + { + if( !isspace(*s) ) + c++; + } + } + /* a valid server name must at least contain the ':'-seperator + * and a number (e.g. ":1") */ + return( c >= 2 ); +} + + static int XpuGetPrinter2( char *printer, char *display, Display **pdpyptr, XPContext *pcontextptr ) { @@ -331,7 +360,13 @@ int XpuSetJobTitle( Display *pdpy, XPContext pcontext, const char *title ) { if( XpuGetSupportedJobAttributes(pdpy, pcontext) & XPUATTRIBUTESUPPORTED_JOB_NAME ) { - XpuSetOneAttribute(pdpy, pcontext, XPJobAttr, "*job-name", title, XPAttrMerge); + char *encoded_title; + + encoded_title = XpuResourceEncode(title); + if (!encoded_title) + return(0); + XpuSetOneAttribute(pdpy, pcontext, XPJobAttr, "*job-name", encoded_title, XPAttrMerge); + XpuResourceFreeString(encoded_title); return(1); } else @@ -661,7 +696,7 @@ Bool XpuParseMediumSourceSize( const char *value, while(*s); *d = '\0'; - /* seperate medium name from string */ + /* separate medium name from string */ d = (char *)search_next_space(name); if( !d ) { @@ -1166,6 +1201,7 @@ XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int * const char *s; long default_resolution = -1; int default_resolution_rec_index = -1; + char namebuf[64]; /* Get default document resolution */ if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "default-printer-resolution", &default_resolution) != 1 ) @@ -1200,12 +1236,16 @@ XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int * if( !list ) return(NULL); - list[rec_count-2].dpi = tmp; + sprintf(namebuf, "%lddpi", tmp); + list[rec_count-2].name = strdup(namebuf); + list[rec_count-2].x_dpi = tmp; + list[rec_count-2].y_dpi = tmp; if( default_resolution != -1 ) { /* Is this the default resolution ? */ - if( list[rec_count-2].dpi == default_resolution ) + if( (list[rec_count-2].x_dpi == default_resolution) && + (list[rec_count-2].y_dpi == default_resolution) ) { default_resolution_rec_index = rec_count-2; } @@ -1217,10 +1257,12 @@ XpuResolutionList XpuGetResolutionList( Display *pdpy, XPContext pcontext, int * if( list ) { /* users: DO NOT COUNT ON THIS DETAIL - * (this is only to make current impl. of XpuFreeMediumSourceSizeList() easier) - * I may remove this implementation detail in a later revision of + * (this is only to make current impl. of XpuGetResolutionList() easier) + * We may remove this implementation detail in a later revision of * the library! */ - list[rec_count-1].dpi = -1; + list[rec_count-1].name = NULL; + list[rec_count-1].x_dpi = -1; + list[rec_count-1].y_dpi = -1; rec_count--; } else @@ -1245,53 +1287,43 @@ void XpuFreeResolutionList( XpuResolutionList list ) { if( list ) { + XpuResolutionRec *curr = list; + + /* See the warning abouve about using this implementation detail for + * checking for the list's end... */ + while( curr->name != NULL ) + { + free((void *)curr->name); + curr++; + } + free(list); } } /* Find resolution in resolution list. - * Lower resolutions are preferred over larger resolution if |dpi_a| <= |dpi_b|, - * otherwise larger resolutions are preferred over small resolutions */ -XpuResolutionRec *XpuFindResolution( XpuResolutionList list, int list_count, long dpi_a, long dpi_b ) +XpuResolutionRec *XpuFindResolutionByName( XpuResolutionList list, int list_count, const char *name) { - XpuResolutionRec *match = NULL; - int i; + int i; - if( dpi_a <= dpi_b ) - { - /* Search list, lower resolutions are better... */ - for( i = 0 ; i < list_count ; i++ ) - { - XpuResolutionRec *curr = &list[i]; - - if( curr->dpi >= dpi_a && curr->dpi <= dpi_b ) - { - if( !match || (curr->dpi < match->dpi) ) - { - match = curr; - } - } - } - } - else + for( i = 0 ; i < list_count ; i++ ) { - /* Search list, higher resolutions are better... */ - for( i = 0 ; i < list_count ; i++ ) + XpuResolutionRec *curr = &list[i]; + if (!strcasecmp(curr->name, name)) + return curr; + + /* Search by plain DPI value (no "dpi" suffix )*/ + if (curr->x_dpi == curr->x_dpi) { - XpuResolutionRec *curr = &list[i]; - - if( curr->dpi >= dpi_b && curr->dpi <= dpi_a ) - { - if( !match || (curr->dpi > match->dpi) ) - { - match = curr; - } - } + char buf[32]; + sprintf(buf, "%ld", curr->x_dpi); + if (!strcasecmp(buf, name)) + return curr; } } - return(match); + return NULL; } /* Get default page (if defined) or document resolution @@ -1299,17 +1331,23 @@ XpuResolutionRec *XpuFindResolution( XpuResolutionList list, int list_count, lon * - No default resolution set yet * - X DPI != Y DPI (not yet implemented in Xprt) */ -Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi_ptr ) +Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *x_dpi_ptr, long *y_dpi_ptr ) { + long dpi; + /* Try to get the current page's resolution (pages may differ in resolution if the DDX supports this) */ - if( XpuGetOneLongAttribute(pdpy, pcontext, XPPageAttr, "default-printer-resolution", dpi_ptr) == 1 ) + if( XpuGetOneLongAttribute(pdpy, pcontext, XPPageAttr, "default-printer-resolution", &dpi) == 1 ) { + *x_dpi_ptr = dpi; + *y_dpi_ptr = dpi; return True; } /* Get document resolution */ - if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "default-printer-resolution", dpi_ptr) == 1 ) + if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "default-printer-resolution", &dpi) == 1 ) { + *x_dpi_ptr = dpi; + *y_dpi_ptr = dpi; return True; } @@ -1319,7 +1357,13 @@ Bool XpuGetResolution( Display *pdpy, XPContext pcontext, long *dpi_ptr ) static int XpuSetResolution( Display *pdpy, XPContext pcontext, XPAttributes type, XpuResolutionRec *rec ) { - XpuSetOneLongAttribute(pdpy, pcontext, type, "*default-printer-resolution", rec->dpi, XPAttrMerge); + if( rec->x_dpi != rec->y_dpi ) + { + fprintf(stderr, "XpuSetResolution: internal error: x_dpi != y_dpi not supported yet.\n"); + return 0; + } + + XpuSetOneLongAttribute(pdpy, pcontext, type, "*default-printer-resolution", rec->x_dpi, XPAttrMerge); return( 1 ); } @@ -1619,6 +1663,205 @@ int XpuSetPagePlex( Display *pdpy, XPContext pcontext, XpuPlexRec *rec ) } +XpuColorspaceList XpuGetColorspaceList( Display *pdpy, XPContext pcontext, int *numEntriesPtr ) +{ + XpuColorspaceList list = NULL; + int rec_count = 1; /* Allocate one more |XpuColorspaceRec| structure + * as terminator */ + char namebuf[256]; /* Temporary name buffer for colorspace names */ + int i; /* Loop counter */ + int nvi; /* Number of visuals */ + Screen *pscreen; /* Print screen */ + XVisualInfo viproto; /* fill in for getting info */ + XVisualInfo *vip; /* retured info */ + + pscreen = XpGetScreenOfContext(pdpy, pcontext); + + nvi = 0; + viproto.screen = XScreenNumberOfScreen(pscreen); + vip = XGetVisualInfo(pdpy, VisualScreenMask, &viproto, &nvi); + if (!vip) + { + fprintf(stderr, "XpuGetColorspaceList: Internal error: vip == NULL\n"); + return NULL; + } + + for( i = 0 ; i < nvi ; i++ ) + { + XVisualInfo *vcurr = vip+i; + char cbuff[64]; + const char *class = NULL; + +#ifdef USE_MOZILLA_TYPES + /* Workaround for the current limitation of the gfx/src/xlibrgb code + * which cannot handle depths > 24bit yet */ + if( vcurr->depth > 24 ) + continue; +#endif /* USE_MOZILLA_TYPES */ + + rec_count++; + list = (XpuColorspaceRec *)realloc(list, sizeof(XpuColorspaceRec)*rec_count); + if( !list ) + return NULL; + + /* ToDO: This needs to be updated for the COLORSPACE X11 extension + * once it is ready and approved by the XOrg arch board. */ + switch (vcurr->class) { + case StaticGray: class = "StaticGray"; break; + case GrayScale: class = "GrayScale"; break; + case StaticColor: class = "StaticColor"; break; + case PseudoColor: class = "PseudoColor"; break; + case TrueColor: class = "TrueColor"; break; + case DirectColor: class = "DirectColor"; break; + default: /* Needed for forward compatibility to the COLORSPACE extension */ + sprintf (cbuff, "unknown_class_%x", vcurr->class); + class = cbuff; + break; + } + + if (vcurr->bits_per_rgb == 8) + { + sprintf(namebuf, "%s/%dbit", class, vcurr->depth); + } + else + { + sprintf(namebuf, "%s/%dbit/%dbpg", class, vcurr->depth, vcurr->bits_per_rgb); + } + list[rec_count-2].name = strdup(namebuf); + list[rec_count-2].visualinfo = *vcurr; + } + + XFree((char *)vip); + + if( list ) + { + /* users: DO NOT COUNT ON THIS DETAIL + * (this is only to make current impl. of XpuGetResolutionList() easier) + * We may remove this implementation detail in a later revision of + * the library! */ + list[rec_count-1].name = NULL; + rec_count--; + } + else + { + rec_count = 0; + } + + *numEntriesPtr = rec_count; + return(list); +} + +void XpuFreeColorspaceList( XpuColorspaceList list ) +{ + if( list ) + { + XpuColorspaceRec *curr = list; + + /* See the warning abouve about using this implementation detail for + * checking for the list's end... */ + while( curr->name != NULL ) + { + free((void *)curr->name); + curr++; + } + + free(list); + } +} + +XpuColorspaceRec * +XpuFindColorspaceByName( XpuColorspaceList list, int list_count, const char *name ) +{ + int i; + + for( i = 0 ; i < list_count ; i++ ) + { + XpuColorspaceRec *curr = &list[i]; + if (!strcmp(curr->name, name)) + return curr; + } + + return(NULL); +} + +Bool XpuGetEnableFontDownload( Display *pdpy, XPContext pcontext ) +{ + Bool enableFontDownload; + char *value; + + value = XpGetOneAttribute(pdpy, pcontext, XPPrinterAttr, "xp-listfonts-modes-supported"); + if( !value ) + { + fprintf(stderr, "XpuGetEnableFontDownload: xp-listfonts-modes-supported printer attribute not found.\n"); + return False; + } + + enableFontDownload = (strstr(value, "xp-list-glyph-fonts") != NULL); + XFree(value); + return enableFontDownload; +} + +int XpuSetEnableFontDownload( Display *pdpy, XPContext pcontext, Bool enableFontDownload ) +{ + char *value, + *newvalue; + + value = XpGetOneAttribute(pdpy, pcontext, XPPrinterAttr, "xp-listfonts-modes-supported"); + if( !value ) + { + fprintf(stderr, "XpuSetEnableFontDownload: xp-listfonts-modes-supported printer attribute not found.\n"); + return 0; /* failure */ + } + + /* Set "xp-list-glyph-fonts" */ + if( enableFontDownload ) + { + /* Return success if "xp-list-glyph-fonts" is already set */ + if( strstr(value, "xp-list-glyph-fonts") != NULL ) + { + XFree(value); + return 1; /* success */ + } + + newvalue = malloc(strlen(value) + 33); + if( !newvalue ) + { + XFree(value); + return 0; /* failure */ + } + + sprintf(newvalue, "%s xp-list-glyph-fonts", value); + XpuSetOneAttribute(pdpy, pcontext, XPDocAttr, "*xp-listfonts-modes", newvalue, XPAttrMerge); + + free(newvalue); + XFree(value); + return 1; /* success */ + } + else + { + char *s, /* copy string "source" */ + *d; /* copy string "destination" */ + + /* Return success if "xp-list-glyph-fonts" not set */ + d = strstr(value, "xp-list-glyph-fonts"); + if( d == NULL ) + { + XFree(value); + return 1; /* success */ + } + + /* strip "xp-list-glyph-fonts" from |value| */ + s = d+19/*strlen("xp-list-glyph-fonts")*/; + while( (*d++ = *s++) != '\0' ) + ; + + XpuSetOneAttribute(pdpy, pcontext, XPDocAttr, "*xp-listfonts-modes", value, XPAttrMerge); + + XFree(value); + return 1; /* success */ + } +} + /* Return flags to indicate which attributes are supported and which not... */ static XpuSupportedFlags XpuGetSupportedAttributes( Display *pdpy, XPContext pcontext, XPAttributes type, const char *attribute_name ) @@ -1651,6 +1894,7 @@ XpuSupportedFlags XpuGetSupportedAttributes( Display *pdpy, XPContext pcontext, else if( !strcmp(s, "default-input-tray") ) flags |= XPUATTRIBUTESUPPORTED_DEFAULT_INPUT_TRAY; else if( !strcmp(s, "default-medium") ) flags |= XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM; else if( !strcmp(s, "plex") ) flags |= XPUATTRIBUTESUPPORTED_PLEX; + else if( !strcmp(s, "xp-listfonts-modes") ) flags |= XPUATTRIBUTESUPPORTED_LISTFONTS_MODES; } XpuDisposeEnumerateXpAttributeValue(&tok_lasts); @@ -1675,4 +1919,193 @@ XpuSupportedFlags XpuGetSupportedPageAttributes(Display *pdpy, XPContext pcontex return XpuGetSupportedAttributes(pdpy, pcontext, XPPrinterAttr, "xp-page-attributes-supported"); } +/* Encode string for usage in a Xrm resource database as + * defined in X(7): [...] To allow a Value to begin + * with whitespace, the two-character sequence ``\space'' + * (backslash followed by space) is recognized and replaced by + * a space character, and the two-character sequence ``\tab'' + * (backslash followed by horizontal tab) is recognized and + * replaced by a horizontal tab character. To allow a Value to + * contain embedded newline characters, the two-character + * sequence ``\n'' is recognized and replaced by a newline + * character. To allow a Value to be broken across multiple + * lines in a text file, the two-character sequence ``\new- + * line'' (backslash followed by newline) is recognized and + * removed from the value. To allow a Value to contain arbi- + * trary character codes, the four-character sequence ``\nnn'', + * where each n is a digit character in the range of + * ``0''-``7'', is recognized and replaced with a single byte + * that contains the octal value specified by the sequence. + * Finally, the two-character sequence ``\\'' is recognized and + * replaced with a single backslash. + */ +char *XpuResourceEncode( const char *s ) +{ + size_t slen; + char *res; + char *d; + int i, + c; + + slen = strlen(s); + res = malloc(slen*4+1); + if (!res) + return NULL; + + d = res; + i = slen; + while (i--) { + c = *s++; + if (c == '\n') { + if (i) { + *d++ = '\\'; + *d++ = 'n'; + *d++ = '\\'; + *d++ = '\n'; + } + else { + *d++ = '\\'; + *d++ = 'n'; + } + } else if (c == '\\') { + *d++ = '\\'; + *d++ = '\\'; + } + else if ((c < ' ' && c != '\t') || + ((unsigned char)c >= 0x7F && (unsigned char)c < 0xA0)) { + sprintf(d, "\\%03o", (unsigned char)c); + d += 4; + } + else { + *d++ = c; + } + } + + *d = '\0'; + + return res; +} + +#ifdef XXXJULIEN_NOTNOW +char *XpuResourceDecode( const char *str ) +{ +} +#endif /* XXXJULIEN_NOTNOW */ + +void XpuResourceFreeString( char *s ) +{ + free(s); +} + +const char *XpuXmbToCompoundText(Display *dpy, const char *xmbtext) +{ + XTextProperty xtp; + int xcr; + char *xtl[2]; + char *ct; + + if (strlen(xmbtext) == 0) + return strdup(xmbtext); + + memset(&xtp, 0, sizeof(xtp)); + xtl[0] = (char *)xmbtext; + xtl[1] = NULL; + + xcr = XmbTextListToTextProperty(dpy, xtl, 1, XCompoundTextStyle, &xtp); + + if (xcr == XNoMemory || xcr == XLocaleNotSupported) + { + fprintf(stderr, "XpuXmbToCompoundText: XmbTextListToTextProperty failure.\n"); + return strdup(xmbtext); + } + + /* Did conversion succeed (some unconvertible characters + * are not a problem) ? */ + if ( !((xcr == Success) || (xcr > 0)) || + (xtp.value == NULL)) + { + fprintf(stderr, "XpuXmbToCompoundText: XmbTextListToTextProperty failure 2.\n"); + return strdup(xmbtext); + } + + ct = malloc(xtp.nitems+1); + if (!ct) + { + XFree(xtp.value); + return NULL; + } + memcpy(ct, xtp.value, xtp.nitems); + ct[xtp.nitems] = '\0'; + + XFree(xtp.value); + + return ct; +} + +void XpuFreeCompundTextString( const char *s ) +{ + free((void *)s); +} + +const char *XpuCompoundTextToXmb(Display *dpy, const char *ct) +{ + XTextProperty xtp; + int xcr; + char **xtl = NULL; + int xtl_count = 0; + char *xmb; + int xmb_len = 0; + int i; + + if (strlen(ct) == 0) + return strdup(ct); + + xtp.value = (unsigned char *)ct; + xtp.nitems = strlen(ct); + xtp.encoding = XInternAtom(dpy, "COMPOUND_TEXT", False); + xtp.format = 8; + + xcr = XmbTextPropertyToTextList(dpy, &xtp, &xtl, &xtl_count); + + if (xcr == XNoMemory || xcr == XLocaleNotSupported) + { + fprintf(stderr, "XpuCompoundTextToXmb: XmbTextPropertyToTextList failure 1.\n"); + return strdup(ct); + } + + /* Did conversion succeed (some unconvertible characters + * are not a problem) ? */ + if ( !((xcr == Success) || (xcr > 0)) || + (xtl == NULL)) + { + fprintf(stderr, "XpuCompoundTextToXmb: XmbTextPropertyToTextList failure 2.\n"); + return strdup(ct); + } + + for (i = 0; i < xtl_count; i++) + { + xmb_len += strlen(xtl[i]); + } + xmb = malloc (xmb_len + 1); + if (!xmb) + { + XFreeStringList(xtl); + return NULL; + } + xmb[0] = '\0'; /* Catch zero-length case */ + for (i = 0; i < xtl_count; i++) + { + strcat(xmb, xtl[i]); + } + + XFreeStringList(xtl); + + return xmb; +} + +void XpuFreeXmbString( const char *s ) +{ + free((void *)s); +} + /* EOF. */ |