diff options
author | marha <marha@users.sourceforge.net> | 2011-04-15 15:08:38 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-04-15 15:08:38 +0000 |
commit | 205a4bdae76f287126db9f45a4f0ba631e3efca1 (patch) | |
tree | 6327d3e449dfe53ad6ee6125290581aae6f5ed35 /libX11/modules | |
parent | 898081f31f99dc35a1602a607a07d1aaff49ac40 (diff) | |
parent | 71372d36e1a3f0230b88808f70d35446fda12260 (diff) | |
download | vcxsrv-205a4bdae76f287126db9f45a4f0ba631e3efca1.tar.gz vcxsrv-205a4bdae76f287126db9f45a4f0ba631e3efca1.tar.bz2 vcxsrv-205a4bdae76f287126db9f45a4f0ba631e3efca1.zip |
svn merge ^/branches/released .
Diffstat (limited to 'libX11/modules')
-rw-r--r-- | libX11/modules/im/ximcp/imCallbk.c | 1506 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imDefIc.c | 4 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imDefIm.c | 51 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imDefLkup.c | 4 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imLcIm.c | 5 | ||||
-rw-r--r-- | libX11/modules/im/ximcp/imRmAttr.c | 8 | ||||
-rw-r--r-- | libX11/modules/om/generic/omGeneric.c | 4378 |
7 files changed, 2984 insertions, 2972 deletions
diff --git a/libX11/modules/im/ximcp/imCallbk.c b/libX11/modules/im/ximcp/imCallbk.c index 866b27c64..761021354 100644 --- a/libX11/modules/im/ximcp/imCallbk.c +++ b/libX11/modules/im/ximcp/imCallbk.c @@ -1,752 +1,754 @@ -/*********************************************************************** -Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts, -Copyright 1994 by FUJITSU LIMITED -Copyright 1994 by Sony Corporation - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Digital, FUJITSU -LIMITED and Sony Corporation not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. - -DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED -AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - Author: Hiroyuki Miyamoto Digital Equipment Corporation - miyamoto@jrd.dec.com - Modifier: Takashi Fujiwara FUJITSU LIMITED - fujiwara@a80.tech.yk.fujitsu.co.jp - Makoto Wakamatsu Sony Corporation - makoto@sm.sony.co.jp - -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "Xlcint.h" -#include "Ximint.h" -#include "XlcPubI.h" -#ifdef X_LOCALE -#define mblen(a,b) _Xmblen(a,b) -extern int _Xmblen (); -#endif - -#define sz_CARD8 1 -#define sz_INT8 1 -#define sz_CARD16 2 -#define sz_INT16 2 -#define sz_BITMASK16 sz_CARD16 -#define sz_CARD32 4 -#define sz_INT32 4 -#define sz_BITMASK32 sz_CARD32 -#define sz_XIMID sizeof(XIMID) -#define sz_XICID sizeof(XICID) -#define sz_XIMATTRID sizeof(XIMATTRID) -#define sz_XICATTRID sizeof(XICATTRID) -#define sz_ximPacketHeader (XIM_HEADER_SIZE + sz_XIMID + sz_XICID) -#define sz_ximGeometry 0 -#define sz_ximStrConversion (sz_CARD32 + sz_CARD32 + sz_CARD32 + sz_CARD32) -#define sz_ximPreeditStart 0 -#define sz_ximPreeditStartReply sz_INT32 -#define sz_ximPreeditCaret (sz_INT32 + sz_CARD32 + sz_CARD32) -#define sz_ximPreeditCaretReply sz_CARD32 -#define sz_ximPreeditDone 0 -#define sz_ximStatusStart 0 -#define sz_ximStatusDone 0 - -typedef enum { - XimCbSuccess, - XimCbNoCallback, - XimCbError, - XimCbQueued, - XimCbBadContextID, - XimCbBadOpcode -} XimCbStatus; - -typedef XimCbStatus (*XimCb)( - Xim, Xic, char*, int - ); - -#define PACKET_TO_MAJOROPCODE(p) (*(CARD8*)((CARD8*)(p))) -#define PACKET_TO_MINOROPCODE(p) (*(CARD8*)((CARD8*)(p) + sz_CARD8)) -#define PACKET_TO_LENGTH(p) (*(CARD16*)((CARD8*)(p) + sz_CARD8 + sz_CARD8)) -#define PACKET_TO_IMID(p) (*(XIMID*)((CARD8*)(p) + XIM_HEADER_SIZE)) -#define PACKET_TO_ICID(p) (*(XICID*)((CARD8*)(p) + XIM_HEADER_SIZE + sz_XIMID)) - -#define _XimWriteData(im,len,data) \ - (im->private.proto.write((im),(len),(XPointer)(data))) -#define _XimReadData(im,buf,buf_len,len) \ - (im->private.proto.read((im),(XPointer)(buf),(buf_len),&(len))) -#define _XimFlushData(im) im->private.proto.flush((im)) - -Private XimCbStatus _XimGeometryCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimStrConversionCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimPreeditStartCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimPreeditDoneCallback(Xim, Xic, char*, int); -Private void _free_memory_for_text(XIMText*); -Private XimCbStatus _XimPreeditDrawCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimPreeditCaretCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimStatusStartCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimStatusDoneCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimStatusDrawCallback(Xim, Xic, char*, int); -Private XimCbStatus _XimPreeditStateNotifyCallback(Xim, Xic, char *, int); - -#if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32)) -#define RConst /**/ -#else -#define RConst const -#endif - -/* NOTE: - * the table below depends on the protocol number - * defined in the IM Protocol document. - */ -static RConst XimCb callback_table[] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #000-009 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #010-019 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #020-029 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #030-039 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #040-049 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #050-059 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #060-069 */ - _XimGeometryCallback, /* #070 */ - _XimStrConversionCallback, /* #071 */ - NULL, /* #072 */ - _XimPreeditStartCallback, /* #073 */ - NULL, /* #074 */ - _XimPreeditDrawCallback, /* #075 */ - _XimPreeditCaretCallback, /* #076 */ - NULL, /* #077 */ - _XimPreeditDoneCallback, /* #078 */ - _XimStatusStartCallback, /* #079 */ - _XimStatusDrawCallback, /* #080 */ - _XimStatusDoneCallback, /* #081 */ - _XimPreeditStateNotifyCallback /* #082 */ - }; - - -Private Bool -_XimIsReadyForProcess(Xic ic) -{ - return(!ic->private.proto.waitCallback); /* check HM */ -} - -Private void -_XimProcessPendingCallbacks(Xic ic) -{ - XimPendingCallback pcbq; - - while (((pcbq = ic->private.proto.pend_cb_que) != (XimPendingCallback)NULL) - && _XimIsReadyForProcess(ic)) { - (void) (*callback_table[pcbq->major_opcode])(pcbq->im, - pcbq->ic, - pcbq->proto, - pcbq->proto_len); - ic->private.proto.pend_cb_que = pcbq->next; - Xfree(pcbq->proto); /* free memory of XimPendingCallback */ - Xfree(pcbq); - } -} - -Private void -_XimPutCbIntoQueue(Xic ic, XimPendingCallback call_data) -{ - XimPendingCallback pcbq = ic->private.proto.pend_cb_que; - - /* Queuing is FIFO - */ - while (pcbq != (XimPendingCallback)NULL) { - if (pcbq->next == (XimPendingCallback)NULL) { - break; - } - pcbq = pcbq->next; - } - if (pcbq == (XimPendingCallback)NULL) { - ic->private.proto.pend_cb_que = call_data; - } - else { - pcbq->next = call_data; - } -} - -Public Bool -_XimCbDispatch(Xim xim, - INT16 len, - XPointer data, - XPointer call_data) -{ - /* `data' points to the beginning of the packet defined in IM Protocol doc. - */ - int major_opcode = PACKET_TO_MAJOROPCODE(data); - XIMID imid = PACKET_TO_IMID(data); - XICID icid = PACKET_TO_ICID(data); - Xim im = (Xim)call_data; /* check HM */ - Xic ic = _XimICOfXICID(im, icid); - char* proto; - int proto_len; - - /* check validity of im/ic - */ - if ((imid != im->private.proto.imid) || !ic) { - return False; /* status = XimCbBadContextID; */ - } - - /* process pending callbacks - */ - _XimProcessPendingCallbacks(ic); - - /* check if the protocol should be processed here - */ - if (major_opcode > 82) { - return False; /* status = XimCbBadOpcode; */ - } - if (!callback_table[major_opcode]) { - return False; /* status = XimCbBadOpcode; */ - } - - /* move the pointer ahead by the IM Protocol packet header size - */ - proto = (char*)data + sz_ximPacketHeader; - proto_len = (int)len - sz_ximPacketHeader; - - /* check if it can be processed right away - * and if no, queue the protocol, otherwise invoke a callback - */ - if (!_XimIsReadyForProcess(ic)) { - - /* queue the protocol - */ - XimPendingCallback pcb; - char *proto_buf = (proto_len > 0) ? (char*)Xmalloc(proto_len) : NULL; - - pcb = (XimPendingCallback)Xmalloc(sizeof(XimPendingCallbackRec)); - if (pcb && (proto_len <= 0 || proto_buf)) { - if (proto_len > 0) - memcpy(proto_buf, proto, proto_len); - - pcb->major_opcode = major_opcode; - pcb->im = im; - pcb->ic = ic; - pcb->proto = proto_buf; - pcb->proto_len = proto_len; - pcb->next = (XimPendingCallback)NULL; /* queue is FIFO */ - _XimPutCbIntoQueue(ic, pcb); - /* status = XimCbQueued; */ - } else { - /* status = XimCbError; */ - } - } - else { - /* invoke each callback according to the major opcode. - * `proto' points to the next address of IM-ID and IC-ID. - * `proto_len' specifies the packet length. - */ - (void) (*callback_table[major_opcode])(im, ic, proto, proto_len); - } - return True; -} - -Private XimCbStatus -_XimGeometryCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.geometry_callback; - - /* invoke the callack - */ - if (cb && cb->callback) { - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimStrConversionCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.string_conversion_callback; /* check HM */ - XIMStringConversionCallbackStruct cbrec; - - /* invoke the callback - */ - if (cb && cb->callback) { - int p = XIM_HEADER_SIZE; - cbrec.position = (XIMStringConversionPosition) - *(CARD32*)&proto[p]; p += sz_CARD32; - cbrec.direction = (XIMCaretDirection) - *(CARD32*)&proto[p]; p += sz_CARD32; - cbrec.operation = (XIMStringConversionOperation) - *(CARD32*)&proto[p]; p += sz_CARD32; - cbrec.factor = (unsigned short) - *(CARD32*)&proto[p]; - - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbrec); - } - else { - - /* no callback registered - */ - _XimError(im, ic, - (CARD16)XIM_BadSomething, - (INT16)len, - (CARD16)XIM_STR_CONVERSION, - (char*)proto); /* send XIM_ERROR */ - return XimCbNoCallback; - } - - /* send a reply - */ - { - CARD8 *buf; - INT16 buf_len; - int p, length_in_bytes, i; - - /* Assumption: - * `cbrec.text->length' means the string length in characters - */ - { - length_in_bytes = (cbrec.text->encoding_is_wchar)? - sizeof(wchar_t) * cbrec.text->length: /* wchar */ - strlen(cbrec.text->string.mbs); /* mb */ - buf_len = XIM_HEADER_SIZE + - sz_CARD16 + - 2 + length_in_bytes + - XIM_PAD(2 + length_in_bytes) + - 2 + 2 + sz_CARD32 * cbrec.text->length; - buf = (CARD8*)Xmalloc(buf_len); - } - _XimSetHeader((XPointer)buf, XIM_STR_CONVERSION_REPLY, 0, &buf_len); - buf_len -= XIM_HEADER_SIZE; /* added by _XimSetHeader (HACK) */ - p = XIM_HEADER_SIZE; - *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; - *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; - *(CARD16*)&buf[p] = (CARD16)cbrec.text->length; p += sz_CARD16; - memcpy(&buf[p],&cbrec.text->string.mbs,length_in_bytes); - p += length_in_bytes; - *(CARD16*)&buf[p] = (CARD16)(sz_CARD32*cbrec.text->length); - p += XIM_PAD(2); - for (i = 0; i < (int)cbrec.text->length; i++) { - *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i]; - p += sz_CARD32; - } - - if (!(_XimWriteData(im, buf_len, buf))) { - return XimCbError; - } - _XimFlushData(im); - - Xfree(buf); - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimPreeditStartCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.preedit_attr.start_callback; - int ret; - - /* invoke the callback - */ - if (cb && cb->callback){ - ret = (*(cb->callback))((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - _XimError(im, ic, - (CARD16)XIM_BadSomething, - (INT16)len, - (CARD16)XIM_PREEDIT_START, - (char*)proto); /* send XIM_ERROR */ - return XimCbNoCallback; - } - - /* send a reply - */ - { - CARD32 buf32[(sz_ximPacketHeader + sz_ximPreeditStartReply) / 4]; - CARD8 *buf = (CARD8 *)buf32; - INT16 buf_len = sz_XIMID + sz_XICID + sz_ximPreeditStartReply; - int p; - - _XimSetHeader((XPointer)buf, XIM_PREEDIT_START_REPLY, 0, &buf_len); - p = XIM_HEADER_SIZE; - *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; - *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; - *(INT32*)&buf[p] = (INT32)ret; - - if (!(_XimWriteData(im, buf_len, buf))) { - return XimCbError; - } - _XimFlushData(im); - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimPreeditDoneCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.preedit_attr.done_callback; - - /* invoke the callback - */ - if (cb && cb->callback) { - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private void -_read_text_from_packet(Xim im, - char* buf, - XIMText** text_ptr) -{ - int status; - XIMText* text; - int tmp_len; - char* tmp_buf; - Status s = 0; - - status = (int)*(BITMASK32*)buf; buf += sz_BITMASK32; - - /* string part - */ - if (status & 0x00000001) /* "no string" bit on */ { - buf += sz_CARD16; /* skip "length of preedit string" */ - buf += 2; /* pad */ - *text_ptr = (XIMText*)NULL; - return; - } - - *text_ptr = text = (XIMText*)Xmalloc(sizeof(XIMText)); - if (text == (XIMText*)NULL) return; - - tmp_len = (int)*(CARD16*)buf; - buf += sz_CARD16; - if ((tmp_buf = (char*)Xmalloc(tmp_len + 1))) { - memcpy(tmp_buf, buf, tmp_len); - tmp_buf[tmp_len] = '\0'; - - text->encoding_is_wchar = False; - text->length = im->methods->ctstombs((XIM)im, - tmp_buf, tmp_len, - NULL, 0, &s); /* CT? HM */ - if (s != XLookupNone) { -#ifndef NO_DEC_I18N_FIX - /* Allow for NULL-terminated */ - if ((text->string.multi_byte = - (char*)Xmalloc(text->length * - XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1))) { -#else - if (text->string.multi_byte = (char*)Xmalloc(text->length+1)) { -#endif - int tmp; -#ifndef NO_DEC_I18N_FIX - char *char_tmp; - int char_len; -#endif - tmp = im->methods->ctstombs((XIM)im, - tmp_buf, tmp_len, -#ifndef NO_DEC_I18N_FIX - text->string.multi_byte, - text->length * XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1, -#else - text->string.multi_byte, text->length, -#endif - &s); - text->string.multi_byte[tmp] = '\0'; -#ifndef NO_DEC_I18N_FIX - text->length = 0; - char_tmp = text->string.multi_byte; - while (*char_tmp != '\0') { - char_len = mblen(char_tmp, strlen(char_tmp)); - char_tmp = char_tmp + char_len; - (text->length)++; - } -#endif - } - } - else { - text->length = 0; - text->string.multi_byte = NULL; - } - - Xfree(tmp_buf); - } - buf += tmp_len; - - buf += XIM_PAD(sz_CARD16 + tmp_len); /* pad */ - - /* feedback part - */ - if (status & 0x00000002) /* "no feedback" bit on */ { - text->feedback = (XIMFeedback*)NULL; - } - else { - int i, j; - - i = (int)*(CARD16*)buf; buf += sz_CARD16; - buf += sz_CARD16; /* skip `unused' */ - text->feedback = (XIMFeedback*)Xmalloc(i*(sizeof(XIMFeedback)/sizeof(CARD32))); - j = 0; - while (i > 0) { - text->feedback[j] = (XIMFeedback)*(CARD32*)buf; - buf += sz_CARD32; - i -= sz_CARD32; - j++; - } - /* - * text->length tells how long both the status string and - * the feedback array are. If there's "no string" the - * text->length was set to zero previously. See above. - * But if there is feedback (i.e. not "no feedback") then - * we need to convey the length of the feedback array. - * It might have been better if the protocol sent two - * different values, one for the length of the status - * string and one for the length of the feedback array. - */ - if (status & 0x00000001) /* "no string" bit on */ { - text->length = j; - } - } -} - -Private void -_free_memory_for_text(XIMText* text) -{ - if (text) { - if (text->string.multi_byte) - Xfree(text->string.multi_byte); - if (text->feedback) - Xfree(text->feedback); - Xfree(text); - } -} - -Private XimCbStatus -_XimPreeditDrawCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.preedit_attr.draw_callback; - XIMPreeditDrawCallbackStruct cbs; - - /* invoke the callback - */ - if (cb && cb->callback) { - cbs.caret = (int)*(INT32*)proto; proto += sz_INT32; - cbs.chg_first = (int)*(INT32*)proto; proto += sz_INT32; - cbs.chg_length = (int)*(INT32*)proto; proto += sz_INT32; - _read_text_from_packet(im, proto, &cbs.text); - - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); - - _free_memory_for_text((XIMText*)cbs.text); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimPreeditCaretCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.preedit_attr.caret_callback; - XIMPreeditCaretCallbackStruct cbs; - - /* invoke the callback - */ - if (cb && cb->callback) { - cbs.position = (int)*(INT32*)proto; proto += sz_INT32; - cbs.direction = (XIMCaretDirection)*(CARD32*)proto; proto += sz_CARD32; - cbs.style = (XIMCaretStyle)*(CARD32*)proto; proto += sz_CARD32; - - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); - } - else { - - /* no callback registered - */ - _XimError(im, ic, - (CARD16)XIM_BadSomething, - (INT16)len, - (CARD16)XIM_PREEDIT_CARET, - (char*)proto); /* send XIM_ERROR */ - return XimCbNoCallback; - } - - /* Send a reply - */ - { - CARD8 buf[sz_ximPacketHeader + sz_ximPreeditCaretReply]; - INT16 len = sz_XIMID + sz_XICID + sz_ximPreeditCaretReply; - int p; - - _XimSetHeader((XPointer)buf, XIM_PREEDIT_CARET_REPLY, 0, &len); - p = XIM_HEADER_SIZE; - *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16; - *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16; - *(CARD32*)&buf[p] = (CARD32)cbs.position; - - if (!(_XimWriteData(im, len, buf))) { - return XimCbError; - } - _XimFlushData(im); - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimStatusStartCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.status_attr.start_callback; - - /* invoke the callback - */ - if (cb && cb->callback) { - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimStatusDoneCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.status_attr.done_callback; - - /* invoke the callback - */ - if (cb && cb->callback) { - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimStatusDrawCallback(Xim im, - Xic ic, - char* proto, - int len) -{ - XICCallback* cb = &ic->core.status_attr.draw_callback; - XIMStatusDrawCallbackStruct cbs; - - /* invoke the callback - */ - if (cb && cb->callback) { - cbs.type = (XIMStatusDataType)*(CARD32*)proto; proto += sz_CARD32; - if (cbs.type == XIMTextType) { - _read_text_from_packet(im, proto, &cbs.data.text); - } - else if (cbs.type == XIMBitmapType) { - cbs.data.bitmap = (Pixmap)*(CARD32*)proto; - } - - (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs); - - if (cbs.type == XIMTextType) - _free_memory_for_text((XIMText *)cbs.data.text); - } - else { - - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - -Private XimCbStatus -_XimPreeditStateNotifyCallback( Xim im, Xic ic, char* proto, int len ) -{ - XICCallback *cb = &ic->core.preedit_attr.state_notify_callback; - - /* invoke the callack - */ - if( cb && cb->callback ) { - XIMPreeditStateNotifyCallbackStruct cbrec; - - cbrec.state = *(BITMASK32 *)proto; - (*cb->callback)( (XIC)ic, cb->client_data, (XPointer)&cbrec ); - } - else { - /* no callback registered - */ - return XimCbNoCallback; - } - - return XimCbSuccess; -} - +/***********************************************************************
+Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts,
+Copyright 1994 by FUJITSU LIMITED
+Copyright 1994 by Sony Corporation
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital, FUJITSU
+LIMITED and Sony Corporation not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED
+AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+ Author: Hiroyuki Miyamoto Digital Equipment Corporation
+ miyamoto@jrd.dec.com
+ Modifier: Takashi Fujiwara FUJITSU LIMITED
+ fujiwara@a80.tech.yk.fujitsu.co.jp
+ Makoto Wakamatsu Sony Corporation
+ makoto@sm.sony.co.jp
+
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "Xlcint.h"
+#include "Ximint.h"
+#include "XlcPubI.h"
+#ifdef X_LOCALE
+#define mblen(a,b) _Xmblen(a,b)
+extern int _Xmblen ();
+#endif
+
+#define sz_CARD8 1
+#define sz_INT8 1
+#define sz_CARD16 2
+#define sz_INT16 2
+#define sz_BITMASK16 sz_CARD16
+#define sz_CARD32 4
+#define sz_INT32 4
+#define sz_BITMASK32 sz_CARD32
+#define sz_XIMID sizeof(XIMID)
+#define sz_XICID sizeof(XICID)
+#define sz_XIMATTRID sizeof(XIMATTRID)
+#define sz_XICATTRID sizeof(XICATTRID)
+#define sz_ximPacketHeader (XIM_HEADER_SIZE + sz_XIMID + sz_XICID)
+#define sz_ximGeometry 0
+#define sz_ximStrConversion (sz_CARD32 + sz_CARD32 + sz_CARD32 + sz_CARD32)
+#define sz_ximPreeditStart 0
+#define sz_ximPreeditStartReply sz_INT32
+#define sz_ximPreeditCaret (sz_INT32 + sz_CARD32 + sz_CARD32)
+#define sz_ximPreeditCaretReply sz_CARD32
+#define sz_ximPreeditDone 0
+#define sz_ximStatusStart 0
+#define sz_ximStatusDone 0
+
+typedef enum {
+ XimCbSuccess,
+ XimCbNoCallback,
+ XimCbError,
+ XimCbQueued,
+ XimCbBadContextID,
+ XimCbBadOpcode
+} XimCbStatus;
+
+typedef XimCbStatus (*XimCb)(
+ Xim, Xic, char*, int
+ );
+
+#define PACKET_TO_MAJOROPCODE(p) (*(CARD8*)((CARD8*)(p)))
+#define PACKET_TO_MINOROPCODE(p) (*(CARD8*)((CARD8*)(p) + sz_CARD8))
+#define PACKET_TO_LENGTH(p) (*(CARD16*)((CARD8*)(p) + sz_CARD8 + sz_CARD8))
+#define PACKET_TO_IMID(p) (*(XIMID*)((CARD8*)(p) + XIM_HEADER_SIZE))
+#define PACKET_TO_ICID(p) (*(XICID*)((CARD8*)(p) + XIM_HEADER_SIZE + sz_XIMID))
+
+#define _XimWriteData(im,len,data) \
+ (im->private.proto.write((im),(len),(XPointer)(data)))
+#define _XimReadData(im,buf,buf_len,len) \
+ (im->private.proto.read((im),(XPointer)(buf),(buf_len),&(len)))
+#define _XimFlushData(im) im->private.proto.flush((im))
+
+Private XimCbStatus _XimGeometryCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimStrConversionCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimPreeditStartCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimPreeditDoneCallback(Xim, Xic, char*, int);
+Private void _free_memory_for_text(XIMText*);
+Private XimCbStatus _XimPreeditDrawCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimPreeditCaretCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimStatusStartCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimStatusDoneCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimStatusDrawCallback(Xim, Xic, char*, int);
+Private XimCbStatus _XimPreeditStateNotifyCallback(Xim, Xic, char *, int);
+
+#if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32))
+#define RConst /**/
+#else
+#define RConst const
+#endif
+
+/* NOTE:
+ * the table below depends on the protocol number
+ * defined in the IM Protocol document.
+ */
+static RConst XimCb callback_table[] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #000-009 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #010-019 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #020-029 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #030-039 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #040-049 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #050-059 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* #060-069 */
+ _XimGeometryCallback, /* #070 */
+ _XimStrConversionCallback, /* #071 */
+ NULL, /* #072 */
+ _XimPreeditStartCallback, /* #073 */
+ NULL, /* #074 */
+ _XimPreeditDrawCallback, /* #075 */
+ _XimPreeditCaretCallback, /* #076 */
+ NULL, /* #077 */
+ _XimPreeditDoneCallback, /* #078 */
+ _XimStatusStartCallback, /* #079 */
+ _XimStatusDrawCallback, /* #080 */
+ _XimStatusDoneCallback, /* #081 */
+ _XimPreeditStateNotifyCallback /* #082 */
+ };
+
+
+Private Bool
+_XimIsReadyForProcess(Xic ic)
+{
+ return(!ic->private.proto.waitCallback); /* check HM */
+}
+
+Private void
+_XimProcessPendingCallbacks(Xic ic)
+{
+ XimPendingCallback pcbq;
+
+ while (((pcbq = ic->private.proto.pend_cb_que) != (XimPendingCallback)NULL)
+ && _XimIsReadyForProcess(ic)) {
+ (void) (*callback_table[pcbq->major_opcode])(pcbq->im,
+ pcbq->ic,
+ pcbq->proto,
+ pcbq->proto_len);
+ ic->private.proto.pend_cb_que = pcbq->next;
+ Xfree(pcbq->proto); /* free memory of XimPendingCallback */
+ Xfree(pcbq);
+ }
+}
+
+Private void
+_XimPutCbIntoQueue(Xic ic, XimPendingCallback call_data)
+{
+ XimPendingCallback pcbq = ic->private.proto.pend_cb_que;
+
+ /* Queuing is FIFO
+ */
+ while (pcbq != (XimPendingCallback)NULL) {
+ if (pcbq->next == (XimPendingCallback)NULL) {
+ break;
+ }
+ pcbq = pcbq->next;
+ }
+ if (pcbq == (XimPendingCallback)NULL) {
+ ic->private.proto.pend_cb_que = call_data;
+ }
+ else {
+ pcbq->next = call_data;
+ }
+}
+
+Public Bool
+_XimCbDispatch(Xim xim,
+ INT16 len,
+ XPointer data,
+ XPointer call_data)
+{
+ /* `data' points to the beginning of the packet defined in IM Protocol doc.
+ */
+ int major_opcode = PACKET_TO_MAJOROPCODE(data);
+ XIMID imid = PACKET_TO_IMID(data);
+ XICID icid = PACKET_TO_ICID(data);
+ Xim im = (Xim)call_data; /* check HM */
+ Xic ic = _XimICOfXICID(im, icid);
+ char* proto;
+ int proto_len;
+
+ /* check validity of im/ic
+ */
+ if ((imid != im->private.proto.imid) || !ic) {
+ return False; /* status = XimCbBadContextID; */
+ }
+
+ /* process pending callbacks
+ */
+ _XimProcessPendingCallbacks(ic);
+
+ /* check if the protocol should be processed here
+ */
+ if (major_opcode > 82) {
+ return False; /* status = XimCbBadOpcode; */
+ }
+ if (!callback_table[major_opcode]) {
+ return False; /* status = XimCbBadOpcode; */
+ }
+
+ /* move the pointer ahead by the IM Protocol packet header size
+ */
+ proto = (char*)data + sz_ximPacketHeader;
+ proto_len = (int)len - sz_ximPacketHeader;
+
+ /* check if it can be processed right away
+ * and if no, queue the protocol, otherwise invoke a callback
+ */
+ if (!_XimIsReadyForProcess(ic)) {
+
+ /* queue the protocol
+ */
+ XimPendingCallback pcb;
+ char *proto_buf = (proto_len > 0) ? (char*)Xmalloc(proto_len) : NULL;
+
+ pcb = (XimPendingCallback)Xmalloc(sizeof(XimPendingCallbackRec));
+ if (pcb && (proto_len <= 0 || proto_buf)) {
+ if (proto_len > 0)
+ memcpy(proto_buf, proto, proto_len);
+
+ pcb->major_opcode = major_opcode;
+ pcb->im = im;
+ pcb->ic = ic;
+ pcb->proto = proto_buf;
+ pcb->proto_len = proto_len;
+ pcb->next = (XimPendingCallback)NULL; /* queue is FIFO */
+ _XimPutCbIntoQueue(ic, pcb);
+ /* status = XimCbQueued; */
+ } else {
+ /* status = XimCbError; */
+ Xfree(pcb);
+ Xfree(proto_buf);
+ }
+ }
+ else {
+ /* invoke each callback according to the major opcode.
+ * `proto' points to the next address of IM-ID and IC-ID.
+ * `proto_len' specifies the packet length.
+ */
+ (void) (*callback_table[major_opcode])(im, ic, proto, proto_len);
+ }
+ return True;
+}
+
+Private XimCbStatus
+_XimGeometryCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.geometry_callback;
+
+ /* invoke the callack
+ */
+ if (cb && cb->callback) {
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimStrConversionCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.string_conversion_callback; /* check HM */
+ XIMStringConversionCallbackStruct cbrec;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ int p = XIM_HEADER_SIZE;
+ cbrec.position = (XIMStringConversionPosition)
+ *(CARD32*)&proto[p]; p += sz_CARD32;
+ cbrec.direction = (XIMCaretDirection)
+ *(CARD32*)&proto[p]; p += sz_CARD32;
+ cbrec.operation = (XIMStringConversionOperation)
+ *(CARD32*)&proto[p]; p += sz_CARD32;
+ cbrec.factor = (unsigned short)
+ *(CARD32*)&proto[p];
+
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbrec);
+ }
+ else {
+
+ /* no callback registered
+ */
+ _XimError(im, ic,
+ (CARD16)XIM_BadSomething,
+ (INT16)len,
+ (CARD16)XIM_STR_CONVERSION,
+ (char*)proto); /* send XIM_ERROR */
+ return XimCbNoCallback;
+ }
+
+ /* send a reply
+ */
+ {
+ CARD8 *buf;
+ INT16 buf_len;
+ int p, length_in_bytes, i;
+
+ /* Assumption:
+ * `cbrec.text->length' means the string length in characters
+ */
+ {
+ length_in_bytes = (cbrec.text->encoding_is_wchar)?
+ sizeof(wchar_t) * cbrec.text->length: /* wchar */
+ strlen(cbrec.text->string.mbs); /* mb */
+ buf_len = XIM_HEADER_SIZE +
+ sz_CARD16 +
+ 2 + length_in_bytes +
+ XIM_PAD(2 + length_in_bytes) +
+ 2 + 2 + sz_CARD32 * cbrec.text->length;
+ buf = (CARD8*)Xmalloc(buf_len);
+ }
+ _XimSetHeader((XPointer)buf, XIM_STR_CONVERSION_REPLY, 0, &buf_len);
+ buf_len -= XIM_HEADER_SIZE; /* added by _XimSetHeader (HACK) */
+ p = XIM_HEADER_SIZE;
+ *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16;
+ *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16;
+ *(CARD16*)&buf[p] = (CARD16)cbrec.text->length; p += sz_CARD16;
+ memcpy(&buf[p],&cbrec.text->string.mbs,length_in_bytes);
+ p += length_in_bytes;
+ *(CARD16*)&buf[p] = (CARD16)(sz_CARD32*cbrec.text->length);
+ p += XIM_PAD(2);
+ for (i = 0; i < (int)cbrec.text->length; i++) {
+ *(CARD32*)&buf[p] = (CARD32)cbrec.text->feedback[i];
+ p += sz_CARD32;
+ }
+
+ if (!(_XimWriteData(im, buf_len, buf))) {
+ return XimCbError;
+ }
+ _XimFlushData(im);
+
+ Xfree(buf);
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimPreeditStartCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.preedit_attr.start_callback;
+ int ret;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback){
+ ret = (*(cb->callback))((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ _XimError(im, ic,
+ (CARD16)XIM_BadSomething,
+ (INT16)len,
+ (CARD16)XIM_PREEDIT_START,
+ (char*)proto); /* send XIM_ERROR */
+ return XimCbNoCallback;
+ }
+
+ /* send a reply
+ */
+ {
+ CARD32 buf32[(sz_ximPacketHeader + sz_ximPreeditStartReply) / 4];
+ CARD8 *buf = (CARD8 *)buf32;
+ INT16 buf_len = sz_XIMID + sz_XICID + sz_ximPreeditStartReply;
+ int p;
+
+ _XimSetHeader((XPointer)buf, XIM_PREEDIT_START_REPLY, 0, &buf_len);
+ p = XIM_HEADER_SIZE;
+ *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16;
+ *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16;
+ *(INT32*)&buf[p] = (INT32)ret;
+
+ if (!(_XimWriteData(im, buf_len, buf))) {
+ return XimCbError;
+ }
+ _XimFlushData(im);
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimPreeditDoneCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.preedit_attr.done_callback;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private void
+_read_text_from_packet(Xim im,
+ char* buf,
+ XIMText** text_ptr)
+{
+ int status;
+ XIMText* text;
+ int tmp_len;
+ char* tmp_buf;
+ Status s = 0;
+
+ status = (int)*(BITMASK32*)buf; buf += sz_BITMASK32;
+
+ /* string part
+ */
+ if (status & 0x00000001) /* "no string" bit on */ {
+ buf += sz_CARD16; /* skip "length of preedit string" */
+ buf += 2; /* pad */
+ *text_ptr = (XIMText*)NULL;
+ return;
+ }
+
+ *text_ptr = text = (XIMText*)Xmalloc(sizeof(XIMText));
+ if (text == (XIMText*)NULL) return;
+
+ tmp_len = (int)*(CARD16*)buf;
+ buf += sz_CARD16;
+ if ((tmp_buf = (char*)Xmalloc(tmp_len + 1))) {
+ memcpy(tmp_buf, buf, tmp_len);
+ tmp_buf[tmp_len] = '\0';
+
+ text->encoding_is_wchar = False;
+ text->length = im->methods->ctstombs((XIM)im,
+ tmp_buf, tmp_len,
+ NULL, 0, &s); /* CT? HM */
+ if (s != XLookupNone) {
+#ifndef NO_DEC_I18N_FIX
+ /* Allow for NULL-terminated */
+ if ((text->string.multi_byte =
+ (char*)Xmalloc(text->length *
+ XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1))) {
+#else
+ if (text->string.multi_byte = (char*)Xmalloc(text->length+1)) {
+#endif
+ int tmp;
+#ifndef NO_DEC_I18N_FIX
+ char *char_tmp;
+ int char_len;
+#endif
+ tmp = im->methods->ctstombs((XIM)im,
+ tmp_buf, tmp_len,
+#ifndef NO_DEC_I18N_FIX
+ text->string.multi_byte,
+ text->length * XLC_PUBLIC(im->core.lcd,mb_cur_max) + 1,
+#else
+ text->string.multi_byte, text->length,
+#endif
+ &s);
+ text->string.multi_byte[tmp] = '\0';
+#ifndef NO_DEC_I18N_FIX
+ text->length = 0;
+ char_tmp = text->string.multi_byte;
+ while (*char_tmp != '\0') {
+ char_len = mblen(char_tmp, strlen(char_tmp));
+ char_tmp = char_tmp + char_len;
+ (text->length)++;
+ }
+#endif
+ }
+ }
+ else {
+ text->length = 0;
+ text->string.multi_byte = NULL;
+ }
+
+ Xfree(tmp_buf);
+ }
+ buf += tmp_len;
+
+ buf += XIM_PAD(sz_CARD16 + tmp_len); /* pad */
+
+ /* feedback part
+ */
+ if (status & 0x00000002) /* "no feedback" bit on */ {
+ text->feedback = (XIMFeedback*)NULL;
+ }
+ else {
+ int i, j;
+
+ i = (int)*(CARD16*)buf; buf += sz_CARD16;
+ buf += sz_CARD16; /* skip `unused' */
+ text->feedback = (XIMFeedback*)Xmalloc(i*(sizeof(XIMFeedback)/sizeof(CARD32)));
+ j = 0;
+ while (i > 0) {
+ text->feedback[j] = (XIMFeedback)*(CARD32*)buf;
+ buf += sz_CARD32;
+ i -= sz_CARD32;
+ j++;
+ }
+ /*
+ * text->length tells how long both the status string and
+ * the feedback array are. If there's "no string" the
+ * text->length was set to zero previously. See above.
+ * But if there is feedback (i.e. not "no feedback") then
+ * we need to convey the length of the feedback array.
+ * It might have been better if the protocol sent two
+ * different values, one for the length of the status
+ * string and one for the length of the feedback array.
+ */
+ if (status & 0x00000001) /* "no string" bit on */ {
+ text->length = j;
+ }
+ }
+}
+
+Private void
+_free_memory_for_text(XIMText* text)
+{
+ if (text) {
+ if (text->string.multi_byte)
+ Xfree(text->string.multi_byte);
+ if (text->feedback)
+ Xfree(text->feedback);
+ Xfree(text);
+ }
+}
+
+Private XimCbStatus
+_XimPreeditDrawCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.preedit_attr.draw_callback;
+ XIMPreeditDrawCallbackStruct cbs;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ cbs.caret = (int)*(INT32*)proto; proto += sz_INT32;
+ cbs.chg_first = (int)*(INT32*)proto; proto += sz_INT32;
+ cbs.chg_length = (int)*(INT32*)proto; proto += sz_INT32;
+ _read_text_from_packet(im, proto, &cbs.text);
+
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs);
+
+ _free_memory_for_text((XIMText*)cbs.text);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimPreeditCaretCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.preedit_attr.caret_callback;
+ XIMPreeditCaretCallbackStruct cbs;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ cbs.position = (int)*(INT32*)proto; proto += sz_INT32;
+ cbs.direction = (XIMCaretDirection)*(CARD32*)proto; proto += sz_CARD32;
+ cbs.style = (XIMCaretStyle)*(CARD32*)proto; proto += sz_CARD32;
+
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs);
+ }
+ else {
+
+ /* no callback registered
+ */
+ _XimError(im, ic,
+ (CARD16)XIM_BadSomething,
+ (INT16)len,
+ (CARD16)XIM_PREEDIT_CARET,
+ (char*)proto); /* send XIM_ERROR */
+ return XimCbNoCallback;
+ }
+
+ /* Send a reply
+ */
+ {
+ CARD8 buf[sz_ximPacketHeader + sz_ximPreeditCaretReply];
+ INT16 len = sz_XIMID + sz_XICID + sz_ximPreeditCaretReply;
+ int p;
+
+ _XimSetHeader((XPointer)buf, XIM_PREEDIT_CARET_REPLY, 0, &len);
+ p = XIM_HEADER_SIZE;
+ *(CARD16*)&buf[p] = (CARD16)im->private.proto.imid; p += sz_CARD16;
+ *(CARD16*)&buf[p] = (CARD16)ic->private.proto.icid; p += sz_CARD16;
+ *(CARD32*)&buf[p] = (CARD32)cbs.position;
+
+ if (!(_XimWriteData(im, len, buf))) {
+ return XimCbError;
+ }
+ _XimFlushData(im);
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimStatusStartCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.status_attr.start_callback;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimStatusDoneCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.status_attr.done_callback;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)NULL);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimStatusDrawCallback(Xim im,
+ Xic ic,
+ char* proto,
+ int len)
+{
+ XICCallback* cb = &ic->core.status_attr.draw_callback;
+ XIMStatusDrawCallbackStruct cbs;
+
+ /* invoke the callback
+ */
+ if (cb && cb->callback) {
+ cbs.type = (XIMStatusDataType)*(CARD32*)proto; proto += sz_CARD32;
+ if (cbs.type == XIMTextType) {
+ _read_text_from_packet(im, proto, &cbs.data.text);
+ }
+ else if (cbs.type == XIMBitmapType) {
+ cbs.data.bitmap = (Pixmap)*(CARD32*)proto;
+ }
+
+ (*cb->callback)((XIC)ic, cb->client_data, (XPointer)&cbs);
+
+ if (cbs.type == XIMTextType)
+ _free_memory_for_text((XIMText *)cbs.data.text);
+ }
+ else {
+
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
+Private XimCbStatus
+_XimPreeditStateNotifyCallback( Xim im, Xic ic, char* proto, int len )
+{
+ XICCallback *cb = &ic->core.preedit_attr.state_notify_callback;
+
+ /* invoke the callack
+ */
+ if( cb && cb->callback ) {
+ XIMPreeditStateNotifyCallbackStruct cbrec;
+
+ cbrec.state = *(BITMASK32 *)proto;
+ (*cb->callback)( (XIC)ic, cb->client_data, (XPointer)&cbrec );
+ }
+ else {
+ /* no callback registered
+ */
+ return XimCbNoCallback;
+ }
+
+ return XimCbSuccess;
+}
+
diff --git a/libX11/modules/im/ximcp/imDefIc.c b/libX11/modules/im/ximcp/imDefIc.c index 6e7519a28..27e04e11c 100644 --- a/libX11/modules/im/ximcp/imDefIc.c +++ b/libX11/modules/im/ximcp/imDefIc.c @@ -1436,7 +1436,7 @@ _XimProtoCreateIC( num = im->core.ic_num_resources;
len = sizeof(XIMResource) * num;
if (!(res = (XIMResourceList)Xmalloc(len)))
- return (XIC)NULL;
+ goto ErrorOnCreatingIC;
(void)memcpy((char *)res, (char *)im->core.ic_resources, len);
ic->private.proto.ic_resources = res;
ic->private.proto.ic_num_resources = num;
@@ -1464,7 +1464,7 @@ _XimProtoCreateIC( num = im->private.proto.ic_num_inner_resources;
len = sizeof(XIMResource) * num;
if (!(res = (XIMResourceList)Xmalloc(len)))
- return (XIC)NULL;
+ goto ErrorOnCreatingIC;
(void)memcpy((char *)res,
(char *)im->private.proto.ic_inner_resources, len);
ic->private.proto.ic_inner_resources = res;
diff --git a/libX11/modules/im/ximcp/imDefIm.c b/libX11/modules/im/ximcp/imDefIm.c index 936ce12b2..2ea4427c3 100644 --- a/libX11/modules/im/ximcp/imDefIm.c +++ b/libX11/modules/im/ximcp/imDefIm.c @@ -1713,11 +1713,8 @@ _XimEncodingNegotiation( if (!(_XimSetEncodingByName(im, &name_ptr, &name_len)))
return False;
- if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len))) {
- if (name_ptr)
- Xfree(name_ptr);
- return False;
- }
+ if (!(_XimSetEncodingByDetail(im, &detail_ptr, &detail_len)))
+ goto free_name_ptr;
len = sizeof(CARD16)
+ sizeof(INT16)
@@ -1727,13 +1724,9 @@ _XimEncodingNegotiation( + sizeof(CARD16)
+ detail_len;
- if (!(buf = (CARD8 *)Xmalloc(XIM_HEADER_SIZE + len))) {
- if (name_ptr)
- Xfree(name_ptr);
- if (detail_ptr)
- Xfree(detail_ptr);
- return False;
- }
+ if (!(buf = (CARD8 *)Xmalloc(XIM_HEADER_SIZE + len)))
+ goto free_detail_ptr;
+
buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
buf_s[0] = im->private.proto.imid;
@@ -1750,7 +1743,7 @@ _XimEncodingNegotiation( _XimSetHeader((XPointer)buf, XIM_ENCODING_NEGOTIATION, 0, &len);
if (!(_XimWrite(im, len, (XPointer)buf))) {
Xfree(buf);
- return False;
+ goto free_detail_ptr;
}
_XimFlush(im);
Xfree(buf);
@@ -1767,27 +1760,21 @@ _XimEncodingNegotiation( preply = (XPointer)Xmalloc(buf_size);
ret_code = _XimRead(im, &len, preply, buf_size,
_XimEncodingNegoCheck, 0);
- if(ret_code != XIM_TRUE) {
- Xfree(preply);
- return False;
- }
+ if(ret_code != XIM_TRUE)
+ goto free_preply;
}
} else
- return False;
+ goto free_detail_ptr;
buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
if (*((CARD8 *)preply) == XIM_ERROR) {
_XimProcError(im, 0, (XPointer)&buf_s[3]);
- if(reply != preply)
- Xfree(preply);
- return False;
+ goto free_preply;
}
if (!(_XimGetEncoding(im, &buf_s[1], name_ptr, name_len,
- detail_ptr, detail_len))) {
- if(reply != preply)
- Xfree(preply);
- return False;
- }
+ detail_ptr, detail_len)))
+ goto free_preply;
+
if (name_ptr)
Xfree(name_ptr);
if (detail_ptr)
@@ -1797,6 +1784,18 @@ _XimEncodingNegotiation( Xfree(preply);
return True;
+
+free_preply:
+ if (reply != preply)
+ Xfree(preply);
+
+free_detail_ptr:
+ Xfree(detail_ptr);
+
+free_name_ptr:
+ Xfree(name_ptr);
+
+ return False;
}
#ifdef XIM_CONNECTABLE
diff --git a/libX11/modules/im/ximcp/imDefLkup.c b/libX11/modules/im/ximcp/imDefLkup.c index a269df062..e53845d4c 100644 --- a/libX11/modules/im/ximcp/imDefLkup.c +++ b/libX11/modules/im/ximcp/imDefLkup.c @@ -691,8 +691,10 @@ _XimCommitRecv( return False;
if (!(_XimProcCommit(ic, (BYTE *)&buf_s[5],
- (int)buf_s[4], &string, &string_len)))
+ (int)buf_s[4], &string, &string_len))) {
+ Xfree(keysym);
return False;
+ }
}
if (!(_XimRegCommitInfo(ic, string, string_len, keysym, keysym_len))) {
diff --git a/libX11/modules/im/ximcp/imLcIm.c b/libX11/modules/im/ximcp/imLcIm.c index 430e318d2..44516e9ee 100644 --- a/libX11/modules/im/ximcp/imLcIm.c +++ b/libX11/modules/im/ximcp/imLcIm.c @@ -489,10 +489,13 @@ _XimWriteCachedDefaultTree( /* This STILL might be racy on NFS */
if ( (fd = _XOpenFileMode (cachename, O_WRONLY | O_CREAT | O_EXCL,
- 0600)) < 0)
+ 0600)) < 0) {
+ Xfree(m);
return;
+ }
if (! (fp = fdopen (fd, "wb")) ) {
close (fd);
+ Xfree(m);
return;
}
fwrite (m, msize, 1, fp);
diff --git a/libX11/modules/im/ximcp/imRmAttr.c b/libX11/modules/im/ximcp/imRmAttr.c index f31af79aa..3183a6005 100644 --- a/libX11/modules/im/ximcp/imRmAttr.c +++ b/libX11/modules/im/ximcp/imRmAttr.c @@ -1433,8 +1433,10 @@ _XimGetAttributeID( bzero((char *)res, res_len);
values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
- if (!(tmp = (XPointer)Xmalloc(values_len)))
+ if (!(tmp = (XPointer)Xmalloc(values_len))) {
+ Xfree(res);
return False;
+ }
bzero(tmp, values_len);
values_list = (XIMValuesList *)tmp;
@@ -1480,8 +1482,10 @@ _XimGetAttributeID( bzero((char *)res, res_len);
values_len = sizeof(XIMValuesList) + (sizeof(char **) * n) + names_len;
- if (!(tmp = (XPointer)Xmalloc(values_len)))
+ if (!(tmp = (XPointer)Xmalloc(values_len))) {
+ Xfree(res);
return False;
+ }
bzero(tmp, values_len);
values_list = (XIMValuesList *)tmp;
diff --git a/libX11/modules/om/generic/omGeneric.c b/libX11/modules/om/generic/omGeneric.c index c78c0a9d6..330186d13 100644 --- a/libX11/modules/om/generic/omGeneric.c +++ b/libX11/modules/om/generic/omGeneric.c @@ -1,2188 +1,2190 @@ -/* #define FONTDEBUG */ -/* - * Copyright 1992, 1993 by TOSHIBA Corp. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of TOSHIBA not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. TOSHIBA make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * Author: Katsuhisa Yano TOSHIBA Corp. - * mopi@osa.ilab.toshiba.co.jp - */ -/* - * Copyright 1995 by FUJITSU LIMITED - * This is source code modified by FUJITSU LIMITED under the Joint - * Development Agreement for the CDE/Motif PST. - * - * Modifier: Takanori Tateno FUJITSU LIMITED - * - */ - -/* - * Fixed the algorithms in parse_fontname() and parse_fontdata() - * to improve the logic for determining which font should be - * returned for a given CharSet. We even added some comments - * so that you can figure out what in the heck we're doing. We - * realize this is a departure from the norm, but hey, we're - * rebels! :-) :-) - * - * Modifiers: Jeff Walls, Paul Anderson: HEWLETT-PACKARD - */ -/* - * Cleaned up mess, removed some blabla - * Egbert Eich, SuSE Linux AG - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "Xlibint.h" -#include "XomGeneric.h" -#include "XlcGeneric.h" -#include <X11/Xos.h> -#include <X11/Xatom.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> - -#define MAXFONTS 100 -#define PIXEL_SIZE_FIELD 7 -#define POINT_SIZE_FIELD 8 -#define CHARSET_ENCODING_FIELD 14 -#define XLFD_MAX_LEN 255 - -#if 0 -extern int _XmbDefaultTextEscapement(), _XwcDefaultTextEscapement(), - _Xutf8DefaultTextEscapement(); -extern int _XmbDefaultTextExtents(), _XwcDefaultTextExtents(), - _Xutf8DefaultTextExtents(); -extern Status _XmbDefaultTextPerCharExtents(), _XwcDefaultTextPerCharExtents(), - _Xutf8DefaultTextPerCharExtents(); -extern int _XmbDefaultDrawString(), _XwcDefaultDrawString(), - _Xutf8DefaultDrawString(); -extern void _XmbDefaultDrawImageString(), _XwcDefaultDrawImageString(), - _Xutf8DefaultDrawImageString(); - -extern int _XmbGenericTextEscapement(), _XwcGenericTextEscapement(), - _Xutf8GenericTextEscapement(); -extern int _XmbGenericTextExtents(), _XwcGenericTextExtents(), - _Xutf8GenericTextExtents(); -extern Status _XmbGenericTextPerCharExtents(), _XwcGenericTextPerCharExtents(), - _Xutf8GenericTextPerCharExtents(); -extern int _XmbGenericDrawString(), _XwcGenericDrawString(), - _Xutf8GenericDrawString(); -extern void _XmbGenericDrawImageString(), _XwcGenericDrawImageString(), - _Xutf8GenericDrawImageString(); - -extern void _XlcDbg_printValue (const char *str, char **value, int num); -#endif - -/* For VW/UDC start */ - -static FontData -init_fontdata( - FontData font_data, - int font_data_count) -{ - FontData fd; - int i; - - fd = (FontData)Xmalloc(sizeof(FontDataRec) * font_data_count); - if(fd == (FontData) NULL) - return False; - - memset(fd, 0x00, sizeof(FontData) * font_data_count); - for(i = 0 ; i < font_data_count ; i++) - fd[i] = font_data[i]; - - return fd; -} - -static VRotate -init_vrotate( - FontData font_data, - int font_data_count, - int type, - CodeRange code_range, - int code_range_num) -{ - VRotate vrotate; - int i; - - if(type == VROTATE_NONE) - return (VRotate)NULL; - - vrotate = (VRotate)Xmalloc(sizeof(VRotateRec) * font_data_count); - if(vrotate == (VRotate) NULL) - return False; - - memset(vrotate, 0x00, sizeof(VRotateRec) * font_data_count); - for(i = 0 ; i < font_data_count ; i++) { - vrotate[i].charset_name = font_data[i].name; - vrotate[i].side = font_data[i].side; - if(type == VROTATE_PART) { - vrotate[i].num_cr = code_range_num; - vrotate[i].code_range = code_range; - } - } - - return vrotate; -} - -static Bool -init_fontset( - XOC oc) -{ - XOCGenericPart *gen; - FontSet font_set; - OMData data; - int count; - - count = XOM_GENERIC(oc->core.om)->data_num; - data = XOM_GENERIC(oc->core.om)->data; - - font_set = (FontSet) Xmalloc(sizeof(FontSetRec) * count); - if (font_set == NULL) - return False; - memset((char *) font_set, 0x00, sizeof(FontSetRec) * count); - - gen = XOC_GENERIC(oc); - gen->font_set_num = count; - gen->font_set = font_set; - - for ( ; count-- > 0; data++, font_set++) { - font_set->charset_count = data->charset_count; - font_set->charset_list = data->charset_list; - - if((font_set->font_data = init_fontdata(data->font_data, - data->font_data_count)) == NULL) - goto err; - font_set->font_data_count = data->font_data_count; - if((font_set->substitute = init_fontdata(data->substitute, - data->substitute_num)) == NULL) - goto err; - font_set->substitute_num = data->substitute_num; - if((font_set->vmap = init_fontdata(data->vmap, - data->vmap_num)) == NULL) - goto err; - font_set->vmap_num = data->vmap_num; - - if(data->vrotate_type != VROTATE_NONE) { - /* A vrotate member is specified primary font data */ - /* as initial value. */ - if((font_set->vrotate = init_vrotate(data->font_data, - data->font_data_count, - data->vrotate_type, - data->vrotate, - data->vrotate_num)) == NULL) - goto err; - font_set->vrotate_num = data->font_data_count; - } - } - return True; - -err: - if(font_set->font_data) - Xfree(font_set->font_data); - if(font_set->substitute) - Xfree(font_set->substitute); - if(font_set->vmap) - Xfree(font_set->vmap); - if(font_set->vrotate) - Xfree(font_set->vrotate); - if(font_set) - Xfree(font_set); - gen->font_set = (FontSet) NULL; - gen->font_set_num = 0; - return False; -} - -/* For VW/UDC end */ - -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; -} - -/* For VW/UDC start */ - -static Bool -load_fontdata( - XOC oc, - FontData font_data, - int font_data_num) -{ - Display *dpy = oc->core.om->core.display; - FontData fd = font_data; - - if(font_data == NULL) return(True); - for( ; font_data_num-- ; fd++) { - if(fd->xlfd_name != (char *) NULL && fd->font == NULL) { - fd->font = XLoadQueryFont(dpy, fd->xlfd_name); - if (fd->font == NULL){ - return False; - } - } - } - return True; -} - -static Bool -load_fontset_data( - XOC oc, - FontSet font_set) -{ - Display *dpy = oc->core.om->core.display; - - if(font_set->font_name == (char *)NULL) return False ; - - /* If font_set->font is not NULL, it contains the *best* - * match font for this FontSet. - * -- jjw/pma (HP) - */ - if(font_set->font == NULL) { - font_set->font = XLoadQueryFont(dpy, font_set->font_name); - if (font_set->font == NULL){ - return False; - } - } - return True; -} - -static Bool -load_font( - XOC oc) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set = gen->font_set; - int num = gen->font_set_num; - - for ( ; num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - - if (load_fontset_data (oc, font_set) != True) - return False; -#ifndef TESTVERSION - if(load_fontdata(oc, font_set->font_data, - font_set->font_data_count) != True) - return False; - - if(load_fontdata(oc, font_set->substitute, - font_set->substitute_num) != True) - return False; -#endif - -/* Add 1996.05.20 */ - if( oc->core.orientation == XOMOrientation_TTB_RTL || - oc->core.orientation == XOMOrientation_TTB_LTR ){ - if (font_set->vpart_initialize == 0) { - load_fontdata(oc, font_set->vmap, font_set->vmap_num); - load_fontdata(oc, (FontData) font_set->vrotate, - font_set->vrotate_num); - font_set->vpart_initialize = 1; - } - } - - if (font_set->font->min_byte1 || font_set->font->max_byte1) - font_set->is_xchar2b = True; - else - font_set->is_xchar2b = False; - } - - return True; -} - -/* For VW/UDC end */ - -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, num = gen->font_set_num; - - for ( ; num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - - 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; - - XFreeFontNames(fn_list); - } - } - - return True; -} - -/* For Vertical Writing start */ - -static void -check_fontset_extents( - XCharStruct *overall, - int *logical_ascent, - int *logical_descent, - XFontStruct *font) -{ - overall->lbearing = min(overall->lbearing, font->min_bounds.lbearing); - overall->rbearing = max(overall->rbearing, font->max_bounds.rbearing); - overall->ascent = max(overall->ascent, font->max_bounds.ascent); - overall->descent = max(overall->descent, font->max_bounds.descent); - overall->width = max(overall->width, font->max_bounds.width); - *logical_ascent = max(*logical_ascent, font->ascent); - *logical_descent = max(*logical_descent, font->descent); -} - -/* For Vertical Writing end */ - -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; - int num = oc->core.font_info.num_font; - - 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; - - /* For Vertical Writing start */ - - while (--num > 0) { - font = *font_list++; - check_fontset_extents(&overall, &logical_ascent, &logical_descent, - font); - } - - { - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set = gen->font_set; - FontData font_data; - int font_set_num = gen->font_set_num; - int font_data_count; - - for( ; font_set_num-- ; font_set++) { - if(font_set->vmap_num > 0) { - font_data = font_set->vmap; - font_data_count = font_set->vmap_num; - for( ; font_data_count-- ; font_data++) { - if(font_data->font != NULL) { - check_fontset_extents(&overall, &logical_ascent, - &logical_descent, - font_data->font); - } - } - } - - if(font_set->vrotate_num > 0 && font_set->vrotate != NULL) { - font_data = (FontData) font_set->vrotate; - font_data_count = font_set->vrotate_num; - for( ; font_data_count-- ; font_data++) { - if(font_data->font != NULL) { - check_fontset_extents(&overall, &logical_ascent, - &logical_descent, - font_data->font); - } - } - } - } - } - - /* For Vertical Writing start */ - - 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; - int font_set_num; - XFontStruct **font_struct_list; - char **font_name_list, *font_name_buf; - int count, length; - - font_set = gen->font_set; - font_set_num = gen->font_set_num; - count = length = 0; - - for ( ; font_set_num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - - length += strlen(font_set->font_name) + 1; - - count++; - } - if (count == 0) - return False; - - font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *) * count); - if (font_struct_list == NULL) - return False; - - font_name_list = (char **) Xmalloc(sizeof(char *) * count); - 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 = count; - 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; - font_set_num = gen->font_set_num; - - for (count = 0; font_set_num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - - font_set->id = count; - 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; - - count++; - } - - 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; - int count = 0; - - list = XListFonts(oc->core.om->core.display, pattern, 1, &count); - if (list == NULL) - return NULL; - - name = (char *) Xmalloc(strlen(*list) + 1); - if (name) - strcpy(name, *list); - - XFreeFontNames(list); - - return name; -} - -/* For VW/UDC start*/ - -static char * -get_rotate_fontname( - char *font_name) -{ - char *pattern = NULL, *ptr = NULL; - char *fields[CHARSET_ENCODING_FIELD]; - char str_pixel[32], str_point[4]; - char *rotate_font_ptr = NULL; - int pixel_size = 0; - int field_num = 0, len = 0; - - if(font_name == (char *) NULL || (len = strlen(font_name)) <= 0 - || len > XLFD_MAX_LEN) - return NULL; - - pattern = (char *)Xmalloc(len + 1); - if(!pattern) - return NULL; - strcpy(pattern, font_name); - - memset(fields, 0, sizeof(char *) * 14); - ptr = pattern; - while(isspace(*ptr)) { - ptr++; - } - if(*ptr == '-') - ptr++; - - for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && ptr && *ptr ; - ptr++, field_num++) { - fields[field_num] = ptr; - - if((ptr = strchr(ptr, '-'))) { - *ptr = '\0'; - } else { - field_num++; /* Count last field */ - break; - } - } - - if(field_num < CHARSET_ENCODING_FIELD) - return NULL; - - /* Pixel Size field : fields[6] */ - for(ptr = fields[PIXEL_SIZE_FIELD - 1] ; ptr && *ptr; ptr++) { - if(!isdigit(*ptr)) { - if(*ptr == '['){ /* 960730 */ - strcpy(pattern, font_name); - return(pattern); - } - if(pattern) - Xfree(pattern); - return NULL; - } - } - pixel_size = atoi(fields[PIXEL_SIZE_FIELD - 1]); - sprintf(str_pixel, "[ 0 ~%d %d 0 ]", pixel_size, pixel_size); - fields[6] = str_pixel; - - /* Point Size field : fields[7] */ - strcpy(str_point, "*"); - fields[POINT_SIZE_FIELD - 1] = str_point; - - len = 0; - for (field_num = 0; field_num < CHARSET_ENCODING_FIELD && - fields[field_num]; field_num++) { - len += 1 + strlen(fields[field_num]); - } - - /* Max XLFD length is 255 */ - if (len > XLFD_MAX_LEN) - return NULL; - - rotate_font_ptr = (char *)Xmalloc(len + 1); - if(!rotate_font_ptr) - return NULL; - - rotate_font_ptr[0] = '\0'; - - for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && - fields[field_num] ; field_num++) { - strcat(rotate_font_ptr, "-"); - strcat(rotate_font_ptr, fields[field_num]); - } - - if(pattern) - Xfree(pattern); - - return rotate_font_ptr; -} - -static Bool -is_match_charset( - FontData font_data, - char *font_name) -{ - char *last; - int length, name_len; - - name_len = strlen(font_name); - last = font_name + name_len; - - length = strlen(font_data->name); - if (length > name_len) - return False; - - if (_XlcCompareISOLatin1(last - length, font_data->name) == 0) - return True; - - return False; -} - -#if 0 -static char * -get_font_name_from_list( - XOC oc, - char *pattern, - FontData font_data) -{ - char **list, *name = (char *)NULL, *fname; - int count = 0, i; - - list = XListFonts(oc->core.om->core.display, pattern, MAXFONTS, &count); - if (list == NULL) - return NULL; - - for (i = 0; i < count; i++) { - fname = list[i]; - if(is_match_charset(font_data, fname) == True) { - name = (char *) Xmalloc(strlen(fname) + 1); - if (name) - strcpy(name, fname); - break; - } - } - - XFreeFontNames(list); - - return name; -} -#endif - -static int -parse_all_name( - XOC oc, - FontData font_data, - char *pattern) -{ - -#ifdef OLDCODE - if(is_match_charset(font_data, pattern) != True) - return False; - - font_data->xlfd_name = (char *)Xmalloc(strlen(pattern)+1); - if(font_data->xlfd_name == NULL) - return (-1); - - strcpy(font_data->xlfd_name, pattern); - return True; -#else /* OLDCODE */ - Display *dpy = oc->core.om->core.display; - char **fn_list = NULL, *prop_fname = NULL; - int list_num; - XFontStruct *fs_list; - if(is_match_charset(font_data, pattern) != True) { - /* - * pattern should not contain any wildcard (execpt '?') - * this was probably added to make this case insensitive. - */ - if ((fn_list = XListFontsWithInfo(dpy, pattern, - MAXFONTS, - &list_num, &fs_list)) == NULL) { - return False; - } - /* shouldn't we loop here ? */ - else if ((prop_fname = get_prop_name(dpy, fs_list)) == NULL) { - XFreeFontInfo(fn_list, fs_list, list_num); - return False; - } - else if ((is_match_charset(font_data, prop_fname) != True)) { - XFree(prop_fname); - XFreeFontInfo(fn_list, fs_list, list_num); - return False; - } - else { - font_data->xlfd_name = prop_fname; - XFreeFontInfo(fn_list, fs_list, list_num); - return True; - } - } - - font_data->xlfd_name = (char *)Xmalloc(strlen(pattern)+1); - if(font_data->xlfd_name == NULL) - return (-1); - - strcpy(font_data->xlfd_name, pattern); - return True; -#endif /* OLDCODE */ -} - -static int -parse_omit_name( - XOC oc, - FontData font_data, - char *pattern) -{ - char* last = (char *) NULL; - char* base_name; - char buf[XLFD_MAX_LEN + 1]; - int length = 0; - int num_fields; - /* - * If the font specified by "pattern" is expandable to be - * a member of "font_data"'s FontSet, we've found a match. - */ - if(is_match_charset(font_data, pattern) == True) { - if ((font_data->xlfd_name = get_font_name(oc, pattern)) != NULL) { - return True; - } - } - - length = strlen (pattern); - - if (length > XLFD_MAX_LEN) - return -1; - - strcpy(buf, pattern); - last = buf + length - 1; - - /* Replace the original encoding with the encoding for this FontSet. */ - - /* Figure out how many fields have been specified in this xlfd. */ - for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++) - if (*base_name == '-') num_fields++; - - switch (num_fields) { - case 12: - /* This is the best way to have specifed the fontset. In this - * case, there is no original encoding. E.g., - * -*-*-*-*-*-*-14-*-*-*-*-* - * To this, we'll append a dash: - * -*-*-*-*-*-*-14-*-*-*-*-*- - * then append the encoding to get: - * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 - */ - /* - * Take care of: - * -*-*-*-*-*-*-14-*-*-*-*- - */ - if (*(last) == '-') - *++last = '*'; - - *++last = '-'; - break; - case 13: - /* Got the charset, not the encoding, zap the charset In this - * case, there is no original encoding, but there is a charset. E.g., - * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990 - * To this, we remove the charset: - * -*-*-*-*-*-*-14-*-*-*-*-*- - * then append the new encoding to get: - * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 - */ - last = strrchr (buf, '-'); - num_fields = 12; - break; - case 14: - /* Both the charset and the encoding are specified. Get rid - * of them so that we can append the new charset encoding. E.g., - * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990-0 - * To this, we'll remove the encoding and charset to get: - * -*-*-*-*-*-*-14-*-*-*-*-*- - * then append the new encoding to get: - * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 - */ - last = strrchr (buf, '-'); - *last = '\0'; - last = strrchr (buf, '-'); - num_fields = 12; - break; - default: - if (*last != '-') - *++last = '-'; - break; - } - - /* At this point, "last" is pointing to the last "-" in the - * xlfd, and all xlfd's at this point take a form similar to: - * -*-*-*-*-*-*-14-*-*-*-*-*- - * (i.e., no encoding). - * After the strcpy, we'll end up with something similar to: - * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0 - * - * If the modified font is found in the current FontSet, - * we've found a match. - */ - - last++; - - if ((last - buf) + strlen(font_data->name) > XLFD_MAX_LEN) - return -1; - - strcpy(last, font_data->name); - if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL) - return True; - - /* This may mot be needed anymore as XListFonts() takes care of this */ - while (num_fields < 12) { - if ((last - buf) > (XLFD_MAX_LEN - 2)) - return -1; - *last = '*'; - *(last + 1) = '-'; - strcpy(last + 2, font_data->name); - num_fields++; - last+=2; - if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL) - return True; - } - - - return False; -} - - -typedef enum{C_PRIMARY, C_SUBSTITUTE, C_VMAP, C_VROTATE } ClassType; - -static int -parse_fontdata( - XOC oc, - FontSet font_set, - FontData font_data, - int font_data_count, - char **name_list, - int name_list_count, - ClassType class, - FontDataRec *font_data_return) -{ - - char **cur_name_list = name_list; - char *font_name = (char *) NULL; - char *pattern = (char *) NULL; - int found_num = 0, ret = 0; - int count = name_list_count; - - if(name_list == NULL || count <= 0) { - return False; - } - - if(font_data == NULL || font_data_count <= 0) { - return False; - } - - /* Loop through each font encoding defined in the "font_data" FontSet. */ - for ( ; font_data_count-- > 0; font_data++) { - Bool is_found = False; - font_name = (char *) NULL; - count = name_list_count; - cur_name_list = name_list; - - /* - * Loop through each font specified by the user - * in the call to XCreateFontset(). - */ - while (count-- > 0) { - pattern = *cur_name_list++; - if (pattern == NULL || *pattern == '\0') - continue; -#ifdef FONTDEBUG - fprintf(stderr,"Font pattern: %s %s\n", - pattern,font_data->name); -#endif - - /* - * If the current font is fully specified (i.e., the - * xlfd contains no wildcards) and the font exists on - * the X Server, we have a match. - */ - if (strchr(pattern, '*') == NULL && - (font_name = get_font_name(oc, pattern))) { - /* - * Find the full xlfd name for this font. If the font is - * already in xlfd format, it is simply returned. If the - * font is an alias for another font, the xlfd of the - * aliased font is returned. - */ - ret = parse_all_name(oc, font_data, font_name); - Xfree(font_name); - - if (ret == -1) return -1; - if (ret == False) continue; - /* - * Since there was an exact match of a fully-specified font - * or a font alias, we can return now since the desired font - * was found for the current font encoding for this FontSet. - * - * Previous implementations of this algorithm would - * not return here. Instead, they continued searching - * through the font encodings for this FontSet. The side-effect - * of that behavior is you may return a "substitute" match - * instead of an "exact" match. We believe there should be a - * preference on exact matches. Therefore, as soon as we - * find one, we bail. - * - * Also, previous implementations seemed to think it was - * important to find either a primary or substitute font - * for each Font encoding in the FontSet before returning an - * acceptable font. We don't believe this is necessary. - * All the client cares about is finding a reasonable font - * for what was passed in. If we find an exact match, - * there's no reason to look any further. - * - * -- jjw/pma (HP) - */ - if (font_data_return) { - font_data_return->xlfd_name = (char *)Xmalloc - (strlen(font_data->xlfd_name) + 1); - if (!font_data_return->xlfd_name) return -1; - - strcpy (font_data_return->xlfd_name, font_data->xlfd_name); - - font_data_return->side = font_data->side; - } -#ifdef FONTDEBUG - fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name); -#endif - - return True; - } - /* - * If the font name is not fully specified - * (i.e., it has wildcards), we have more work to do. - * See the comments in parse_omit_name() - * for the list of things to do. - */ - ret = parse_omit_name(oc, font_data, pattern); - - if (ret == -1) return -1; - if (ret == False) continue; - - /* - * A font which matched the wild-carded specification was found. - * Only update the return data if a font has not yet been found. - * This maintains the convention that FontSets listed higher in - * a CodeSet in the Locale Database have higher priority than - * those FontSets listed lower in the CodeSet. In the following - * example: - * - * fs1 { - * charset HP-JIS:GR - * font JISX0208.1990-0:GL;\ - * JISX0208.1990-1:GR;\ - * JISX0208.1983-0:GL;\ - * JISX0208.1983-1:GR - * } - * - * a font found in the JISX0208.1990-0 FontSet will have a - * higher priority than a font found in the JISX0208.1983-0 - * FontSet. - */ - if (font_data_return && font_data_return->xlfd_name == NULL) { - -#ifdef FONTDEBUG - fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name); -#endif - font_data_return->xlfd_name = (char *)Xmalloc - (strlen(font_data->xlfd_name) + 1); - if (!font_data_return->xlfd_name) return -1; - - strcpy (font_data_return->xlfd_name, font_data->xlfd_name); - font_data_return->side = font_data->side; - } - - found_num++; - is_found = True; - - break; - } - - switch(class) { - case C_PRIMARY: - if(is_found == False) { - /* - * Did not find a font for the current FontSet. Check the - * FontSet's "substitute" font for a match. If we find a - * match, we'll keep searching in hopes of finding an exact - * match later down the FontSet list. - * - * when we return and we have found a font font_data_return - * contains the first (ie. best) match no matter if this - * is a C_PRIMARY or a C_SUBSTITUTE font - */ - ret = parse_fontdata(oc, font_set, font_set->substitute, - font_set->substitute_num, name_list, - name_list_count, C_SUBSTITUTE, - font_data_return); - if (ret == -1) return -1; - if (ret == False) continue; - - found_num++; - is_found = True; - } -#ifdef TESTVERSION - else - return True; -#endif - break; - - case C_SUBSTITUTE: - case C_VMAP: - if(is_found == True) - return True; - break; - - case C_VROTATE: - if(is_found == True) { - char *rotate_name; - - if((rotate_name = get_rotate_fontname(font_data->xlfd_name)) - != NULL) { - Xfree(font_data->xlfd_name); - font_data->xlfd_name = rotate_name; - - return True; - } - Xfree(font_data->xlfd_name); - font_data->xlfd_name = NULL; - return False; - } - break; - } - } - - if(class == C_PRIMARY && found_num >= 1) - return True; - - return False; -} - - -static int -parse_vw( - XOC oc, - FontSet font_set, - char **name_list, - int count) -{ - FontData vmap = font_set->vmap; - VRotate vrotate = font_set->vrotate; - int vmap_num = font_set->vmap_num; - int vrotate_num = font_set->vrotate_num; - int ret = 0, i = 0; - - if(vmap_num > 0) { - if(parse_fontdata(oc, font_set, vmap, vmap_num, name_list, - count, C_VMAP,NULL) == -1) - return (-1); - } - - if(vrotate_num > 0) { - ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num, - name_list, count, C_VROTATE, NULL); - if(ret == -1) { - return (-1); - } else if(ret == False) { - CodeRange code_range; - int num_cr; - int sub_num = font_set->substitute_num; - - code_range = vrotate[0].code_range; /* ? */ - num_cr = vrotate[0].num_cr; /* ? */ - for(i = 0 ; i < vrotate_num ; i++) { - if(vrotate[i].xlfd_name) - Xfree(vrotate[i].xlfd_name); - } - Xfree(vrotate); - - if(sub_num > 0) { - vrotate = font_set->vrotate = (VRotate)Xmalloc - (sizeof(VRotateRec) * sub_num); - if(font_set->vrotate == (VRotate)NULL) - return (-1); - memset(font_set->vrotate, 0x00, sizeof(VRotateRec) * sub_num); - - for(i = 0 ; i < sub_num ; i++) { - vrotate[i].charset_name = font_set->substitute[i].name; - vrotate[i].side = font_set->substitute[i].side; - vrotate[i].code_range = code_range; - vrotate[i].num_cr = num_cr; - } - vrotate_num = font_set->vrotate_num = sub_num; - } else { - vrotate = font_set->vrotate = (VRotate)NULL; - } - - ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num, - name_list, count, C_VROTATE, NULL); - if(ret == -1) - return (-1); - } - } - - return True; -} - -static int -parse_fontname( - XOC oc) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set; - FontDataRec font_data_return; - char *base_name, **name_list; - int font_set_num = 0; - int found_num = 0; - int count = 0; - int ret; - int i; - - name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count); - if (name_list == NULL) - return -1; - - font_set = gen->font_set; - font_set_num = gen->font_set_num; - - /* Loop through all of the CharSets defined in the Locale - * database for the current Locale. - */ - for( ; font_set_num-- > 0 ; font_set++) { - if(font_set->font_name) - continue; - - if(font_set->font_data_count > 0) { - - /* - * If there are a non-zero number of FontSets defined - * for this CharSet. - * Try to find a font for this CharSet. If we find an - * acceptable font, we save the information for return - * to the client. If we do not find an acceptable font, - * a "missing_charset" will be reported to the client - * for this CharSet. - */ - font_data_return. xlfd_name = NULL; - font_data_return.side = XlcUnknown; - - ret = parse_fontdata(oc, font_set, font_set->font_data, - font_set->font_data_count, - name_list, count, C_PRIMARY, - &font_data_return); - if(ret == -1) { - goto err; - } else if(ret == True) { - /* - * We can't just loop thru fontset->font_data to - * find the first (ie. best) match: parse_fontdata - * will try a substitute font if no primary one could - * be matched. It returns the required information in - * font_data_return. - */ - font_set->font_name = (char *)Xmalloc - (strlen(font_data_return.xlfd_name) + 1); - if(font_set->font_name == (char *) NULL) - goto err; - strcpy(font_set->font_name, font_data_return.xlfd_name); - font_set->side = font_data_return.side; - - Xfree (font_data_return.xlfd_name); - font_data_return.xlfd_name = NULL; - - if(parse_vw(oc, font_set, name_list, count) == -1) - goto err; - found_num++; - } - - } else if(font_set->substitute_num > 0) { - /* - * If there are no FontSets defined for this - * CharSet. We can only find "substitute" fonts. - */ - ret = parse_fontdata(oc, font_set, font_set->substitute, - font_set->substitute_num, - name_list, count, C_SUBSTITUTE, NULL); - if(ret == -1) { - goto err; - } else if(ret == True) { - for(i=0;i<font_set->substitute_num;i++){ - if(font_set->substitute[i].xlfd_name != NULL){ - break; - } - } - font_set->font_name = (char *)Xmalloc - (strlen(font_set->substitute[i].xlfd_name) + 1); - if(font_set->font_name == (char *) NULL) - goto err; - strcpy(font_set->font_name,font_set->substitute[i].xlfd_name); - font_set->side = font_set->substitute[i].side; - if(parse_vw(oc, font_set, name_list, count) == -1) - goto err; - - found_num++; - } - } - } - - 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); - /* Prevent this from being freed twice */ - oc->core.base_name_list = NULL; - - return -1; -} - -/* For VW/UDC end*/ - -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_num; - int result = 1; - - font_set = gen->font_set; - font_set_num = gen->font_set_num; - count = length = 0; - - for ( ; font_set_num-- > 0; font_set++) { - if (font_set->info || font_set->font) { - continue; - } - - /* Change 1996.01.23 start */ - if(font_set->font_data_count <= 0 || - font_set->font_data == (FontData)NULL) { - if(font_set->substitute_num <= 0 || - font_set->substitute == (FontData)NULL) { - if(font_set->charset_list != NULL){ - length += - strlen(font_set->charset_list[0]->encoding_name) + 1; - } else { - length += 1; - } - } else { - length += strlen(font_set->substitute->name) + 1; - } - } else { - length += strlen(font_set->font_data->name) + 1; - } - /* Change 1996.01.23 end */ - count++; - } - - if (count < 1) { - return True; - } - - charset_list = (char **) Xmalloc(sizeof(char *) * count); - 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; - oc->core.missing_list.charset_count = count; - - font_set = gen->font_set; - font_set_num = gen->font_set_num; - - for ( ; font_set_num-- > 0; font_set++) { - if (font_set->info || font_set->font) { - continue; - } - - /* Change 1996.01.23 start */ - if(font_set->font_data_count <= 0 || - font_set->font_data == (FontData)NULL) { - if(font_set->substitute_num <= 0 || - font_set->substitute == (FontData)NULL) { - if(font_set->charset_list != NULL){ - strcpy(charset_buf, - font_set->charset_list[0]->encoding_name); - } else { - strcpy(charset_buf, ""); - } - result = 0; - } else { - strcpy(charset_buf, font_set->substitute->name); - } - } else { - strcpy(charset_buf, font_set->font_data->name); - } - /* Change 1996.01.23 end */ - *charset_list++ = charset_buf; - charset_buf += strlen(charset_buf) + 1; - } - - if(result == 0) { - return(False); - } - - return True; -} - -static Bool -create_fontset( - XOC oc) -{ - XOMGenericPart *gen = XOM_GENERIC(oc->core.om); - 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 (gen->on_demand_loading == True) { - if (load_font_info(oc) == False) - return False; - } else { - 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; -} - -/* For VW/UDC start */ -static void -free_fontdataOC( - Display *dpy, - FontData font_data, - int font_data_count) -{ - for( ; font_data_count-- ; font_data++) { - if(font_data->xlfd_name){ - Xfree(font_data->xlfd_name); - font_data->xlfd_name = NULL; - } - if(font_data->font){ /* ADD 1996.01.7 */ - if(font_data->font->fid) /* Add 1996.01.23 */ - XFreeFont(dpy,font_data->font); /* ADD 1996.01.7 */ - else /* Add 1996.01.23 */ - XFreeFontInfo(NULL, font_data->font, 1);/* Add 1996.01.23 */ - font_data->font = NULL; - } -/* - * font_data->name and font_data->scopes belong to the OM not OC. - * To save space this data is shared between OM and OC. We are - * not allowed to free it here. - * It has been moved to free_fontdataOM() - */ -/* - if(font_data->scopes){ - Xfree(font_data->scopes); - font_data->scopes = NULL; - } - if(font_data->name){ - Xfree(font_data->name); - font_data->name = NULL; - } -*/ - } -} - -static void destroy_fontdata( - XOCGenericPart *gen, - Display *dpy) -{ - FontSet font_set = (FontSet) NULL; - int font_set_num = 0; - - if (gen->font_set) { - font_set = gen->font_set; - font_set_num = gen->font_set_num; - for( ; font_set_num-- ; font_set++) { - if (font_set->font) { - if(font_set->font->fid) - XFreeFont(dpy,font_set->font); - else - XFreeFontInfo(NULL, font_set->font, 1); - font_set->font = NULL; - } - if(font_set->font_data) { - if (font_set->info) - XFreeFontInfo(NULL, font_set->info, 1); - free_fontdataOC(dpy, - font_set->font_data, font_set->font_data_count); - Xfree(font_set->font_data); - font_set->font_data = NULL; - } - if(font_set->substitute) { - free_fontdataOC(dpy, - font_set->substitute, font_set->substitute_num); - Xfree(font_set->substitute); - font_set->substitute = NULL; - } - if(font_set->vmap) { - free_fontdataOC(dpy, - font_set->vmap, font_set->vmap_num); - Xfree(font_set->vmap); - font_set->vmap = NULL; - } - if(font_set->vrotate) { - free_fontdataOC(dpy, - (FontData)font_set->vrotate, - font_set->vrotate_num); - Xfree(font_set->vrotate); - font_set->vrotate = NULL; - } - } - Xfree(gen->font_set); - gen->font_set = NULL; - } -} -/* For VW/UDC end */ - -static void -destroy_oc( - XOC oc) -{ - Display *dpy = oc->core.om->core.display; - XOCGenericPart *gen = XOC_GENERIC(oc); - - if (gen->mbs_to_cs) - _XlcCloseConverter(gen->mbs_to_cs); - - if (gen->wcs_to_cs) - _XlcCloseConverter(gen->wcs_to_cs); - - if (gen->utf8_to_cs) - _XlcCloseConverter(gen->utf8_to_cs); - -/* For VW/UDC start */ /* Change 1996.01.8 */ - destroy_fontdata(gen,dpy); -/* -*/ -/* For VW/UDC end */ - - 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 (oc->core.font_info.font_struct_list) { - 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) -{ - XOCGenericPart *gen = XOC_GENERIC(oc); - FontSet font_set = gen->font_set; - char *ret; - int num = gen->font_set_num; - - if (oc->core.resources == NULL) - return NULL; - - ret = _XlcSetValues((XPointer) oc, oc->core.resources, - oc->core.num_resources, args, num_args, XlcSetMask); - if(ret != NULL){ - return(ret); - } else { - for ( ; num-- > 0; font_set++) { - if (font_set->font_name == NULL) - continue; - if (font_set->vpart_initialize != 0) - continue; - if( oc->core.orientation == XOMOrientation_TTB_RTL || - oc->core.orientation == XOMOrientation_TTB_LTR ){ - load_fontdata(oc, font_set->vmap, font_set->vmap_num); - load_fontdata(oc, (FontData) font_set->vrotate, - font_set->vrotate_num); - font_set->vpart_initialize = 1; - } - } - return(NULL); - } -} - -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 XOCMethodsRec oc_default_methods = { - destroy_oc, - set_oc_values, - get_oc_values, - _XmbDefaultTextEscapement, - _XmbDefaultTextExtents, - _XmbDefaultTextPerCharExtents, - _XmbDefaultDrawString, - _XmbDefaultDrawImageString, - _XwcDefaultTextEscapement, - _XwcDefaultTextExtents, - _XwcDefaultTextPerCharExtents, - _XwcDefaultDrawString, - _XwcDefaultDrawImageString, - _Xutf8DefaultTextEscapement, - _Xutf8DefaultTextExtents, - _Xutf8DefaultTextPerCharExtents, - _Xutf8DefaultDrawString, - _Xutf8DefaultDrawImageString -}; - -static XOCMethodsRec oc_generic_methods = { - destroy_oc, - set_oc_values, - get_oc_values, - _XmbGenericTextEscapement, - _XmbGenericTextExtents, - _XmbGenericTextPerCharExtents, - _XmbGenericDrawString, - _XmbGenericDrawImageString, - _XwcGenericTextEscapement, - _XwcGenericTextExtents, - _XwcGenericTextPerCharExtents, - _XwcGenericDrawString, - _XwcGenericDrawImageString, - _Xutf8GenericTextEscapement, - _Xutf8GenericTextExtents, - _Xutf8GenericTextPerCharExtents, - _Xutf8GenericDrawString, - _Xutf8GenericDrawImageString -}; - -typedef struct _XOCMethodsListRec { - const char *name; - XOCMethods methods; -} XOCMethodsListRec, *XOCMethodsList; - -static XOCMethodsListRec oc_methods_list[] = { - { "default", &oc_default_methods }, - { "generic", &oc_generic_methods } -}; - -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), XlcDefaultMask | 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; - XOMGenericPart *gen = XOM_GENERIC(om); - XOCMethodsList methods_list = oc_methods_list; - int count; - - 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 = &oc_generic_methods; - - if (gen->object_name) { - count = XlcNumber(oc_methods_list); - - for ( ; count-- > 0; methods_list++) { - if (!_XlcCompareISOLatin1(gen->object_name, methods_list->name)) { - oc->methods = methods_list->methods; - break; - } - } - } - - return oc; - -err: - destroy_oc(oc); - - return (XOC) NULL; -} - -static void -free_fontdataOM( - FontData font_data, - int font_data_count) -{ - for( ; font_data_count-- ; font_data++) { - if(font_data->name){ - Xfree(font_data->name); - font_data->name = NULL; - } - if(font_data->scopes){ - Xfree(font_data->scopes); - font_data->scopes = NULL; - } - } -} - -static Status -close_om( - XOM om) -{ - XOMGenericPart *gen = XOM_GENERIC(om); - OMData data; - int count; - - if ((data = gen->data)) { - for (count = gen->data_num; count-- > 0; data++) { - if (data->charset_list){ - Xfree(data->charset_list); - data->charset_list = NULL; - } - /* free font_data for om */ - if (data->font_data) { - free_fontdataOM(data->font_data,data->font_data_count); - Xfree(data->font_data); - data->font_data = NULL; - } - /* free substitute for om */ - if (data->substitute) { - free_fontdataOM(data->substitute,data->substitute_num); - Xfree(data->substitute); - data->substitute = NULL; - } - /* free vmap for om */ - if (data->vmap) { - free_fontdataOM(data->vmap,data->vmap_num); - Xfree(data->vmap); - data->vmap = NULL; - } - /* free vrotate for om */ - if (data->vrotate) { - Xfree(data->vrotate); - data->vrotate = NULL; - } - } - Xfree(gen->data); - gen->data = NULL; - } - - if (gen->object_name){ - Xfree(gen->object_name); - gen->object_name = NULL; - } - - if (om->core.res_name){ - Xfree(om->core.res_name); - om->core.res_name = NULL; - } - if (om->core.res_class){ - Xfree(om->core.res_class); - om->core.res_class = NULL; - } - if (om->core.required_charset.charset_list && - om->core.required_charset.charset_count > 0){ - XFreeStringList(om->core.required_charset.charset_list); - om->core.required_charset.charset_list = NULL; - } else { - Xfree((char*)om->core.required_charset.charset_list); - om->core.required_charset.charset_list = NULL; - } - if (om->core.orientation_list.orientation){ - Xfree(om->core.orientation_list.orientation); - om->core.orientation_list.orientation = NULL; - } - - 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 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 XOM -create_om( - 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 = &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); - - return om; - -err: - close_om(om); - - return (XOM) NULL; -} - -static OMData -add_data( - XOM om) -{ - XOMGenericPart *gen = XOM_GENERIC(om); - OMData new; - int num; - - if ((num = gen->data_num)) - new = (OMData) Xrealloc(gen->data, (num + 1) * sizeof(OMDataRec)); - else - new = (OMData) Xmalloc(sizeof(OMDataRec)); - - if (new == NULL) - return NULL; - - gen->data_num = num + 1; - gen->data = new; - - new += num; - bzero((char *) new, sizeof(OMDataRec)); - - return new; -} - -/* For VW/UDC */ - -FontData -read_EncodingInfo( - int count, - char **value) -{ - FontData font_data,ret; - char *buf, *bufptr,*scp; - int len; - font_data = (FontData) Xmalloc(sizeof(FontDataRec) * count); - if (font_data == NULL) - return NULL; - bzero((char *) font_data, sizeof(FontDataRec) * count); - - ret = font_data; - for ( ; count-- > 0; font_data++) { -/* - strcpy(buf, *value++); -*/ - buf = *value; value++; - if ((bufptr = strchr(buf, ':'))) { - len = (int)(bufptr - buf); - bufptr++ ; - } else - len = strlen(buf); - font_data->name = (char *) Xmalloc(len + 1); - if (font_data->name == NULL) - return NULL; - strncpy(font_data->name, buf,len); - font_data->name[len] = 0; - if (bufptr && _XlcCompareISOLatin1(bufptr, "GL") == 0) - font_data->side = XlcGL; - else if (bufptr && _XlcCompareISOLatin1(bufptr, "GR") == 0) - font_data->side = XlcGR; - else - font_data->side = XlcGLGR; - - if (bufptr && (scp = strchr(bufptr, '['))){ - font_data->scopes = _XlcParse_scopemaps(scp,&(font_data->scopes_num)); - } - } - return(ret); -} - -static CodeRange read_vrotate( - int count, - char **value, - int *type, - int *vrotate_num) -{ - CodeRange range; - if(!strcmp(value[0],"all")){ - *type = VROTATE_ALL ; - *vrotate_num = 0 ; - return (NULL); - } else if(*(value[0]) == '['){ - *type = VROTATE_PART ; - range = (CodeRange) _XlcParse_scopemaps(value[0],vrotate_num); - return (range); - } else { - *type = VROTATE_NONE ; - *vrotate_num = 0 ; - return (NULL); - } -} - -static void read_vw( - XLCd lcd, - OMData font_set, - int num) -{ - char **value, buf[BUFSIZ]; - int count; - - sprintf(buf, "fs%d.font.vertical_map", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count > 0){ - _XlcDbg_printValue(buf,value,count); - font_set->vmap_num = count; - font_set->vmap = read_EncodingInfo(count,value); - } - - sprintf(buf, "fs%d.font.vertical_rotate", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count > 0){ - _XlcDbg_printValue(buf,value,count); - font_set->vrotate = read_vrotate(count,value,&(font_set->vrotate_type), - &(font_set->vrotate_num)); - } -} -/* VW/UDC end */ -static Bool -init_om( - XOM om) -{ - XLCd lcd = om->core.lcd; - XOMGenericPart *gen = XOM_GENERIC(om); - OMData data; - XlcCharSet *charset_list; - FontData font_data; - char **required_list; - XOrientation *orientation; - char **value, buf[BUFSIZ], *bufptr; - int count = 0, num = 0, length = 0; - - _XlcGetResource(lcd, "XLC_FONTSET", "on_demand_loading", &value, &count); - if (count > 0 && _XlcCompareISOLatin1(*value, "True") == 0) - gen->on_demand_loading = True; - - _XlcGetResource(lcd, "XLC_FONTSET", "object_name", &value, &count); - if (count > 0) { - gen->object_name = (char *) Xmalloc(strlen(*value) + 1); - if (gen->object_name == NULL) - return False; - strcpy(gen->object_name, *value); - } - - for (num = 0; ; num++) { - - sprintf(buf, "fs%d.charset.name", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - - if( count < 1){ - sprintf(buf, "fs%d.charset", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count < 1) - break; - } - - data = add_data(om); - if (data == NULL) - return False; - - charset_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet) * count); - if (charset_list == NULL) - return False; - data->charset_list = charset_list; - data->charset_count = count; - - while (count-- > 0){ - *charset_list++ = _XlcGetCharSet(*value++); - } - sprintf(buf, "fs%d.charset.udc_area", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if( count > 0){ - UDCArea udc; - int i,flag = 0; - udc = (UDCArea)Xmalloc(count * sizeof(UDCAreaRec)); - if (udc == NULL) - return False; - for(i=0;i<count;i++){ - sscanf(value[i],"\\x%lx,\\x%lx", &(udc[i].start), - &(udc[i].end)); - } - for(i=0;i<data->charset_count;i++){ - if(data->charset_list[i]->udc_area == NULL){ - data->charset_list[i]->udc_area = udc; - data->charset_list[i]->udc_area_num = count; - flag = 1; - } - } - if(flag == 0){ - Xfree(udc); - } - } - - sprintf(buf, "fs%d.font.primary", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count < 1){ - sprintf(buf, "fs%d.font", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count < 1) - return False; - } - - font_data = read_EncodingInfo(count,value); - if (font_data == NULL) - return False; - - data->font_data = font_data; - data->font_data_count = count; - - sprintf(buf, "fs%d.font.substitute", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count > 0){ - font_data = read_EncodingInfo(count,value); - if (font_data == NULL) - return False; - data->substitute = font_data; - data->substitute_num = count; - } else { - sprintf(buf, "fs%d.font", num); - _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); - if (count < 1) { - data->substitute = NULL; - data->substitute_num = 0; - } else { - font_data = read_EncodingInfo(count,value); - data->substitute = font_data; - data->substitute_num = count; - } - } - read_vw(lcd,data,num); - length += strlen(data->font_data->name) + 1; - } - - /* required charset list */ - required_list = (char **) Xmalloc(sizeof(char *) * gen->data_num); - 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 = gen->data_num; - - count = gen->data_num; - data = gen->data; - - for ( ; count-- > 0; data++) { - strcpy(bufptr, data->font_data->name); - *required_list++ = bufptr; - bufptr += strlen(bufptr) + 1; - } - - /* orientation list */ - orientation = (XOrientation *) Xmalloc(sizeof(XOrientation) * 2); - if (orientation == NULL) - return False; - - orientation[0] = XOMOrientation_LTR_TTB; - orientation[1] = XOMOrientation_TTB_RTL; - om->core.orientation_list.orientation = orientation; - om->core.orientation_list.num_orientation = 2; - - /* 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 -_XomGenericOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb, - _Xconst char *res_name, _Xconst char *res_class) -{ - XOM om; - - om = create_om(lcd, dpy, rdb, res_name, res_class); - if (om == NULL) - return (XOM) NULL; - - if (init_om(om) == False) - goto err; - - return om; - -err: - close_om(om); - - return (XOM) NULL; -} - -Bool -_XInitOM( - XLCd lcd) -{ - lcd->methods->open_om = _XomGenericOpenOM; - - return True; -} +/* #define FONTDEBUG */
+/*
+ * Copyright 1992, 1993 by TOSHIBA Corp.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of TOSHIBA not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. TOSHIBA make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author: Katsuhisa Yano TOSHIBA Corp.
+ * mopi@osa.ilab.toshiba.co.jp
+ */
+/*
+ * Copyright 1995 by FUJITSU LIMITED
+ * This is source code modified by FUJITSU LIMITED under the Joint
+ * Development Agreement for the CDE/Motif PST.
+ *
+ * Modifier: Takanori Tateno FUJITSU LIMITED
+ *
+ */
+
+/*
+ * Fixed the algorithms in parse_fontname() and parse_fontdata()
+ * to improve the logic for determining which font should be
+ * returned for a given CharSet. We even added some comments
+ * so that you can figure out what in the heck we're doing. We
+ * realize this is a departure from the norm, but hey, we're
+ * rebels! :-) :-)
+ *
+ * Modifiers: Jeff Walls, Paul Anderson: HEWLETT-PACKARD
+ */
+/*
+ * Cleaned up mess, removed some blabla
+ * Egbert Eich, SuSE Linux AG
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "XomGeneric.h"
+#include "XlcGeneric.h"
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define MAXFONTS 100
+#define PIXEL_SIZE_FIELD 7
+#define POINT_SIZE_FIELD 8
+#define CHARSET_ENCODING_FIELD 14
+#define XLFD_MAX_LEN 255
+
+#if 0
+extern int _XmbDefaultTextEscapement(), _XwcDefaultTextEscapement(),
+ _Xutf8DefaultTextEscapement();
+extern int _XmbDefaultTextExtents(), _XwcDefaultTextExtents(),
+ _Xutf8DefaultTextExtents();
+extern Status _XmbDefaultTextPerCharExtents(), _XwcDefaultTextPerCharExtents(),
+ _Xutf8DefaultTextPerCharExtents();
+extern int _XmbDefaultDrawString(), _XwcDefaultDrawString(),
+ _Xutf8DefaultDrawString();
+extern void _XmbDefaultDrawImageString(), _XwcDefaultDrawImageString(),
+ _Xutf8DefaultDrawImageString();
+
+extern int _XmbGenericTextEscapement(), _XwcGenericTextEscapement(),
+ _Xutf8GenericTextEscapement();
+extern int _XmbGenericTextExtents(), _XwcGenericTextExtents(),
+ _Xutf8GenericTextExtents();
+extern Status _XmbGenericTextPerCharExtents(), _XwcGenericTextPerCharExtents(),
+ _Xutf8GenericTextPerCharExtents();
+extern int _XmbGenericDrawString(), _XwcGenericDrawString(),
+ _Xutf8GenericDrawString();
+extern void _XmbGenericDrawImageString(), _XwcGenericDrawImageString(),
+ _Xutf8GenericDrawImageString();
+
+extern void _XlcDbg_printValue (const char *str, char **value, int num);
+#endif
+
+/* For VW/UDC start */
+
+static FontData
+init_fontdata(
+ FontData font_data,
+ int font_data_count)
+{
+ FontData fd;
+ int i;
+
+ fd = (FontData)Xmalloc(sizeof(FontDataRec) * font_data_count);
+ if(fd == (FontData) NULL)
+ return False;
+
+ memset(fd, 0x00, sizeof(FontData) * font_data_count);
+ for(i = 0 ; i < font_data_count ; i++)
+ fd[i] = font_data[i];
+
+ return fd;
+}
+
+static VRotate
+init_vrotate(
+ FontData font_data,
+ int font_data_count,
+ int type,
+ CodeRange code_range,
+ int code_range_num)
+{
+ VRotate vrotate;
+ int i;
+
+ if(type == VROTATE_NONE)
+ return (VRotate)NULL;
+
+ vrotate = (VRotate)Xmalloc(sizeof(VRotateRec) * font_data_count);
+ if(vrotate == (VRotate) NULL)
+ return False;
+
+ memset(vrotate, 0x00, sizeof(VRotateRec) * font_data_count);
+ for(i = 0 ; i < font_data_count ; i++) {
+ vrotate[i].charset_name = font_data[i].name;
+ vrotate[i].side = font_data[i].side;
+ if(type == VROTATE_PART) {
+ vrotate[i].num_cr = code_range_num;
+ vrotate[i].code_range = code_range;
+ }
+ }
+
+ return vrotate;
+}
+
+static Bool
+init_fontset(
+ XOC oc)
+{
+ XOCGenericPart *gen;
+ FontSet font_set;
+ OMData data;
+ int count;
+
+ count = XOM_GENERIC(oc->core.om)->data_num;
+ data = XOM_GENERIC(oc->core.om)->data;
+
+ font_set = (FontSet) Xmalloc(sizeof(FontSetRec) * count);
+ if (font_set == NULL)
+ return False;
+ memset((char *) font_set, 0x00, sizeof(FontSetRec) * count);
+
+ gen = XOC_GENERIC(oc);
+ gen->font_set_num = count;
+ gen->font_set = font_set;
+
+ for ( ; count-- > 0; data++, font_set++) {
+ font_set->charset_count = data->charset_count;
+ font_set->charset_list = data->charset_list;
+
+ if((font_set->font_data = init_fontdata(data->font_data,
+ data->font_data_count)) == NULL)
+ goto err;
+ font_set->font_data_count = data->font_data_count;
+ if((font_set->substitute = init_fontdata(data->substitute,
+ data->substitute_num)) == NULL)
+ goto err;
+ font_set->substitute_num = data->substitute_num;
+ if((font_set->vmap = init_fontdata(data->vmap,
+ data->vmap_num)) == NULL)
+ goto err;
+ font_set->vmap_num = data->vmap_num;
+
+ if(data->vrotate_type != VROTATE_NONE) {
+ /* A vrotate member is specified primary font data */
+ /* as initial value. */
+ if((font_set->vrotate = init_vrotate(data->font_data,
+ data->font_data_count,
+ data->vrotate_type,
+ data->vrotate,
+ data->vrotate_num)) == NULL)
+ goto err;
+ font_set->vrotate_num = data->font_data_count;
+ }
+ }
+ return True;
+
+err:
+ if(font_set->font_data)
+ Xfree(font_set->font_data);
+ if(font_set->substitute)
+ Xfree(font_set->substitute);
+ if(font_set->vmap)
+ Xfree(font_set->vmap);
+ if(font_set->vrotate)
+ Xfree(font_set->vrotate);
+ if(font_set)
+ Xfree(font_set);
+ gen->font_set = (FontSet) NULL;
+ gen->font_set_num = 0;
+ return False;
+}
+
+/* For VW/UDC end */
+
+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;
+}
+
+/* For VW/UDC start */
+
+static Bool
+load_fontdata(
+ XOC oc,
+ FontData font_data,
+ int font_data_num)
+{
+ Display *dpy = oc->core.om->core.display;
+ FontData fd = font_data;
+
+ if(font_data == NULL) return(True);
+ for( ; font_data_num-- ; fd++) {
+ if(fd->xlfd_name != (char *) NULL && fd->font == NULL) {
+ fd->font = XLoadQueryFont(dpy, fd->xlfd_name);
+ if (fd->font == NULL){
+ return False;
+ }
+ }
+ }
+ return True;
+}
+
+static Bool
+load_fontset_data(
+ XOC oc,
+ FontSet font_set)
+{
+ Display *dpy = oc->core.om->core.display;
+
+ if(font_set->font_name == (char *)NULL) return False ;
+
+ /* If font_set->font is not NULL, it contains the *best*
+ * match font for this FontSet.
+ * -- jjw/pma (HP)
+ */
+ if(font_set->font == NULL) {
+ font_set->font = XLoadQueryFont(dpy, font_set->font_name);
+ if (font_set->font == NULL){
+ return False;
+ }
+ }
+ return True;
+}
+
+static Bool
+load_font(
+ XOC oc)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set = gen->font_set;
+ int num = gen->font_set_num;
+
+ for ( ; num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+
+ if (load_fontset_data (oc, font_set) != True)
+ return False;
+#ifndef TESTVERSION
+ if(load_fontdata(oc, font_set->font_data,
+ font_set->font_data_count) != True)
+ return False;
+
+ if(load_fontdata(oc, font_set->substitute,
+ font_set->substitute_num) != True)
+ return False;
+#endif
+
+/* Add 1996.05.20 */
+ if( oc->core.orientation == XOMOrientation_TTB_RTL ||
+ oc->core.orientation == XOMOrientation_TTB_LTR ){
+ if (font_set->vpart_initialize == 0) {
+ load_fontdata(oc, font_set->vmap, font_set->vmap_num);
+ load_fontdata(oc, (FontData) font_set->vrotate,
+ font_set->vrotate_num);
+ font_set->vpart_initialize = 1;
+ }
+ }
+
+ if (font_set->font->min_byte1 || font_set->font->max_byte1)
+ font_set->is_xchar2b = True;
+ else
+ font_set->is_xchar2b = False;
+ }
+
+ return True;
+}
+
+/* For VW/UDC end */
+
+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, num = gen->font_set_num;
+
+ for ( ; num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+
+ 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;
+
+ XFreeFontNames(fn_list);
+ }
+ }
+
+ return True;
+}
+
+/* For Vertical Writing start */
+
+static void
+check_fontset_extents(
+ XCharStruct *overall,
+ int *logical_ascent,
+ int *logical_descent,
+ XFontStruct *font)
+{
+ overall->lbearing = min(overall->lbearing, font->min_bounds.lbearing);
+ overall->rbearing = max(overall->rbearing, font->max_bounds.rbearing);
+ overall->ascent = max(overall->ascent, font->max_bounds.ascent);
+ overall->descent = max(overall->descent, font->max_bounds.descent);
+ overall->width = max(overall->width, font->max_bounds.width);
+ *logical_ascent = max(*logical_ascent, font->ascent);
+ *logical_descent = max(*logical_descent, font->descent);
+}
+
+/* For Vertical Writing end */
+
+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;
+ int num = oc->core.font_info.num_font;
+
+ 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;
+
+ /* For Vertical Writing start */
+
+ while (--num > 0) {
+ font = *font_list++;
+ check_fontset_extents(&overall, &logical_ascent, &logical_descent,
+ font);
+ }
+
+ {
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set = gen->font_set;
+ FontData font_data;
+ int font_set_num = gen->font_set_num;
+ int font_data_count;
+
+ for( ; font_set_num-- ; font_set++) {
+ if(font_set->vmap_num > 0) {
+ font_data = font_set->vmap;
+ font_data_count = font_set->vmap_num;
+ for( ; font_data_count-- ; font_data++) {
+ if(font_data->font != NULL) {
+ check_fontset_extents(&overall, &logical_ascent,
+ &logical_descent,
+ font_data->font);
+ }
+ }
+ }
+
+ if(font_set->vrotate_num > 0 && font_set->vrotate != NULL) {
+ font_data = (FontData) font_set->vrotate;
+ font_data_count = font_set->vrotate_num;
+ for( ; font_data_count-- ; font_data++) {
+ if(font_data->font != NULL) {
+ check_fontset_extents(&overall, &logical_ascent,
+ &logical_descent,
+ font_data->font);
+ }
+ }
+ }
+ }
+ }
+
+ /* For Vertical Writing start */
+
+ 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;
+ int font_set_num;
+ XFontStruct **font_struct_list;
+ char **font_name_list, *font_name_buf;
+ int count, length;
+
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+ count = length = 0;
+
+ for ( ; font_set_num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+
+ length += strlen(font_set->font_name) + 1;
+
+ count++;
+ }
+ if (count == 0)
+ return False;
+
+ font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *) * count);
+ if (font_struct_list == NULL)
+ return False;
+
+ font_name_list = (char **) Xmalloc(sizeof(char *) * count);
+ 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 = count;
+ 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;
+ font_set_num = gen->font_set_num;
+
+ for (count = 0; font_set_num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+
+ font_set->id = count;
+ 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;
+
+ count++;
+ }
+
+ 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;
+ int count = 0;
+
+ list = XListFonts(oc->core.om->core.display, pattern, 1, &count);
+ if (list == NULL)
+ return NULL;
+
+ name = (char *) Xmalloc(strlen(*list) + 1);
+ if (name)
+ strcpy(name, *list);
+
+ XFreeFontNames(list);
+
+ return name;
+}
+
+/* For VW/UDC start*/
+
+static char *
+get_rotate_fontname(
+ char *font_name)
+{
+ char *pattern = NULL, *ptr = NULL;
+ char *fields[CHARSET_ENCODING_FIELD];
+ char str_pixel[32], str_point[4];
+ char *rotate_font_ptr = NULL;
+ int pixel_size = 0;
+ int field_num = 0, len = 0;
+
+ if(font_name == (char *) NULL || (len = strlen(font_name)) <= 0
+ || len > XLFD_MAX_LEN)
+ return NULL;
+
+ pattern = (char *)Xmalloc(len + 1);
+ if(!pattern)
+ return NULL;
+ strcpy(pattern, font_name);
+
+ memset(fields, 0, sizeof(char *) * 14);
+ ptr = pattern;
+ while(isspace(*ptr)) {
+ ptr++;
+ }
+ if(*ptr == '-')
+ ptr++;
+
+ for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && ptr && *ptr ;
+ ptr++, field_num++) {
+ fields[field_num] = ptr;
+
+ if((ptr = strchr(ptr, '-'))) {
+ *ptr = '\0';
+ } else {
+ field_num++; /* Count last field */
+ break;
+ }
+ }
+
+ if(field_num < CHARSET_ENCODING_FIELD)
+ goto free_pattern;
+
+ /* Pixel Size field : fields[6] */
+ for(ptr = fields[PIXEL_SIZE_FIELD - 1] ; ptr && *ptr; ptr++) {
+ if(!isdigit(*ptr)) {
+ if(*ptr == '['){ /* 960730 */
+ strcpy(pattern, font_name);
+ return(pattern);
+ }
+ goto free_pattern;
+ }
+ }
+ pixel_size = atoi(fields[PIXEL_SIZE_FIELD - 1]);
+ sprintf(str_pixel, "[ 0 ~%d %d 0 ]", pixel_size, pixel_size);
+ fields[6] = str_pixel;
+
+ /* Point Size field : fields[7] */
+ strcpy(str_point, "*");
+ fields[POINT_SIZE_FIELD - 1] = str_point;
+
+ len = 0;
+ for (field_num = 0; field_num < CHARSET_ENCODING_FIELD &&
+ fields[field_num]; field_num++) {
+ len += 1 + strlen(fields[field_num]);
+ }
+
+ /* Max XLFD length is 255 */
+ if (len > XLFD_MAX_LEN)
+ goto free_pattern;
+
+ rotate_font_ptr = (char *)Xmalloc(len + 1);
+ if(!rotate_font_ptr)
+ goto free_pattern;
+
+ rotate_font_ptr[0] = '\0';
+
+ for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD &&
+ fields[field_num] ; field_num++) {
+ strcat(rotate_font_ptr, "-");
+ strcat(rotate_font_ptr, fields[field_num]);
+ }
+
+free_pattern:
+ Xfree(pattern);
+
+ return rotate_font_ptr;
+}
+
+static Bool
+is_match_charset(
+ FontData font_data,
+ char *font_name)
+{
+ char *last;
+ int length, name_len;
+
+ name_len = strlen(font_name);
+ last = font_name + name_len;
+
+ length = strlen(font_data->name);
+ if (length > name_len)
+ return False;
+
+ if (_XlcCompareISOLatin1(last - length, font_data->name) == 0)
+ return True;
+
+ return False;
+}
+
+#if 0
+static char *
+get_font_name_from_list(
+ XOC oc,
+ char *pattern,
+ FontData font_data)
+{
+ char **list, *name = (char *)NULL, *fname;
+ int count = 0, i;
+
+ list = XListFonts(oc->core.om->core.display, pattern, MAXFONTS, &count);
+ if (list == NULL)
+ return NULL;
+
+ for (i = 0; i < count; i++) {
+ fname = list[i];
+ if(is_match_charset(font_data, fname) == True) {
+ name = (char *) Xmalloc(strlen(fname) + 1);
+ if (name)
+ strcpy(name, fname);
+ break;
+ }
+ }
+
+ XFreeFontNames(list);
+
+ return name;
+}
+#endif
+
+static int
+parse_all_name(
+ XOC oc,
+ FontData font_data,
+ char *pattern)
+{
+
+#ifdef OLDCODE
+ if(is_match_charset(font_data, pattern) != True)
+ return False;
+
+ font_data->xlfd_name = (char *)Xmalloc(strlen(pattern)+1);
+ if(font_data->xlfd_name == NULL)
+ return (-1);
+
+ strcpy(font_data->xlfd_name, pattern);
+ return True;
+#else /* OLDCODE */
+ Display *dpy = oc->core.om->core.display;
+ char **fn_list = NULL, *prop_fname = NULL;
+ int list_num;
+ XFontStruct *fs_list;
+ if(is_match_charset(font_data, pattern) != True) {
+ /*
+ * pattern should not contain any wildcard (execpt '?')
+ * this was probably added to make this case insensitive.
+ */
+ if ((fn_list = XListFontsWithInfo(dpy, pattern,
+ MAXFONTS,
+ &list_num, &fs_list)) == NULL) {
+ return False;
+ }
+ /* shouldn't we loop here ? */
+ else if ((prop_fname = get_prop_name(dpy, fs_list)) == NULL) {
+ XFreeFontInfo(fn_list, fs_list, list_num);
+ return False;
+ }
+ else if ((is_match_charset(font_data, prop_fname) != True)) {
+ XFree(prop_fname);
+ XFreeFontInfo(fn_list, fs_list, list_num);
+ return False;
+ }
+ else {
+ font_data->xlfd_name = prop_fname;
+ XFreeFontInfo(fn_list, fs_list, list_num);
+ return True;
+ }
+ }
+
+ font_data->xlfd_name = (char *)Xmalloc(strlen(pattern)+1);
+ if(font_data->xlfd_name == NULL)
+ return (-1);
+
+ strcpy(font_data->xlfd_name, pattern);
+ return True;
+#endif /* OLDCODE */
+}
+
+static int
+parse_omit_name(
+ XOC oc,
+ FontData font_data,
+ char *pattern)
+{
+ char* last = (char *) NULL;
+ char* base_name;
+ char buf[XLFD_MAX_LEN + 1];
+ int length = 0;
+ int num_fields;
+ /*
+ * If the font specified by "pattern" is expandable to be
+ * a member of "font_data"'s FontSet, we've found a match.
+ */
+ if(is_match_charset(font_data, pattern) == True) {
+ if ((font_data->xlfd_name = get_font_name(oc, pattern)) != NULL) {
+ return True;
+ }
+ }
+
+ length = strlen (pattern);
+
+ if (length > XLFD_MAX_LEN)
+ return -1;
+
+ strcpy(buf, pattern);
+ last = buf + length - 1;
+
+ /* Replace the original encoding with the encoding for this FontSet. */
+
+ /* Figure out how many fields have been specified in this xlfd. */
+ for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
+ if (*base_name == '-') num_fields++;
+
+ switch (num_fields) {
+ case 12:
+ /* This is the best way to have specifed the fontset. In this
+ * case, there is no original encoding. E.g.,
+ * -*-*-*-*-*-*-14-*-*-*-*-*
+ * To this, we'll append a dash:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-
+ * then append the encoding to get:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
+ */
+ /*
+ * Take care of:
+ * -*-*-*-*-*-*-14-*-*-*-*-
+ */
+ if (*(last) == '-')
+ *++last = '*';
+
+ *++last = '-';
+ break;
+ case 13:
+ /* Got the charset, not the encoding, zap the charset In this
+ * case, there is no original encoding, but there is a charset. E.g.,
+ * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990
+ * To this, we remove the charset:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-
+ * then append the new encoding to get:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
+ */
+ last = strrchr (buf, '-');
+ num_fields = 12;
+ break;
+ case 14:
+ /* Both the charset and the encoding are specified. Get rid
+ * of them so that we can append the new charset encoding. E.g.,
+ * -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990-0
+ * To this, we'll remove the encoding and charset to get:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-
+ * then append the new encoding to get:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
+ */
+ last = strrchr (buf, '-');
+ *last = '\0';
+ last = strrchr (buf, '-');
+ num_fields = 12;
+ break;
+ default:
+ if (*last != '-')
+ *++last = '-';
+ break;
+ }
+
+ /* At this point, "last" is pointing to the last "-" in the
+ * xlfd, and all xlfd's at this point take a form similar to:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-
+ * (i.e., no encoding).
+ * After the strcpy, we'll end up with something similar to:
+ * -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
+ *
+ * If the modified font is found in the current FontSet,
+ * we've found a match.
+ */
+
+ last++;
+
+ if ((last - buf) + strlen(font_data->name) > XLFD_MAX_LEN)
+ return -1;
+
+ strcpy(last, font_data->name);
+ if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL)
+ return True;
+
+ /* This may mot be needed anymore as XListFonts() takes care of this */
+ while (num_fields < 12) {
+ if ((last - buf) > (XLFD_MAX_LEN - 2))
+ return -1;
+ *last = '*';
+ *(last + 1) = '-';
+ strcpy(last + 2, font_data->name);
+ num_fields++;
+ last+=2;
+ if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL)
+ return True;
+ }
+
+
+ return False;
+}
+
+
+typedef enum{C_PRIMARY, C_SUBSTITUTE, C_VMAP, C_VROTATE } ClassType;
+
+static int
+parse_fontdata(
+ XOC oc,
+ FontSet font_set,
+ FontData font_data,
+ int font_data_count,
+ char **name_list,
+ int name_list_count,
+ ClassType class,
+ FontDataRec *font_data_return)
+{
+
+ char **cur_name_list = name_list;
+ char *font_name = (char *) NULL;
+ char *pattern = (char *) NULL;
+ int found_num = 0, ret = 0;
+ int count = name_list_count;
+
+ if(name_list == NULL || count <= 0) {
+ return False;
+ }
+
+ if(font_data == NULL || font_data_count <= 0) {
+ return False;
+ }
+
+ /* Loop through each font encoding defined in the "font_data" FontSet. */
+ for ( ; font_data_count-- > 0; font_data++) {
+ Bool is_found = False;
+ font_name = (char *) NULL;
+ count = name_list_count;
+ cur_name_list = name_list;
+
+ /*
+ * Loop through each font specified by the user
+ * in the call to XCreateFontset().
+ */
+ while (count-- > 0) {
+ pattern = *cur_name_list++;
+ if (pattern == NULL || *pattern == '\0')
+ continue;
+#ifdef FONTDEBUG
+ fprintf(stderr,"Font pattern: %s %s\n",
+ pattern,font_data->name);
+#endif
+
+ /*
+ * If the current font is fully specified (i.e., the
+ * xlfd contains no wildcards) and the font exists on
+ * the X Server, we have a match.
+ */
+ if (strchr(pattern, '*') == NULL &&
+ (font_name = get_font_name(oc, pattern))) {
+ /*
+ * Find the full xlfd name for this font. If the font is
+ * already in xlfd format, it is simply returned. If the
+ * font is an alias for another font, the xlfd of the
+ * aliased font is returned.
+ */
+ ret = parse_all_name(oc, font_data, font_name);
+ Xfree(font_name);
+
+ if (ret == -1) return -1;
+ if (ret == False) continue;
+ /*
+ * Since there was an exact match of a fully-specified font
+ * or a font alias, we can return now since the desired font
+ * was found for the current font encoding for this FontSet.
+ *
+ * Previous implementations of this algorithm would
+ * not return here. Instead, they continued searching
+ * through the font encodings for this FontSet. The side-effect
+ * of that behavior is you may return a "substitute" match
+ * instead of an "exact" match. We believe there should be a
+ * preference on exact matches. Therefore, as soon as we
+ * find one, we bail.
+ *
+ * Also, previous implementations seemed to think it was
+ * important to find either a primary or substitute font
+ * for each Font encoding in the FontSet before returning an
+ * acceptable font. We don't believe this is necessary.
+ * All the client cares about is finding a reasonable font
+ * for what was passed in. If we find an exact match,
+ * there's no reason to look any further.
+ *
+ * -- jjw/pma (HP)
+ */
+ if (font_data_return) {
+ font_data_return->xlfd_name = (char *)Xmalloc
+ (strlen(font_data->xlfd_name) + 1);
+ if (!font_data_return->xlfd_name) return -1;
+
+ strcpy (font_data_return->xlfd_name, font_data->xlfd_name);
+
+ font_data_return->side = font_data->side;
+ }
+#ifdef FONTDEBUG
+ fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name);
+#endif
+
+ return True;
+ }
+ /*
+ * If the font name is not fully specified
+ * (i.e., it has wildcards), we have more work to do.
+ * See the comments in parse_omit_name()
+ * for the list of things to do.
+ */
+ ret = parse_omit_name(oc, font_data, pattern);
+
+ if (ret == -1) return -1;
+ if (ret == False) continue;
+
+ /*
+ * A font which matched the wild-carded specification was found.
+ * Only update the return data if a font has not yet been found.
+ * This maintains the convention that FontSets listed higher in
+ * a CodeSet in the Locale Database have higher priority than
+ * those FontSets listed lower in the CodeSet. In the following
+ * example:
+ *
+ * fs1 {
+ * charset HP-JIS:GR
+ * font JISX0208.1990-0:GL;\
+ * JISX0208.1990-1:GR;\
+ * JISX0208.1983-0:GL;\
+ * JISX0208.1983-1:GR
+ * }
+ *
+ * a font found in the JISX0208.1990-0 FontSet will have a
+ * higher priority than a font found in the JISX0208.1983-0
+ * FontSet.
+ */
+ if (font_data_return && font_data_return->xlfd_name == NULL) {
+
+#ifdef FONTDEBUG
+ fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name);
+#endif
+ font_data_return->xlfd_name = (char *)Xmalloc
+ (strlen(font_data->xlfd_name) + 1);
+ if (!font_data_return->xlfd_name) return -1;
+
+ strcpy (font_data_return->xlfd_name, font_data->xlfd_name);
+ font_data_return->side = font_data->side;
+ }
+
+ found_num++;
+ is_found = True;
+
+ break;
+ }
+
+ switch(class) {
+ case C_PRIMARY:
+ if(is_found == False) {
+ /*
+ * Did not find a font for the current FontSet. Check the
+ * FontSet's "substitute" font for a match. If we find a
+ * match, we'll keep searching in hopes of finding an exact
+ * match later down the FontSet list.
+ *
+ * when we return and we have found a font font_data_return
+ * contains the first (ie. best) match no matter if this
+ * is a C_PRIMARY or a C_SUBSTITUTE font
+ */
+ ret = parse_fontdata(oc, font_set, font_set->substitute,
+ font_set->substitute_num, name_list,
+ name_list_count, C_SUBSTITUTE,
+ font_data_return);
+ if (ret == -1) return -1;
+ if (ret == False) continue;
+
+ found_num++;
+ is_found = True;
+ }
+#ifdef TESTVERSION
+ else
+ return True;
+#endif
+ break;
+
+ case C_SUBSTITUTE:
+ case C_VMAP:
+ if(is_found == True)
+ return True;
+ break;
+
+ case C_VROTATE:
+ if(is_found == True) {
+ char *rotate_name;
+
+ if((rotate_name = get_rotate_fontname(font_data->xlfd_name))
+ != NULL) {
+ Xfree(font_data->xlfd_name);
+ font_data->xlfd_name = rotate_name;
+
+ return True;
+ }
+ Xfree(font_data->xlfd_name);
+ font_data->xlfd_name = NULL;
+ return False;
+ }
+ break;
+ }
+ }
+
+ if(class == C_PRIMARY && found_num >= 1)
+ return True;
+
+ return False;
+}
+
+
+static int
+parse_vw(
+ XOC oc,
+ FontSet font_set,
+ char **name_list,
+ int count)
+{
+ FontData vmap = font_set->vmap;
+ VRotate vrotate = font_set->vrotate;
+ int vmap_num = font_set->vmap_num;
+ int vrotate_num = font_set->vrotate_num;
+ int ret = 0, i = 0;
+
+ if(vmap_num > 0) {
+ if(parse_fontdata(oc, font_set, vmap, vmap_num, name_list,
+ count, C_VMAP,NULL) == -1)
+ return (-1);
+ }
+
+ if(vrotate_num > 0) {
+ ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
+ name_list, count, C_VROTATE, NULL);
+ if(ret == -1) {
+ return (-1);
+ } else if(ret == False) {
+ CodeRange code_range;
+ int num_cr;
+ int sub_num = font_set->substitute_num;
+
+ code_range = vrotate[0].code_range; /* ? */
+ num_cr = vrotate[0].num_cr; /* ? */
+ for(i = 0 ; i < vrotate_num ; i++) {
+ if(vrotate[i].xlfd_name)
+ Xfree(vrotate[i].xlfd_name);
+ }
+ Xfree(vrotate);
+
+ if(sub_num > 0) {
+ vrotate = font_set->vrotate = (VRotate)Xmalloc
+ (sizeof(VRotateRec) * sub_num);
+ if(font_set->vrotate == (VRotate)NULL)
+ return (-1);
+ memset(font_set->vrotate, 0x00, sizeof(VRotateRec) * sub_num);
+
+ for(i = 0 ; i < sub_num ; i++) {
+ vrotate[i].charset_name = font_set->substitute[i].name;
+ vrotate[i].side = font_set->substitute[i].side;
+ vrotate[i].code_range = code_range;
+ vrotate[i].num_cr = num_cr;
+ }
+ vrotate_num = font_set->vrotate_num = sub_num;
+ } else {
+ vrotate = font_set->vrotate = (VRotate)NULL;
+ }
+
+ ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
+ name_list, count, C_VROTATE, NULL);
+ if(ret == -1)
+ return (-1);
+ }
+ }
+
+ return True;
+}
+
+static int
+parse_fontname(
+ XOC oc)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set;
+ FontDataRec font_data_return;
+ char *base_name, **name_list;
+ int font_set_num = 0;
+ int found_num = 0;
+ int count = 0;
+ int ret;
+ int i;
+
+ name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
+ if (name_list == NULL)
+ return -1;
+
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+
+ /* Loop through all of the CharSets defined in the Locale
+ * database for the current Locale.
+ */
+ for( ; font_set_num-- > 0 ; font_set++) {
+ if(font_set->font_name)
+ continue;
+
+ if(font_set->font_data_count > 0) {
+
+ /*
+ * If there are a non-zero number of FontSets defined
+ * for this CharSet.
+ * Try to find a font for this CharSet. If we find an
+ * acceptable font, we save the information for return
+ * to the client. If we do not find an acceptable font,
+ * a "missing_charset" will be reported to the client
+ * for this CharSet.
+ */
+ font_data_return. xlfd_name = NULL;
+ font_data_return.side = XlcUnknown;
+
+ ret = parse_fontdata(oc, font_set, font_set->font_data,
+ font_set->font_data_count,
+ name_list, count, C_PRIMARY,
+ &font_data_return);
+ if(ret == -1) {
+ goto err;
+ } else if(ret == True) {
+ /*
+ * We can't just loop thru fontset->font_data to
+ * find the first (ie. best) match: parse_fontdata
+ * will try a substitute font if no primary one could
+ * be matched. It returns the required information in
+ * font_data_return.
+ */
+ font_set->font_name = (char *)Xmalloc
+ (strlen(font_data_return.xlfd_name) + 1);
+ if(font_set->font_name == (char *) NULL)
+ goto err;
+ strcpy(font_set->font_name, font_data_return.xlfd_name);
+ font_set->side = font_data_return.side;
+
+ Xfree (font_data_return.xlfd_name);
+ font_data_return.xlfd_name = NULL;
+
+ if(parse_vw(oc, font_set, name_list, count) == -1)
+ goto err;
+ found_num++;
+ }
+
+ } else if(font_set->substitute_num > 0) {
+ /*
+ * If there are no FontSets defined for this
+ * CharSet. We can only find "substitute" fonts.
+ */
+ ret = parse_fontdata(oc, font_set, font_set->substitute,
+ font_set->substitute_num,
+ name_list, count, C_SUBSTITUTE, NULL);
+ if(ret == -1) {
+ goto err;
+ } else if(ret == True) {
+ for(i=0;i<font_set->substitute_num;i++){
+ if(font_set->substitute[i].xlfd_name != NULL){
+ break;
+ }
+ }
+ font_set->font_name = (char *)Xmalloc
+ (strlen(font_set->substitute[i].xlfd_name) + 1);
+ if(font_set->font_name == (char *) NULL)
+ goto err;
+ strcpy(font_set->font_name,font_set->substitute[i].xlfd_name);
+ font_set->side = font_set->substitute[i].side;
+ if(parse_vw(oc, font_set, name_list, count) == -1)
+ goto err;
+
+ found_num++;
+ }
+ }
+ }
+
+ 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);
+ /* Prevent this from being freed twice */
+ oc->core.base_name_list = NULL;
+
+ return -1;
+}
+
+/* For VW/UDC end*/
+
+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_num;
+ int result = 1;
+
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+ count = length = 0;
+
+ for ( ; font_set_num-- > 0; font_set++) {
+ if (font_set->info || font_set->font) {
+ continue;
+ }
+
+ /* Change 1996.01.23 start */
+ if(font_set->font_data_count <= 0 ||
+ font_set->font_data == (FontData)NULL) {
+ if(font_set->substitute_num <= 0 ||
+ font_set->substitute == (FontData)NULL) {
+ if(font_set->charset_list != NULL){
+ length +=
+ strlen(font_set->charset_list[0]->encoding_name) + 1;
+ } else {
+ length += 1;
+ }
+ } else {
+ length += strlen(font_set->substitute->name) + 1;
+ }
+ } else {
+ length += strlen(font_set->font_data->name) + 1;
+ }
+ /* Change 1996.01.23 end */
+ count++;
+ }
+
+ if (count < 1) {
+ return True;
+ }
+
+ charset_list = (char **) Xmalloc(sizeof(char *) * count);
+ 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;
+ oc->core.missing_list.charset_count = count;
+
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+
+ for ( ; font_set_num-- > 0; font_set++) {
+ if (font_set->info || font_set->font) {
+ continue;
+ }
+
+ /* Change 1996.01.23 start */
+ if(font_set->font_data_count <= 0 ||
+ font_set->font_data == (FontData)NULL) {
+ if(font_set->substitute_num <= 0 ||
+ font_set->substitute == (FontData)NULL) {
+ if(font_set->charset_list != NULL){
+ strcpy(charset_buf,
+ font_set->charset_list[0]->encoding_name);
+ } else {
+ strcpy(charset_buf, "");
+ }
+ result = 0;
+ } else {
+ strcpy(charset_buf, font_set->substitute->name);
+ }
+ } else {
+ strcpy(charset_buf, font_set->font_data->name);
+ }
+ /* Change 1996.01.23 end */
+ *charset_list++ = charset_buf;
+ charset_buf += strlen(charset_buf) + 1;
+ }
+
+ if(result == 0) {
+ return(False);
+ }
+
+ return True;
+}
+
+static Bool
+create_fontset(
+ XOC oc)
+{
+ XOMGenericPart *gen = XOM_GENERIC(oc->core.om);
+ 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 (gen->on_demand_loading == True) {
+ if (load_font_info(oc) == False)
+ return False;
+ } else {
+ 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;
+}
+
+/* For VW/UDC start */
+static void
+free_fontdataOC(
+ Display *dpy,
+ FontData font_data,
+ int font_data_count)
+{
+ for( ; font_data_count-- ; font_data++) {
+ if(font_data->xlfd_name){
+ Xfree(font_data->xlfd_name);
+ font_data->xlfd_name = NULL;
+ }
+ if(font_data->font){ /* ADD 1996.01.7 */
+ if(font_data->font->fid) /* Add 1996.01.23 */
+ XFreeFont(dpy,font_data->font); /* ADD 1996.01.7 */
+ else /* Add 1996.01.23 */
+ XFreeFontInfo(NULL, font_data->font, 1);/* Add 1996.01.23 */
+ font_data->font = NULL;
+ }
+/*
+ * font_data->name and font_data->scopes belong to the OM not OC.
+ * To save space this data is shared between OM and OC. We are
+ * not allowed to free it here.
+ * It has been moved to free_fontdataOM()
+ */
+/*
+ if(font_data->scopes){
+ Xfree(font_data->scopes);
+ font_data->scopes = NULL;
+ }
+ if(font_data->name){
+ Xfree(font_data->name);
+ font_data->name = NULL;
+ }
+*/
+ }
+}
+
+static void destroy_fontdata(
+ XOCGenericPart *gen,
+ Display *dpy)
+{
+ FontSet font_set = (FontSet) NULL;
+ int font_set_num = 0;
+
+ if (gen->font_set) {
+ font_set = gen->font_set;
+ font_set_num = gen->font_set_num;
+ for( ; font_set_num-- ; font_set++) {
+ if (font_set->font) {
+ if(font_set->font->fid)
+ XFreeFont(dpy,font_set->font);
+ else
+ XFreeFontInfo(NULL, font_set->font, 1);
+ font_set->font = NULL;
+ }
+ if(font_set->font_data) {
+ if (font_set->info)
+ XFreeFontInfo(NULL, font_set->info, 1);
+ free_fontdataOC(dpy,
+ font_set->font_data, font_set->font_data_count);
+ Xfree(font_set->font_data);
+ font_set->font_data = NULL;
+ }
+ if(font_set->substitute) {
+ free_fontdataOC(dpy,
+ font_set->substitute, font_set->substitute_num);
+ Xfree(font_set->substitute);
+ font_set->substitute = NULL;
+ }
+ if(font_set->vmap) {
+ free_fontdataOC(dpy,
+ font_set->vmap, font_set->vmap_num);
+ Xfree(font_set->vmap);
+ font_set->vmap = NULL;
+ }
+ if(font_set->vrotate) {
+ free_fontdataOC(dpy,
+ (FontData)font_set->vrotate,
+ font_set->vrotate_num);
+ Xfree(font_set->vrotate);
+ font_set->vrotate = NULL;
+ }
+ }
+ Xfree(gen->font_set);
+ gen->font_set = NULL;
+ }
+}
+/* For VW/UDC end */
+
+static void
+destroy_oc(
+ XOC oc)
+{
+ Display *dpy = oc->core.om->core.display;
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+
+ if (gen->mbs_to_cs)
+ _XlcCloseConverter(gen->mbs_to_cs);
+
+ if (gen->wcs_to_cs)
+ _XlcCloseConverter(gen->wcs_to_cs);
+
+ if (gen->utf8_to_cs)
+ _XlcCloseConverter(gen->utf8_to_cs);
+
+/* For VW/UDC start */ /* Change 1996.01.8 */
+ destroy_fontdata(gen,dpy);
+/*
+*/
+/* For VW/UDC end */
+
+ 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 (oc->core.font_info.font_struct_list) {
+ 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)
+{
+ XOCGenericPart *gen = XOC_GENERIC(oc);
+ FontSet font_set = gen->font_set;
+ char *ret;
+ int num = gen->font_set_num;
+
+ if (oc->core.resources == NULL)
+ return NULL;
+
+ ret = _XlcSetValues((XPointer) oc, oc->core.resources,
+ oc->core.num_resources, args, num_args, XlcSetMask);
+ if(ret != NULL){
+ return(ret);
+ } else {
+ for ( ; num-- > 0; font_set++) {
+ if (font_set->font_name == NULL)
+ continue;
+ if (font_set->vpart_initialize != 0)
+ continue;
+ if( oc->core.orientation == XOMOrientation_TTB_RTL ||
+ oc->core.orientation == XOMOrientation_TTB_LTR ){
+ load_fontdata(oc, font_set->vmap, font_set->vmap_num);
+ load_fontdata(oc, (FontData) font_set->vrotate,
+ font_set->vrotate_num);
+ font_set->vpart_initialize = 1;
+ }
+ }
+ return(NULL);
+ }
+}
+
+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 XOCMethodsRec oc_default_methods = {
+ destroy_oc,
+ set_oc_values,
+ get_oc_values,
+ _XmbDefaultTextEscapement,
+ _XmbDefaultTextExtents,
+ _XmbDefaultTextPerCharExtents,
+ _XmbDefaultDrawString,
+ _XmbDefaultDrawImageString,
+ _XwcDefaultTextEscapement,
+ _XwcDefaultTextExtents,
+ _XwcDefaultTextPerCharExtents,
+ _XwcDefaultDrawString,
+ _XwcDefaultDrawImageString,
+ _Xutf8DefaultTextEscapement,
+ _Xutf8DefaultTextExtents,
+ _Xutf8DefaultTextPerCharExtents,
+ _Xutf8DefaultDrawString,
+ _Xutf8DefaultDrawImageString
+};
+
+static XOCMethodsRec oc_generic_methods = {
+ destroy_oc,
+ set_oc_values,
+ get_oc_values,
+ _XmbGenericTextEscapement,
+ _XmbGenericTextExtents,
+ _XmbGenericTextPerCharExtents,
+ _XmbGenericDrawString,
+ _XmbGenericDrawImageString,
+ _XwcGenericTextEscapement,
+ _XwcGenericTextExtents,
+ _XwcGenericTextPerCharExtents,
+ _XwcGenericDrawString,
+ _XwcGenericDrawImageString,
+ _Xutf8GenericTextEscapement,
+ _Xutf8GenericTextExtents,
+ _Xutf8GenericTextPerCharExtents,
+ _Xutf8GenericDrawString,
+ _Xutf8GenericDrawImageString
+};
+
+typedef struct _XOCMethodsListRec {
+ const char *name;
+ XOCMethods methods;
+} XOCMethodsListRec, *XOCMethodsList;
+
+static XOCMethodsListRec oc_methods_list[] = {
+ { "default", &oc_default_methods },
+ { "generic", &oc_generic_methods }
+};
+
+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), XlcDefaultMask | 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;
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ XOCMethodsList methods_list = oc_methods_list;
+ int count;
+
+ 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 = &oc_generic_methods;
+
+ if (gen->object_name) {
+ count = XlcNumber(oc_methods_list);
+
+ for ( ; count-- > 0; methods_list++) {
+ if (!_XlcCompareISOLatin1(gen->object_name, methods_list->name)) {
+ oc->methods = methods_list->methods;
+ break;
+ }
+ }
+ }
+
+ return oc;
+
+err:
+ destroy_oc(oc);
+
+ return (XOC) NULL;
+}
+
+static void
+free_fontdataOM(
+ FontData font_data,
+ int font_data_count)
+{
+ for( ; font_data_count-- ; font_data++) {
+ if(font_data->name){
+ Xfree(font_data->name);
+ font_data->name = NULL;
+ }
+ if(font_data->scopes){
+ Xfree(font_data->scopes);
+ font_data->scopes = NULL;
+ }
+ }
+}
+
+static Status
+close_om(
+ XOM om)
+{
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ OMData data;
+ int count;
+
+ if ((data = gen->data)) {
+ for (count = gen->data_num; count-- > 0; data++) {
+ if (data->charset_list){
+ Xfree(data->charset_list);
+ data->charset_list = NULL;
+ }
+ /* free font_data for om */
+ if (data->font_data) {
+ free_fontdataOM(data->font_data,data->font_data_count);
+ Xfree(data->font_data);
+ data->font_data = NULL;
+ }
+ /* free substitute for om */
+ if (data->substitute) {
+ free_fontdataOM(data->substitute,data->substitute_num);
+ Xfree(data->substitute);
+ data->substitute = NULL;
+ }
+ /* free vmap for om */
+ if (data->vmap) {
+ free_fontdataOM(data->vmap,data->vmap_num);
+ Xfree(data->vmap);
+ data->vmap = NULL;
+ }
+ /* free vrotate for om */
+ if (data->vrotate) {
+ Xfree(data->vrotate);
+ data->vrotate = NULL;
+ }
+ }
+ Xfree(gen->data);
+ gen->data = NULL;
+ }
+
+ if (gen->object_name){
+ Xfree(gen->object_name);
+ gen->object_name = NULL;
+ }
+
+ if (om->core.res_name){
+ Xfree(om->core.res_name);
+ om->core.res_name = NULL;
+ }
+ if (om->core.res_class){
+ Xfree(om->core.res_class);
+ om->core.res_class = NULL;
+ }
+ if (om->core.required_charset.charset_list &&
+ om->core.required_charset.charset_count > 0){
+ XFreeStringList(om->core.required_charset.charset_list);
+ om->core.required_charset.charset_list = NULL;
+ } else {
+ Xfree((char*)om->core.required_charset.charset_list);
+ om->core.required_charset.charset_list = NULL;
+ }
+ if (om->core.orientation_list.orientation){
+ Xfree(om->core.orientation_list.orientation);
+ om->core.orientation_list.orientation = NULL;
+ }
+
+ 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 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 XOM
+create_om(
+ 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 = &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);
+
+ return om;
+
+err:
+ close_om(om);
+
+ return (XOM) NULL;
+}
+
+static OMData
+add_data(
+ XOM om)
+{
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ OMData new;
+ int num;
+
+ if ((num = gen->data_num))
+ new = (OMData) Xrealloc(gen->data, (num + 1) * sizeof(OMDataRec));
+ else
+ new = (OMData) Xmalloc(sizeof(OMDataRec));
+
+ if (new == NULL)
+ return NULL;
+
+ gen->data_num = num + 1;
+ gen->data = new;
+
+ new += num;
+ bzero((char *) new, sizeof(OMDataRec));
+
+ return new;
+}
+
+/* For VW/UDC */
+
+FontData
+read_EncodingInfo(
+ int count,
+ char **value)
+{
+ FontData font_data,ret;
+ char *buf, *bufptr,*scp;
+ int len;
+ font_data = (FontData) Xmalloc(sizeof(FontDataRec) * count);
+ if (font_data == NULL)
+ return NULL;
+ bzero((char *) font_data, sizeof(FontDataRec) * count);
+
+ ret = font_data;
+ for ( ; count-- > 0; font_data++) {
+/*
+ strcpy(buf, *value++);
+*/
+ buf = *value; value++;
+ if ((bufptr = strchr(buf, ':'))) {
+ len = (int)(bufptr - buf);
+ bufptr++ ;
+ } else
+ len = strlen(buf);
+ font_data->name = (char *) Xmalloc(len + 1);
+ if (font_data->name == NULL) {
+ Xfree(font_data);
+ return NULL;
+ }
+ strncpy(font_data->name, buf,len);
+ font_data->name[len] = 0;
+ if (bufptr && _XlcCompareISOLatin1(bufptr, "GL") == 0)
+ font_data->side = XlcGL;
+ else if (bufptr && _XlcCompareISOLatin1(bufptr, "GR") == 0)
+ font_data->side = XlcGR;
+ else
+ font_data->side = XlcGLGR;
+
+ if (bufptr && (scp = strchr(bufptr, '['))){
+ font_data->scopes = _XlcParse_scopemaps(scp,&(font_data->scopes_num));
+ }
+ }
+ return(ret);
+}
+
+static CodeRange read_vrotate(
+ int count,
+ char **value,
+ int *type,
+ int *vrotate_num)
+{
+ CodeRange range;
+ if(!strcmp(value[0],"all")){
+ *type = VROTATE_ALL ;
+ *vrotate_num = 0 ;
+ return (NULL);
+ } else if(*(value[0]) == '['){
+ *type = VROTATE_PART ;
+ range = (CodeRange) _XlcParse_scopemaps(value[0],vrotate_num);
+ return (range);
+ } else {
+ *type = VROTATE_NONE ;
+ *vrotate_num = 0 ;
+ return (NULL);
+ }
+}
+
+static void read_vw(
+ XLCd lcd,
+ OMData font_set,
+ int num)
+{
+ char **value, buf[BUFSIZ];
+ int count;
+
+ sprintf(buf, "fs%d.font.vertical_map", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count > 0){
+ _XlcDbg_printValue(buf,value,count);
+ font_set->vmap_num = count;
+ font_set->vmap = read_EncodingInfo(count,value);
+ }
+
+ sprintf(buf, "fs%d.font.vertical_rotate", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count > 0){
+ _XlcDbg_printValue(buf,value,count);
+ font_set->vrotate = read_vrotate(count,value,&(font_set->vrotate_type),
+ &(font_set->vrotate_num));
+ }
+}
+/* VW/UDC end */
+static Bool
+init_om(
+ XOM om)
+{
+ XLCd lcd = om->core.lcd;
+ XOMGenericPart *gen = XOM_GENERIC(om);
+ OMData data;
+ XlcCharSet *charset_list;
+ FontData font_data;
+ char **required_list;
+ XOrientation *orientation;
+ char **value, buf[BUFSIZ], *bufptr;
+ int count = 0, num = 0, length = 0;
+
+ _XlcGetResource(lcd, "XLC_FONTSET", "on_demand_loading", &value, &count);
+ if (count > 0 && _XlcCompareISOLatin1(*value, "True") == 0)
+ gen->on_demand_loading = True;
+
+ _XlcGetResource(lcd, "XLC_FONTSET", "object_name", &value, &count);
+ if (count > 0) {
+ gen->object_name = (char *) Xmalloc(strlen(*value) + 1);
+ if (gen->object_name == NULL)
+ return False;
+ strcpy(gen->object_name, *value);
+ }
+
+ for (num = 0; ; num++) {
+
+ sprintf(buf, "fs%d.charset.name", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+
+ if( count < 1){
+ sprintf(buf, "fs%d.charset", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count < 1)
+ break;
+ }
+
+ data = add_data(om);
+ if (data == NULL)
+ return False;
+
+ charset_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet) * count);
+ if (charset_list == NULL)
+ return False;
+ data->charset_list = charset_list;
+ data->charset_count = count;
+
+ while (count-- > 0){
+ *charset_list++ = _XlcGetCharSet(*value++);
+ }
+ sprintf(buf, "fs%d.charset.udc_area", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if( count > 0){
+ UDCArea udc;
+ int i,flag = 0;
+ udc = (UDCArea)Xmalloc(count * sizeof(UDCAreaRec));
+ if (udc == NULL)
+ return False;
+ for(i=0;i<count;i++){
+ sscanf(value[i],"\\x%lx,\\x%lx", &(udc[i].start),
+ &(udc[i].end));
+ }
+ for(i=0;i<data->charset_count;i++){
+ if(data->charset_list[i]->udc_area == NULL){
+ data->charset_list[i]->udc_area = udc;
+ data->charset_list[i]->udc_area_num = count;
+ flag = 1;
+ }
+ }
+ if(flag == 0){
+ Xfree(udc);
+ }
+ }
+
+ sprintf(buf, "fs%d.font.primary", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count < 1){
+ sprintf(buf, "fs%d.font", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count < 1)
+ return False;
+ }
+
+ font_data = read_EncodingInfo(count,value);
+ if (font_data == NULL)
+ return False;
+
+ data->font_data = font_data;
+ data->font_data_count = count;
+
+ sprintf(buf, "fs%d.font.substitute", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count > 0){
+ font_data = read_EncodingInfo(count,value);
+ if (font_data == NULL)
+ return False;
+ data->substitute = font_data;
+ data->substitute_num = count;
+ } else {
+ sprintf(buf, "fs%d.font", num);
+ _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
+ if (count < 1) {
+ data->substitute = NULL;
+ data->substitute_num = 0;
+ } else {
+ font_data = read_EncodingInfo(count,value);
+ data->substitute = font_data;
+ data->substitute_num = count;
+ }
+ }
+ read_vw(lcd,data,num);
+ length += strlen(data->font_data->name) + 1;
+ }
+
+ /* required charset list */
+ required_list = (char **) Xmalloc(sizeof(char *) * gen->data_num);
+ if (required_list == NULL)
+ return False;
+
+ om->core.required_charset.charset_list = required_list;
+ om->core.required_charset.charset_count = gen->data_num;
+
+ count = gen->data_num;
+ data = gen->data;
+
+ if (count > 0) {
+ bufptr = (char *) Xmalloc(length);
+ if (bufptr == NULL) {
+ Xfree(required_list);
+ return False;
+ }
+
+ for ( ; count-- > 0; data++) {
+ strcpy(bufptr, data->font_data->name);
+ *required_list++ = bufptr;
+ bufptr += strlen(bufptr) + 1;
+ }
+ }
+
+ /* orientation list */
+ orientation = (XOrientation *) Xmalloc(sizeof(XOrientation) * 2);
+ if (orientation == NULL)
+ return False;
+
+ orientation[0] = XOMOrientation_LTR_TTB;
+ orientation[1] = XOMOrientation_TTB_RTL;
+ om->core.orientation_list.orientation = orientation;
+ om->core.orientation_list.num_orientation = 2;
+
+ /* 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
+_XomGenericOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
+ _Xconst char *res_name, _Xconst char *res_class)
+{
+ XOM om;
+
+ om = create_om(lcd, dpy, rdb, res_name, res_class);
+ if (om == NULL)
+ return (XOM) NULL;
+
+ if (init_om(om) == False)
+ goto err;
+
+ return om;
+
+err:
+ close_om(om);
+
+ return (XOM) NULL;
+}
+
+Bool
+_XInitOM(
+ XLCd lcd)
+{
+ lcd->methods->open_om = _XomGenericOpenOM;
+
+ return True;
+}
|