#define NEED_REPLIES
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "Xlibint.h"
#if defined(XF86BIGFONT) && !defined(MUSTCOPY)
#define USE_XF86BIGFONT
#endif
#ifdef USE_XF86BIGFONT
#include <sys/types.h>
#ifdef HAS_SHM
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <X11/extensions/xf86bigfstr.h>
#endif
#include "Xlcint.h"
#include "XlcPubI.h"
static XFontStruct *_XQueryFont(
Display* ,
Font ,
unsigned long
);
#ifdef USE_XF86BIGFONT
typedef struct {
XExtCodes *codes;
CARD32 serverSignature;
CARD32 serverCapabilities;
} XF86BigfontCodes;
#define CAP_VerifiedLocal 256
static XF86BigfontCodes *_XF86BigfontCodes(
Display*
);
static XFontStruct *_XF86BigfontQueryFont(
Display* ,
XF86BigfontCodes* ,
Font ,
unsigned long
);
void _XF86BigfontFreeFontMetrics(
XFontStruct*
);
#endif
XFontStruct *XLoadQueryFont(
register Display *dpy,
_Xconst char *name)
{
XFontStruct *font_result;
register long nbytes;
Font fid;
xOpenFontReq *req;
unsigned long seq;
#ifdef USE_XF86BIGFONT
XF86BigfontCodes *extcodes = _XF86BigfontCodes(dpy);
#endif
if (_XF86LoadQueryLocaleFont(dpy, name, &font_result, (Font *)0))
return font_result;
LockDisplay(dpy);
GetReq(OpenFont, req);
seq = dpy->request;
nbytes = req->nbytes = name ? strlen(name) : 0;
req->fid = fid = XAllocID(dpy);
req->length += (nbytes+3)>>2;
Data (dpy, name, nbytes);
font_result = NULL;
#ifdef USE_XF86BIGFONT
if (extcodes) {
font_result = _XF86BigfontQueryFont(dpy, extcodes, fid, seq);
seq = 0;
}
#endif
if (!font_result)
font_result = _XQueryFont(dpy, fid, seq);
UnlockDisplay(dpy);
SyncHandle();
return font_result;
}
XFontStruct *XQueryFont (
register Display *dpy,
Font fid)
{
XFontStruct *font_result;
#ifdef USE_XF86BIGFONT
XF86BigfontCodes *extcodes = _XF86BigfontCodes(dpy);
#endif
LockDisplay(dpy);
font_result = NULL;
#ifdef USE_XF86BIGFONT
if (extcodes) {
font_result = _XF86BigfontQueryFont(dpy, extcodes, fid, 0L);
}
#endif
if (!font_result)
font_result = _XQueryFont(dpy, fid, 0L);
UnlockDisplay(dpy);
SyncHandle();
return font_result;
}
int
XFreeFont(
register Display *dpy,
XFontStruct *fs)
{
register xResourceReq *req;
register _XExtension *ext;
LockDisplay(dpy);
for (ext = dpy->ext_procs; ext; ext = ext->next)
if (ext->free_Font) (*ext->free_Font)(dpy, fs, &ext->codes);
GetResReq (CloseFont, fs->fid, req);
UnlockDisplay(dpy);
SyncHandle();
if (fs->per_char) {
#ifdef USE_XF86BIGFONT
_XF86BigfontFreeFontMetrics(fs);
#else
Xfree ((char *) fs->per_char);
#endif
}
_XFreeExtData(fs->ext_data);
if (fs->properties)
Xfree ((char *) fs->properties);
Xfree ((char *) fs);
return 1;
}
static XFontStruct *
_XQueryFont (
register Display *dpy,
Font fid,
unsigned long seq)
{
register XFontStruct *fs;
register long nbytes;
xQueryFontReply reply;
register xResourceReq *req;
register _XExtension *ext;
_XAsyncHandler async;
_XAsyncErrorState async_state;
if (seq) {
async_state.min_sequence_number = seq;
async_state.max_sequence_number = seq;
async_state.error_code = BadName;
async_state.major_opcode = X_OpenFont;
async_state.minor_opcode = 0;
async_state.error_count = 0;
async.next = dpy->async_handlers;
async.handler = _XAsyncErrorHandler;
async.data = (XPointer)&async_state;
dpy->async_handlers = &async;
}
GetResReq(QueryFont, fid, req);
if (!_XReply (dpy, (xReply *) &reply,
((SIZEOF(xQueryFontReply) - SIZEOF(xReply)) >> 2), xFalse)) {
if (seq)
DeqAsyncHandler(dpy, &async);
return (XFontStruct *)NULL;
}
if (seq)
DeqAsyncHandler(dpy, &async);
if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) {
_XEatData(dpy, (unsigned long)(reply.nFontProps * SIZEOF(xFontProp) +
reply.nCharInfos * SIZEOF(xCharInfo)));
return (XFontStruct *)NULL;
}
fs->ext_data = NULL;
fs->fid = fid;
fs->direction = reply.drawDirection;
fs->min_char_or_byte2 = reply.minCharOrByte2;
fs->max_char_or_byte2 = reply.maxCharOrByte2;
fs->min_byte1 = reply.minByte1;
fs->max_byte1 = reply.maxByte1;
fs->default_char = reply.defaultChar;
fs->all_chars_exist = reply.allCharsExist;
fs->ascent = cvtINT16toInt (reply.fontAscent);
fs->descent = cvtINT16toInt (reply.fontDescent);
#ifdef MUSTCOPY
{
xCharInfo *xcip;
xcip = (xCharInfo *) &reply.minBounds;
fs->min_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing);
fs->min_bounds.rbearing = cvtINT16toShort(xcip->rightSideBearing);
fs->min_bounds.width = cvtINT16toShort(xcip->characterWidth);
fs->min_bounds.ascent = cvtINT16toShort(xcip->ascent);
fs->min_bounds.descent = cvtINT16toShort(xcip->descent);
fs->min_bounds.attributes = xcip->attributes;
xcip = (xCharInfo *) &reply.maxBounds;
fs->max_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing);
fs->max_bounds.rbearing = cvtINT16toShort(xcip->rightSideBearing);
fs->max_bounds.width = cvtINT16toShort(xcip->characterWidth);
fs->max_bounds.ascent = cvtINT16toShort(xcip->ascent);
fs->max_bounds.descent = cvtINT16toShort(xcip->descent);
fs->max_bounds.attributes = xcip->attributes;
}
#else
fs->min_bounds = * (XCharStruct *) &reply.minBounds;
fs->max_bounds = * (XCharStruct *) &reply.maxBounds;
#endif
fs->n_properties = reply.nFontProps;
fs->properties = NULL;
if (fs->n_properties > 0) {
nbytes = reply.nFontProps * sizeof(XFontProp);
fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes);
nbytes = reply.nFontProps * SIZEOF(xFontProp);
if (! fs->properties) {
Xfree((char *) fs);
_XEatData(dpy, (unsigned long)
(nbytes + reply.nCharInfos * SIZEOF(xCharInfo)));
return (XFontStruct *)NULL;
}
_XRead32 (dpy, (long *)fs->properties, nbytes);
}
fs->per_char = NULL;
if (reply.nCharInfos > 0){
nbytes = reply.nCharInfos * sizeof(XCharStruct);
if (! (fs->per_char = (XCharStruct *) Xmalloc ((unsigned) nbytes))) {
if (fs->properties) Xfree((char *) fs->properties);
Xfree((char *) fs);
_XEatData(dpy, (unsigned long)
(reply.nCharInfos * SIZEOF(xCharInfo)));
return (XFontStruct *)NULL;
}
#ifdef MUSTCOPY
{
register XCharStruct *cs = fs->per_char;
register int i;
for (i = 0; i < reply.nCharInfos; i++, cs++) {
xCharInfo xcip;
_XRead(dpy, (char *)&xcip, SIZEOF(xCharInfo));
cs->lbearing = cvtINT16toShort(xcip.leftSideBearing);
cs->rbearing = cvtINT16toShort(xcip.rightSideBearing);
cs->width = cvtINT16toShort(xcip.characterWidth);
cs->ascent = cvtINT16toShort(xcip.ascent);
cs->descent = cvtINT16toShort(xcip.descent);
cs->attributes = xcip.attributes;
}
}
#else
nbytes = reply.nCharInfos * SIZEOF(xCharInfo);
_XRead16 (dpy, (char *)fs->per_char, nbytes);
#endif
}
for (ext = dpy->ext_procs; ext; ext = ext->next)
if (ext->create_Font) (*ext->create_Font)(dpy, fs, &ext->codes);
return fs;
}
#ifdef USE_XF86BIGFONT
static int XF86BigfontNumber = 1040697125;
static int
_XF86BigfontFreeCodes (
XExtData *extension)
{
return 0;
}
static XF86BigfontCodes *
_XF86BigfontCodes (
register Display *dpy)
{
XEDataObject dpy_union;
XExtData *pData;
XF86BigfontCodes *pCodes;
char *envval;
dpy_union.display = dpy;
pData = XFindOnExtensionList(XEHeadOfExtensionList(dpy_union),
XF86BigfontNumber);
if (pData)
return (XF86BigfontCodes *) pData->private_data;
pData = (XExtData *) Xmalloc(sizeof(XExtData) + sizeof(XF86BigfontCodes));
if (!pData) {
return (XF86BigfontCodes *) NULL;
}
envval = getenv("XF86BIGFONT_DISABLE");
if (envval != NULL && envval[0] != '\0')
pCodes = NULL;
else {
XExtCodes *codes = XInitExtension(dpy, XF86BIGFONTNAME);
if (codes == NULL)
pCodes = NULL;
else {
pCodes = (XF86BigfontCodes *) &pData[1];
pCodes->codes = codes;
}
}
pData->number = XF86BigfontNumber;
pData->private_data = (XPointer) pCodes;
pData->free_private = _XF86BigfontFreeCodes;
XAddToExtensionList(XEHeadOfExtensionList(dpy_union), pData);
if (pCodes) {
int result;
xXF86BigfontQueryVersionReply reply;
register xXF86BigfontQueryVersionReq *req;
LockDisplay(dpy);
GetReq(XF86BigfontQueryVersion, req);
req->reqType = pCodes->codes->major_opcode;
req->xf86bigfontReqType = X_XF86BigfontQueryVersion;
result = _XReply (dpy, (xReply *) &reply,
(SIZEOF(xXF86BigfontQueryVersionReply) - SIZEOF(xReply)) >> 2,
xFalse);
UnlockDisplay(dpy);
SyncHandle();
if(!result)
goto ignore_extension;
if (!(reply.majorVersion > 1
|| (reply.majorVersion == 1 && reply.minorVersion >= 1)))
goto ignore_extension;
pCodes->serverSignature = reply.signature;
pCodes->serverCapabilities = reply.capabilities;
}
return pCodes;
ignore_extension:
pCodes = (XF86BigfontCodes *) NULL;
pData->private_data = (XPointer) pCodes;
return pCodes;
}
static int
_XF86BigfontFreeNop (
XExtData *extension)
{
return 0;
}
static XFontStruct *
_XF86BigfontQueryFont (
register Display *dpy,
XF86BigfontCodes *extcodes,
Font fid,
unsigned long seq)
{
register XFontStruct *fs;
register long nbytes;
xXF86BigfontQueryFontReply reply;
register xXF86BigfontQueryFontReq *req;
register _XExtension *ext;
_XAsyncHandler async1;
_XAsyncErrorState async1_state;
_XAsyncHandler async2;
_XAsyncErrorState async2_state;
if (seq) {
async1_state.min_sequence_number = seq;
async1_state.max_sequence_number = seq;
async1_state.error_code = BadName;
async1_state.major_opcode = X_OpenFont;
async1_state.minor_opcode = 0;
async1_state.error_count = 0;
async1.next = dpy->async_handlers;
async1.handler = _XAsyncErrorHandler;
async1.data = (XPointer)&async1_state;
dpy->async_handlers = &async1;
}
GetReq(XF86BigfontQueryFont, req);
req->reqType = extcodes->codes->major_opcode;
req->xf86bigfontReqType = X_XF86BigfontQueryFont;
req->id = fid;
req->flags = (extcodes->serverCapabilities & XF86Bigfont_CAP_LocalShm
? XF86Bigfont_FLAGS_Shm : 0);
async2_state.min_sequence_number = dpy->request;
async2_state.max_sequence_number = dpy->request;
async2_state.error_code = BadFont;
async2_state.major_opcode = extcodes->codes->major_opcode;
async2_state.minor_opcode = X_XF86BigfontQueryFont;
async2_state.error_count = 0;
async2.next = dpy->async_handlers;
async2.handler = _XAsyncErrorHandler;
async2.data = (XPointer)&async2_state;
dpy->async_handlers = &async2;
if (!_XReply (dpy, (xReply *) &reply,
((SIZEOF(xXF86BigfontQueryFontReply) - SIZEOF(xReply)) >> 2), xFalse)) {
DeqAsyncHandler(dpy, &async2);
if (seq)
DeqAsyncHandler(dpy, &async1);
return (XFontStruct *)NULL;
}
DeqAsyncHandler(dpy, &async2);
if (seq)
DeqAsyncHandler(dpy, &async1);
if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) {
_XEatData(dpy,
reply.nFontProps * SIZEOF(xFontProp)
+ (reply.nCharInfos > 0 && reply.shmid == (CARD32)(-1)
? reply.nUniqCharInfos * SIZEOF(xCharInfo)
+ (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16)
: 0));
return (XFontStruct *)NULL;
}
fs->ext_data = NULL;
fs->fid = fid;
fs->direction = reply.drawDirection;
fs->min_char_or_byte2 = reply.minCharOrByte2;
fs->max_char_or_byte2 = reply.maxCharOrByte2;
fs->min_byte1 = reply.minByte1;
fs->max_byte1 = reply.maxByte1;
fs->default_char = reply.defaultChar;
fs->all_chars_exist = reply.allCharsExist;
fs->ascent = cvtINT16toInt (reply.fontAscent);
fs->descent = cvtINT16toInt (reply.fontDescent);
fs->min_bounds = * (XCharStruct *) &reply.minBounds;
fs->max_bounds = * (XCharStruct *) &reply.maxBounds;
fs->n_properties = reply.nFontProps;
fs->properties = NULL;
if (fs->n_properties > 0) {
nbytes = reply.nFontProps * sizeof(XFontProp);
fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes);
nbytes = reply.nFontProps * SIZEOF(xFontProp);
if (! fs->properties) {
Xfree((char *) fs);
_XEatData(dpy,
nbytes
+ (reply.nCharInfos > 0 && reply.shmid == (CARD32)(-1)
? reply.nUniqCharInfos * SIZEOF(xCharInfo)
+ (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16)
: 0));
return (XFontStruct *)NULL;
}
_XRead32 (dpy, (long *)fs->properties, nbytes);
}
fs->per_char = NULL;
if (reply.nCharInfos > 0) {
if (reply.shmid == (CARD32)(-1)) {
xCharInfo* pUniqCI;
CARD16* pIndex2UniqIndex;
int i;
nbytes = reply.nUniqCharInfos * SIZEOF(xCharInfo)
+ (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16);
pUniqCI = (xCharInfo *) Xmalloc (nbytes);
if (!pUniqCI) {
if (fs->properties) Xfree((char *) fs->properties);
Xfree((char *) fs);
_XEatData(dpy, nbytes);
return (XFontStruct *)NULL;
}
if (! (fs->per_char = (XCharStruct *) Xmalloc (reply.nCharInfos * sizeof(XCharStruct)))) {
Xfree((char *) pUniqCI);
if (fs->properties) Xfree((char *) fs->properties);
Xfree((char *) fs);
_XEatData(dpy, nbytes);
return (XFontStruct *)NULL;
}
_XRead16 (dpy, (char *) pUniqCI, nbytes);
pIndex2UniqIndex = (CARD16*) (pUniqCI + reply.nUniqCharInfos);
for (i = 0; i < reply.nCharInfos; i++) {
if (pIndex2UniqIndex[i] >= reply.nUniqCharInfos) {
fprintf(stderr, "_XF86BigfontQueryFont: server returned wrong data\n");
Xfree((char *) pUniqCI);
if (fs->properties) Xfree((char *) fs->properties);
Xfree((char *) fs);
return (XFontStruct *)NULL;
}
fs->per_char[i] = * (XCharStruct *) &pUniqCI[pIndex2UniqIndex[i]];
}
Xfree((char *) pUniqCI);
} else {
#ifdef HAS_SHM
XExtData *pData;
XEDataObject fs_union;
char *addr;
pData = (XExtData *) Xmalloc(sizeof(XExtData));
if (!pData) {
if (fs->properties) Xfree((char *) fs->properties);
Xfree((char *) fs);
return (XFontStruct *)NULL;
}
if ((addr = shmat(reply.shmid, NULL, SHM_RDONLY)) == (char *)-1) {
if (extcodes->serverCapabilities & CAP_VerifiedLocal)
fprintf(stderr, "_XF86BigfontQueryFont: could not attach shm segment\n");
Xfree((char *) pData);
if (fs->properties) Xfree((char *) fs->properties);
Xfree((char *) fs);
extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm;
return (XFontStruct *)NULL;
}
if (!(extcodes->serverCapabilities & CAP_VerifiedLocal)) {
struct shmid_ds buf;
if (!(shmctl(reply.shmid, IPC_STAT, &buf) >= 0
&& buf.shm_segsz >= reply.shmsegoffset + reply.nCharInfos * sizeof(XCharStruct) + sizeof(CARD32)
&& *(CARD32 *)(addr + reply.shmsegoffset + reply.nCharInfos * sizeof(XCharStruct)) == extcodes->serverSignature)) {
shmdt(addr);
Xfree((char *) pData);
if (fs->properties) Xfree((char *) fs->properties);
Xfree((char *) fs);
extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm;
return (XFontStruct *)NULL;
}
extcodes->serverCapabilities |= CAP_VerifiedLocal;
}
pData->number = XF86BigfontNumber;
pData->private_data = (XPointer) addr;
pData->free_private = _XF86BigfontFreeNop;
fs_union.font = fs;
XAddToExtensionList(XEHeadOfExtensionList(fs_union), pData);
fs->per_char = (XCharStruct *) (addr + reply.shmsegoffset);
#else
fprintf(stderr, "_XF86BigfontQueryFont: try recompiling libX11 with HasShm, Xserver has shm support\n");
if (fs->properties) Xfree((char *) fs->properties);
Xfree((char *) fs);
extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm;
return (XFontStruct *)NULL;
#endif
}
}
for (ext = dpy->ext_procs; ext; ext = ext->next)
if (ext->create_Font) (*ext->create_Font)(dpy, fs, &ext->codes);
return fs;
}
void
_XF86BigfontFreeFontMetrics (XFontStruct *fs)
{
#ifdef HAS_SHM
XExtData *pData;
XEDataObject fs_union;
fs_union.font = fs;
if ((pData = XFindOnExtensionList(XEHeadOfExtensionList(fs_union),
XF86BigfontNumber)))
shmdt ((char *) pData->private_data);
else
Xfree ((char *) fs->per_char);
#else
Xfree ((char *) fs->per_char);
#endif
}
#endif
int _XF86LoadQueryLocaleFont(
Display *dpy,
_Xconst char *name,
XFontStruct **xfp,
Font *fidp)
{
int l;
const char *charset, *p;
char buf[256];
XFontStruct *fs;
XLCd lcd;
if (!name)
return 0;
l = strlen(name);
if (l < 2 || name[l - 1] != '*' || name[l - 2] != '-')
return 0;
charset = NULL;
lcd = _XlcCurrentLC();
if ((lcd = _XlcCurrentLC()) != 0)
charset = XLC_PUBLIC(lcd, encoding_name);
if (!charset || (p = strrchr(charset, '-')) == 0 || p == charset || p[1] == 0 || (p[1] == '*' && p[2] == 0)) {
charset = "ISO8859-1";
p = charset + 7;
}
if (l - 2 - (p - charset) < 0)
return 0;
if (_XlcNCompareISOLatin1(name + l - 2 - (p - charset), charset, p - charset))
return 0;
if (strlen(p + 1) + l - 1 >= sizeof(buf) - 1)
return 0;
strcpy(buf, name);
strcpy(buf + l - 1, p + 1);
fs = XLoadQueryFont(dpy, buf);
if (!fs)
return 0;
if (xfp) {
*xfp = fs;
if (fidp)
*fidp = fs->fid;
} else if (fidp) {
if (fs->per_char) {
#ifdef USE_XF86BIGFONT
_XF86BigfontFreeFontMetrics(fs);
#else
Xfree ((char *) fs->per_char);
#endif
}
_XFreeExtData(fs->ext_data);
if (fs->properties)
Xfree ((char *) fs->properties);
*fidp = fs->fid;
Xfree ((char *) fs);
} else {
XFreeFont(dpy, fs);
}
return 1;
}