/* Copyright 1985, 1986, 1987, 1991, 1998 The Open Group Portions Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES. Except as contained in this notice, the names of The Open Group and/or Sun Microsystems, Inc. shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group and/or Sun Microsystems, Inc., as applicable. X Window System is a trademark of The Open Group OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF logo, LBX, X Window System, and Xinerama are trademarks of the Open Group. All other trademarks and registered trademarks mentioned herein are the property of their respective owners. No right, title or interest in or to any trademark, service mark, logo or trade name of Sun Microsystems, Inc. or its licensors is granted. */ /* $XFree86: xc/lib/X11/XDefaultOMIF.c,v 1.4 2003/04/13 19:22:18 dawes Exp $ */ #include "Xlibint.h" #include "Xlcint.h" #include "XlcPublic.h" #include #include #include #define MAXFONTS 100 #define XOM_GENERIC(om) (&((XOMGeneric) om)->gen) #define XOC_GENERIC(font_set) (&((XOCGeneric) font_set)->gen) #define DefineLocalBuf char local_buf[BUFSIZ] #define AllocLocalBuf(length) (length > BUFSIZ ? (char *)Xmalloc(length) : local_buf) #define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr) typedef struct _FontDataRec { char *name; } FontDataRec, *FontData; typedef struct _OMDataRec { int font_data_count; FontData font_data; } OMDataRec, *OMData; typedef struct _XOMGenericPart { OMData data; } XOMGenericPart; typedef struct _XOMGenericRec { XOMMethods methods; XOMCoreRec core; XOMGenericPart gen; } XOMGenericRec, *XOMGeneric; typedef struct _FontSetRec { int id; int font_data_count; FontData font_data; char *font_name; XFontStruct *info; XFontStruct *font; } FontSetRec, *FontSet; typedef struct _XOCGenericPart { XlcConv wcs_to_cs; FontSet font_set; } XOCGenericPart; typedef struct _XOCGenericRec { XOCMethods methods; XOCCoreRec core; XOCGenericPart gen; } XOCGenericRec, *XOCGeneric; static Bool init_fontset( XOC oc) { XOCGenericPart *gen; FontSet font_set; OMData data; data = XOM_GENERIC(oc->core.om)->data; font_set = (FontSet) Xmalloc(sizeof(FontSetRec)); if (font_set == NULL) return False; bzero((char *) font_set, sizeof(FontSetRec)); gen = XOC_GENERIC(oc); gen->font_set = font_set; font_set->font_data_count = data->font_data_count; font_set->font_data = data->font_data; return True; } static char * get_prop_name( Display *dpy, XFontStruct *fs) { unsigned long fp; if (XGetFontProperty(fs, XA_FONT, &fp)) return XGetAtomName(dpy, fp); return (char *) NULL; } static FontData check_charset( FontSet font_set, char *font_name) { FontData font_data; char *last; int count; ssize_t length, name_len; name_len = strlen(font_name); last = font_name + name_len; count = font_set->font_data_count; font_data = font_set->font_data; for ( ; count-- > 0; font_data++) { length = strlen(font_data->name); if (length > name_len) return(NULL); if (_XlcCompareISOLatin1(last - length, font_data->name) == 0) return font_data; } return (FontData) NULL; } #if 0 /* Unused */ static int check_fontname( XOC oc, char *name) { Display *dpy = oc->core.om->core.display; XOCGenericPart *gen = XOC_GENERIC(oc); FontData data; FontSet font_set; XFontStruct *fs_list; char **fn_list, *fname, *prop_fname = NULL; int list_num, i; int list2_num; char **fn2_list = NULL; int found_num = 0; fn_list = XListFonts(dpy, name, MAXFONTS, &list_num); if (fn_list == NULL) return found_num; for (i = 0; i < list_num; i++) { fname = fn_list[i]; font_set = gen->font_set; if ((data = check_charset(font_set, fname)) == NULL) { if ((fn2_list = XListFontsWithInfo(dpy, name, MAXFONTS, &list2_num, &fs_list)) && (prop_fname = get_prop_name(dpy, fs_list)) && (data = check_charset(font_set, prop_fname))) fname = prop_fname; } if (data) { font_set->font_name = (char *) Xmalloc(strlen(fname) + 1); if (font_set->font_name) { strcpy(font_set->font_name, fname); found_num++; } } if (fn2_list) { XFreeFontInfo(fn2_list, fs_list, list2_num); fn2_list = NULL; if (prop_fname) { Xfree(prop_fname); prop_fname = NULL; } } if (found_num == 1) break; } XFreeFontNames(fn_list); return found_num; } #endif static Bool load_font( XOC oc) { Display *dpy = oc->core.om->core.display; XOCGenericPart *gen = XOC_GENERIC(oc); FontSet font_set = gen->font_set; if (font_set->font_name == NULL) return False; if (font_set->font == NULL) { font_set->font = XLoadQueryFont(dpy, font_set->font_name); if (font_set->font == NULL) return False; } return True; } #if 0 static Bool load_font_info( XOC oc) { Display *dpy = oc->core.om->core.display; XOCGenericPart *gen = XOC_GENERIC(oc); FontSet font_set = gen->font_set; char **fn_list; int fn_num; if (font_set->font_name == NULL) return False; if (font_set->info == NULL) { fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num, &font_set->info); if (font_set->info == NULL) return False; if (fn_num > 0) font_set->info->fid = XLoadFont(dpy, font_set->font_name); if (fn_list) XFreeFontNames(fn_list); } return True; } #endif static void set_fontset_extents( XOC oc) { XRectangle *ink = &oc->core.font_set_extents.max_ink_extent; XRectangle *logical = &oc->core.font_set_extents.max_logical_extent; XFontStruct **font_list, *font; XCharStruct overall; int logical_ascent, logical_descent; font_list = oc->core.font_info.font_struct_list; font = *font_list++; overall = font->max_bounds; overall.lbearing = font->min_bounds.lbearing; logical_ascent = font->ascent; logical_descent = font->descent; ink->x = overall.lbearing; ink->y = -(overall.ascent); ink->width = overall.rbearing - overall.lbearing; ink->height = overall.ascent + overall.descent; logical->x = 0; logical->y = -(logical_ascent); logical->width = overall.width; logical->height = logical_ascent + logical_descent; } static Bool init_core_part( XOC oc) { XOCGenericPart *gen = XOC_GENERIC(oc); FontSet font_set; XFontStruct **font_struct_list; char **font_name_list, *font_name_buf; int count, length; font_set = gen->font_set; count = length = 0; if (font_set->font_name != NULL) { length += strlen(font_set->font_name) + 1; count++; } if (count == 0) return False; font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *)); if (font_struct_list == NULL) return False; font_name_list = (char **) Xmalloc(sizeof(char *)); if (font_name_list == NULL) goto err; font_name_buf = (char *) Xmalloc(length); if (font_name_buf == NULL) goto err; oc->core.font_info.num_font = 1; oc->core.font_info.font_name_list = font_name_list; oc->core.font_info.font_struct_list = font_struct_list; font_set = gen->font_set; if (font_set->font_name != NULL) { font_set->id = 1; if (font_set->font) *font_struct_list++ = font_set->font; else *font_struct_list++ = font_set->info; strcpy(font_name_buf, font_set->font_name); Xfree(font_set->font_name); *font_name_list++ = font_set->font_name = font_name_buf; font_name_buf += strlen(font_name_buf) + 1; } set_fontset_extents(oc); return True; err: if (font_name_list) Xfree(font_name_list); Xfree(font_struct_list); return False; } static char * get_font_name( XOC oc, char *pattern) { char **list, *name, *prop_name; int count; XFontStruct *fs; Display *dpy = oc->core.om->core.display; list = XListFonts(dpy, pattern, 1, &count); if (list != NULL) { name = (char *) Xmalloc(strlen(*list) + 1); if (name) strcpy(name, *list); XFreeFontNames(list); } else { fs = XLoadQueryFont(dpy, pattern); if (fs == NULL) return NULL; prop_name = get_prop_name(dpy, fs); if (prop_name == NULL) return NULL; name = (char*) Xmalloc(strlen(prop_name) + 1); if (name) strcpy(name, prop_name); XFreeFont(dpy, fs); } return name; } static int parse_fontname( XOC oc) { XOCGenericPart *gen = XOC_GENERIC(oc); FontSet font_set; FontData font_data; char *pattern, *last, buf[BUFSIZ]; int font_data_count, found_num = 0; ssize_t length; int count, num_fields; char *base_name, *font_name, **name_list, **cur_name_list; char *charset_p = NULL; Bool append_charset; /* append_charset flag should be set to True when the XLFD fontname doesn't contain a chaset part. */ name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count); if (name_list == NULL) return -1; cur_name_list = name_list; while (count-- > 0) { pattern = *cur_name_list++; if (pattern == NULL || *pattern == '\0') continue; append_charset = False; if (strchr(pattern, '*') == NULL && (font_name = get_font_name(oc, pattern))) { font_set = gen->font_set; font_data = check_charset(font_set, font_name); if (font_data == NULL) { Display *dpy = oc->core.om->core.display; char **fn_list = NULL, *prop_fname = NULL; int list_num; XFontStruct *fs_list; if ((fn_list = XListFontsWithInfo(dpy, font_name, MAXFONTS, &list_num, &fs_list)) && (prop_fname = get_prop_name(dpy, fs_list)) && (font_data = check_charset(font_set, prop_fname))) { if (fn_list) { XFreeFontInfo(fn_list, fs_list, list_num); fn_list = NULL; } font_name = prop_fname; } } if (font_data == NULL) continue; font_set->font_name = (char *) Xmalloc(strlen(font_name) + 1); if (font_set->font_name == NULL) { Xfree(font_name); goto err; } strcpy(font_set->font_name, font_name); Xfree(font_name); found_num++; goto found; } /* 1266793 Limit the length of the string copy to prevent stack corruption. strcpy(buf, pattern); */ strncpy(buf, pattern, BUFSIZ); buf[BUFSIZ-1] = '\0'; length = strlen(buf); last = buf + length - 1; for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++) if (*base_name == '-') num_fields++; if (strchr(pattern, '*') == NULL) { if (num_fields == 12) { append_charset = True; *++last = '-'; last++; } else continue; } else { if (num_fields == 13 || num_fields == 14) { /* * There are 14 fields in an XLFD name -- make certain the * charset (& encoding) is placed in the correct field. */ append_charset = True; last = strrchr (buf, '-'); if (num_fields == 14) { *last = '\0'; last = strrchr (buf, '-'); } last++; } else if (*last == '*') { append_charset = True; if (length > 3 && *(last-3) == '-' && *(last-2) == '*' && *(last-1) == '-') { last -= 2; } *++last = '-'; last++; } else { last = strrchr (buf, '-'); charset_p = last; charset_p = strrchr (buf, '-'); while (*(--charset_p) != '-'); charset_p++; } } font_set = gen->font_set; font_data = font_set->font_data; font_data_count = font_set->font_data_count; for ( ; font_data_count-- > 0; font_data++) { if (append_charset) { /* 1266793 Limit the length of the string copy to prevent stack corruption. strcpy(last, font_data->name); */ strncpy(last, font_data->name, BUFSIZ - length); buf[BUFSIZ-1] = '\0'; } else { if (_XlcCompareISOLatin1(charset_p, font_data->name)) { continue; } } if ((font_set->font_name = get_font_name(oc, buf))) break; } if (font_set->font_name != NULL) { found_num++; goto found; } } found: base_name = (char *) Xmalloc(strlen(oc->core.base_name_list) + 1); if (base_name == NULL) goto err; strcpy(base_name, oc->core.base_name_list); oc->core.base_name_list = base_name; XFreeStringList(name_list); return found_num; err: XFreeStringList(name_list); return -1; } static Bool set_missing_list( XOC oc) { XOCGenericPart *gen = XOC_GENERIC(oc); FontSet font_set; char **charset_list, *charset_buf; int count, length; font_set = gen->font_set; count = length = 0; if (!font_set->info && !font_set->font) { length += strlen(font_set->font_data->name) + 1; count++; } if (count == 0) return True; charset_list = (char **) Xmalloc(sizeof(char *)); if (charset_list == NULL) return False; charset_buf = (char *) Xmalloc(length); if (charset_buf == NULL) { Xfree(charset_list); return False; } oc->core.missing_list.charset_list = charset_list; font_set = gen->font_set; if (!font_set->info && !font_set->font) { strcpy(charset_buf, font_set->font_data->name); *charset_list++ = charset_buf; charset_buf += strlen(charset_buf) + 1; } return True; } static Bool create_fontset( XOC oc) { int found_num; if (init_fontset(oc) == False) return False; found_num = parse_fontname(oc); if (found_num <= 0) { if (found_num == 0) set_missing_list(oc); return False; } if (load_font(oc) == False) return False; if (init_core_part(oc) == False) return False; if (set_missing_list(oc) == False) return False; return True; } static void destroy_oc( XOC oc) { Display *dpy = oc->core.om->core.display; XOCGenericPart *gen = XOC_GENERIC(oc); XFontStruct **font_list, *font; if (gen->font_set) Xfree(gen->font_set); if (oc->core.base_name_list) Xfree(oc->core.base_name_list); if (oc->core.font_info.font_name_list) XFreeStringList(oc->core.font_info.font_name_list); if ((font_list = oc->core.font_info.font_struct_list)) { if ((font = *font_list)) { if (font->fid) XFreeFont(dpy, font); else XFreeFontInfo(NULL, font, 1); } Xfree(oc->core.font_info.font_struct_list); } if (oc->core.missing_list.charset_list) XFreeStringList(oc->core.missing_list.charset_list); #ifdef notdef if (oc->core.res_name) Xfree(oc->core.res_name); if (oc->core.res_class) Xfree(oc->core.res_class); #endif Xfree(oc); } static char * set_oc_values( XOC oc, XlcArgList args, int num_args) { if (oc->core.resources == NULL) return NULL; return _XlcSetValues((XPointer) oc, oc->core.resources, oc->core.num_resources, args, num_args, XlcSetMask); } static char * get_oc_values( XOC oc, XlcArgList args, int num_args) { if (oc->core.resources == NULL) return NULL; return _XlcGetValues((XPointer) oc, oc->core.resources, oc->core.num_resources, args, num_args, XlcGetMask); } static Bool wcs_to_mbs( XOC oc, char *to, _Xconst wchar_t *from, int length) { XlcConv conv = XOC_GENERIC(oc)->wcs_to_cs; XLCd lcd; int ret, to_left = length; if (conv == NULL) { lcd = oc->core.om->core.lcd; conv = _XlcOpenConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte); if (conv == NULL) return False; XOC_GENERIC(oc)->wcs_to_cs = conv; } else _XlcResetConverter(conv); ret = _XlcConvert(conv, (XPointer *) &from, &length, (XPointer *) &to, &to_left, NULL, 0); if (ret != 0 || length > 0) return False; return True; } static int _XmbDefaultTextEscapement(XOC oc, _Xconst char *text, int length) { return XTextWidth(*oc->core.font_info.font_struct_list, text, length); } static int _XwcDefaultTextEscapement(XOC oc, _Xconst wchar_t *text, int length) { DefineLocalBuf; char *buf = AllocLocalBuf(length); int ret = 0; if (buf == NULL) return 0; if (wcs_to_mbs(oc, buf, text, length) == False) goto err; ret = _XmbDefaultTextEscapement(oc, buf, length); err: FreeLocalBuf(buf); return ret; } static int _XmbDefaultTextExtents(XOC oc, _Xconst char *text, int length, XRectangle *overall_ink, XRectangle *overall_logical) { int direction, logical_ascent, logical_descent; XCharStruct overall; XTextExtents(*oc->core.font_info.font_struct_list, text, length, &direction, &logical_ascent, &logical_descent, &overall); if (overall_ink) { overall_ink->x = overall.lbearing; overall_ink->y = -(overall.ascent); overall_ink->width = overall.rbearing - overall.lbearing; overall_ink->height = overall.ascent + overall.descent; } if (overall_logical) { overall_logical->x = 0; overall_logical->y = -(logical_ascent); overall_logical->width = overall.width; overall_logical->height = logical_ascent + logical_descent; } return overall.width; } static int _XwcDefaultTextExtents(XOC oc, _Xconst wchar_t *text, int length, XRectangle *overall_ink, XRectangle *overall_logical) { DefineLocalBuf; char *buf = AllocLocalBuf(length); int ret = 0; if (buf == NULL) return 0; if (wcs_to_mbs(oc, buf, text, length) == False) goto err; ret = _XmbDefaultTextExtents(oc, buf, length, overall_ink, overall_logical); err: FreeLocalBuf(buf); return ret; } static Status _XmbDefaultTextPerCharExtents(XOC oc, _Xconst char *text, int length, XRectangle *ink_buf, XRectangle *logical_buf, int buf_size, int *num_chars, XRectangle *overall_ink, XRectangle *overall_logical) { XFontStruct *font = *oc->core.font_info.font_struct_list; XCharStruct *def, *cs, overall; Bool first = True; if (buf_size < length) return 0; bzero((char *) &overall, sizeof(XCharStruct)); *num_chars = 0; CI_GET_DEFAULT_INFO_1D(font, def) while (length-- > 0) { CI_GET_CHAR_INFO_1D(font, *text, def, cs) text++; if (cs == NULL) continue; ink_buf->x = overall.width + cs->lbearing; ink_buf->y = -(cs->ascent); ink_buf->width = cs->rbearing - cs->lbearing; ink_buf->height = cs->ascent + cs->descent; ink_buf++; logical_buf->x = overall.width; logical_buf->y = -(font->ascent); logical_buf->width = cs->width; logical_buf->height = font->ascent + font->descent; logical_buf++; if (first) { overall = *cs; first = False; } else { overall.ascent = max(overall.ascent, cs->ascent); overall.descent = max(overall.descent, cs->descent); overall.lbearing = min(overall.lbearing, overall.width + cs->lbearing); overall.rbearing = max(overall.rbearing, overall.width + cs->rbearing); overall.width += cs->width; } (*num_chars)++; } if (overall_ink) { overall_ink->x = overall.lbearing; overall_ink->y = -(overall.ascent); overall_ink->width = overall.rbearing - overall.lbearing; overall_ink->height = overall.ascent + overall.descent; } if (overall_logical) { overall_logical->x = 0; overall_logical->y = -(font->ascent); overall_logical->width = overall.width; overall_logical->height = font->ascent + font->descent; } return 1; } static Status _XwcDefaultTextPerCharExtents(XOC oc, _Xconst wchar_t *text, int length, XRectangle *ink_buf, XRectangle *logical_buf, int buf_size, int *num_chars, XRectangle *overall_ink, XRectangle *overall_logical) { DefineLocalBuf; char *buf = AllocLocalBuf(length); Status ret = 0; if (buf == NULL) return 0; if (wcs_to_mbs(oc, buf, text, length) == False) goto err; ret = _XmbDefaultTextPerCharExtents(oc, buf, length, ink_buf, logical_buf, buf_size, num_chars, overall_ink, overall_logical); err: FreeLocalBuf(buf); return ret; } static int _XmbDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, _Xconst char *text, int length) { XFontStruct *font = *oc->core.font_info.font_struct_list; XSetFont(dpy, gc, font->fid); XDrawString(dpy, d, gc, x, y, text, length); return XTextWidth(font, text, length); } static int _XwcDefaultDrawString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, _Xconst wchar_t *text, int length) { DefineLocalBuf; char *buf = AllocLocalBuf(length); int ret = 0; if (buf == NULL) return 0; if (wcs_to_mbs(oc, buf, text, length) == False) goto err; ret = _XmbDefaultDrawString(dpy, d, oc, gc, x, y, buf, length); err: FreeLocalBuf(buf); return ret; } static void _XmbDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, _Xconst char *text, int length) { XSetFont(dpy, gc, (*oc->core.font_info.font_struct_list)->fid); XDrawImageString(dpy, d, gc, x, y, text, length); } static void _XwcDefaultDrawImageString(Display *dpy, Drawable d, XOC oc, GC gc, int x, int y, _Xconst wchar_t *text, int length) { DefineLocalBuf; char *buf = AllocLocalBuf(length); if (buf == NULL) return; if (wcs_to_mbs(oc, buf, text, length) == False) goto err; _XmbDefaultDrawImageString(dpy, d, oc, gc, x, y, buf, length); err: FreeLocalBuf(buf); } static _Xconst XOCMethodsRec oc_default_methods = { destroy_oc, set_oc_values, get_oc_values, _XmbDefaultTextEscapement, _XmbDefaultTextExtents, _XmbDefaultTextPerCharExtents, _XmbDefaultDrawString, _XmbDefaultDrawImageString, _XwcDefaultTextEscapement, _XwcDefaultTextExtents, _XwcDefaultTextPerCharExtents, _XwcDefaultDrawString, _XwcDefaultDrawImageString }; static XlcResource oc_resources[] = { { XNBaseFontName, NULLQUARK, sizeof(char *), XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask }, { XNOMAutomatic, NULLQUARK, sizeof(Bool), XOffsetOf(XOCRec, core.om_automatic), XlcGetMask }, { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList), XOffsetOf(XOCRec, core.missing_list), XlcGetMask }, { XNDefaultString, NULLQUARK, sizeof(char *), XOffsetOf(XOCRec, core.default_string), XlcGetMask }, { XNOrientation, NULLQUARK, sizeof(XOrientation), XOffsetOf(XOCRec, core.orientation), XlcSetMask | XlcGetMask }, { XNResourceName, NULLQUARK, sizeof(char *), XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask }, { XNResourceClass, NULLQUARK, sizeof(char *), XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask }, { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo), XOffsetOf(XOCRec, core.font_info), XlcGetMask } }; static XOC create_oc( XOM om, XlcArgList args, int num_args) { XOC oc; oc = (XOC) Xmalloc(sizeof(XOCGenericRec)); if (oc == NULL) return (XOC) NULL; bzero((char *) oc, sizeof(XOCGenericRec)); oc->core.om = om; if (oc_resources[0].xrm_name == NULLQUARK) _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources)); if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources), args, num_args, XlcCreateMask | XlcDefaultMask)) goto err; if (oc->core.base_name_list == NULL) goto err; oc->core.resources = oc_resources; oc->core.num_resources = XlcNumber(oc_resources); if (create_fontset(oc) == False) goto err; oc->methods = (XOCMethods)&oc_default_methods; return oc; err: destroy_oc(oc); return (XOC) NULL; } static Status close_om( XOM om) { XOMGenericPart *gen = XOM_GENERIC(om); OMData data; FontData font_data; int count; if ((data = gen->data)) { if (data->font_data) { for (font_data = data->font_data, count = data->font_data_count; count-- > 0 ; font_data++) { if (font_data->name) Xfree(font_data->name); } Xfree(data->font_data); } Xfree(gen->data); } if (om->core.res_name) Xfree(om->core.res_name); if (om->core.res_class) Xfree(om->core.res_class); if (om->core.required_charset.charset_list) XFreeStringList(om->core.required_charset.charset_list); else Xfree((char*)om->core.required_charset.charset_list); if (om->core.orientation_list.orientation) Xfree(om->core.orientation_list.orientation); Xfree(om); return 1; } static char * set_om_values( XOM om, XlcArgList args, int num_args) { if (om->core.resources == NULL) return NULL; return _XlcSetValues((XPointer) om, om->core.resources, om->core.num_resources, args, num_args, XlcSetMask); } static char * get_om_values( XOM om, XlcArgList args, int num_args) { if (om->core.resources == NULL) return NULL; return _XlcGetValues((XPointer) om, om->core.resources, om->core.num_resources, args, num_args, XlcGetMask); } static _Xconst XOMMethodsRec methods = { close_om, set_om_values, get_om_values, create_oc }; static XlcResource om_resources[] = { { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList), XOffsetOf(XOMRec, core.required_charset), XlcGetMask }, { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation), XOffsetOf(XOMRec, core.orientation_list), XlcGetMask }, { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool), XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask }, { XNContextualDrawing, NULLQUARK, sizeof(Bool), XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask } }; static OMData add_data( XOM om) { XOMGenericPart *gen = XOM_GENERIC(om); OMData new; new = (OMData) Xmalloc(sizeof(OMDataRec)); if (new == NULL) return NULL; gen->data = new; bzero((char *) new, sizeof(OMDataRec)); return new; } static _Xconst char *supported_charset_list[] = { "ISO8859-1", /* fix for bug4332979 */ "adobe-fontspecific", /* fix for bug4237353: "JISX0201.1976-0" entry should be removed from supported_charset_list because it is not a supported_charset for C locale "JISX0201.1976-0", */ "SUNOLCURSOR-1", "SUNOLGLYPH-1" }; static Bool init_om( XOM om) { XOMGenericPart *gen = XOM_GENERIC(om); OMData data; FontData font_data; char **required_list; XOrientation *orientation; char **value, buf[BUFSIZ], *bufptr; int count, length = 0; value = (char**)supported_charset_list; count = XlcNumber(supported_charset_list); data = add_data(om); if (data == NULL) return False; font_data = (FontData) Xmalloc(sizeof(FontDataRec) * count); if (font_data == NULL) return False; bzero((char *) font_data, sizeof(FontDataRec) * count); data->font_data = font_data; data->font_data_count = count; for ( ; count-- > 0; font_data++) { /* 1266793 This one is fine. *value points to one of the local strings in supported_charset_list[]. */ strcpy(buf, *value++); font_data->name = (char *) Xmalloc(strlen(buf) + 1); if (font_data->name == NULL) return False; strcpy(font_data->name, buf); } length += strlen(data->font_data->name) + 1; /* required charset list */ required_list = (char **) Xmalloc(sizeof(char *)); if (required_list == NULL) return False; bufptr = (char *) Xmalloc(length); if (bufptr == NULL) { Xfree(required_list); return False; } om->core.required_charset.charset_list = required_list; om->core.required_charset.charset_count = 1; /* always 1 */ data = gen->data; strcpy(bufptr, data->font_data->name); *required_list++ = bufptr; bufptr += strlen(bufptr) + 1; /* orientation list */ orientation = (XOrientation *) Xmalloc(sizeof(XOrientation)); if (orientation == NULL) return False; *orientation = XOMOrientation_LTR_TTB; om->core.orientation_list.orientation = orientation; om->core.orientation_list.num_orientation = 1; /* directional dependent drawing */ om->core.directional_dependent = False; /* contexual drawing */ om->core.contextual_drawing = False; /* context dependent */ om->core.context_dependent = False; return True; } XOM _XDefaultOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb, _Xconst char *res_name, _Xconst char *res_class) { XOM om; om = (XOM) Xmalloc(sizeof(XOMGenericRec)); if (om == NULL) return (XOM) NULL; bzero((char *) om, sizeof(XOMGenericRec)); om->methods = (XOMMethods)&methods; om->core.lcd = lcd; om->core.display = dpy; om->core.rdb = rdb; if (res_name) { om->core.res_name = (char *)Xmalloc(strlen(res_name) + 1); if (om->core.res_name == NULL) goto err; strcpy(om->core.res_name, res_name); } if (res_class) { om->core.res_class = (char *)Xmalloc(strlen(res_class) + 1); if (om->core.res_class == NULL) goto err; strcpy(om->core.res_class, res_class); } if (om_resources[0].xrm_name == NULLQUARK) _XlcCompileResourceList(om_resources, XlcNumber(om_resources)); om->core.resources = om_resources; om->core.num_resources = XlcNumber(om_resources); if (init_om(om) == False) goto err; return om; err: close_om(om); return (XOM) NULL; }