static void init_state( XlcConv conv) { State state = (State) conv->state; static XlcCharSet default_GL_charset = NULL; static XlcCharSet default_GR_charset = NULL; if (default_GL_charset == NULL) { default_GL_charset = _XlcGetCharSet("ISO8859-1:GL"); default_GR_charset = _XlcGetCharSet("ISO8859-1:GR"); } /* The initial state is ISO-8859-1 on both sides. */ state->GL_charset = state->charset = default_GL_charset; state->GR_charset = default_GR_charset; state->Other_charset = NULL; state->ext_seg_left = 0; }
/* Registers an XlcCharSet in the list of character sets. Returns True if successful. */ Bool _XlcAddCharSet( XlcCharSet charset) { XlcCharSetList list; if (_XlcGetCharSet(charset->name)) return False; list = (XlcCharSetList) Xmalloc(sizeof(XlcCharSetListRec)); if (list == NULL) return False; list->charset = charset; list->next = charset_list; charset_list = list; return True; }
static XlcConv create_tofontcs_conv( XLCd lcd, XlcConvMethods methods) { XlcConv conv; int i, num, k, count; char **value, buf[20]; Utf8Conv *preferred; lazy_init_all_charsets(); for (i = 0, num = 0;; i++) { sprintf(buf, "fs%d.charset.name", i); _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); if (count < 1) { sprintf(buf, "fs%d.charset", i); _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); if (count < 1) break; } num += count; } conv = (XlcConv) Xmalloc(sizeof(XlcConvRec) + (num + 1) * sizeof(Utf8Conv)); if (conv == (XlcConv) NULL) return (XlcConv) NULL; preferred = (Utf8Conv *) ((char *) conv + sizeof(XlcConvRec)); /* Loop through all fontsets mentioned in the locale. */ for (i = 0, num = 0;; i++) { sprintf(buf, "fs%d.charset.name", i); _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); if (count < 1) { sprintf(buf, "fs%d.charset", i); _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); if (count < 1) break; } while (count-- > 0) { XlcCharSet charset = _XlcGetCharSet(*value++); const char *name = charset->encoding_name; /* If it wasn't already encountered... */ for (k = num - 1; k >= 0; k--) if (!strcmp(preferred[k]->name, name)) break; if (k < 0) { /* For fonts "ISO10646-1" means not utf8 but ucs2.*/ if (!strcmp("ISO10646-1", name)) { preferred[num++] = &all_charsets[ucs2_conv_index]; continue; } /* Look it up in all_charsets[]. */ for (k = 0; k < all_charsets_count-1; k++) if (!strcmp(all_charsets[k].name, name)) { /* Add it to the preferred set. */ preferred[num++] = &all_charsets[k]; break; } } } } preferred[num] = (Utf8Conv) NULL; conv->methods = methods; conv->state = (XPointer) preferred; return conv; }
/* Creates a new XlcCharSet, given its name (including side suffix) and Compound Text ESC sequence (normally at most 4 bytes), and makes it eligible for Compound Text processing. */ XlcCharSet _XlcAddCT( const char *name, const char *ct_sequence) { CTInfo ct_info, existing_info; XlcCharSet charset; const char *ct_ptr; int length; unsigned int type; unsigned char final_byte; charset = _XlcGetCharSet(name); if (charset != NULL) { /* Even if the charset already exists, it is OK to register a second Compound Text sequence for it. */ } else { /* Attempt to create the charset. */ charset = _XlcCreateDefaultCharSet(name, ct_sequence); if (charset == NULL) return (XlcCharSet) NULL; _XlcAddCharSet(charset); } /* Allocate a CTinfo record. */ length = strlen(ct_sequence); ct_info = Xmalloc(sizeof(CTInfoRec) + length+1); if (ct_info == NULL) return charset; ct_info->charset = charset; ct_info->ct_sequence = strcpy((char *) (ct_info + 1), ct_sequence); /* Parse the Compound Text sequence. */ ct_ptr = ct_sequence; type = _XlcParseCT(&ct_ptr, &length, &final_byte); ct_info->type = type; ct_info->final_byte = final_byte; switch (type) { case XctGL94: case XctGR94: case XctGR96: case XctGL94MB: case XctGR94MB: case XctOtherCoding: ct_info->ext_segment = NULL; ct_info->ext_segment_len = 0; break; case XctExtSeg: { /* By convention, the extended segment name is the encoding_name in lowercase. */ const char *q = charset->encoding_name; int n = strlen(q); char *p; /* Ensure ct_info->ext_segment_len <= 0x3fff - 6. */ if (n > 0x3fff - 6 - 1) { Xfree(ct_info); return charset; } p = Xmalloc(n+1); if (p == NULL) { Xfree(ct_info); return charset; } ct_info->ext_segment = p; ct_info->ext_segment_len = n+1; for ( ; n > 0; p++, q++, n--) *p = (*q >= 'A' && *q <= 'Z' ? *q - 'A' + 'a' : *q); *p = XctSTX; break; } default: Xfree(ct_info); return (XlcCharSet) NULL; } /* Insert it into the list, if not already present. */ existing_info = _XlcGetCTInfo(type, ct_info->final_byte, ct_info->ext_segment, ct_info->ext_segment_len); if (existing_info == NULL) { /* Insert it at the end. If there are duplicates CTinfo entries for the same XlcCharSet, we want the first (standard) one to override the second (user defined) one. */ ct_info->next = NULL; if (ct_list_end) ct_list_end->next = ct_info; else ct_list = ct_info; ct_list_end = ct_info; } else { if (existing_info->charset != charset /* We have a conflict, with one exception: JISX0208.1983-0 and JISX0208.1990-0 are the same for all practical purposes. */ && !(strncmp(existing_info->charset->name, "JISX0208", 8) == 0 && strncmp(charset->name, "JISX0208", 8) == 0)) { fprintf(stderr, "Xlib: charsets %s and %s have the same CT sequence\n", charset->name, existing_info->charset->name); if (strcmp(charset->ct_sequence, ct_sequence) == 0) charset->ct_sequence = ""; } Xfree(ct_info); } return charset; }