1/* 2 * Copyright 1992, 1993 by TOSHIBA Corp. 3 * 4 * Permission to use, copy, modify, and distribute this software and its 5 * documentation for any purpose and without fee is hereby granted, provided 6 * that the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of TOSHIBA not be used in advertising 9 * or publicity pertaining to distribution of the software without specific, 10 * written prior permission. TOSHIBA make no representations about the 11 * suitability of this software for any purpose. It is provided "as is" 12 * without express or implied warranty. 13 * 14 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 16 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 17 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 19 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20 * SOFTWARE. 21 * 22 * Author: Katsuhisa Yano TOSHIBA Corp. 23 * mopi@osa.ilab.toshiba.co.jp 24 */ 25 26#ifdef HAVE_CONFIG_H 27#include <config.h> 28#endif 29#include <stdio.h> 30#include "Xlibint.h" 31#include "XlcPublic.h" 32#include "XlcPubI.h" 33 34/* The list of all known XlcCharSets. They are identified by their name. */ 35 36typedef struct _XlcCharSetListRec { 37 XlcCharSet charset; 38 struct _XlcCharSetListRec *next; 39} XlcCharSetListRec, *XlcCharSetList; 40 41static XlcCharSetList charset_list = NULL; 42 43/* Returns the charset with the given name (including side suffix). 44 Returns NULL if not found. */ 45XlcCharSet 46_XlcGetCharSet( 47 const char *name) 48{ 49 XlcCharSetList list; 50 XrmQuark xrm_name; 51 52 xrm_name = XrmStringToQuark(name); 53 54 for (list = charset_list; list; list = list->next) { 55 if (xrm_name == list->charset->xrm_name) 56 return (XlcCharSet) list->charset; 57 } 58 59 return (XlcCharSet) NULL; 60} 61 62/* Returns the charset with the given encoding (no side suffix) and 63 responsible for at least the given side (XlcGL or XlcGR). 64 Returns NULL if not found. */ 65XlcCharSet 66_XlcGetCharSetWithSide( 67 const char *encoding_name, 68 XlcSide side) 69{ 70 XlcCharSetList list; 71 XrmQuark xrm_encoding_name; 72 73 xrm_encoding_name = XrmStringToQuark(encoding_name); 74 75 for (list = charset_list; list; list = list->next) { 76 if (list->charset->xrm_encoding_name == xrm_encoding_name 77 && (list->charset->side == XlcGLGR || list->charset->side == side)) 78 return (XlcCharSet) list->charset; 79 } 80 81 return (XlcCharSet) NULL; 82} 83 84/* Registers an XlcCharSet in the list of character sets. 85 Returns True if successful. */ 86Bool 87_XlcAddCharSet( 88 XlcCharSet charset) 89{ 90 XlcCharSetList list; 91 92 if (_XlcGetCharSet(charset->name)) 93 return False; 94 95 list = Xmalloc(sizeof(XlcCharSetListRec)); 96 if (list == NULL) 97 return False; 98 99 list->charset = charset; 100 list->next = charset_list; 101 charset_list = list; 102 103 return True; 104} 105 106/* List of resources for XlcCharSet. */ 107static XlcResource resources[] = { 108 { XlcNName, NULLQUARK, sizeof(char *), 109 XOffsetOf(XlcCharSetRec, name), XlcGetMask }, 110 { XlcNEncodingName, NULLQUARK, sizeof(char *), 111 XOffsetOf(XlcCharSetRec, encoding_name), XlcGetMask }, 112 { XlcNSide, NULLQUARK, sizeof(XlcSide), 113 XOffsetOf(XlcCharSetRec, side), XlcGetMask }, 114 { XlcNCharSize, NULLQUARK, sizeof(int), 115 XOffsetOf(XlcCharSetRec, char_size), XlcGetMask }, 116 { XlcNSetSize, NULLQUARK, sizeof(int), 117 XOffsetOf(XlcCharSetRec, set_size), XlcGetMask }, 118 { XlcNControlSequence, NULLQUARK, sizeof(char *), 119 XOffsetOf(XlcCharSetRec, ct_sequence), XlcGetMask } 120}; 121 122/* Retrieves a number of attributes of an XlcCharSet. 123 Return NULL if successful, otherwise the name of the first argument 124 specifying a nonexistent attribute. */ 125static char * 126get_values( 127 XlcCharSet charset, 128 XlcArgList args, 129 int num_args) 130{ 131 if (resources[0].xrm_name == NULLQUARK) 132 _XlcCompileResourceList(resources, XlcNumber(resources)); 133 134 return _XlcGetValues((XPointer) charset, resources, XlcNumber(resources), 135 args, num_args, XlcGetMask); 136} 137 138/* Retrieves a number of attributes of an XlcCharSet. 139 Return NULL if successful, otherwise the name of the first argument 140 specifying a nonexistent attribute. */ 141char * 142_XlcGetCSValues(XlcCharSet charset, ...) 143{ 144 va_list var; 145 XlcArgList args; 146 char *ret; 147 int num_args; 148 149 va_start(var, charset); 150 _XlcCountVaList(var, &num_args); 151 va_end(var); 152 153 va_start(var, charset); 154 _XlcVaToArgList(var, num_args, &args); 155 va_end(var); 156 157 if (args == (XlcArgList) NULL) 158 return (char *) NULL; 159 160 ret = get_values(charset, args, num_args); 161 162 Xfree(args); 163 164 return ret; 165} 166 167/* Creates a new XlcCharSet, given its name (including side suffix) and 168 Compound Text ESC sequence (normally at most 4 bytes). */ 169XlcCharSet 170_XlcCreateDefaultCharSet( 171 const char *name, 172 const char *ct_sequence) 173{ 174 XlcCharSet charset; 175 size_t name_len, ct_sequence_len; 176 const char *colon; 177 char *tmp; 178 179 charset = Xcalloc(1, sizeof(XlcCharSetRec)); 180 if (charset == NULL) 181 return (XlcCharSet) NULL; 182 183 name_len = strlen(name); 184 ct_sequence_len = strlen(ct_sequence); 185 186 /* Fill in name and xrm_name. */ 187 tmp = Xmalloc(name_len + 1 + ct_sequence_len + 1); 188 if (tmp == NULL) { 189 Xfree(charset); 190 return (XlcCharSet) NULL; 191 } 192 memcpy(tmp, name, name_len+1); 193 charset->name = tmp; 194 charset->xrm_name = XrmStringToQuark(charset->name); 195 196 /* Fill in encoding_name and xrm_encoding_name. */ 197 if ((colon = strchr(charset->name, ':')) != NULL) { 198 size_t length = (size_t)(colon - charset->name); 199 char *encoding_tmp = Xmalloc(length + 1); 200 if (encoding_tmp == NULL) { 201 Xfree((char *) charset->name); 202 Xfree(charset); 203 return (XlcCharSet) NULL; 204 } 205 memcpy(encoding_tmp, charset->name, length); 206 encoding_tmp[length] = '\0'; 207 charset->encoding_name = encoding_tmp; 208 charset->xrm_encoding_name = XrmStringToQuark(charset->encoding_name); 209 } else { 210 charset->encoding_name = charset->name; 211 charset->xrm_encoding_name = charset->xrm_name; 212 } 213 214 /* Fill in ct_sequence. */ 215 tmp += name_len + 1; 216 memcpy(tmp, ct_sequence, ct_sequence_len+1); 217 charset->ct_sequence = tmp; 218 219 /* Fill in side, char_size, set_size. */ 220 if (!_XlcParseCharSet(charset)) 221 /* If ct_sequence is not usable in Compound Text, remove it. */ 222 charset->ct_sequence = ""; 223 224 return (XlcCharSet) charset; 225} 226