xref: /OK3568_Linux_fs/external/xserver/Xext/xf86bigfont.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * BIGFONT extension for sharing font metrics between clients (if possible)
3*4882a593Smuzhiyun  * and for transmitting font metrics to clients in a compressed form.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 1999-2000  Bruno Haible
6*4882a593Smuzhiyun  * Copyright (c) 1999-2000  The XFree86 Project, Inc.
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun /* THIS IS NOT AN X CONSORTIUM STANDARD */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /*
12*4882a593Smuzhiyun  * Big fonts suffer from the following: All clients that have opened a
13*4882a593Smuzhiyun  * font can access the complete glyph metrics array (the XFontStruct member
14*4882a593Smuzhiyun  * `per_char') directly, without going through a macro. Moreover these
15*4882a593Smuzhiyun  * glyph metrics are ink metrics, i.e. are not redundant even for a
16*4882a593Smuzhiyun  * fixed-width font. For a Unicode font, the size of this array is 768 KB.
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  * Problems: 1. It eats a lot of memory in each client. 2. All this glyph
19*4882a593Smuzhiyun  * metrics data is piped through the socket when the font is opened.
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * This extension addresses these two problems for local clients, by using
22*4882a593Smuzhiyun  * shared memory. It also addresses the second problem for non-local clients,
23*4882a593Smuzhiyun  * by compressing the data before transmit by a factor of nearly 6.
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * If you use this extension, your OS ought to nicely support shared memory.
26*4882a593Smuzhiyun  * This means: Shared memory should be swappable to the swap, and the limits
27*4882a593Smuzhiyun  * should be high enough (SHMMNI at least 64, SHMMAX at least 768 KB,
28*4882a593Smuzhiyun  * SHMALL at least 48 MB). It is a plus if your OS allows shmat() calls
29*4882a593Smuzhiyun  * on segments that have already been marked "removed", because it permits
30*4882a593Smuzhiyun  * these segments to be cleaned up by the OS if the X server is killed with
31*4882a593Smuzhiyun  * signal SIGKILL.
32*4882a593Smuzhiyun  *
33*4882a593Smuzhiyun  * This extension is transparently exploited by Xlib (functions XQueryFont,
34*4882a593Smuzhiyun  * XLoadQueryFont).
35*4882a593Smuzhiyun  */
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
38*4882a593Smuzhiyun #include <dix-config.h>
39*4882a593Smuzhiyun #endif
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #include <sys/types.h>
42*4882a593Smuzhiyun #ifdef HAS_SHM
43*4882a593Smuzhiyun #ifdef SVR4
44*4882a593Smuzhiyun #include <sys/sysmacros.h>
45*4882a593Smuzhiyun #endif
46*4882a593Smuzhiyun #if defined(__CYGWIN__)
47*4882a593Smuzhiyun #include <sys/param.h>
48*4882a593Smuzhiyun #include <sys/sysmacros.h>
49*4882a593Smuzhiyun #endif
50*4882a593Smuzhiyun #include <sys/ipc.h>
51*4882a593Smuzhiyun #include <sys/shm.h>
52*4882a593Smuzhiyun #include <sys/stat.h>
53*4882a593Smuzhiyun #include <stdlib.h>
54*4882a593Smuzhiyun #include <unistd.h>
55*4882a593Smuzhiyun #include <time.h>
56*4882a593Smuzhiyun #include <errno.h>
57*4882a593Smuzhiyun #endif
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun #include <X11/X.h>
60*4882a593Smuzhiyun #include <X11/Xproto.h>
61*4882a593Smuzhiyun #include "misc.h"
62*4882a593Smuzhiyun #include "os.h"
63*4882a593Smuzhiyun #include "dixstruct.h"
64*4882a593Smuzhiyun #include "gcstruct.h"
65*4882a593Smuzhiyun #include "dixfontstr.h"
66*4882a593Smuzhiyun #include "extnsionst.h"
67*4882a593Smuzhiyun #include "extinit.h"
68*4882a593Smuzhiyun #include "protocol-versions.h"
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun #include <X11/extensions/xf86bigfproto.h>
71*4882a593Smuzhiyun #include "xf86bigfontsrv.h"
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun static void XF86BigfontResetProc(ExtensionEntry *       /* extEntry */
74*4882a593Smuzhiyun     );
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #ifdef HAS_SHM
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /* A random signature, transmitted to the clients so they can verify that the
79*4882a593Smuzhiyun    shared memory segment they are attaching to was really established by the
80*4882a593Smuzhiyun    X server they are talking to. */
81*4882a593Smuzhiyun static CARD32 signature;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /* Index for additional information stored in a FontRec's devPrivates array. */
84*4882a593Smuzhiyun static int FontShmdescIndex;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun static unsigned int pagesize;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun static Bool badSysCall = FALSE;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__)
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun static void
SigSysHandler(int signo)93*4882a593Smuzhiyun SigSysHandler(int signo)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun     badSysCall = TRUE;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun static Bool
CheckForShmSyscall(void)99*4882a593Smuzhiyun CheckForShmSyscall(void)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun     void (*oldHandler) (int);
102*4882a593Smuzhiyun     int shmid = -1;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun     /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
105*4882a593Smuzhiyun     oldHandler = OsSignal(SIGSYS, SigSysHandler);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun     badSysCall = FALSE;
108*4882a593Smuzhiyun     shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
109*4882a593Smuzhiyun     if (shmid != -1) {
110*4882a593Smuzhiyun         /* Successful allocation - clean up */
111*4882a593Smuzhiyun         shmctl(shmid, IPC_RMID, NULL);
112*4882a593Smuzhiyun     }
113*4882a593Smuzhiyun     else {
114*4882a593Smuzhiyun         /* Allocation failed */
115*4882a593Smuzhiyun         badSysCall = TRUE;
116*4882a593Smuzhiyun     }
117*4882a593Smuzhiyun     OsSignal(SIGSYS, oldHandler);
118*4882a593Smuzhiyun     return !badSysCall;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun #define MUST_CHECK_FOR_SHM_SYSCALL
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun #endif
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun #endif
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /* ========== Management of shared memory segments ========== */
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun #ifdef HAS_SHM
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun #ifdef __linux__
132*4882a593Smuzhiyun /* On Linux, shared memory marked as "removed" can still be attached.
133*4882a593Smuzhiyun    Nice feature, because the kernel will automatically free the associated
134*4882a593Smuzhiyun    storage when the server and all clients are gone. */
135*4882a593Smuzhiyun #define EARLY_REMOVE
136*4882a593Smuzhiyun #endif
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun typedef struct _ShmDesc {
139*4882a593Smuzhiyun     struct _ShmDesc *next;
140*4882a593Smuzhiyun     struct _ShmDesc **prev;
141*4882a593Smuzhiyun     int shmid;
142*4882a593Smuzhiyun     char *attach_addr;
143*4882a593Smuzhiyun } ShmDescRec, *ShmDescPtr;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun static ShmDescPtr ShmList = (ShmDescPtr) NULL;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun static ShmDescPtr
shmalloc(unsigned int size)148*4882a593Smuzhiyun shmalloc(unsigned int size)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun     ShmDescPtr pDesc;
151*4882a593Smuzhiyun     int shmid;
152*4882a593Smuzhiyun     char *addr;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun #ifdef MUST_CHECK_FOR_SHM_SYSCALL
155*4882a593Smuzhiyun     if (pagesize == 0)
156*4882a593Smuzhiyun         return (ShmDescPtr) NULL;
157*4882a593Smuzhiyun #endif
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun     /* On some older Linux systems, the number of shared memory segments
160*4882a593Smuzhiyun        system-wide is 127. In Linux 2.4, it is 4095.
161*4882a593Smuzhiyun        Therefore there is a tradeoff to be made between allocating a
162*4882a593Smuzhiyun        shared memory segment on one hand, and allocating memory and piping
163*4882a593Smuzhiyun        the glyph metrics on the other hand. If the glyph metrics size is
164*4882a593Smuzhiyun        small, we prefer the traditional way. */
165*4882a593Smuzhiyun     if (size < 3500)
166*4882a593Smuzhiyun         return (ShmDescPtr) NULL;
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun     pDesc = malloc(sizeof(ShmDescRec));
169*4882a593Smuzhiyun     if (!pDesc)
170*4882a593Smuzhiyun         return (ShmDescPtr) NULL;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun     size = (size + pagesize - 1) & -pagesize;
173*4882a593Smuzhiyun     shmid = shmget(IPC_PRIVATE, size, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
174*4882a593Smuzhiyun     if (shmid == -1) {
175*4882a593Smuzhiyun         ErrorF(XF86BIGFONTNAME " extension: shmget() failed, size = %u, %s\n",
176*4882a593Smuzhiyun                size, strerror(errno));
177*4882a593Smuzhiyun         free(pDesc);
178*4882a593Smuzhiyun         return (ShmDescPtr) NULL;
179*4882a593Smuzhiyun     }
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun     if ((addr = shmat(shmid, 0, 0)) == (char *) -1) {
182*4882a593Smuzhiyun         ErrorF(XF86BIGFONTNAME " extension: shmat() failed, size = %u, %s\n",
183*4882a593Smuzhiyun                size, strerror(errno));
184*4882a593Smuzhiyun         shmctl(shmid, IPC_RMID, (void *) 0);
185*4882a593Smuzhiyun         free(pDesc);
186*4882a593Smuzhiyun         return (ShmDescPtr) NULL;
187*4882a593Smuzhiyun     }
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun #ifdef EARLY_REMOVE
190*4882a593Smuzhiyun     shmctl(shmid, IPC_RMID, (void *) 0);
191*4882a593Smuzhiyun #endif
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun     pDesc->shmid = shmid;
194*4882a593Smuzhiyun     pDesc->attach_addr = addr;
195*4882a593Smuzhiyun     if (ShmList)
196*4882a593Smuzhiyun         ShmList->prev = &pDesc->next;
197*4882a593Smuzhiyun     pDesc->next = ShmList;
198*4882a593Smuzhiyun     pDesc->prev = &ShmList;
199*4882a593Smuzhiyun     ShmList = pDesc;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun     return pDesc;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun static void
shmdealloc(ShmDescPtr pDesc)205*4882a593Smuzhiyun shmdealloc(ShmDescPtr pDesc)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun #ifndef EARLY_REMOVE
208*4882a593Smuzhiyun     shmctl(pDesc->shmid, IPC_RMID, (void *) 0);
209*4882a593Smuzhiyun #endif
210*4882a593Smuzhiyun     shmdt(pDesc->attach_addr);
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun     if (pDesc->next)
213*4882a593Smuzhiyun         pDesc->next->prev = pDesc->prev;
214*4882a593Smuzhiyun     *pDesc->prev = pDesc->next;
215*4882a593Smuzhiyun     free(pDesc);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun #endif
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun /* Called when a font is closed. */
221*4882a593Smuzhiyun void
XF86BigfontFreeFontShm(FontPtr pFont)222*4882a593Smuzhiyun XF86BigfontFreeFontShm(FontPtr pFont)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun #ifdef HAS_SHM
225*4882a593Smuzhiyun     ShmDescPtr pDesc;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun     /* If during shutdown of the server, XF86BigfontCleanup() has already
228*4882a593Smuzhiyun      * called shmdealloc() for all segments, we don't need to do it here.
229*4882a593Smuzhiyun      */
230*4882a593Smuzhiyun     if (!ShmList)
231*4882a593Smuzhiyun         return;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun     pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex);
234*4882a593Smuzhiyun     if (pDesc)
235*4882a593Smuzhiyun         shmdealloc(pDesc);
236*4882a593Smuzhiyun #endif
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun /* Called upon fatal signal. */
240*4882a593Smuzhiyun void
XF86BigfontCleanup(void)241*4882a593Smuzhiyun XF86BigfontCleanup(void)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun #ifdef HAS_SHM
244*4882a593Smuzhiyun     while (ShmList)
245*4882a593Smuzhiyun         shmdealloc(ShmList);
246*4882a593Smuzhiyun #endif
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun /* Called when a server generation dies. */
250*4882a593Smuzhiyun static void
XF86BigfontResetProc(ExtensionEntry * extEntry)251*4882a593Smuzhiyun XF86BigfontResetProc(ExtensionEntry * extEntry)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun     /* This function is normally called from CloseDownExtensions(), called
254*4882a593Smuzhiyun      * from main(). It will be followed by a call to FreeAllResources(),
255*4882a593Smuzhiyun      * which will call XF86BigfontFreeFontShm() for each font. Thus it
256*4882a593Smuzhiyun      * appears that we do not need to do anything in this function. --
257*4882a593Smuzhiyun      * But I prefer to write robust code, and not keep shared memory lying
258*4882a593Smuzhiyun      * around when it's not needed any more. (Someone might close down the
259*4882a593Smuzhiyun      * extension without calling FreeAllResources()...)
260*4882a593Smuzhiyun      */
261*4882a593Smuzhiyun     XF86BigfontCleanup();
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun /* ========== Handling of extension specific requests ========== */
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun static int
ProcXF86BigfontQueryVersion(ClientPtr client)267*4882a593Smuzhiyun ProcXF86BigfontQueryVersion(ClientPtr client)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun     xXF86BigfontQueryVersionReply reply;
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xXF86BigfontQueryVersionReq);
272*4882a593Smuzhiyun     reply = (xXF86BigfontQueryVersionReply) {
273*4882a593Smuzhiyun         .type = X_Reply,
274*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
275*4882a593Smuzhiyun         .length = 0,
276*4882a593Smuzhiyun         .majorVersion = SERVER_XF86BIGFONT_MAJOR_VERSION,
277*4882a593Smuzhiyun         .minorVersion = SERVER_XF86BIGFONT_MINOR_VERSION,
278*4882a593Smuzhiyun         .uid = geteuid(),
279*4882a593Smuzhiyun         .gid = getegid(),
280*4882a593Smuzhiyun #ifdef HAS_SHM
281*4882a593Smuzhiyun         .signature = signature,
282*4882a593Smuzhiyun         .capabilities = (client->local && !client->swapped)
283*4882a593Smuzhiyun                          ? XF86Bigfont_CAP_LocalShm : 0
284*4882a593Smuzhiyun #else
285*4882a593Smuzhiyun         .signature = 0,
286*4882a593Smuzhiyun         .capabilities = 0
287*4882a593Smuzhiyun #endif
288*4882a593Smuzhiyun     };
289*4882a593Smuzhiyun     if (client->swapped) {
290*4882a593Smuzhiyun         swaps(&reply.sequenceNumber);
291*4882a593Smuzhiyun         swapl(&reply.length);
292*4882a593Smuzhiyun         swaps(&reply.majorVersion);
293*4882a593Smuzhiyun         swaps(&reply.minorVersion);
294*4882a593Smuzhiyun         swapl(&reply.uid);
295*4882a593Smuzhiyun         swapl(&reply.gid);
296*4882a593Smuzhiyun         swapl(&reply.signature);
297*4882a593Smuzhiyun     }
298*4882a593Smuzhiyun     WriteToClient(client, sizeof(xXF86BigfontQueryVersionReply), &reply);
299*4882a593Smuzhiyun     return Success;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun static void
swapCharInfo(xCharInfo * pCI)303*4882a593Smuzhiyun swapCharInfo(xCharInfo * pCI)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun     swaps(&pCI->leftSideBearing);
306*4882a593Smuzhiyun     swaps(&pCI->rightSideBearing);
307*4882a593Smuzhiyun     swaps(&pCI->characterWidth);
308*4882a593Smuzhiyun     swaps(&pCI->ascent);
309*4882a593Smuzhiyun     swaps(&pCI->descent);
310*4882a593Smuzhiyun     swaps(&pCI->attributes);
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun /* static CARD32 hashCI (xCharInfo *p); */
314*4882a593Smuzhiyun #define hashCI(p) \
315*4882a593Smuzhiyun 	(CARD32)(((p->leftSideBearing << 27) + (p->leftSideBearing >> 5) + \
316*4882a593Smuzhiyun 	          (p->rightSideBearing << 23) + (p->rightSideBearing >> 9) + \
317*4882a593Smuzhiyun 	          (p->characterWidth << 16) + \
318*4882a593Smuzhiyun 	          (p->ascent << 11) + (p->descent << 6)) ^ p->attributes)
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun static int
ProcXF86BigfontQueryFont(ClientPtr client)321*4882a593Smuzhiyun ProcXF86BigfontQueryFont(ClientPtr client)
322*4882a593Smuzhiyun {
323*4882a593Smuzhiyun     FontPtr pFont;
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun     REQUEST(xXF86BigfontQueryFontReq);
326*4882a593Smuzhiyun     CARD32 stuff_flags;
327*4882a593Smuzhiyun     xCharInfo *pmax;
328*4882a593Smuzhiyun     xCharInfo *pmin;
329*4882a593Smuzhiyun     int nCharInfos;
330*4882a593Smuzhiyun     int shmid;
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun #ifdef HAS_SHM
333*4882a593Smuzhiyun     ShmDescPtr pDesc = NULL;
334*4882a593Smuzhiyun #else
335*4882a593Smuzhiyun #define pDesc 0
336*4882a593Smuzhiyun #endif
337*4882a593Smuzhiyun     xCharInfo *pCI;
338*4882a593Smuzhiyun     CARD16 *pIndex2UniqIndex;
339*4882a593Smuzhiyun     CARD16 *pUniqIndex2Index;
340*4882a593Smuzhiyun     CARD32 nUniqCharInfos;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun #if 0
343*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xXF86BigfontQueryFontReq);
344*4882a593Smuzhiyun #else
345*4882a593Smuzhiyun     switch (client->req_len) {
346*4882a593Smuzhiyun     case 2:                    /* client with version 1.0 libX11 */
347*4882a593Smuzhiyun         stuff_flags = (client->local &&
348*4882a593Smuzhiyun                        !client->swapped ? XF86Bigfont_FLAGS_Shm : 0);
349*4882a593Smuzhiyun         break;
350*4882a593Smuzhiyun     case 3:                    /* client with version 1.1 libX11 */
351*4882a593Smuzhiyun         stuff_flags = stuff->flags;
352*4882a593Smuzhiyun         break;
353*4882a593Smuzhiyun     default:
354*4882a593Smuzhiyun         return BadLength;
355*4882a593Smuzhiyun     }
356*4882a593Smuzhiyun #endif
357*4882a593Smuzhiyun     if (dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess) !=
358*4882a593Smuzhiyun         Success)
359*4882a593Smuzhiyun         return BadFont;         /* procotol spec says only error is BadFont */
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun     pmax = FONTINKMAX(pFont);
362*4882a593Smuzhiyun     pmin = FONTINKMIN(pFont);
363*4882a593Smuzhiyun     nCharInfos =
364*4882a593Smuzhiyun         (pmax->rightSideBearing == pmin->rightSideBearing
365*4882a593Smuzhiyun          && pmax->leftSideBearing == pmin->leftSideBearing
366*4882a593Smuzhiyun          && pmax->descent == pmin->descent
367*4882a593Smuzhiyun          && pmax->ascent == pmin->ascent
368*4882a593Smuzhiyun          && pmax->characterWidth == pmin->characterWidth)
369*4882a593Smuzhiyun         ? 0 : N2dChars(pFont);
370*4882a593Smuzhiyun     shmid = -1;
371*4882a593Smuzhiyun     pCI = NULL;
372*4882a593Smuzhiyun     pIndex2UniqIndex = NULL;
373*4882a593Smuzhiyun     pUniqIndex2Index = NULL;
374*4882a593Smuzhiyun     nUniqCharInfos = 0;
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun     if (nCharInfos > 0) {
377*4882a593Smuzhiyun #ifdef HAS_SHM
378*4882a593Smuzhiyun         if (!badSysCall)
379*4882a593Smuzhiyun             pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex);
380*4882a593Smuzhiyun         if (pDesc) {
381*4882a593Smuzhiyun             pCI = (xCharInfo *) pDesc->attach_addr;
382*4882a593Smuzhiyun             if (stuff_flags & XF86Bigfont_FLAGS_Shm)
383*4882a593Smuzhiyun                 shmid = pDesc->shmid;
384*4882a593Smuzhiyun         }
385*4882a593Smuzhiyun         else {
386*4882a593Smuzhiyun             if (stuff_flags & XF86Bigfont_FLAGS_Shm && !badSysCall)
387*4882a593Smuzhiyun                 pDesc = shmalloc(nCharInfos * sizeof(xCharInfo)
388*4882a593Smuzhiyun                                  + sizeof(CARD32));
389*4882a593Smuzhiyun             if (pDesc) {
390*4882a593Smuzhiyun                 pCI = (xCharInfo *) pDesc->attach_addr;
391*4882a593Smuzhiyun                 shmid = pDesc->shmid;
392*4882a593Smuzhiyun             }
393*4882a593Smuzhiyun             else {
394*4882a593Smuzhiyun #endif
395*4882a593Smuzhiyun                 pCI = xallocarray(nCharInfos, sizeof(xCharInfo));
396*4882a593Smuzhiyun                 if (!pCI)
397*4882a593Smuzhiyun                     return BadAlloc;
398*4882a593Smuzhiyun #ifdef HAS_SHM
399*4882a593Smuzhiyun             }
400*4882a593Smuzhiyun #endif
401*4882a593Smuzhiyun             /* Fill nCharInfos starting at pCI. */
402*4882a593Smuzhiyun             {
403*4882a593Smuzhiyun                 xCharInfo *prCI = pCI;
404*4882a593Smuzhiyun                 int ninfos = 0;
405*4882a593Smuzhiyun                 int ncols = pFont->info.lastCol - pFont->info.firstCol + 1;
406*4882a593Smuzhiyun                 int row;
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun                 for (row = pFont->info.firstRow;
409*4882a593Smuzhiyun                      row <= pFont->info.lastRow && ninfos < nCharInfos; row++) {
410*4882a593Smuzhiyun                     unsigned char chars[512];
411*4882a593Smuzhiyun                     xCharInfo *tmpCharInfos[256];
412*4882a593Smuzhiyun                     unsigned long count;
413*4882a593Smuzhiyun                     int col;
414*4882a593Smuzhiyun                     unsigned long i;
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun                     i = 0;
417*4882a593Smuzhiyun                     for (col = pFont->info.firstCol;
418*4882a593Smuzhiyun                          col <= pFont->info.lastCol; col++) {
419*4882a593Smuzhiyun                         chars[i++] = row;
420*4882a593Smuzhiyun                         chars[i++] = col;
421*4882a593Smuzhiyun                     }
422*4882a593Smuzhiyun                     (*pFont->get_metrics) (pFont, ncols, chars, TwoD16Bit,
423*4882a593Smuzhiyun                                            &count, tmpCharInfos);
424*4882a593Smuzhiyun                     for (i = 0; i < count && ninfos < nCharInfos; i++) {
425*4882a593Smuzhiyun                         *prCI++ = *tmpCharInfos[i];
426*4882a593Smuzhiyun                         ninfos++;
427*4882a593Smuzhiyun                     }
428*4882a593Smuzhiyun                 }
429*4882a593Smuzhiyun             }
430*4882a593Smuzhiyun #ifdef HAS_SHM
431*4882a593Smuzhiyun             if (pDesc && !badSysCall) {
432*4882a593Smuzhiyun                 *(CARD32 *) (pCI + nCharInfos) = signature;
433*4882a593Smuzhiyun                 if (!xfont2_font_set_private(pFont, FontShmdescIndex, pDesc)) {
434*4882a593Smuzhiyun                     shmdealloc(pDesc);
435*4882a593Smuzhiyun                     return BadAlloc;
436*4882a593Smuzhiyun                 }
437*4882a593Smuzhiyun             }
438*4882a593Smuzhiyun         }
439*4882a593Smuzhiyun #endif
440*4882a593Smuzhiyun         if (shmid == -1) {
441*4882a593Smuzhiyun             /* Cannot use shared memory, so remove-duplicates the xCharInfos
442*4882a593Smuzhiyun                using a temporary hash table. */
443*4882a593Smuzhiyun             /* Note that CARD16 is suitable as index type, because
444*4882a593Smuzhiyun                nCharInfos <= 0x10000. */
445*4882a593Smuzhiyun             CARD32 hashModulus;
446*4882a593Smuzhiyun             CARD16 *pHash2UniqIndex;
447*4882a593Smuzhiyun             CARD16 *pUniqIndex2NextUniqIndex;
448*4882a593Smuzhiyun             CARD32 NextIndex;
449*4882a593Smuzhiyun             CARD32 NextUniqIndex;
450*4882a593Smuzhiyun             CARD16 *tmp;
451*4882a593Smuzhiyun             CARD32 i, j;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun             hashModulus = 67;
454*4882a593Smuzhiyun             if (hashModulus > nCharInfos + 1)
455*4882a593Smuzhiyun                 hashModulus = nCharInfos + 1;
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun             tmp = xallocarray(4 * nCharInfos + 1, sizeof(CARD16));
458*4882a593Smuzhiyun             if (!tmp) {
459*4882a593Smuzhiyun                 if (!pDesc)
460*4882a593Smuzhiyun                     free(pCI);
461*4882a593Smuzhiyun                 return BadAlloc;
462*4882a593Smuzhiyun             }
463*4882a593Smuzhiyun             pIndex2UniqIndex = tmp;
464*4882a593Smuzhiyun             /* nCharInfos elements */
465*4882a593Smuzhiyun             pUniqIndex2Index = tmp + nCharInfos;
466*4882a593Smuzhiyun             /* max. nCharInfos elements */
467*4882a593Smuzhiyun             pUniqIndex2NextUniqIndex = tmp + 2 * nCharInfos;
468*4882a593Smuzhiyun             /* max. nCharInfos elements */
469*4882a593Smuzhiyun             pHash2UniqIndex = tmp + 3 * nCharInfos;
470*4882a593Smuzhiyun             /* hashModulus (<= nCharInfos+1) elements */
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun             /* Note that we can use 0xffff as end-of-list indicator, because
473*4882a593Smuzhiyun                even if nCharInfos = 0x10000, 0xffff can not occur as valid
474*4882a593Smuzhiyun                entry before the last element has been inserted. And once the
475*4882a593Smuzhiyun                last element has been inserted, we don't need the hash table
476*4882a593Smuzhiyun                any more. */
477*4882a593Smuzhiyun             for (j = 0; j < hashModulus; j++)
478*4882a593Smuzhiyun                 pHash2UniqIndex[j] = (CARD16) (-1);
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun             NextUniqIndex = 0;
481*4882a593Smuzhiyun             for (NextIndex = 0; NextIndex < nCharInfos; NextIndex++) {
482*4882a593Smuzhiyun                 xCharInfo *p = &pCI[NextIndex];
483*4882a593Smuzhiyun                 CARD32 hashCode = hashCI(p) % hashModulus;
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun                 for (i = pHash2UniqIndex[hashCode];
486*4882a593Smuzhiyun                      i != (CARD16) (-1); i = pUniqIndex2NextUniqIndex[i]) {
487*4882a593Smuzhiyun                     j = pUniqIndex2Index[i];
488*4882a593Smuzhiyun                     if (pCI[j].leftSideBearing == p->leftSideBearing
489*4882a593Smuzhiyun                         && pCI[j].rightSideBearing == p->rightSideBearing
490*4882a593Smuzhiyun                         && pCI[j].characterWidth == p->characterWidth
491*4882a593Smuzhiyun                         && pCI[j].ascent == p->ascent
492*4882a593Smuzhiyun                         && pCI[j].descent == p->descent
493*4882a593Smuzhiyun                         && pCI[j].attributes == p->attributes)
494*4882a593Smuzhiyun                         break;
495*4882a593Smuzhiyun                 }
496*4882a593Smuzhiyun                 if (i != (CARD16) (-1)) {
497*4882a593Smuzhiyun                     /* Found *p at Index j, UniqIndex i */
498*4882a593Smuzhiyun                     pIndex2UniqIndex[NextIndex] = i;
499*4882a593Smuzhiyun                 }
500*4882a593Smuzhiyun                 else {
501*4882a593Smuzhiyun                     /* Allocate a new entry in the Uniq table */
502*4882a593Smuzhiyun                     if (hashModulus <= 2 * NextUniqIndex
503*4882a593Smuzhiyun                         && hashModulus < nCharInfos + 1) {
504*4882a593Smuzhiyun                         /* Time to increate hash table size */
505*4882a593Smuzhiyun                         hashModulus = 2 * hashModulus + 1;
506*4882a593Smuzhiyun                         if (hashModulus > nCharInfos + 1)
507*4882a593Smuzhiyun                             hashModulus = nCharInfos + 1;
508*4882a593Smuzhiyun                         for (j = 0; j < hashModulus; j++)
509*4882a593Smuzhiyun                             pHash2UniqIndex[j] = (CARD16) (-1);
510*4882a593Smuzhiyun                         for (i = 0; i < NextUniqIndex; i++)
511*4882a593Smuzhiyun                             pUniqIndex2NextUniqIndex[i] = (CARD16) (-1);
512*4882a593Smuzhiyun                         for (i = 0; i < NextUniqIndex; i++) {
513*4882a593Smuzhiyun                             j = pUniqIndex2Index[i];
514*4882a593Smuzhiyun                             p = &pCI[j];
515*4882a593Smuzhiyun                             hashCode = hashCI(p) % hashModulus;
516*4882a593Smuzhiyun                             pUniqIndex2NextUniqIndex[i] =
517*4882a593Smuzhiyun                                 pHash2UniqIndex[hashCode];
518*4882a593Smuzhiyun                             pHash2UniqIndex[hashCode] = i;
519*4882a593Smuzhiyun                         }
520*4882a593Smuzhiyun                         p = &pCI[NextIndex];
521*4882a593Smuzhiyun                         hashCode = hashCI(p) % hashModulus;
522*4882a593Smuzhiyun                     }
523*4882a593Smuzhiyun                     i = NextUniqIndex++;
524*4882a593Smuzhiyun                     pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode];
525*4882a593Smuzhiyun                     pHash2UniqIndex[hashCode] = i;
526*4882a593Smuzhiyun                     pUniqIndex2Index[i] = NextIndex;
527*4882a593Smuzhiyun                     pIndex2UniqIndex[NextIndex] = i;
528*4882a593Smuzhiyun                 }
529*4882a593Smuzhiyun             }
530*4882a593Smuzhiyun             nUniqCharInfos = NextUniqIndex;
531*4882a593Smuzhiyun             /* fprintf(stderr, "font metrics: nCharInfos = %d, nUniqCharInfos = %d, hashModulus = %d\n", nCharInfos, nUniqCharInfos, hashModulus); */
532*4882a593Smuzhiyun         }
533*4882a593Smuzhiyun     }
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun     {
536*4882a593Smuzhiyun         int nfontprops = pFont->info.nprops;
537*4882a593Smuzhiyun         int rlength = sizeof(xXF86BigfontQueryFontReply)
538*4882a593Smuzhiyun             + nfontprops * sizeof(xFontProp)
539*4882a593Smuzhiyun             + (nCharInfos > 0 && shmid == -1
540*4882a593Smuzhiyun                ? nUniqCharInfos * sizeof(xCharInfo)
541*4882a593Smuzhiyun                + (nCharInfos + 1) / 2 * 2 * sizeof(CARD16)
542*4882a593Smuzhiyun                : 0);
543*4882a593Smuzhiyun         xXF86BigfontQueryFontReply *reply = calloc(1, rlength);
544*4882a593Smuzhiyun         char *p;
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun         if (!reply) {
547*4882a593Smuzhiyun             if (nCharInfos > 0) {
548*4882a593Smuzhiyun                 if (shmid == -1)
549*4882a593Smuzhiyun                     free(pIndex2UniqIndex);
550*4882a593Smuzhiyun                 if (!pDesc)
551*4882a593Smuzhiyun                     free(pCI);
552*4882a593Smuzhiyun             }
553*4882a593Smuzhiyun             return BadAlloc;
554*4882a593Smuzhiyun         }
555*4882a593Smuzhiyun         reply->type = X_Reply;
556*4882a593Smuzhiyun         reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
557*4882a593Smuzhiyun         reply->sequenceNumber = client->sequence;
558*4882a593Smuzhiyun         reply->minBounds = pFont->info.ink_minbounds;
559*4882a593Smuzhiyun         reply->maxBounds = pFont->info.ink_maxbounds;
560*4882a593Smuzhiyun         reply->minCharOrByte2 = pFont->info.firstCol;
561*4882a593Smuzhiyun         reply->maxCharOrByte2 = pFont->info.lastCol;
562*4882a593Smuzhiyun         reply->defaultChar = pFont->info.defaultCh;
563*4882a593Smuzhiyun         reply->nFontProps = pFont->info.nprops;
564*4882a593Smuzhiyun         reply->drawDirection = pFont->info.drawDirection;
565*4882a593Smuzhiyun         reply->minByte1 = pFont->info.firstRow;
566*4882a593Smuzhiyun         reply->maxByte1 = pFont->info.lastRow;
567*4882a593Smuzhiyun         reply->allCharsExist = pFont->info.allExist;
568*4882a593Smuzhiyun         reply->fontAscent = pFont->info.fontAscent;
569*4882a593Smuzhiyun         reply->fontDescent = pFont->info.fontDescent;
570*4882a593Smuzhiyun         reply->nCharInfos = nCharInfos;
571*4882a593Smuzhiyun         reply->nUniqCharInfos = nUniqCharInfos;
572*4882a593Smuzhiyun         reply->shmid = shmid;
573*4882a593Smuzhiyun         reply->shmsegoffset = 0;
574*4882a593Smuzhiyun         if (client->swapped) {
575*4882a593Smuzhiyun             swaps(&reply->sequenceNumber);
576*4882a593Smuzhiyun             swapl(&reply->length);
577*4882a593Smuzhiyun             swapCharInfo(&reply->minBounds);
578*4882a593Smuzhiyun             swapCharInfo(&reply->maxBounds);
579*4882a593Smuzhiyun             swaps(&reply->minCharOrByte2);
580*4882a593Smuzhiyun             swaps(&reply->maxCharOrByte2);
581*4882a593Smuzhiyun             swaps(&reply->defaultChar);
582*4882a593Smuzhiyun             swaps(&reply->nFontProps);
583*4882a593Smuzhiyun             swaps(&reply->fontAscent);
584*4882a593Smuzhiyun             swaps(&reply->fontDescent);
585*4882a593Smuzhiyun             swapl(&reply->nCharInfos);
586*4882a593Smuzhiyun             swapl(&reply->nUniqCharInfos);
587*4882a593Smuzhiyun             swapl(&reply->shmid);
588*4882a593Smuzhiyun             swapl(&reply->shmsegoffset);
589*4882a593Smuzhiyun         }
590*4882a593Smuzhiyun         p = (char *) &reply[1];
591*4882a593Smuzhiyun         {
592*4882a593Smuzhiyun             FontPropPtr pFP;
593*4882a593Smuzhiyun             xFontProp *prFP;
594*4882a593Smuzhiyun             int i;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun             for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) p;
597*4882a593Smuzhiyun                  i < nfontprops; i++, pFP++, prFP++) {
598*4882a593Smuzhiyun                 prFP->name = pFP->name;
599*4882a593Smuzhiyun                 prFP->value = pFP->value;
600*4882a593Smuzhiyun                 if (client->swapped) {
601*4882a593Smuzhiyun                     swapl(&prFP->name);
602*4882a593Smuzhiyun                     swapl(&prFP->value);
603*4882a593Smuzhiyun                 }
604*4882a593Smuzhiyun             }
605*4882a593Smuzhiyun             p = (char *) prFP;
606*4882a593Smuzhiyun         }
607*4882a593Smuzhiyun         if (nCharInfos > 0 && shmid == -1) {
608*4882a593Smuzhiyun             xCharInfo *pci;
609*4882a593Smuzhiyun             CARD16 *ps;
610*4882a593Smuzhiyun             int i, j;
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun             pci = (xCharInfo *) p;
613*4882a593Smuzhiyun             for (i = 0; i < nUniqCharInfos; i++, pci++) {
614*4882a593Smuzhiyun                 *pci = pCI[pUniqIndex2Index[i]];
615*4882a593Smuzhiyun                 if (client->swapped)
616*4882a593Smuzhiyun                     swapCharInfo(pci);
617*4882a593Smuzhiyun             }
618*4882a593Smuzhiyun             ps = (CARD16 *) pci;
619*4882a593Smuzhiyun             for (j = 0; j < nCharInfos; j++, ps++) {
620*4882a593Smuzhiyun                 *ps = pIndex2UniqIndex[j];
621*4882a593Smuzhiyun                 if (client->swapped) {
622*4882a593Smuzhiyun                     swaps(ps);
623*4882a593Smuzhiyun                 }
624*4882a593Smuzhiyun             }
625*4882a593Smuzhiyun         }
626*4882a593Smuzhiyun         WriteToClient(client, rlength, reply);
627*4882a593Smuzhiyun         free(reply);
628*4882a593Smuzhiyun         if (nCharInfos > 0) {
629*4882a593Smuzhiyun             if (shmid == -1)
630*4882a593Smuzhiyun                 free(pIndex2UniqIndex);
631*4882a593Smuzhiyun             if (!pDesc)
632*4882a593Smuzhiyun                 free(pCI);
633*4882a593Smuzhiyun         }
634*4882a593Smuzhiyun         return Success;
635*4882a593Smuzhiyun     }
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun static int
ProcXF86BigfontDispatch(ClientPtr client)639*4882a593Smuzhiyun ProcXF86BigfontDispatch(ClientPtr client)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun     REQUEST(xReq);
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun     switch (stuff->data) {
644*4882a593Smuzhiyun     case X_XF86BigfontQueryVersion:
645*4882a593Smuzhiyun         return ProcXF86BigfontQueryVersion(client);
646*4882a593Smuzhiyun     case X_XF86BigfontQueryFont:
647*4882a593Smuzhiyun         return ProcXF86BigfontQueryFont(client);
648*4882a593Smuzhiyun     default:
649*4882a593Smuzhiyun         return BadRequest;
650*4882a593Smuzhiyun     }
651*4882a593Smuzhiyun }
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun static int _X_COLD
SProcXF86BigfontQueryVersion(ClientPtr client)654*4882a593Smuzhiyun SProcXF86BigfontQueryVersion(ClientPtr client)
655*4882a593Smuzhiyun {
656*4882a593Smuzhiyun     REQUEST(xXF86BigfontQueryVersionReq);
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun     swaps(&stuff->length);
659*4882a593Smuzhiyun     return ProcXF86BigfontQueryVersion(client);
660*4882a593Smuzhiyun }
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun static int _X_COLD
SProcXF86BigfontQueryFont(ClientPtr client)663*4882a593Smuzhiyun SProcXF86BigfontQueryFont(ClientPtr client)
664*4882a593Smuzhiyun {
665*4882a593Smuzhiyun     REQUEST(xXF86BigfontQueryFontReq);
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun     swaps(&stuff->length);
668*4882a593Smuzhiyun     REQUEST_SIZE_MATCH(xXF86BigfontQueryFontReq);
669*4882a593Smuzhiyun     swapl(&stuff->id);
670*4882a593Smuzhiyun     return ProcXF86BigfontQueryFont(client);
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun static int _X_COLD
SProcXF86BigfontDispatch(ClientPtr client)674*4882a593Smuzhiyun SProcXF86BigfontDispatch(ClientPtr client)
675*4882a593Smuzhiyun {
676*4882a593Smuzhiyun     REQUEST(xReq);
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun     switch (stuff->data) {
679*4882a593Smuzhiyun     case X_XF86BigfontQueryVersion:
680*4882a593Smuzhiyun         return SProcXF86BigfontQueryVersion(client);
681*4882a593Smuzhiyun     case X_XF86BigfontQueryFont:
682*4882a593Smuzhiyun         return SProcXF86BigfontQueryFont(client);
683*4882a593Smuzhiyun     default:
684*4882a593Smuzhiyun         return BadRequest;
685*4882a593Smuzhiyun     }
686*4882a593Smuzhiyun }
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun void
XFree86BigfontExtensionInit(void)689*4882a593Smuzhiyun XFree86BigfontExtensionInit(void)
690*4882a593Smuzhiyun {
691*4882a593Smuzhiyun     if (AddExtension(XF86BIGFONTNAME,
692*4882a593Smuzhiyun                      XF86BigfontNumberEvents,
693*4882a593Smuzhiyun                      XF86BigfontNumberErrors,
694*4882a593Smuzhiyun                      ProcXF86BigfontDispatch,
695*4882a593Smuzhiyun                      SProcXF86BigfontDispatch,
696*4882a593Smuzhiyun                      XF86BigfontResetProc, StandardMinorOpcode)) {
697*4882a593Smuzhiyun #ifdef HAS_SHM
698*4882a593Smuzhiyun #ifdef MUST_CHECK_FOR_SHM_SYSCALL
699*4882a593Smuzhiyun         /*
700*4882a593Smuzhiyun          * Note: Local-clients will not be optimized without shared memory
701*4882a593Smuzhiyun          * support. Remote-client optimization does not depend on shared
702*4882a593Smuzhiyun          * memory support.  Thus, the extension is still registered even
703*4882a593Smuzhiyun          * when shared memory support is not functional.
704*4882a593Smuzhiyun          */
705*4882a593Smuzhiyun         if (!CheckForShmSyscall()) {
706*4882a593Smuzhiyun             ErrorF(XF86BIGFONTNAME
707*4882a593Smuzhiyun                    " extension local-client optimization disabled due to lack of shared memory support in the kernel\n");
708*4882a593Smuzhiyun             return;
709*4882a593Smuzhiyun         }
710*4882a593Smuzhiyun #endif
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun         srand((unsigned int) time(NULL));
713*4882a593Smuzhiyun         signature = ((unsigned int) (65536.0 / (RAND_MAX + 1.0) * rand()) << 16)
714*4882a593Smuzhiyun             + (unsigned int) (65536.0 / (RAND_MAX + 1.0) * rand());
715*4882a593Smuzhiyun         /* fprintf(stderr, "signature = 0x%08X\n", signature); */
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun         FontShmdescIndex = xfont2_allocate_font_private_index();
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun #if !defined(CSRG_BASED) && !defined(__CYGWIN__)
720*4882a593Smuzhiyun         pagesize = SHMLBA;
721*4882a593Smuzhiyun #else
722*4882a593Smuzhiyun #ifdef _SC_PAGESIZE
723*4882a593Smuzhiyun         pagesize = sysconf(_SC_PAGESIZE);
724*4882a593Smuzhiyun #else
725*4882a593Smuzhiyun         pagesize = getpagesize();
726*4882a593Smuzhiyun #endif
727*4882a593Smuzhiyun #endif
728*4882a593Smuzhiyun #endif
729*4882a593Smuzhiyun     }
730*4882a593Smuzhiyun }
731