aboutsummaryrefslogtreecommitdiff
path: root/libX11/src
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/src')
-rw-r--r--libX11/src/ConvSel.c2
-rw-r--r--libX11/src/CrGlCur.c530
-rw-r--r--libX11/src/GetDflt.c10
-rw-r--r--libX11/src/Makefile.am850
-rw-r--r--libX11/src/OpenDis.c1
-rw-r--r--libX11/src/RdBitF.c33
-rw-r--r--libX11/src/StrKeysym.c4
-rw-r--r--libX11/src/XlibInt.c8
-rw-r--r--libX11/src/Xrm.c5324
-rw-r--r--libX11/src/config.h243
-rw-r--r--libX11/src/genhextable.py39
-rw-r--r--libX11/src/makefile278
-rw-r--r--libX11/src/util/makefile6
-rw-r--r--libX11/src/util/makekeys.c3
-rw-r--r--libX11/src/xcb_io.c3
-rw-r--r--libX11/src/xcms/config.h2
-rw-r--r--libX11/src/xcms/makefile71
-rw-r--r--libX11/src/xkb/Makefile27
-rw-r--r--libX11/src/xkb/XKB.c5
-rw-r--r--libX11/src/xkb/XKBBind.c28
-rw-r--r--libX11/src/xkb/XKBGeom.c4
-rw-r--r--libX11/src/xkb/XKBGetMap.c28
-rw-r--r--libX11/src/xkb/XKBMisc.c1
-rw-r--r--libX11/src/xkb/XKBSetGeom.c4
-rw-r--r--libX11/src/xkb/XKBUse.c28
-rw-r--r--libX11/src/xlibi18n/XDefaultOMIF.c1
-rw-r--r--libX11/src/xlibi18n/XimProto.h7
-rw-r--r--libX11/src/xlibi18n/lcDB.c2
-rw-r--r--libX11/src/xlibi18n/lcDynamic.c2
-rw-r--r--libX11/src/xlibi18n/lcFile.c2
-rw-r--r--libX11/src/xlibi18n/makefile80
31 files changed, 4248 insertions, 3378 deletions
diff --git a/libX11/src/ConvSel.c b/libX11/src/ConvSel.c
index fb6e8e338..2dece58b5 100644
--- a/libX11/src/ConvSel.c
+++ b/libX11/src/ConvSel.c
@@ -49,5 +49,5 @@ XConvertSelection(
req->time = time;
UnlockDisplay(dpy);
SyncHandle();
- return 1;
+ return Success;
}
diff --git a/libX11/src/CrGlCur.c b/libX11/src/CrGlCur.c
index 460660f81..4f332836b 100644
--- a/libX11/src/CrGlCur.c
+++ b/libX11/src/CrGlCur.c
@@ -1,260 +1,270 @@
-/*
-
-Copyright 1986, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "Xlibint.h"
-
-#ifdef USE_DYNAMIC_XCURSOR
-
-#ifdef __UNIXOS2__
-#define RTLD_LAZY 1
-#define LIBXCURSOR "Xcursor.dll"
-#endif
-#include <stdio.h>
-#include <string.h>
-#if defined(hpux)
-#include <dl.h>
-#else
-#include <dlfcn.h>
-#endif
-#include "Cr.h"
-
-#ifdef __CYGWIN__
-#define LIBXCURSOR "cygXcursor-1.dll"
-#endif
-
-#if defined(hpux)
-typedef shl_t XModuleType;
-#else
-typedef void *XModuleType;
-#endif
-
-#ifndef LIBXCURSOR
-#define LIBXCURSOR "libXcursor.so.1"
-#endif
-
-static char libraryName[] = LIBXCURSOR;
-
-static XModuleType
-open_library (void)
-{
- char *library = libraryName;
- char *dot;
- XModuleType module;
- for (;;)
- {
-#if defined(hpux)
- module = shl_load(library, BIND_DEFERRED, 0L);
-#else
- module = dlopen(library, RTLD_LAZY);
-#endif
- if (module)
- return module;
- dot = strrchr (library, '.');
- if (!dot)
- break;
- *dot = '\0';
- }
- return NULL;
-}
-
-static void *
-fetch_symbol (XModuleType module, const char *under_symbol)
-{
- void *result = NULL;
- const char *symbol = under_symbol + 1;
-#if defined(hpux)
- int getsyms_cnt, i;
- struct shl_symbol *symbols;
-
- getsyms_cnt = shl_getsymbols(module, TYPE_PROCEDURE,
- EXPORT_SYMBOLS, malloc, &symbols);
-
- for(i=0; i<getsyms_cnt; i++) {
- if(!strcmp(symbols[i].name, symbol)) {
- result = symbols[i].value;
- break;
- }
- }
-
- if(getsyms_cnt > 0) {
- free(symbols);
- }
-#else
- result = dlsym (module, symbol);
- if (!result)
- result = dlsym (module, under_symbol);
-#endif
- return result;
-}
-
-typedef void (*NoticeCreateBitmapFunc) (Display *dpy,
- Pixmap pid,
- unsigned int width,
- unsigned int height);
-
-typedef void (*NoticePutBitmapFunc) (Display *dpy,
- Drawable draw,
- XImage *image);
-
-typedef Cursor (*TryShapeBitmapCursorFunc) (Display *dpy,
- Pixmap source,
- Pixmap mask,
- XColor *foreground,
- XColor *background,
- unsigned int x,
- unsigned int y);
-
-typedef Cursor (*TryShapeCursorFunc) (Display *dpy,
- Font source_font,
- Font mask_font,
- unsigned int source_char,
- unsigned int mask_char,
- XColor _Xconst *foreground,
- XColor _Xconst *background);
-
-static XModuleType _XcursorModule;
-static Bool _XcursorModuleTried;
-
-#define GetFunc(type,name,ret) {\
- static Bool been_here; \
- static type staticFunc; \
- \
- _XLockMutex (_Xglobal_lock); \
- if (!been_here) \
- { \
- been_here = True; \
- if (!_XcursorModuleTried) \
- { \
- _XcursorModuleTried = True; \
- _XcursorModule = open_library (); \
- } \
- if (_XcursorModule) \
- staticFunc = (type) fetch_symbol (_XcursorModule, "_" name); \
- } \
- ret = staticFunc; \
- _XUnlockMutex (_Xglobal_lock); \
-}
-
-static Cursor
-_XTryShapeCursor (Display *dpy,
- Font source_font,
- Font mask_font,
- unsigned int source_char,
- unsigned int mask_char,
- XColor _Xconst *foreground,
- XColor _Xconst *background)
-{
- TryShapeCursorFunc func;
-
- GetFunc (TryShapeCursorFunc, "XcursorTryShapeCursor", func);
- if (func)
- return (*func) (dpy, source_font, mask_font, source_char, mask_char,
- foreground, background);
- return None;
-}
-
-void
-_XNoticeCreateBitmap (Display *dpy,
- Pixmap pid,
- unsigned int width,
- unsigned int height)
-{
- NoticeCreateBitmapFunc func;
-
- GetFunc (NoticeCreateBitmapFunc, "XcursorNoticeCreateBitmap", func);
- if (func)
- (*func) (dpy, pid, width, height);
-}
-
-void
-_XNoticePutBitmap (Display *dpy,
- Drawable draw,
- XImage *image)
-{
- NoticePutBitmapFunc func;
-
- GetFunc (NoticePutBitmapFunc, "XcursorNoticePutBitmap", func);
- if (func)
- (*func) (dpy, draw, image);
-}
-
-Cursor
-_XTryShapeBitmapCursor (Display *dpy,
- Pixmap source,
- Pixmap mask,
- XColor *foreground,
- XColor *background,
- unsigned int x,
- unsigned int y)
-{
- TryShapeBitmapCursorFunc func;
-
- GetFunc (TryShapeBitmapCursorFunc, "XcursorTryShapeBitmapCursor", func);
- if (func)
- return (*func) (dpy, source, mask, foreground, background, x, y);
- return None;
-}
-#endif
-
-Cursor XCreateGlyphCursor(
- register Display *dpy,
- Font source_font,
- Font mask_font,
- unsigned int source_char,
- unsigned int mask_char,
- XColor _Xconst *foreground,
- XColor _Xconst *background)
-{
- Cursor cid;
- register xCreateGlyphCursorReq *req;
-
-#ifdef USE_DYNAMIC_XCURSOR
- cid = _XTryShapeCursor (dpy, source_font, mask_font,
- source_char, mask_char, foreground, background);
- if (cid)
- return cid;
-#endif
- LockDisplay(dpy);
- GetReq(CreateGlyphCursor, req);
- cid = req->cid = XAllocID(dpy);
- req->source = source_font;
- req->mask = mask_font;
- req->sourceChar = source_char;
- req->maskChar = mask_char;
- req->foreRed = foreground->red;
- req->foreGreen = foreground->green;
- req->foreBlue = foreground->blue;
- req->backRed = background->red;
- req->backGreen = background->green;
- req->backBlue = background->blue;
- UnlockDisplay(dpy);
- SyncHandle();
- return (cid);
-}
-
+/*
+
+Copyright 1986, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+
+#ifdef USE_DYNAMIC_XCURSOR
+
+#ifdef __UNIXOS2__
+#define RTLD_LAZY 1
+#define LIBXCURSOR "Xcursor.dll"
+#endif
+#include <stdio.h>
+#include <string.h>
+#if defined(hpux)
+#include <dl.h>
+#else
+#include <dlfcn.h>
+#endif
+#include "Cr.h"
+
+#ifdef __CYGWIN__
+#define LIBXCURSOR "cygXcursor-1.dll"
+#endif
+
+#if defined(hpux)
+typedef shl_t XModuleType;
+#else
+#ifdef _MSC_VER
+#include <X11/XWindows.h>
+typedef HANDLE XModuleType;
+#define dlsym GetProcAddress
+#else
+typedef void *XModuleType;
+#endif
+#endif
+
+#ifndef LIBXCURSOR
+#define LIBXCURSOR "libXcursor.so.1"
+#endif
+
+static char libraryName[] = LIBXCURSOR;
+
+static XModuleType
+open_library (void)
+{
+ char *library = libraryName;
+ char *dot;
+ XModuleType module;
+ for (;;)
+ {
+#if defined(hpux)
+ module = shl_load(library, BIND_DEFERRED, 0L);
+#else
+#ifdef _MSC_VER
+ module = LoadLibrary(library);
+#else
+ module = dlopen(library, RTLD_LAZY);
+#endif
+#endif
+ if (module)
+ return module;
+ dot = strrchr (library, '.');
+ if (!dot)
+ break;
+ *dot = '\0';
+ }
+ return NULL;
+}
+
+static void *
+fetch_symbol (XModuleType module, const char *under_symbol)
+{
+ void *result = NULL;
+ const char *symbol = under_symbol + 1;
+#if defined(hpux)
+ int getsyms_cnt, i;
+ struct shl_symbol *symbols;
+
+ getsyms_cnt = shl_getsymbols(module, TYPE_PROCEDURE,
+ EXPORT_SYMBOLS, malloc, &symbols);
+
+ for(i=0; i<getsyms_cnt; i++) {
+ if(!strcmp(symbols[i].name, symbol)) {
+ result = symbols[i].value;
+ break;
+ }
+ }
+
+ if(getsyms_cnt > 0) {
+ free(symbols);
+ }
+#else
+ result = dlsym (module, symbol);
+ if (!result)
+ result = dlsym (module, under_symbol);
+#endif
+ return result;
+}
+
+typedef void (*NoticeCreateBitmapFunc) (Display *dpy,
+ Pixmap pid,
+ unsigned int width,
+ unsigned int height);
+
+typedef void (*NoticePutBitmapFunc) (Display *dpy,
+ Drawable draw,
+ XImage *image);
+
+typedef Cursor (*TryShapeBitmapCursorFunc) (Display *dpy,
+ Pixmap source,
+ Pixmap mask,
+ XColor *foreground,
+ XColor *background,
+ unsigned int x,
+ unsigned int y);
+
+typedef Cursor (*TryShapeCursorFunc) (Display *dpy,
+ Font source_font,
+ Font mask_font,
+ unsigned int source_char,
+ unsigned int mask_char,
+ XColor _Xconst *foreground,
+ XColor _Xconst *background);
+
+static XModuleType _XcursorModule;
+static Bool _XcursorModuleTried;
+
+#define GetFunc(type,name,ret) {\
+ static Bool been_here; \
+ static type staticFunc; \
+ \
+ _XLockMutex (_Xglobal_lock); \
+ if (!been_here) \
+ { \
+ been_here = True; \
+ if (!_XcursorModuleTried) \
+ { \
+ _XcursorModuleTried = True; \
+ _XcursorModule = open_library (); \
+ } \
+ if (_XcursorModule) \
+ staticFunc = (type) fetch_symbol (_XcursorModule, "_" name); \
+ } \
+ ret = staticFunc; \
+ _XUnlockMutex (_Xglobal_lock); \
+}
+
+static Cursor
+_XTryShapeCursor (Display *dpy,
+ Font source_font,
+ Font mask_font,
+ unsigned int source_char,
+ unsigned int mask_char,
+ XColor _Xconst *foreground,
+ XColor _Xconst *background)
+{
+ TryShapeCursorFunc func;
+
+ GetFunc (TryShapeCursorFunc, "XcursorTryShapeCursor", func);
+ if (func)
+ return (*func) (dpy, source_font, mask_font, source_char, mask_char,
+ foreground, background);
+ return None;
+}
+
+void
+_XNoticeCreateBitmap (Display *dpy,
+ Pixmap pid,
+ unsigned int width,
+ unsigned int height)
+{
+ NoticeCreateBitmapFunc func;
+
+ GetFunc (NoticeCreateBitmapFunc, "XcursorNoticeCreateBitmap", func);
+ if (func)
+ (*func) (dpy, pid, width, height);
+}
+
+void
+_XNoticePutBitmap (Display *dpy,
+ Drawable draw,
+ XImage *image)
+{
+ NoticePutBitmapFunc func;
+
+ GetFunc (NoticePutBitmapFunc, "XcursorNoticePutBitmap", func);
+ if (func)
+ (*func) (dpy, draw, image);
+}
+
+Cursor
+_XTryShapeBitmapCursor (Display *dpy,
+ Pixmap source,
+ Pixmap mask,
+ XColor *foreground,
+ XColor *background,
+ unsigned int x,
+ unsigned int y)
+{
+ TryShapeBitmapCursorFunc func;
+
+ GetFunc (TryShapeBitmapCursorFunc, "XcursorTryShapeBitmapCursor", func);
+ if (func)
+ return (*func) (dpy, source, mask, foreground, background, x, y);
+ return None;
+}
+#endif
+
+Cursor XCreateGlyphCursor(
+ register Display *dpy,
+ Font source_font,
+ Font mask_font,
+ unsigned int source_char,
+ unsigned int mask_char,
+ XColor _Xconst *foreground,
+ XColor _Xconst *background)
+{
+ Cursor cid;
+ register xCreateGlyphCursorReq *req;
+
+#ifdef USE_DYNAMIC_XCURSOR
+ cid = _XTryShapeCursor (dpy, source_font, mask_font,
+ source_char, mask_char, foreground, background);
+ if (cid)
+ return cid;
+#endif
+ LockDisplay(dpy);
+ GetReq(CreateGlyphCursor, req);
+ cid = req->cid = XAllocID(dpy);
+ req->source = source_font;
+ req->mask = mask_font;
+ req->sourceChar = source_char;
+ req->maskChar = mask_char;
+ req->foreRed = foreground->red;
+ req->foreGreen = foreground->green;
+ req->foreBlue = foreground->blue;
+ req->backRed = background->red;
+ req->backGreen = background->green;
+ req->backBlue = background->blue;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return (cid);
+}
+
diff --git a/libX11/src/GetDflt.c b/libX11/src/GetDflt.c
index dfda1c64d..0443e2d1a 100644
--- a/libX11/src/GetDflt.c
+++ b/libX11/src/GetDflt.c
@@ -160,9 +160,13 @@ InitDefaults(
* ~/.Xdefaults. Next, if there is an XENVIRONMENT environment variable,
* then load that file.
*/
-
+
if (dpy->xdefaults == NULL) {
+ #ifdef _MSC_VER
+ const char *slashDotXdefaults = ".Xdefaults";
+ #else
const char *slashDotXdefaults = "/.Xdefaults";
+ #endif
(void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaults) - 1);
(void) strcat (fname, slashDotXdefaults);
@@ -172,7 +176,11 @@ InitDefaults(
}
if (!(xenv = getenv ("XENVIRONMENT"))) {
+ #ifdef _MSC_VER
+ const char *slashDotXdefaultsDash = ".Xdefaults-";
+ #else
const char *slashDotXdefaultsDash = "/.Xdefaults-";
+ #endif
int len;
(void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaultsDash) - 1);
diff --git a/libX11/src/Makefile.am b/libX11/src/Makefile.am
index 71e02e71b..ecf4a99aa 100644
--- a/libX11/src/Makefile.am
+++ b/libX11/src/Makefile.am
@@ -1,425 +1,425 @@
-if XKB
-XKB_SUBDIRS = xkb
-endif
-SUBDIRS = util xcms xlibi18n $(XKB_SUBDIRS)
-
-lib_LTLIBRARIES = libX11.la libX11-xcb.la
-
-BUILT_SOURCES=ks_tables.h
-CLEANFILES=ks_tables.h ks_tables_h
-
-AM_CPPFLAGS= \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/include/X11 \
- -I$(top_builddir)/include \
- -I$(top_builddir)/include/X11 \
- -I$(top_srcdir)/src/xcms \
- -I$(top_srcdir)/src/xkb \
- -I$(top_srcdir)/src/xlibi18n \
- -D_BSD_SOURCE -DX11_t -DTRANS_CLIENT
-
-AM_CFLAGS= \
- $(X11_CFLAGS) \
- $(BIGFONT_CFLAGS) \
- $(XMALLOC_ZERO_CFLAGS) \
- $(CWARNFLAGS)
-
-#
-# =============================== I18N =============================
-#
-
-I18N_LIBS = \
- xlibi18n/libi18n.la
-
-#
-# =============================== XCMS =============================
-#
-
-XCMS_LIBS = \
- xcms/libxcms.la
-
-#
-# =============================== XKB ==============================
-#
-
-XKB_LIBS = \
- xkb/libxkb.la
-
-#
-# =============================== XLIB =============================
-#
-
-libX11_la_SOURCES = \
- AllCells.c \
- AllowEv.c \
- AllPlanes.c \
- AutoRep.c \
- Backgnd.c \
- BdrWidth.c \
- Bell.c \
- Border.c \
- ChAccCon.c \
- ChActPGb.c \
- ChClMode.c \
- ChCmap.c \
- ChGC.c \
- ChKeyCon.c \
- ChkIfEv.c \
- ChkMaskEv.c \
- ChkTypEv.c \
- ChkTypWEv.c \
- ChkWinEv.c \
- ChPntCon.c \
- ChProp.c \
- ChSaveSet.c \
- ChWAttrs.c \
- ChWindow.c \
- CirWin.c \
- CirWinDn.c \
- CirWinUp.c \
- ClDisplay.c \
- ClearArea.c \
- Clear.c \
- Cmap.h \
- ConfWind.c \
- Context.c \
- ConvSel.c \
- CopyArea.c \
- CopyCmap.c \
- CopyGC.c \
- CopyPlane.c \
- CrBFData.c \
- CrCmap.c \
- CrCursor.c \
- CrGC.c \
- CrGlCur.c \
- Cr.h \
- CrPFBData.c \
- CrPixmap.c \
- CrWindow.c \
- Cursor.c \
- DefCursor.c \
- DelProp.c \
- Depths.c \
- DestSubs.c \
- DestWind.c \
- DisName.c \
- DrArc.c \
- DrArcs.c \
- DrLine.c \
- DrLines.c \
- DrPoint.c \
- DrPoints.c \
- DrRect.c \
- DrRects.c \
- DrSegs.c \
- ErrDes.c \
- ErrHndlr.c \
- evtomask.c \
- EvToWire.c \
- FetchName.c \
- FillArc.c \
- FillArcs.c \
- FillPoly.c \
- FillRct.c \
- FillRcts.c \
- FilterEv.c \
- Flush.c \
- Font.c \
- FontInfo.c \
- FontNames.c \
- FreeCmap.c \
- FreeCols.c \
- FreeCurs.c \
- FreeEData.c \
- FreeEventData.c \
- FreeGC.c \
- FreePix.c \
- FSSaver.c \
- FSWrap.c \
- GCMisc.c \
- Geom.c \
- GetAtomNm.c \
- GetColor.c \
- GetDflt.c \
- GetEventData.c \
- GetFPath.c \
- GetFProp.c \
- GetGCVals.c \
- GetGeom.c \
- GetHColor.c \
- GetHints.c \
- GetIFocus.c \
- GetImage.c \
- GetKCnt.c \
- GetMoEv.c \
- GetNrmHint.c \
- GetPCnt.c \
- GetPntMap.c \
- GetProp.c \
- GetRGBCMap.c \
- GetSOwner.c \
- GetSSaver.c \
- GetStCmap.c \
- GetTxtProp.c \
- GetWAttrs.c \
- GetWMCMapW.c \
- GetWMProto.c \
- globals.c \
- GrButton.c \
- GrKeybd.c \
- GrKey.c \
- GrPointer.c \
- GrServer.c \
- Host.c \
- Iconify.c \
- IfEvent.c \
- imConv.c \
- ImText16.c \
- ImText.c \
- ImUtil.c \
- InitExt.c \
- InsCmap.c \
- IntAtom.c \
- KeyBind.c \
- Key.h \
- KeysymStr.c \
- KillCl.c \
- LiHosts.c \
- LiICmaps.c \
- LiProps.c \
- ListExt.c \
- LoadFont.c \
- LockDis.c \
- locking.c \
- locking.h \
- LookupCol.c \
- LowerWin.c \
- Macros.c \
- MapRaised.c \
- MapSubs.c \
- MapWindow.c \
- MaskEvent.c \
- Misc.c \
- ModMap.c \
- MoveWin.c \
- NextEvent.c \
- OCWrap.c \
- OMWrap.c \
- OpenDis.c \
- ParseCmd.c \
- ParseCol.c \
- ParseGeom.c \
- PeekEvent.c \
- PeekIfEv.c \
- Pending.c \
- PixFormats.c \
- PmapBgnd.c \
- PmapBord.c \
- poly.h \
- PolyReg.c \
- PolyTxt16.c \
- PolyTxt.c \
- PropAlloc.c \
- PutBEvent.c \
- PutImage.c \
- Quarks.c \
- QuBest.c \
- QuColor.c \
- QuColors.c \
- QuCurShp.c \
- QuExt.c \
- QuKeybd.c \
- QuPntr.c \
- QuStipShp.c \
- QuTextE16.c \
- QuTextExt.c \
- QuTileShp.c \
- QuTree.c \
- RaiseWin.c \
- RdBitF.c \
- RecolorC.c \
- ReconfWin.c \
- ReconfWM.c \
- Region.c \
- RegstFlt.c \
- RepWindow.c \
- RestackWs.c \
- RotProp.c \
- ScrResStr.c \
- SelInput.c \
- SendEvent.c \
- SetBack.c \
- SetClMask.c \
- SetClOrig.c \
- SetCRects.c \
- SetDashes.c \
- SetFont.c \
- SetFore.c \
- SetFPath.c \
- SetFunc.c \
- SetHints.c \
- SetIFocus.c \
- SetLocale.c \
- SetLStyle.c \
- SetNrmHint.c \
- SetPMask.c \
- SetPntMap.c \
- SetRGBCMap.c \
- SetSOwner.c \
- SetSSaver.c \
- SetState.c \
- SetStCmap.c \
- SetStip.c \
- SetTile.c \
- SetTSOrig.c \
- SetTxtProp.c \
- SetWMCMapW.c \
- SetWMProto.c \
- StBytes.c \
- StColor.c \
- StColors.c \
- StName.c \
- StNColor.c \
- StrKeysym.c \
- StrToText.c \
- Sync.c \
- Synchro.c \
- Text16.c \
- Text.c \
- TextExt16.c \
- TextExt.c \
- TextToStr.c \
- TrCoords.c \
- UndefCurs.c \
- UngrabBut.c \
- UngrabKbd.c \
- UngrabKey.c \
- UngrabPtr.c \
- UngrabSvr.c \
- UninsCmap.c \
- UnldFont.c \
- UnmapSubs.c \
- UnmapWin.c \
- utlist.h \
- VisUtil.c \
- WarpPtr.c \
- Window.c \
- WinEvent.c \
- Withdraw.c \
- WMGeom.c \
- WMProps.c \
- WrBitF.c \
- Xatomtype.h \
- xcb_disp.c \
- xcb_io.c \
- Xintatom.h \
- Xintconn.h \
- XlibAsync.c \
- XlibInt.c \
- Xprivate.h \
- XomGeneric.h \
- Xresinternal.h \
- Xrm.c \
- Xxcbint.h
-
-#
-# ========================= Extra stuff ============================
-#
-
-if OS2
-libX11_la_SOURCES+=os2Stubs.c
-endif OS2
-
-if UDC
-libX11_la_SOURCES+=udcInf.c
-endif
-
-if THRSTUBS
-libX11_la_SOURCES+=UIThrStubs.c
-endif
-
-x11datadir = @X11_DATADIR@
-x11data_DATA = XErrorDB
-
-EXTRA_DIST = \
- $(x11data_DATA) \
- os2Stubs.c \
- udcInf.c \
- UIThrStubs.c
-
-libX11_xcb_la_SOURCES = x11_xcb.c Xxcbint.h
-libX11_xcb_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libX11_xcb_la_LIBADD = libX11.la
-
-#
-# Figure out which sub-libraries to link into Xlib
-#
-
-if XLOCALE
-USE_I18N_LIBS = $(I18N_LIBS)
-endif
-
-if XCMS
-USE_XCMS_LIBS = $(XCMS_LIBS)
-endif
-
-if XKB
-USE_XKB_LIBS = $(XKB_LIBS)
-endif
-
-libX11_la_LDFLAGS = -version-number 6:3:0 -no-undefined
-
-libX11_la_LIBADD = \
- $(USE_I18N_LIBS) \
- $(USE_XCMS_LIBS) \
- $(USE_XKB_LIBS) \
- $(X11_LIBS)
-
-preprocess: $(patsubst %.c,%.ii,$(libX11_la_SOURCES))
-.c.ii:
- $(COMPILE) -E -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
-
-if LINT
-# Check source code with tools like lint & sparse
-
-ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
-
-lint: $(BUILT_SOURCES)
- for f in $(libX11_la_SOURCES) ; do \
- $(LINT) $(ALL_LINT_FLAGS) $$f ; \
- done
- @for subdir in $(SUBDIRS) ; do \
- echo "Making $@ in src/$$subdir"; \
- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) lint) ; \
- done
-endif LINT
-
-if MAKE_LINT_LIB
-lintlibdir = $(libdir)
-
-lintlib_DATA = $(LINTLIB)
-
-lintlib_src = $(libX11_la_SOURCES) xcms/*.c xkb/*.c
-
-CLEANFILES += $(lintlib_DATA)
-
-$(LINTLIB): $(libX11_la_SOURCES)
- $(AM_V_GEN)$(LINT) -y -oX11 -x $(ALL_LINT_FLAGS) $(lintlib_src)
-endif MAKE_LINT_LIB
-
-#
-# Building ks_tables.h requires the makekeys utility
-#
-
-KEYSYMDEFS=@KEYSYMDEFS@
-
-ks_tables.h: $(KEYSYMDEFS) $(top_builddir)/src/util/makekeys$(EXEEXT)
- $(top_builddir)/src/util/makekeys $(KEYSYMDEFS) > ks_tables_h
- mv ks_tables_h $@
-
-$(top_builddir)/src/util/makekeys$(EXEEXT): force
- cd util && $(MAKE)
-
-force:
+if XKB
+XKB_SUBDIRS = xkb
+endif
+SUBDIRS = util xcms xlibi18n $(XKB_SUBDIRS)
+
+lib_LTLIBRARIES = libX11.la libX11-xcb.la
+
+BUILT_SOURCES=ks_tables.h
+CLEANFILES=ks_tables.h ks_tables_h
+
+AM_CPPFLAGS= \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/include/X11 \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/include/X11 \
+ -I$(top_srcdir)/src/xcms \
+ -I$(top_srcdir)/src/xkb \
+ -I$(top_srcdir)/src/xlibi18n \
+ -D_BSD_SOURCE -DX11_t -DTRANS_CLIENT
+
+AM_CFLAGS= \
+ $(X11_CFLAGS) \
+ $(BIGFONT_CFLAGS) \
+ $(XMALLOC_ZERO_CFLAGS) \
+ $(CWARNFLAGS)
+
+#
+# =============================== I18N =============================
+#
+
+I18N_LIBS = \
+ xlibi18n/libi18n.la
+
+#
+# =============================== XCMS =============================
+#
+
+XCMS_LIBS = \
+ xcms/libxcms.la
+
+#
+# =============================== XKB ==============================
+#
+
+XKB_LIBS = \
+ xkb/libxkb.la
+
+#
+# =============================== XLIB =============================
+#
+
+libX11_la_SOURCES = \
+ AllCells.c \
+ AllowEv.c \
+ AllPlanes.c \
+ AutoRep.c \
+ Backgnd.c \
+ BdrWidth.c \
+ Bell.c \
+ Border.c \
+ ChAccCon.c \
+ ChActPGb.c \
+ ChClMode.c \
+ ChCmap.c \
+ ChGC.c \
+ ChKeyCon.c \
+ ChkIfEv.c \
+ ChkMaskEv.c \
+ ChkTypEv.c \
+ ChkTypWEv.c \
+ ChkWinEv.c \
+ ChPntCon.c \
+ ChProp.c \
+ ChSaveSet.c \
+ ChWAttrs.c \
+ ChWindow.c \
+ CirWin.c \
+ CirWinDn.c \
+ CirWinUp.c \
+ ClDisplay.c \
+ ClearArea.c \
+ Clear.c \
+ Cmap.h \
+ ConfWind.c \
+ Context.c \
+ ConvSel.c \
+ CopyArea.c \
+ CopyCmap.c \
+ CopyGC.c \
+ CopyPlane.c \
+ CrBFData.c \
+ CrCmap.c \
+ CrCursor.c \
+ CrGC.c \
+ CrGlCur.c \
+ Cr.h \
+ CrPFBData.c \
+ CrPixmap.c \
+ CrWindow.c \
+ Cursor.c \
+ DefCursor.c \
+ DelProp.c \
+ Depths.c \
+ DestSubs.c \
+ DestWind.c \
+ DisName.c \
+ DrArc.c \
+ DrArcs.c \
+ DrLine.c \
+ DrLines.c \
+ DrPoint.c \
+ DrPoints.c \
+ DrRect.c \
+ DrRects.c \
+ DrSegs.c \
+ ErrDes.c \
+ ErrHndlr.c \
+ evtomask.c \
+ EvToWire.c \
+ FetchName.c \
+ FillArc.c \
+ FillArcs.c \
+ FillPoly.c \
+ FillRct.c \
+ FillRcts.c \
+ FilterEv.c \
+ Flush.c \
+ Font.c \
+ FontInfo.c \
+ FontNames.c \
+ FreeCmap.c \
+ FreeCols.c \
+ FreeCurs.c \
+ FreeEData.c \
+ FreeEventData.c \
+ FreeGC.c \
+ FreePix.c \
+ FSSaver.c \
+ FSWrap.c \
+ GCMisc.c \
+ Geom.c \
+ GetAtomNm.c \
+ GetColor.c \
+ GetDflt.c \
+ GetEventData.c \
+ GetFPath.c \
+ GetFProp.c \
+ GetGCVals.c \
+ GetGeom.c \
+ GetHColor.c \
+ GetHints.c \
+ GetIFocus.c \
+ GetImage.c \
+ GetKCnt.c \
+ GetMoEv.c \
+ GetNrmHint.c \
+ GetPCnt.c \
+ GetPntMap.c \
+ GetProp.c \
+ GetRGBCMap.c \
+ GetSOwner.c \
+ GetSSaver.c \
+ GetStCmap.c \
+ GetTxtProp.c \
+ GetWAttrs.c \
+ GetWMCMapW.c \
+ GetWMProto.c \
+ globals.c \
+ GrButton.c \
+ GrKeybd.c \
+ GrKey.c \
+ GrPointer.c \
+ GrServer.c \
+ Host.c \
+ Iconify.c \
+ IfEvent.c \
+ imConv.c \
+ ImText16.c \
+ ImText.c \
+ ImUtil.c \
+ InitExt.c \
+ InsCmap.c \
+ IntAtom.c \
+ KeyBind.c \
+ Key.h \
+ KeysymStr.c \
+ KillCl.c \
+ LiHosts.c \
+ LiICmaps.c \
+ LiProps.c \
+ ListExt.c \
+ LoadFont.c \
+ LockDis.c \
+ locking.c \
+ locking.h \
+ LookupCol.c \
+ LowerWin.c \
+ Macros.c \
+ MapRaised.c \
+ MapSubs.c \
+ MapWindow.c \
+ MaskEvent.c \
+ Misc.c \
+ ModMap.c \
+ MoveWin.c \
+ NextEvent.c \
+ OCWrap.c \
+ OMWrap.c \
+ OpenDis.c \
+ ParseCmd.c \
+ ParseCol.c \
+ ParseGeom.c \
+ PeekEvent.c \
+ PeekIfEv.c \
+ Pending.c \
+ PixFormats.c \
+ PmapBgnd.c \
+ PmapBord.c \
+ poly.h \
+ PolyReg.c \
+ PolyTxt16.c \
+ PolyTxt.c \
+ PropAlloc.c \
+ PutBEvent.c \
+ PutImage.c \
+ Quarks.c \
+ QuBest.c \
+ QuColor.c \
+ QuColors.c \
+ QuCurShp.c \
+ QuExt.c \
+ QuKeybd.c \
+ QuPntr.c \
+ QuStipShp.c \
+ QuTextE16.c \
+ QuTextExt.c \
+ QuTileShp.c \
+ QuTree.c \
+ RaiseWin.c \
+ RdBitF.c \
+ RecolorC.c \
+ ReconfWin.c \
+ ReconfWM.c \
+ Region.c \
+ RegstFlt.c \
+ RepWindow.c \
+ RestackWs.c \
+ RotProp.c \
+ ScrResStr.c \
+ SelInput.c \
+ SendEvent.c \
+ SetBack.c \
+ SetClMask.c \
+ SetClOrig.c \
+ SetCRects.c \
+ SetDashes.c \
+ SetFont.c \
+ SetFore.c \
+ SetFPath.c \
+ SetFunc.c \
+ SetHints.c \
+ SetIFocus.c \
+ SetLocale.c \
+ SetLStyle.c \
+ SetNrmHint.c \
+ SetPMask.c \
+ SetPntMap.c \
+ SetRGBCMap.c \
+ SetSOwner.c \
+ SetSSaver.c \
+ SetState.c \
+ SetStCmap.c \
+ SetStip.c \
+ SetTile.c \
+ SetTSOrig.c \
+ SetTxtProp.c \
+ SetWMCMapW.c \
+ SetWMProto.c \
+ StBytes.c \
+ StColor.c \
+ StColors.c \
+ StName.c \
+ StNColor.c \
+ StrKeysym.c \
+ StrToText.c \
+ Sync.c \
+ Synchro.c \
+ Text16.c \
+ Text.c \
+ TextExt16.c \
+ TextExt.c \
+ TextToStr.c \
+ TrCoords.c \
+ UndefCurs.c \
+ UngrabBut.c \
+ UngrabKbd.c \
+ UngrabKey.c \
+ UngrabPtr.c \
+ UngrabSvr.c \
+ UninsCmap.c \
+ UnldFont.c \
+ UnmapSubs.c \
+ UnmapWin.c \
+ utlist.h \
+ VisUtil.c \
+ WarpPtr.c \
+ Window.c \
+ WinEvent.c \
+ Withdraw.c \
+ WMGeom.c \
+ WMProps.c \
+ WrBitF.c \
+ Xatomtype.h \
+ xcb_disp.c \
+ xcb_io.c \
+ Xintatom.h \
+ Xintconn.h \
+ XlibAsync.c \
+ XlibInt.c \
+ Xprivate.h \
+ XomGeneric.h \
+ Xresinternal.h \
+ Xrm.c \
+ Xxcbint.h
+
+#
+# ========================= Extra stuff ============================
+#
+
+if OS2
+libX11_la_SOURCES+=os2Stubs.c
+endif OS2
+
+if UDC
+libX11_la_SOURCES+=udcInf.c
+endif
+
+if THRSTUBS
+libX11_la_SOURCES+=UIThrStubs.c
+endif
+
+x11datadir = @X11_DATADIR@
+x11data_DATA = XErrorDB
+
+EXTRA_DIST = \
+ $(x11data_DATA) \
+ os2Stubs.c \
+ udcInf.c \
+ UIThrStubs.c
+
+libX11_xcb_la_SOURCES = x11_xcb.c Xxcbint.h
+libX11_xcb_la_LDFLAGS = -version-number 1:0:0 -no-undefined
+libX11_xcb_la_LIBADD = libX11.la
+
+#
+# Figure out which sub-libraries to link into Xlib
+#
+
+if XLOCALE
+USE_I18N_LIBS = $(I18N_LIBS)
+endif
+
+if XCMS
+USE_XCMS_LIBS = $(XCMS_LIBS)
+endif
+
+if XKB
+USE_XKB_LIBS = $(XKB_LIBS)
+endif
+
+libX11_la_LDFLAGS = -version-number 6:3:0 -no-undefined
+
+libX11_la_LIBADD = \
+ $(USE_I18N_LIBS) \
+ $(USE_XCMS_LIBS) \
+ $(USE_XKB_LIBS) \
+ $(X11_LIBS)
+
+preprocess: $(patsubst %.c,%.ii,$(libX11_la_SOURCES))
+.c.ii:
+ $(COMPILE) -E -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+if LINT
+# Check source code with tools like lint & sparse
+
+ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
+
+lint: $(BUILT_SOURCES)
+ for f in $(libX11_la_SOURCES) ; do \
+ $(LINT) $(ALL_LINT_FLAGS) $$f ; \
+ done
+ @for subdir in $(SUBDIRS) ; do \
+ echo "Making $@ in src/$$subdir"; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) lint) ; \
+ done
+endif LINT
+
+if MAKE_LINT_LIB
+lintlibdir = $(libdir)
+
+lintlib_DATA = $(LINTLIB)
+
+lintlib_src = $(libX11_la_SOURCES) xcms/*.c xkb/*.c
+
+CLEANFILES += $(lintlib_DATA)
+
+$(LINTLIB): $(libX11_la_SOURCES)
+ $(AM_V_GEN)$(LINT) -y -oX11 -x $(ALL_LINT_FLAGS) $(lintlib_src)
+endif MAKE_LINT_LIB
+
+#
+# Building ks_tables.h requires the makekeys utility
+#
+
+KEYSYMDEFS=@KEYSYMDEFS@
+
+ks_tables.h: $(KEYSYMDEFS) $(top_builddir)/src/util/makekeys$(EXEEXT)
+ $(top_builddir)/src/util/makekeys $(KEYSYMDEFS) > ks_tables_h
+ mv ks_tables_h $@
+
+$(top_builddir)/src/util/makekeys$(EXEEXT): force
+ cd util && $(MAKE)
+
+force:
diff --git a/libX11/src/OpenDis.c b/libX11/src/OpenDis.c
index 0b779b0ad..e5336a847 100644
--- a/libX11/src/OpenDis.c
+++ b/libX11/src/OpenDis.c
@@ -32,6 +32,7 @@ in this Software without prior written authorization from The Open Group.
#include <X11/Xatom.h>
#include <X11/Xresource.h>
#include <stdio.h>
+#include <unistd.h>
#include "Xintconn.h"
#ifdef XKB
diff --git a/libX11/src/RdBitF.c b/libX11/src/RdBitF.c
index 07967aebe..e9a509c55 100644
--- a/libX11/src/RdBitF.c
+++ b/libX11/src/RdBitF.c
@@ -54,22 +54,23 @@ from The Open Group.
#define MAX_SIZE 255
/* shared data for the image read/parse logic */
-static const short hexTable[256] = {
- ['0'] = 0, ['1'] = 1,
- ['2'] = 2, ['3'] = 3,
- ['4'] = 4, ['5'] = 5,
- ['6'] = 6, ['7'] = 7,
- ['8'] = 8, ['9'] = 9,
- ['A'] = 10, ['B'] = 11,
- ['C'] = 12, ['D'] = 13,
- ['E'] = 14, ['F'] = 15,
- ['a'] = 10, ['b'] = 11,
- ['c'] = 12, ['d'] = 13,
- ['e'] = 14, ['f'] = 15,
-
- [' '] = -1, [','] = -1,
- ['}'] = -1, ['\n'] = -1,
- ['\t'] = -1
+static const signed char hexTable[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ ,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0
+ , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0
+ , 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
diff --git a/libX11/src/StrKeysym.c b/libX11/src/StrKeysym.c
index 6e9c427f8..907db507b 100644
--- a/libX11/src/StrKeysym.c
+++ b/libX11/src/StrKeysym.c
@@ -39,12 +39,14 @@ in this Software without prior written authorization from The Open Group.
#ifndef KEYSYMDB
#ifndef XKEYSYMDB
-#define KEYSYMDB "/usr/lib/X11/XKeysymDB"
+#define KEYSYMDB "XKeysymDB"
#else
#define KEYSYMDB XKEYSYMDB
#endif
#endif
+#include <unistd.h>
+
static Bool initialized;
static XrmDatabase keysymdb;
static XrmQuark Qkeysym[2];
diff --git a/libX11/src/XlibInt.c b/libX11/src/XlibInt.c
index a78da9bf1..33bbe5458 100644
--- a/libX11/src/XlibInt.c
+++ b/libX11/src/XlibInt.c
@@ -33,6 +33,7 @@ from The Open Group.
#ifdef WIN32
#define _XLIBINT_
+#include <X11\Xw32defs.h>
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -198,6 +199,11 @@ void _XPollfdCacheDel(
#endif
}
+#ifdef _MSC_VER
+#undef min
+#define min __min
+#endif
+
static int sync_hazard(Display *dpy)
{
unsigned long span = dpy->request - dpy->last_request_read;
@@ -239,7 +245,7 @@ void _XSeqSyncFunction(
static int
_XPrivSyncFunction (Display *dpy)
{
-#if XTHREADS
+#ifdef XTHREADS
assert(!dpy->lock_fns);
#endif
assert(dpy->synchandler == _XPrivSyncFunction);
diff --git a/libX11/src/Xrm.c b/libX11/src/Xrm.c
index c466cae7f..f3816741b 100644
--- a/libX11/src/Xrm.c
+++ b/libX11/src/Xrm.c
@@ -1,2662 +1,2662 @@
-
-/***********************************************************
-Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard
-
- 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 name Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL 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.
-
-******************************************************************/
-/*
-
-Copyright 1987, 1988, 1990, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <ctype.h>
-#include "Xlibint.h"
-#include <X11/Xresource.h>
-#include "Xlcint.h"
-#ifdef XTHREADS
-#include "locking.h"
-#endif
-#include <X11/Xos.h>
-#include <sys/stat.h>
-#include "Xresinternal.h"
-#include "Xresource.h"
-
-/*
-
-These Xrm routines allow very fast lookup of resources in the resource
-database. Several usage patterns are exploited:
-
-(1) Widgets get a lot of resources at one time. Rather than look up each from
-scratch, we can precompute the prioritized list of database levels once, then
-search for each resource starting at the beginning of the list.
-
-(2) Many database levels don't contain any leaf resource nodes. There is no
-point in looking for resources on a level that doesn't contain any. This
-information is kept on a per-level basis.
-
-(3) Sometimes the widget instance tree is structured such that you get the same
-class name repeated on the fully qualified widget name. This can result in the
-same database level occuring multiple times on the search list. The code below
-only checks to see if you get two identical search lists in a row, rather than
-look back through all database levels, but in practice this removes all
-duplicates I've ever observed.
-
-Joel McCormack
-
-*/
-
-/*
-
-The Xrm representation has been completely redesigned to substantially reduce
-memory and hopefully improve performance.
-
-The database is structured into two kinds of tables: LTables that contain
-only values, and NTables that contain only other tables.
-
-Some invariants:
-
-The next pointer of the top-level node table points to the top-level leaf
-table, if any.
-
-Within an LTable, for a given name, the tight value always precedes the
-loose value, and if both are present the loose value is always right after
-the tight value.
-
-Within an NTable, all of the entries for a given name are contiguous,
-in the order tight NTable, loose NTable, tight LTable, loose LTable.
-
-Bob Scheifler
-
-*/
-
-static XrmQuark XrmQString, XrmQANY;
-
-typedef Bool (*DBEnumProc)(
- XrmDatabase* /* db */,
- XrmBindingList /* bindings */,
- XrmQuarkList /* quarks */,
- XrmRepresentation* /* type */,
- XrmValue* /* value */,
- XPointer /* closure */
-);
-
-typedef struct _VEntry {
- struct _VEntry *next; /* next in chain */
- XrmQuark name; /* name of this entry */
- unsigned int tight:1; /* 1 if it is a tight binding */
- unsigned int string:1; /* 1 if type is String */
- unsigned int size:30; /* size of value */
-} VEntryRec, *VEntry;
-
-
-typedef struct _DEntry {
- VEntryRec entry; /* entry */
- XrmRepresentation type; /* representation type */
-} DEntryRec, *DEntry;
-
-/* the value is right after the structure */
-#define StringValue(ve) (XPointer)((ve) + 1)
-#define RepType(ve) ((DEntry)(ve))->type
-/* the value is right after the structure */
-#define DataValue(ve) (XPointer)(((DEntry)(ve)) + 1)
-#define RawValue(ve) (char *)((ve)->string ? StringValue(ve) : DataValue(ve))
-
-typedef struct _NTable {
- struct _NTable *next; /* next in chain */
- XrmQuark name; /* name of this entry */
- unsigned int tight:1; /* 1 if it is a tight binding */
- unsigned int leaf:1; /* 1 if children are values */
- unsigned int hasloose:1; /* 1 if has loose children */
- unsigned int hasany:1; /* 1 if has ANY entry */
- unsigned int pad:4; /* unused */
- unsigned int mask:8; /* hash size - 1 */
- unsigned int entries:16; /* number of children */
-} NTableRec, *NTable;
-
-/* the buckets are right after the structure */
-#define NodeBuckets(ne) ((NTable *)((ne) + 1))
-#define NodeHash(ne,q) NodeBuckets(ne)[(q) & (ne)->mask]
-
-/* leaf tables have an extra level of indirection for the buckets,
- * so that resizing can be done without invalidating a search list.
- * This is completely ugly, and wastes some memory, but the Xlib
- * spec doesn't really specify whether invalidation is OK, and the
- * old implementation did not invalidate.
- */
-typedef struct _LTable {
- NTableRec table;
- VEntry *buckets;
-} LTableRec, *LTable;
-
-#define LeafHash(le,q) (le)->buckets[(q) & (le)->table.mask]
-
-/* An XrmDatabase just holds a pointer to the first top-level table.
- * The type name is no longer descriptive, but better to not change
- * the Xresource.h header file. This type also gets used to define
- * XrmSearchList, which is a complete crock, but we'll just leave it
- * and caste types as required.
- */
-typedef struct _XrmHashBucketRec {
- NTable table;
- XPointer mbstate;
- XrmMethods methods;
-#ifdef XTHREADS
- LockInfoRec linfo;
-#endif
-} XrmHashBucketRec;
-
-/* closure used in get/put resource */
-typedef struct _VClosure {
- XrmRepresentation *type; /* type of value */
- XrmValuePtr value; /* value itself */
-} VClosureRec, *VClosure;
-
-/* closure used in get search list */
-typedef struct _SClosure {
- LTable *list; /* search list */
- int idx; /* index of last filled element */
- int limit; /* maximum index */
-} SClosureRec, *SClosure;
-
-/* placed in XrmSearchList to indicate next table is loose only */
-#define LOOSESEARCH ((LTable)1)
-
-/* closure used in enumerate database */
-typedef struct _EClosure {
- XrmDatabase db; /* the database */
- DBEnumProc proc; /* the user proc */
- XPointer closure; /* the user closure */
- XrmBindingList bindings; /* binding list */
- XrmQuarkList quarks; /* quark list */
- int mode; /* XrmEnum<kind> */
-} EClosureRec, *EClosure;
-
-/* types for typecasting ETable based functions to NTable based functions */
-typedef Bool (*getNTableSProcp)(
- NTable table,
- XrmNameList names,
- XrmClassList classes,
- SClosure closure);
-typedef Bool (*getNTableVProcp)(
- NTable table,
- XrmNameList names,
- XrmClassList classes,
- VClosure closure);
-typedef Bool (*getNTableEProcp)(
- NTable table,
- XrmNameList names,
- XrmClassList classes,
- register int level,
- EClosure closure);
-
-/* predicate to determine when to resize a hash table */
-#define GrowthPred(n,m) ((unsigned)(n) > (((m) + 1) << 2))
-
-#define GROW(prev) \
- if (GrowthPred((*prev)->entries, (*prev)->mask)) \
- GrowTable(prev)
-
-/* pick a reasonable value for maximum depth of resource database */
-#define MAXDBDEPTH 100
-
-/* macro used in get/search functions */
-
-/* find an entry named ename, with leafness given by leaf */
-#define NFIND(ename) \
- q = ename; \
- entry = NodeHash(table, q); \
- while (entry && entry->name != q) \
- entry = entry->next; \
- if (leaf && entry && !entry->leaf) { \
- entry = entry->next; \
- if (entry && !entry->leaf) \
- entry = entry->next; \
- if (entry && entry->name != q) \
- entry = (NTable)NULL; \
- }
-
-/* resourceQuarks keeps track of what quarks have been associated with values
- * in all LTables. If a quark has never been used in an LTable, we don't need
- * to bother looking for it.
- */
-
-static unsigned char *resourceQuarks = (unsigned char *)NULL;
-static XrmQuark maxResourceQuark = -1;
-
-/* determines if a quark has been used for a value in any database */
-#define IsResourceQuark(q) ((q) > 0 && (q) <= maxResourceQuark && \
- resourceQuarks[(q) >> 3] & (1 << ((q) & 7)))
-
-typedef unsigned char XrmBits;
-
-#define BSLASH ((XrmBits) (1 << 5))
-#define NORMAL ((XrmBits) (1 << 4))
-#define EOQ ((XrmBits) (1 << 3))
-#define SEP ((XrmBits) (1 << 2))
-#define ENDOF ((XrmBits) (1 << 1))
-#define SPACE (NORMAL|EOQ|SEP|(XrmBits)0)
-#define RSEP (NORMAL|EOQ|SEP|(XrmBits)1)
-#define EOS (EOQ|SEP|ENDOF|(XrmBits)0)
-#define EOL (EOQ|SEP|ENDOF|(XrmBits)1)
-#define BINDING (NORMAL|EOQ)
-#define ODIGIT (NORMAL|(XrmBits)1)
-
-#define next_char(ch,str) xrmtypes[(unsigned char)((ch) = *(++(str)))]
-#define next_mbchar(ch,len,str) xrmtypes[(unsigned char)(ch = (*db->methods->mbchar)(db->mbstate, str, &len), str += len, ch)]
-
-#define is_space(bits) ((bits) == SPACE)
-#define is_EOQ(bits) ((bits) & EOQ)
-#define is_EOF(bits) ((bits) == EOS)
-#define is_EOL(bits) ((bits) & ENDOF)
-#define is_binding(bits) ((bits) == BINDING)
-#define is_odigit(bits) ((bits) == ODIGIT)
-#define is_separator(bits) ((bits) & SEP)
-#define is_nonpcs(bits) (!(bits))
-#define is_normal(bits) ((bits) & NORMAL)
-#define is_simple(bits) ((bits) & (NORMAL|BSLASH))
-#define is_special(bits) ((bits) & (ENDOF|BSLASH))
-
-/* parsing types */
-static XrmBits const xrmtypes[256] = {
- EOS,0,0,0,0,0,0,0,
- 0,SPACE,EOL,0,0,
-#if defined(WIN32) || defined(__UNIXOS2__)
- EOL, /* treat CR the same as LF, just in case */
-#else
- 0,
-#endif
- 0,0,
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,
- SPACE,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
- NORMAL,NORMAL,BINDING,NORMAL,NORMAL,NORMAL,BINDING,NORMAL,
- ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,
- NORMAL,NORMAL,RSEP,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
- NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
- NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
- NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
- NORMAL,NORMAL,NORMAL,NORMAL,BSLASH,NORMAL,NORMAL,NORMAL,
- NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
- NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
- NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
- NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,0
- /* The rest will be automatically initialized to zero. */
-};
-
-void XrmInitialize(void)
-{
- XrmQString = XrmPermStringToQuark("String");
- XrmQANY = XrmPermStringToQuark("?");
-}
-
-XrmDatabase XrmGetDatabase(
- Display *display)
-{
- XrmDatabase retval;
- LockDisplay(display);
- retval = display->db;
- UnlockDisplay(display);
- return retval;
-}
-
-void XrmSetDatabase(
- Display *display,
- XrmDatabase database)
-{
- LockDisplay(display);
- /* destroy database if set up imlicitely by XGetDefault() */
- if (display->db && (display->flags & XlibDisplayDfltRMDB)) {
- XrmDestroyDatabase(display->db);
- display->flags &= ~XlibDisplayDfltRMDB;
- }
- display->db = database;
- UnlockDisplay(display);
-}
-
-void
-XrmStringToQuarkList(
- register _Xconst char *name,
- register XrmQuarkList quarks) /* RETURN */
-{
- register XrmBits bits;
- register Signature sig = 0;
- register char ch, *tname;
- register int i = 0;
-
- if ((tname = (char *)name)) {
- tname--;
- while (!is_EOF(bits = next_char(ch, tname))) {
- if (is_binding (bits)) {
- if (i) {
- /* Found a complete name */
- *quarks++ = _XrmInternalStringToQuark(name,tname - name,
- sig, False);
- i = 0;
- sig = 0;
- }
- name = tname+1;
- }
- else {
- sig = (sig << 1) + ch; /* Compute the signature. */
- i++;
- }
- }
- *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False);
- }
- *quarks = NULLQUARK;
-}
-
-void
-XrmStringToBindingQuarkList(
- register _Xconst char *name,
- register XrmBindingList bindings, /* RETURN */
- register XrmQuarkList quarks) /* RETURN */
-{
- register XrmBits bits;
- register Signature sig = 0;
- register char ch, *tname;
- register XrmBinding binding;
- register int i = 0;
-
- if ((tname = (char *)name)) {
- tname--;
- binding = XrmBindTightly;
- while (!is_EOF(bits = next_char(ch, tname))) {
- if (is_binding (bits)) {
- if (i) {
- /* Found a complete name */
- *bindings++ = binding;
- *quarks++ = _XrmInternalStringToQuark(name, tname - name,
- sig, False);
-
- i = 0;
- sig = 0;
- binding = XrmBindTightly;
- }
- name = tname+1;
-
- if (ch == '*')
- binding = XrmBindLoosely;
- }
- else {
- sig = (sig << 1) + ch; /* Compute the signature. */
- i++;
- }
- }
- *bindings = binding;
- *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False);
- }
- *quarks = NULLQUARK;
-}
-
-#ifdef DEBUG
-
-static void PrintQuarkList(
- XrmQuarkList quarks,
- FILE *stream)
-{
- Bool firstNameSeen;
-
- for (firstNameSeen = False; *quarks; quarks++) {
- if (firstNameSeen) {
- (void) fprintf(stream, ".");
- }
- firstNameSeen = True;
- (void) fputs(XrmQuarkToString(*quarks), stream);
- }
-} /* PrintQuarkList */
-
-#endif /* DEBUG */
-
-
-/*
- * Fallback methods for Xrm parsing.
- * Simulate a C locale. No state needed here.
- */
-
-static void
-c_mbnoop(
- XPointer state)
-{
-}
-
-static char
-c_mbchar(
- XPointer state,
- const char *str,
- int *lenp)
-{
- *lenp = 1;
- return *str;
-}
-
-static const char *
-c_lcname(
- XPointer state)
-{
- return "C";
-}
-
-static const XrmMethodsRec mb_methods = {
- c_mbnoop, /* mbinit */
- c_mbchar, /* mbchar */
- c_mbnoop, /* mbfinish */
- c_lcname, /* lcname */
- c_mbnoop /* destroy */
-};
-
-
-static XrmDatabase NewDatabase(void)
-{
- register XrmDatabase db;
-
- db = (XrmDatabase) Xmalloc(sizeof(XrmHashBucketRec));
- if (db) {
- _XCreateMutex(&db->linfo);
- db->table = (NTable)NULL;
- db->mbstate = (XPointer)NULL;
- db->methods = _XrmInitParseInfo(&db->mbstate);
- if (!db->methods)
- db->methods = &mb_methods;
- }
- return db;
-}
-
-/* move all values from ftable to ttable, and free ftable's buckets.
- * ttable is quaranteed empty to start with.
- */
-static void MoveValues(
- LTable ftable,
- register LTable ttable)
-{
- register VEntry fentry, nfentry;
- register VEntry *prev;
- register VEntry *bucket;
- register VEntry tentry;
- register int i;
-
- for (i = ftable->table.mask, bucket = ftable->buckets; i >= 0; i--) {
- for (fentry = *bucket++; fentry; fentry = nfentry) {
- prev = &LeafHash(ttable, fentry->name);
- tentry = *prev;
- *prev = fentry;
- /* chain on all with same name, to preserve invariant order */
- while ((nfentry = fentry->next) && nfentry->name == fentry->name)
- fentry = nfentry;
- fentry->next = tentry;
- }
- }
- Xfree((char *)ftable->buckets);
-}
-
-/* move all tables from ftable to ttable, and free ftable.
- * ttable is quaranteed empty to start with.
- */
-static void MoveTables(
- NTable ftable,
- register NTable ttable)
-{
- register NTable fentry, nfentry;
- register NTable *prev;
- register NTable *bucket;
- register NTable tentry;
- register int i;
-
- for (i = ftable->mask, bucket = NodeBuckets(ftable); i >= 0; i--) {
- for (fentry = *bucket++; fentry; fentry = nfentry) {
- prev = &NodeHash(ttable, fentry->name);
- tentry = *prev;
- *prev = fentry;
- /* chain on all with same name, to preserve invariant order */
- while ((nfentry = fentry->next) && nfentry->name == fentry->name)
- fentry = nfentry;
- fentry->next = tentry;
- }
- }
- Xfree((char *)ftable);
-}
-
-/* grow the table, based on current number of entries */
-static void GrowTable(
- NTable *prev)
-{
- register NTable table;
- register int i;
-
- table = *prev;
- i = table->mask;
- if (i == 255) /* biggest it gets */
- return;
- while (i < 255 && GrowthPred(table->entries, i))
- i = (i << 1) + 1;
- i++; /* i is now the new size */
- if (table->leaf) {
- register LTable ltable;
- LTableRec otable;
-
- ltable = (LTable)table;
- /* cons up a copy to make MoveValues look symmetric */
- otable = *ltable;
- ltable->buckets = (VEntry *)Xmalloc(i * sizeof(VEntry));
- if (!ltable->buckets) {
- ltable->buckets = otable.buckets;
- return;
- }
- ltable->table.mask = i - 1;
- bzero((char *)ltable->buckets, i * sizeof(VEntry));
- MoveValues(&otable, ltable);
- } else {
- register NTable ntable;
-
- ntable = (NTable)Xmalloc(sizeof(NTableRec) + i * sizeof(NTable));
- if (!ntable)
- return;
- *ntable = *table;
- ntable->mask = i - 1;
- bzero((char *)NodeBuckets(ntable), i * sizeof(NTable));
- *prev = ntable;
- MoveTables(table, ntable);
- }
-}
-
-/* merge values from ftable into *pprev, destroy ftable in the process */
-static void MergeValues(
- LTable ftable,
- NTable *pprev,
- Bool override)
-{
- register VEntry fentry, tentry;
- register VEntry *prev;
- register LTable ttable;
- VEntry *bucket;
- int i;
- register XrmQuark q;
-
- ttable = (LTable)*pprev;
- if (ftable->table.hasloose)
- ttable->table.hasloose = 1;
- for (i = ftable->table.mask, bucket = ftable->buckets;
- i >= 0;
- i--, bucket++) {
- for (fentry = *bucket; fentry; ) {
- q = fentry->name;
- prev = &LeafHash(ttable, q);
- tentry = *prev;
- while (tentry && tentry->name != q)
- tentry = *(prev = &tentry->next);
- /* note: test intentionally uses fentry->name instead of q */
- /* permits serendipitous inserts */
- while (tentry && tentry->name == fentry->name) {
- /* if tentry is earlier, skip it */
- if (!fentry->tight && tentry->tight) {
- tentry = *(prev = &tentry->next);
- continue;
- }
- if (fentry->tight != tentry->tight) {
- /* no match, chain in fentry */
- *prev = fentry;
- prev = &fentry->next;
- fentry = *prev;
- *prev = tentry;
- ttable->table.entries++;
- } else if (override) {
- /* match, chain in fentry, splice out and free tentry */
- *prev = fentry;
- prev = &fentry->next;
- fentry = *prev;
- *prev = tentry->next;
- /* free the overridden entry */
- Xfree((char *)tentry);
- /* get next tentry */
- tentry = *prev;
- } else {
- /* match, discard fentry */
- prev = &tentry->next;
- tentry = fentry; /* use as a temp var */
- fentry = fentry->next;
- /* free the overpowered entry */
- Xfree((char *)tentry);
- /* get next tentry */
- tentry = *prev;
- }
- if (!fentry)
- break;
- }
- /* at this point, tentry cannot match any fentry named q */
- /* chain in all bindings together, preserve invariant order */
- while (fentry && fentry->name == q) {
- *prev = fentry;
- prev = &fentry->next;
- fentry = *prev;
- *prev = tentry;
- ttable->table.entries++;
- }
- }
- }
- Xfree((char *)ftable->buckets);
- Xfree((char *)ftable);
- /* resize if necessary, now that we're all done */
- GROW(pprev);
-}
-
-/* merge tables from ftable into *pprev, destroy ftable in the process */
-static void MergeTables(
- NTable ftable,
- NTable *pprev,
- Bool override)
-{
- register NTable fentry, tentry;
- NTable nfentry;
- register NTable *prev;
- register NTable ttable;
- NTable *bucket;
- int i;
- register XrmQuark q;
-
- ttable = *pprev;
- if (ftable->hasloose)
- ttable->hasloose = 1;
- if (ftable->hasany)
- ttable->hasany = 1;
- for (i = ftable->mask, bucket = NodeBuckets(ftable);
- i >= 0;
- i--, bucket++) {
- for (fentry = *bucket; fentry; ) {
- q = fentry->name;
- prev = &NodeHash(ttable, q);
- tentry = *prev;
- while (tentry && tentry->name != q)
- tentry = *(prev = &tentry->next);
- /* note: test intentionally uses fentry->name instead of q */
- /* permits serendipitous inserts */
- while (tentry && tentry->name == fentry->name) {
- /* if tentry is earlier, skip it */
- if ((fentry->leaf && !tentry->leaf) ||
- (!fentry->tight && tentry->tight &&
- (fentry->leaf || !tentry->leaf))) {
- tentry = *(prev = &tentry->next);
- continue;
- }
- nfentry = fentry->next;
- if (fentry->leaf != tentry->leaf ||
- fentry->tight != tentry->tight) {
- /* no match, just chain in */
- *prev = fentry;
- *(prev = &fentry->next) = tentry;
- ttable->entries++;
- } else {
- if (fentry->leaf)
- MergeValues((LTable)fentry, prev, override);
- else
- MergeTables(fentry, prev, override);
- /* bump to next tentry */
- tentry = *(prev = &(*prev)->next);
- }
- /* bump to next fentry */
- fentry = nfentry;
- if (!fentry)
- break;
- }
- /* at this point, tentry cannot match any fentry named q */
- /* chain in all bindings together, preserve invariant order */
- while (fentry && fentry->name == q) {
- *prev = fentry;
- prev = &fentry->next;
- fentry = *prev;
- *prev = tentry;
- ttable->entries++;
- }
- }
- }
- Xfree((char *)ftable);
- /* resize if necessary, now that we're all done */
- GROW(pprev);
-}
-
-void XrmCombineDatabase(
- XrmDatabase from, XrmDatabase *into,
- Bool override)
-{
- register NTable *prev;
- register NTable ftable, ttable, nftable;
-
- if (!*into) {
- *into = from;
- } else if (from) {
- _XLockMutex(&from->linfo);
- _XLockMutex(&(*into)->linfo);
- if ((ftable = from->table)) {
- prev = &(*into)->table;
- ttable = *prev;
- if (!ftable->leaf) {
- nftable = ftable->next;
- if (ttable && !ttable->leaf) {
- /* both have node tables, merge them */
- MergeTables(ftable, prev, override);
- /* bump to into's leaf table, if any */
- ttable = *(prev = &(*prev)->next);
- } else {
- /* into has no node table, link from's in */
- *prev = ftable;
- *(prev = &ftable->next) = ttable;
- }
- /* bump to from's leaf table, if any */
- ftable = nftable;
- } else {
- /* bump to into's leaf table, if any */
- if (ttable && !ttable->leaf)
- ttable = *(prev = &ttable->next);
- }
- if (ftable) {
- /* if into has a leaf, merge, else insert */
- if (ttable)
- MergeValues((LTable)ftable, prev, override);
- else
- *prev = ftable;
- }
- }
- (from->methods->destroy)(from->mbstate);
- _XUnlockMutex(&from->linfo);
- _XFreeMutex(&from->linfo);
- Xfree((char *)from);
- _XUnlockMutex(&(*into)->linfo);
- }
-}
-
-void XrmMergeDatabases(
- XrmDatabase from, XrmDatabase *into)
-{
- XrmCombineDatabase(from, into, True);
-}
-
-/* store a value in the database, overriding any existing entry */
-static void PutEntry(
- XrmDatabase db,
- XrmBindingList bindings,
- XrmQuarkList quarks,
- XrmRepresentation type,
- XrmValuePtr value)
-{
- register NTable *pprev, *prev;
- register NTable table;
- register XrmQuark q;
- register VEntry *vprev;
- register VEntry entry;
- NTable *nprev, *firstpprev;
-
-#define NEWTABLE(q,i) \
- table = (NTable)Xmalloc(sizeof(LTableRec)); \
- if (!table) \
- return; \
- table->name = q; \
- table->hasloose = 0; \
- table->hasany = 0; \
- table->mask = 0; \
- table->entries = 0; \
- if (quarks[i]) { \
- table->leaf = 0; \
- nprev = NodeBuckets(table); \
- } else { \
- table->leaf = 1; \
- if (!(nprev = (NTable *)Xmalloc(sizeof(VEntry *)))) {\
- Xfree(table); \
- return; \
- } \
- ((LTable)table)->buckets = (VEntry *)nprev; \
- } \
- *nprev = (NTable)NULL; \
- table->next = *prev; \
- *prev = table
-
- if (!db || !*quarks)
- return;
- table = *(prev = &db->table);
- /* if already at leaf, bump to the leaf table */
- if (!quarks[1] && table && !table->leaf)
- table = *(prev = &table->next);
- pprev = prev;
- if (!table || (quarks[1] && table->leaf)) {
- /* no top-level node table, create one and chain it in */
- NEWTABLE(NULLQUARK,1);
- table->tight = 1; /* arbitrary */
- prev = nprev;
- } else {
- /* search along until we need a value */
- while (quarks[1]) {
- q = *quarks;
- table = *(prev = &NodeHash(table, q));
- while (table && table->name != q)
- table = *(prev = &table->next);
- if (!table)
- break; /* not found */
- if (quarks[2]) {
- if (table->leaf)
- break; /* not found */
- } else {
- if (!table->leaf) {
- /* bump to leaf table, if any */
- table = *(prev = &table->next);
- if (!table || table->name != q)
- break; /* not found */
- if (!table->leaf) {
- /* bump to leaf table, if any */
- table = *(prev = &table->next);
- if (!table || table->name != q)
- break; /* not found */
- }
- }
- }
- if (*bindings == XrmBindTightly) {
- if (!table->tight)
- break; /* not found */
- } else {
- if (table->tight) {
- /* bump to loose table, if any */
- table = *(prev = &table->next);
- if (!table || table->name != q ||
- !quarks[2] != table->leaf)
- break; /* not found */
- }
- }
- /* found that one, bump to next quark */
- pprev = prev;
- quarks++;
- bindings++;
- }
- if (!quarks[1]) {
- /* found all the way to a leaf */
- q = *quarks;
- entry = *(vprev = &LeafHash((LTable)table, q));
- while (entry && entry->name != q)
- entry = *(vprev = &entry->next);
- /* if want loose and have tight, bump to next entry */
- if (entry && *bindings == XrmBindLoosely && entry->tight)
- entry = *(vprev = &entry->next);
- if (entry && entry->name == q &&
- (*bindings == XrmBindTightly) == entry->tight) {
- /* match, need to override */
- if ((type == XrmQString) == entry->string &&
- entry->size == value->size) {
- /* update type if not String, can be different */
- if (!entry->string)
- RepType(entry) = type;
- /* identical size, just overwrite value */
- memcpy(RawValue(entry), (char *)value->addr, value->size);
- return;
- }
- /* splice out and free old entry */
- *vprev = entry->next;
- Xfree((char *)entry);
- (*pprev)->entries--;
- }
- /* this is where to insert */
- prev = (NTable *)vprev;
- }
- }
- /* keep the top table, because we may have to grow it */
- firstpprev = pprev;
- /* iterate until we get to the leaf */
- while (quarks[1]) {
- /* build a new table and chain it in */
- NEWTABLE(*quarks,2);
- if (*quarks++ == XrmQANY)
- (*pprev)->hasany = 1;
- if (*bindings++ == XrmBindTightly) {
- table->tight = 1;
- } else {
- table->tight = 0;
- (*pprev)->hasloose = 1;
- }
- (*pprev)->entries++;
- pprev = prev;
- prev = nprev;
- }
- /* now allocate the value entry */
- entry = (VEntry)Xmalloc(((type == XrmQString) ?
- sizeof(VEntryRec) : sizeof(DEntryRec)) +
- value->size);
- if (!entry)
- return;
- entry->name = q = *quarks;
- if (*bindings == XrmBindTightly) {
- entry->tight = 1;
- } else {
- entry->tight = 0;
- (*pprev)->hasloose = 1;
- }
- /* chain it in, with a bit of type cast ugliness */
- entry->next = *((VEntry *)prev);
- *((VEntry *)prev) = entry;
- entry->size = value->size;
- if (type == XrmQString) {
- entry->string = 1;
- } else {
- entry->string = 0;
- RepType(entry) = type;
- }
- /* save a copy of the value */
- memcpy(RawValue(entry), (char *)value->addr, value->size);
- (*pprev)->entries++;
- /* this is a new leaf, need to remember it for search lists */
- if (q > maxResourceQuark) {
- unsigned oldsize = (maxResourceQuark + 1) >> 3;
- unsigned size = ((q | 0x7f) + 1) >> 3; /* reallocate in chunks */
- if (resourceQuarks) {
- unsigned char *prevQuarks = resourceQuarks;
-
- resourceQuarks = (unsigned char *)Xrealloc((char *)resourceQuarks,
- size);
- if (!resourceQuarks) {
- Xfree(prevQuarks);
- }
- } else
- resourceQuarks = (unsigned char *)Xmalloc(size);
- if (resourceQuarks) {
- bzero((char *)&resourceQuarks[oldsize], size - oldsize);
- maxResourceQuark = (size << 3) - 1;
- } else {
- maxResourceQuark = -1;
- }
- }
- if (q > 0 && resourceQuarks)
- resourceQuarks[q >> 3] |= 1 << (q & 0x7);
- GROW(firstpprev);
-
-#undef NEWTABLE
-}
-
-void XrmQPutResource(
- XrmDatabase *pdb,
- XrmBindingList bindings,
- XrmQuarkList quarks,
- XrmRepresentation type,
- XrmValuePtr value)
-{
- if (!*pdb) *pdb = NewDatabase();
- _XLockMutex(&(*pdb)->linfo);
- PutEntry(*pdb, bindings, quarks, type, value);
- _XUnlockMutex(&(*pdb)->linfo);
-}
-
-void
-XrmPutResource(
- XrmDatabase *pdb,
- _Xconst char *specifier,
- _Xconst char *type,
- XrmValuePtr value)
-{
- XrmBinding bindings[MAXDBDEPTH+1];
- XrmQuark quarks[MAXDBDEPTH+1];
-
- if (!*pdb) *pdb = NewDatabase();
- _XLockMutex(&(*pdb)->linfo);
- XrmStringToBindingQuarkList(specifier, bindings, quarks);
- PutEntry(*pdb, bindings, quarks, XrmStringToQuark(type), value);
- _XUnlockMutex(&(*pdb)->linfo);
-}
-
-void
-XrmQPutStringResource(
- XrmDatabase *pdb,
- XrmBindingList bindings,
- XrmQuarkList quarks,
- _Xconst char *str)
-{
- XrmValue value;
-
- if (!*pdb) *pdb = NewDatabase();
- value.addr = (XPointer) str;
- value.size = strlen(str)+1;
- _XLockMutex(&(*pdb)->linfo);
- PutEntry(*pdb, bindings, quarks, XrmQString, &value);
- _XUnlockMutex(&(*pdb)->linfo);
-}
-
-/* Function Name: GetDatabase
- * Description: Parses a string and stores it as a database.
- * Arguments: db - the database.
- * str - a pointer to the string containing the database.
- * filename - source filename, if any.
- * doall - whether to do all lines or just one
- */
-
-/*
- * This function is highly optimized to inline as much as possible.
- * Be very careful with modifications, or simplifications, as they
- * may adversely affect the performance.
- *
- * Chris Peterson, MIT X Consortium 5/17/90.
- */
-
-/*
- * Xlib spec says max 100 quarks in a lookup, will stop and return if
- * return if any single production's lhs has more than 100 components.
- */
-#define QLIST_SIZE 100
-
-/*
- * This should be big enough to handle things like the XKeysymDB or biggish
- * ~/.Xdefaults or app-defaults files. Anything bigger will be allocated on
- * the heap.
- */
-#define DEF_BUFF_SIZE 8192
-
-static void GetIncludeFile(
- XrmDatabase db,
- _Xconst char *base,
- _Xconst char *fname,
- int fnamelen);
-
-static void GetDatabase(
- XrmDatabase db,
- _Xconst register char *str,
- _Xconst char *filename,
- Bool doall)
-{
- char *rhs;
- char *lhs, lhs_s[DEF_BUFF_SIZE];
- XrmQuark quarks[QLIST_SIZE + 1]; /* allow for a terminal NullQuark */
- XrmBinding bindings[QLIST_SIZE + 1];
-
- register char *ptr;
- register XrmBits bits = 0;
- register char c;
- register Signature sig;
- register char *ptr_max;
- register int num_quarks;
- register XrmBindingList t_bindings;
-
- int len, alloc_chars;
- unsigned long str_len;
- XrmValue value;
- Bool only_pcs;
- Bool dolines;
-
- if (!db)
- return;
-
- /*
- * if strlen (str) < DEF_BUFF_SIZE allocate buffers on the stack for
- * speed otherwise malloc the buffer. From a buffer overflow standpoint
- * we can be sure that neither: a) a component on the lhs, or b) a
- * value on the rhs, will be longer than the overall length of str,
- * i.e. strlen(str).
- *
- * This should give good performance when parsing "*foo: bar" type
- * databases as might be passed with -xrm command line options; but
- * with larger databases, e.g. .Xdefaults, app-defaults, or KeysymDB
- * files, the size of the buffers will be overly large. One way
- * around this would be to double-parse each production with a resulting
- * performance hit. In any event we can be assured that a lhs component
- * name or a rhs value won't be longer than str itself.
- */
-
- str_len = strlen (str);
- if (DEF_BUFF_SIZE > str_len) lhs = lhs_s;
- else if ((lhs = (char*) Xmalloc (str_len)) == NULL)
- return;
-
- alloc_chars = DEF_BUFF_SIZE < str_len ? str_len : DEF_BUFF_SIZE;
- if ((rhs = (char*) Xmalloc (alloc_chars)) == NULL) {
- if (lhs != lhs_s) Xfree (lhs);
- return;
- }
-
- (*db->methods->mbinit)(db->mbstate);
- str--;
- dolines = True;
- while (!is_EOF(bits) && dolines) {
- dolines = doall;
-
- /*
- * First: Remove extra whitespace.
- */
-
- do {
- bits = next_char(c, str);
- } while is_space(bits);
-
- /*
- * Ignore empty lines.
- */
-
- if (is_EOL(bits))
- continue; /* start a new line. */
-
- /*
- * Second: check the first character in a line to see if it is
- * "!" signifying a comment, or "#" signifying a directive.
- */
-
- if (c == '!') { /* Comment, spin to next newline */
- while (is_simple(bits = next_char(c, str))) {}
- if (is_EOL(bits))
- continue;
- while (!is_EOL(bits = next_mbchar(c, len, str))) {}
- str--;
- continue; /* start a new line. */
- }
-
- if (c == '#') { /* Directive */
- /* remove extra whitespace */
- only_pcs = True;
- while (is_space(bits = next_char(c, str))) {};
- /* only "include" directive is currently defined */
- if (!strncmp(str, "include", 7)) {
- str += (7-1);
- /* remove extra whitespace */
- while (is_space(bits = next_char(c, str))) {};
- /* must have a starting " */
- if (c == '"') {
- _Xconst char *fname = str+1;
- len = 0;
- do {
- if (only_pcs) {
- bits = next_char(c, str);
- if (is_nonpcs(bits))
- only_pcs = False;
- }
- if (!only_pcs)
- bits = next_mbchar(c, len, str);
- } while (c != '"' && !is_EOL(bits));
- /* must have an ending " */
- if (c == '"')
- GetIncludeFile(db, filename, fname, str - len - fname);
- }
- }
- /* spin to next newline */
- if (only_pcs) {
- while (is_simple(bits))
- bits = next_char(c, str);
- if (is_EOL(bits))
- continue;
- }
- while (!is_EOL(bits))
- bits = next_mbchar(c, len, str);
- str--;
- continue; /* start a new line. */
- }
-
- /*
- * Third: loop through the LHS of the resource specification
- * storing characters and converting this to a Quark.
- */
-
- num_quarks = 0;
- t_bindings = bindings;
-
- sig = 0;
- ptr = lhs;
- *t_bindings = XrmBindTightly;
- for(;;) {
- if (!is_binding(bits)) {
- while (!is_EOQ(bits)) {
- *ptr++ = c;
- sig = (sig << 1) + c; /* Compute the signature. */
- bits = next_char(c, str);
- }
-
- quarks[num_quarks++] =
- _XrmInternalStringToQuark(lhs, ptr - lhs, sig, False);
-
- if (num_quarks > QLIST_SIZE) {
- Xfree(rhs);
- if (lhs != lhs_s) Xfree (lhs);
- (*db->methods->mbfinish)(db->mbstate);
- return;
- }
-
- if (is_separator(bits)) {
- if (!is_space(bits))
- break;
-
- /* Remove white space */
- do {
- *ptr++ = c;
- sig = (sig << 1) + c; /* Compute the signature. */
- } while (is_space(bits = next_char(c, str)));
-
- /*
- * The spec doesn't permit it, but support spaces
- * internal to resource name/class
- */
-
- if (is_separator(bits))
- break;
- num_quarks--;
- continue;
- }
-
- if (c == '.')
- *(++t_bindings) = XrmBindTightly;
- else
- *(++t_bindings) = XrmBindLoosely;
-
- sig = 0;
- ptr = lhs;
- }
- else {
- /*
- * Magic unspecified feature #254.
- *
- * If two separators appear with no Text between them then
- * ignore them.
- *
- * If anyone of those separators is a '*' then the binding
- * will be loose, otherwise it will be tight.
- */
-
- if (c == '*')
- *t_bindings = XrmBindLoosely;
- }
-
- bits = next_char(c, str);
- }
-
- quarks[num_quarks] = NULLQUARK;
-
- /*
- * Make sure that there is a ':' in this line.
- */
-
- if (c != ':') {
- char oldc;
-
- /*
- * A parsing error has occured, toss everything on the line
- * a new_line can still be escaped with a '\'.
- */
-
- while (is_normal(bits))
- bits = next_char(c, str);
- if (is_EOL(bits))
- continue;
- bits = next_mbchar(c, len, str);
- do {
- oldc = c;
- bits = next_mbchar(c, len, str);
- } while (c && (c != '\n' || oldc == '\\'));
- str--;
- continue;
- }
-
- /*
- * I now have a quark and binding list for the entire left hand
- * side. "c" currently points to the ":" separating the left hand
- * side for the right hand side. It is time to begin processing
- * the right hand side.
- */
-
- /*
- * Fourth: Remove more whitespace
- */
-
- for(;;) {
- if (is_space(bits = next_char(c, str)))
- continue;
- if (c != '\\')
- break;
- bits = next_char(c, str);
- if (c == '\n')
- continue;
- str--;
- bits = BSLASH;
- c = '\\';
- break;
- }
-
- /*
- * Fifth: Process the right hand side.
- */
-
- ptr = rhs;
- ptr_max = ptr + alloc_chars - 4;
- only_pcs = True;
- len = 1;
-
- for(;;) {
-
- /*
- * Tight loop for the normal case: Non backslash, non-end of value
- * character that will fit into the allocated buffer.
- */
-
- if (only_pcs) {
- while (is_normal(bits) && ptr < ptr_max) {
- *ptr++ = c;
- bits = next_char(c, str);
- }
- if (is_EOL(bits))
- break;
- if (is_nonpcs(bits)) {
- only_pcs = False;
- bits = next_mbchar(c, len, str);
- }
- }
- while (!is_special(bits) && ptr + len <= ptr_max) {
- len = -len;
- while (len)
- *ptr++ = str[len++];
- if (*str == '\0') {
- bits = EOS;
- break;
- }
- bits = next_mbchar(c, len, str);
- }
-
- if (is_EOL(bits)) {
- str--;
- break;
- }
-
- if (c == '\\') {
- /*
- * We need to do some magic after a backslash.
- */
- Bool read_next = True;
-
- if (only_pcs) {
- bits = next_char(c, str);
- if (is_nonpcs(bits))
- only_pcs = False;
- }
- if (!only_pcs)
- bits = next_mbchar(c, len, str);
-
- if (is_EOL(bits)) {
- if (is_EOF(bits))
- continue;
- } else if (c == 'n') {
- /*
- * "\n" means insert a newline.
- */
- *ptr++ = '\n';
- } else if (c == '\\') {
- /*
- * "\\" completes to just one backslash.
- */
- *ptr++ = '\\';
- } else {
- /*
- * pick up to three octal digits after the '\'.
- */
- char temp[3];
- int count = 0;
- while (is_odigit(bits) && count < 3) {
- temp[count++] = c;
- if (only_pcs) {
- bits = next_char(c, str);
- if (is_nonpcs(bits))
- only_pcs = False;
- }
- if (!only_pcs)
- bits = next_mbchar(c, len, str);
- }
-
- /*
- * If we found three digits then insert that octal code
- * into the value string as a character.
- */
-
- if (count == 3) {
- *ptr++ = (unsigned char) ((temp[0] - '0') * 0100 +
- (temp[1] - '0') * 010 +
- (temp[2] - '0'));
- }
- else {
- int tcount;
-
- /*
- * Otherwise just insert those characters into the
- * string, since no special processing is needed on
- * numerics we can skip the special processing.
- */
-
- for (tcount = 0; tcount < count; tcount++) {
- *ptr++ = temp[tcount]; /* print them in
- the correct order */
- }
- }
- read_next = False;
- }
- if (read_next) {
- if (only_pcs) {
- bits = next_char(c, str);
- if (is_nonpcs(bits))
- only_pcs = False;
- }
- if (!only_pcs)
- bits = next_mbchar(c, len, str);
- }
- }
-
- /*
- * It is important to make sure that there is room for at least
- * four more characters in the buffer, since I can add that
- * many characters into the buffer after a backslash has occured.
- */
-
- if (ptr + len > ptr_max) {
- char * temp_str;
-
- alloc_chars += BUFSIZ/10;
- temp_str = Xrealloc(rhs, sizeof(char) * alloc_chars);
-
- if (!temp_str) {
- Xfree(rhs);
- if (lhs != lhs_s) Xfree (lhs);
- (*db->methods->mbfinish)(db->mbstate);
- return;
- }
-
- ptr = temp_str + (ptr - rhs); /* reset pointer. */
- rhs = temp_str;
- ptr_max = rhs + alloc_chars - 4;
- }
- }
-
- /*
- * Lastly: Terminate the value string, and store this entry
- * into the database.
- */
-
- *ptr++ = '\0';
-
- /* Store it in database */
- value.size = ptr - rhs;
- value.addr = (XPointer) rhs;
-
- PutEntry(db, bindings, quarks, XrmQString, &value);
- }
-
- if (lhs != lhs_s) Xfree (lhs);
- Xfree (rhs);
-
- (*db->methods->mbfinish)(db->mbstate);
-}
-
-void
-XrmPutStringResource(
- XrmDatabase *pdb,
- _Xconst char*specifier,
- _Xconst char*str)
-{
- XrmValue value;
- XrmBinding bindings[MAXDBDEPTH+1];
- XrmQuark quarks[MAXDBDEPTH+1];
-
- if (!*pdb) *pdb = NewDatabase();
- XrmStringToBindingQuarkList(specifier, bindings, quarks);
- value.addr = (XPointer) str;
- value.size = strlen(str)+1;
- _XLockMutex(&(*pdb)->linfo);
- PutEntry(*pdb, bindings, quarks, XrmQString, &value);
- _XUnlockMutex(&(*pdb)->linfo);
-}
-
-
-void
-XrmPutLineResource(
- XrmDatabase *pdb,
- _Xconst char*line)
-{
- if (!*pdb) *pdb = NewDatabase();
- _XLockMutex(&(*pdb)->linfo);
- GetDatabase(*pdb, line, (char *)NULL, False);
- _XUnlockMutex(&(*pdb)->linfo);
-}
-
-XrmDatabase
-XrmGetStringDatabase(
- _Xconst char *data)
-{
- XrmDatabase db;
-
- db = NewDatabase();
- _XLockMutex(&db->linfo);
- GetDatabase(db, data, (char *)NULL, True);
- _XUnlockMutex(&db->linfo);
- return db;
-}
-
-/* Function Name: ReadInFile
- * Description: Reads the file into a buffer.
- * Arguments: filename - the name of the file.
- * Returns: An allocated string containing the contents of the file.
- */
-
-static char *
-ReadInFile(_Xconst char *filename)
-{
- register int fd, size;
- char * filebuf;
-
-#ifdef __UNIXOS2__
- filename = __XOS2RedirRoot(filename);
-#endif
-
- /*
- * MS-Windows and OS/2 note: Default open mode includes O_TEXT
- */
- if ( (fd = _XOpenFile (filename, O_RDONLY)) == -1 )
- return (char *)NULL;
-
- /*
- * MS-Windows and OS/2 note: depending on how the sources are
- * untarred, the newlines in resource files may or may not have
- * been expanded to CRLF. Either way the size returned by fstat
- * is sufficient to read the file into because in text-mode any
- * CRLFs in a file will be converted to newlines (LF) with the
- * result that the number of bytes actually read with be <=
- * to the size returned by fstat.
- */
- {
- struct stat status_buffer;
- if ( (fstat(fd, &status_buffer)) == -1 ) {
- close (fd);
- return (char *)NULL;
- } else
- size = status_buffer.st_size;
- }
-
- if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */
- close(fd);
- return (char *)NULL;
- }
- size = read (fd, filebuf, size);
-
-#ifdef __UNIXOS2__
- { /* kill CRLF */
- int i,k;
- for (i=k=0; i<size; i++)
- if (filebuf[i] != 0x0d) {
- filebuf[k++] = filebuf[i];
- }
- filebuf[k] = 0;
- }
-#endif
-
- if (size < 0) {
- close (fd);
- Xfree(filebuf);
- return (char *)NULL;
- }
- close (fd);
-
- filebuf[size] = '\0'; /* NULL terminate it. */
- return filebuf;
-}
-
-static void
-GetIncludeFile(
- XrmDatabase db,
- _Xconst char *base,
- _Xconst char *fname,
- int fnamelen)
-{
- int len;
- char *str;
- char realfname[BUFSIZ];
-
- if (fnamelen <= 0 || fnamelen >= BUFSIZ)
- return;
- if (*fname != '/' && base && (str = strrchr(base, '/'))) {
- len = str - base + 1;
- if (len + fnamelen >= BUFSIZ)
- return;
- strncpy(realfname, base, len);
- strncpy(realfname + len, fname, fnamelen);
- realfname[len + fnamelen] = '\0';
- } else {
- strncpy(realfname, fname, fnamelen);
- realfname[fnamelen] = '\0';
- }
- if (!(str = ReadInFile(realfname)))
- return;
- GetDatabase(db, str, realfname, True);
- Xfree(str);
-}
-
-XrmDatabase
-XrmGetFileDatabase(
- _Xconst char *filename)
-{
- XrmDatabase db;
- char *str;
-
- if (!(str = ReadInFile(filename)))
- return (XrmDatabase)NULL;
-
- db = NewDatabase();
- _XLockMutex(&db->linfo);
- GetDatabase(db, str, filename, True);
- _XUnlockMutex(&db->linfo);
- Xfree(str);
- return db;
-}
-
-Status
-XrmCombineFileDatabase(
- _Xconst char *filename,
- XrmDatabase *target,
- Bool override)
-{
- XrmDatabase db;
- char *str;
-
- if (!(str = ReadInFile(filename)))
- return 0;
- if (override) {
- db = *target;
- if (!db)
- *target = db = NewDatabase();
- } else
- db = NewDatabase();
- _XLockMutex(&db->linfo);
- GetDatabase(db, str, filename, True);
- _XUnlockMutex(&db->linfo);
- Xfree(str);
- if (!override)
- XrmCombineDatabase(db, target, False);
- return 1;
-}
-
-/* call the user proc for every value in the table, arbitrary order.
- * stop if user proc returns True. level is current depth in database.
- */
-/*ARGSUSED*/
-static Bool EnumLTable(
- LTable table,
- XrmNameList names,
- XrmClassList classes,
- register int level,
- register EClosure closure)
-{
- register VEntry *bucket;
- register int i;
- register VEntry entry;
- XrmValue value;
- XrmRepresentation type;
- Bool tightOk;
-
- closure->bindings[level] = (table->table.tight ?
- XrmBindTightly : XrmBindLoosely);
- closure->quarks[level] = table->table.name;
- level++;
- tightOk = !*names;
- closure->quarks[level + 1] = NULLQUARK;
- for (i = table->table.mask, bucket = table->buckets;
- i >= 0;
- i--, bucket++) {
- for (entry = *bucket; entry; entry = entry->next) {
- if (entry->tight && !tightOk)
- continue;
- closure->bindings[level] = (entry->tight ?
- XrmBindTightly : XrmBindLoosely);
- closure->quarks[level] = entry->name;
- value.size = entry->size;
- if (entry->string) {
- type = XrmQString;
- value.addr = StringValue(entry);
- } else {
- type = RepType(entry);
- value.addr = DataValue(entry);
- }
- if ((*closure->proc)(&closure->db, closure->bindings+1,
- closure->quarks+1, &type, &value,
- closure->closure))
- return True;
- }
- }
- return False;
-}
-
-static Bool EnumAllNTable(
- NTable table,
- register int level,
- register EClosure closure)
-{
- register NTable *bucket;
- register int i;
- register NTable entry;
- XrmQuark empty = NULLQUARK;
-
- if (level >= MAXDBDEPTH)
- return False;
- for (i = table->mask, bucket = NodeBuckets(table);
- i >= 0;
- i--, bucket++) {
- for (entry = *bucket; entry; entry = entry->next) {
- if (entry->leaf) {
- if (EnumLTable((LTable)entry, &empty, &empty, level, closure))
- return True;
- } else {
- closure->bindings[level] = (entry->tight ?
- XrmBindTightly : XrmBindLoosely);
- closure->quarks[level] = entry->name;
- if (EnumAllNTable(entry, level+1, closure))
- return True;
- }
- }
- }
- return False;
-}
-
-/* recurse on every table in the table, arbitrary order.
- * stop if user proc returns True. level is current depth in database.
- */
-static Bool EnumNTable(
- NTable table,
- XrmNameList names,
- XrmClassList classes,
- register int level,
- register EClosure closure)
-{
- register NTable entry;
- register XrmQuark q;
- register unsigned int leaf;
- Bool (*get)(
- NTable table,
- XrmNameList names,
- XrmClassList classes,
- register int level,
- EClosure closure);
- Bool bilevel;
-
-/* find entries named ename, leafness leaf, tight or loose, and call get */
-#define ITIGHTLOOSE(ename) \
- NFIND(ename); \
- if (entry) { \
- if (leaf == entry->leaf) { \
- if (!leaf && !entry->tight && entry->next && \
- entry->next->name == q && entry->next->tight && \
- (bilevel || entry->next->hasloose) && \
- EnumLTable((LTable)entry->next, names+1, classes+1, \
- level, closure)) \
- return True; \
- if ((*get)(entry, names+1, classes+1, level, closure)) \
- return True; \
- if (entry->tight && (entry = entry->next) && \
- entry->name == q && leaf == entry->leaf && \
- (*get)(entry, names+1, classes+1, level, closure)) \
- return True; \
- } else if (entry->leaf) { \
- if ((bilevel || entry->hasloose) && \
- EnumLTable((LTable)entry, names+1, classes+1, level, closure))\
- return True; \
- if (entry->tight && (entry = entry->next) && \
- entry->name == q && (bilevel || entry->hasloose) && \
- EnumLTable((LTable)entry, names+1, classes+1, level, closure))\
- return True; \
- } \
- }
-
-/* find entries named ename, leafness leaf, loose only, and call get */
-#define ILOOSE(ename) \
- NFIND(ename); \
- if (entry && entry->tight && (entry = entry->next) && entry->name != q) \
- entry = (NTable)NULL; \
- if (entry) { \
- if (leaf == entry->leaf) { \
- if ((*get)(entry, names+1, classes+1, level, closure)) \
- return True; \
- } else if (entry->leaf && (bilevel || entry->hasloose)) { \
- if (EnumLTable((LTable)entry, names+1, classes+1, level, closure))\
- return True; \
- } \
- }
-
- if (level >= MAXDBDEPTH)
- return False;
- closure->bindings[level] = (table->tight ?
- XrmBindTightly : XrmBindLoosely);
- closure->quarks[level] = table->name;
- level++;
- if (!*names) {
- if (EnumAllNTable(table, level, closure))
- return True;
- } else {
- if (names[1] || closure->mode == XrmEnumAllLevels) {
- get = EnumNTable; /* recurse */
- leaf = 0;
- bilevel = !names[1];
- } else {
- get = (getNTableEProcp)EnumLTable; /* bottom of recursion */
- leaf = 1;
- bilevel = False;
- }
- if (table->hasloose && closure->mode == XrmEnumAllLevels) {
- NTable *bucket;
- int i;
- XrmQuark empty = NULLQUARK;
-
- for (i = table->mask, bucket = NodeBuckets(table);
- i >= 0;
- i--, bucket++) {
- q = NULLQUARK;
- for (entry = *bucket; entry; entry = entry->next) {
- if (!entry->tight && entry->name != q &&
- entry->name != *names && entry->name != *classes) {
- q = entry->name;
- if (entry->leaf) {
- if (EnumLTable((LTable)entry, &empty, &empty,
- level, closure))
- return True;
- } else {
- if (EnumNTable(entry, &empty, &empty,
- level, closure))
- return True;
- }
- }
- }
- }
- }
-
- ITIGHTLOOSE(*names); /* do name, tight and loose */
- ITIGHTLOOSE(*classes); /* do class, tight and loose */
- if (table->hasany) {
- ITIGHTLOOSE(XrmQANY); /* do ANY, tight and loose */
- }
- if (table->hasloose) {
- while (1) {
- names++;
- classes++;
- if (!*names)
- break;
- if (!names[1] && closure->mode != XrmEnumAllLevels) {
- get = (getNTableEProcp)EnumLTable; /* bottom of recursion */
- leaf = 1;
- }
- ILOOSE(*names); /* loose names */
- ILOOSE(*classes); /* loose classes */
- if (table->hasany) {
- ILOOSE(XrmQANY); /* loose ANY */
- }
- }
- names--;
- classes--;
- }
- }
- /* now look for matching leaf nodes */
- entry = table->next;
- if (!entry)
- return False;
- if (entry->leaf) {
- if (entry->tight && !table->tight)
- entry = entry->next;
- } else {
- entry = entry->next;
- if (!entry || !entry->tight)
- return False;
- }
- if (!entry || entry->name != table->name)
- return False;
- /* found one */
- level--;
- if ((!*names || entry->hasloose) &&
- EnumLTable((LTable)entry, names, classes, level, closure))
- return True;
- if (entry->tight && entry == table->next && (entry = entry->next) &&
- entry->name == table->name && (!*names || entry->hasloose))
- return EnumLTable((LTable)entry, names, classes, level, closure);
- return False;
-
-#undef ITIGHTLOOSE
-#undef ILOOSE
-}
-
-/* call the proc for every value in the database, arbitrary order.
- * stop if the proc returns True.
- */
-Bool XrmEnumerateDatabase(
- XrmDatabase db,
- XrmNameList names,
- XrmClassList classes,
- int mode,
- DBEnumProc proc,
- XPointer closure)
-{
- XrmBinding bindings[MAXDBDEPTH+2];
- XrmQuark quarks[MAXDBDEPTH+2];
- register NTable table;
- EClosureRec eclosure;
- Bool retval = False;
-
- if (!db)
- return False;
- _XLockMutex(&db->linfo);
- eclosure.db = db;
- eclosure.proc = proc;
- eclosure.closure = closure;
- eclosure.bindings = bindings;
- eclosure.quarks = quarks;
- eclosure.mode = mode;
- table = db->table;
- if (table && !table->leaf && !*names && mode == XrmEnumOneLevel)
- table = table->next;
- if (table) {
- if (!table->leaf)
- retval = EnumNTable(table, names, classes, 0, &eclosure);
- else
- retval = EnumLTable((LTable)table, names, classes, 0, &eclosure);
- }
- _XUnlockMutex(&db->linfo);
- return retval;
-}
-
-static void PrintBindingQuarkList(
- XrmBindingList bindings,
- XrmQuarkList quarks,
- FILE *stream)
-{
- Bool firstNameSeen;
-
- for (firstNameSeen = False; *quarks; bindings++, quarks++) {
- if (*bindings == XrmBindLoosely) {
- (void) fprintf(stream, "*");
- } else if (firstNameSeen) {
- (void) fprintf(stream, ".");
- }
- firstNameSeen = True;
- (void) fputs(XrmQuarkToString(*quarks), stream);
- }
-}
-
-/* output out the entry in correct file syntax */
-/*ARGSUSED*/
-static Bool DumpEntry(
- XrmDatabase *db,
- XrmBindingList bindings,
- XrmQuarkList quarks,
- XrmRepresentation *type,
- XrmValuePtr value,
- XPointer data)
-{
- FILE *stream = (FILE *)data;
- register unsigned int i;
- register char *s;
- register char c;
-
- if (*type != XrmQString)
- (void) putc('!', stream);
- PrintBindingQuarkList(bindings, quarks, stream);
- s = value->addr;
- i = value->size;
- if (*type == XrmQString) {
- (void) fputs(":\t", stream);
- if (i)
- i--;
- }
- else
- (void) fprintf(stream, "=%s:\t", XrmRepresentationToString(*type));
- if (i && (*s == ' ' || *s == '\t'))
- (void) putc('\\', stream); /* preserve leading whitespace */
- while (i--) {
- c = *s++;
- if (c == '\n') {
- if (i)
- (void) fputs("\\n\\\n", stream);
- else
- (void) fputs("\\n", stream);
- } else if (c == '\\')
- (void) fputs("\\\\", stream);
- else if ((c < ' ' && c != '\t') ||
- ((unsigned char)c >= 0x7f && (unsigned char)c < 0xa0))
- (void) fprintf(stream, "\\%03o", (unsigned char)c);
- else
- (void) putc(c, stream);
- }
- (void) putc('\n', stream);
- return ferror(stream) != 0;
-}
-
-#ifdef DEBUG
-
-void PrintTable(
- NTable table,
- FILE *file)
-{
- XrmBinding bindings[MAXDBDEPTH+1];
- XrmQuark quarks[MAXDBDEPTH+1];
- EClosureRec closure;
- XrmQuark empty = NULLQUARK;
-
- closure.db = (XrmDatabase)NULL;
- closure.proc = DumpEntry;
- closure.closure = (XPointer)file;
- closure.bindings = bindings;
- closure.quarks = quarks;
- closure.mode = XrmEnumAllLevels;
- if (table->leaf)
- EnumLTable((LTable)table, &empty, &empty, 0, &closure);
- else
- EnumNTable(table, &empty, &empty, 0, &closure);
-}
-
-#endif /* DEBUG */
-
-void
-XrmPutFileDatabase(
- XrmDatabase db,
- _Xconst char *fileName)
-{
- FILE *file;
- XrmQuark empty = NULLQUARK;
-
- if (!db) return;
- if (!(file = fopen(fileName, "w"))) return;
- if (XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels,
- DumpEntry, (XPointer) file))
- unlink((char *)fileName);
- fclose(file);
-}
-
-/* macros used in get/search functions */
-
-/* find entries named ename, leafness leaf, tight or loose, and call get */
-#define GTIGHTLOOSE(ename,looseleaf) \
- NFIND(ename); \
- if (entry) { \
- if (leaf == entry->leaf) { \
- if (!leaf && !entry->tight && entry->next && \
- entry->next->name == q && entry->next->tight && \
- entry->next->hasloose && \
- looseleaf((LTable)entry->next, names+1, classes+1, closure)) \
- return True; \
- if ((*get)(entry, names+1, classes+1, closure)) \
- return True; \
- if (entry->tight && (entry = entry->next) && \
- entry->name == q && leaf == entry->leaf && \
- (*get)(entry, names+1, classes+1, closure)) \
- return True; \
- } else if (entry->leaf) { \
- if (entry->hasloose && \
- looseleaf((LTable)entry, names+1, classes+1, closure)) \
- return True; \
- if (entry->tight && (entry = entry->next) && \
- entry->name == q && entry->hasloose && \
- looseleaf((LTable)entry, names+1, classes+1, closure)) \
- return True; \
- } \
- }
-
-/* find entries named ename, leafness leaf, loose only, and call get */
-#define GLOOSE(ename,looseleaf) \
- NFIND(ename); \
- if (entry && entry->tight && (entry = entry->next) && entry->name != q) \
- entry = (NTable)NULL; \
- if (entry) { \
- if (leaf == entry->leaf) { \
- if ((*get)(entry, names+1, classes+1, closure)) \
- return True; \
- } else if (entry->leaf && entry->hasloose) { \
- if (looseleaf((LTable)entry, names+1, classes+1, closure)) \
- return True; \
- } \
- }
-
-/* add tight/loose entry to the search list, return True if list is full */
-/*ARGSUSED*/
-static Bool AppendLEntry(
- LTable table,
- XrmNameList names,
- XrmClassList classes,
- register SClosure closure)
-{
- /* check for duplicate */
- if (closure->idx >= 0 && closure->list[closure->idx] == table)
- return False;
- if (closure->idx == closure->limit)
- return True;
- /* append it */
- closure->idx++;
- closure->list[closure->idx] = table;
- return False;
-}
-
-/* add loose entry to the search list, return True if list is full */
-/*ARGSUSED*/
-static Bool AppendLooseLEntry(
- LTable table,
- XrmNameList names,
- XrmClassList classes,
- register SClosure closure)
-{
- /* check for duplicate */
- if (closure->idx >= 0 && closure->list[closure->idx] == table)
- return False;
- if (closure->idx >= closure->limit - 1)
- return True;
- /* append it */
- closure->idx++;
- closure->list[closure->idx] = LOOSESEARCH;
- closure->idx++;
- closure->list[closure->idx] = table;
- return False;
-}
-
-/* search for a leaf table */
-static Bool SearchNEntry(
- NTable table,
- XrmNameList names,
- XrmClassList classes,
- SClosure closure)
-{
- register NTable entry;
- register XrmQuark q;
- register unsigned int leaf;
- Bool (*get)(
- NTable table,
- XrmNameList names,
- XrmClassList classes,
- SClosure closure);
-
- if (names[1]) {
- get = SearchNEntry; /* recurse */
- leaf = 0;
- } else {
- get = (getNTableSProcp)AppendLEntry; /* bottom of recursion */
- leaf = 1;
- }
- GTIGHTLOOSE(*names, AppendLooseLEntry); /* do name, tight and loose */
- GTIGHTLOOSE(*classes, AppendLooseLEntry); /* do class, tight and loose */
- if (table->hasany) {
- GTIGHTLOOSE(XrmQANY, AppendLooseLEntry); /* do ANY, tight and loose */
- }
- if (table->hasloose) {
- while (1) {
- names++;
- classes++;
- if (!*names)
- break;
- if (!names[1]) {
- get = (getNTableSProcp)AppendLEntry; /* bottom of recursion */
- leaf = 1;
- }
- GLOOSE(*names, AppendLooseLEntry); /* loose names */
- GLOOSE(*classes, AppendLooseLEntry); /* loose classes */
- if (table->hasany) {
- GLOOSE(XrmQANY, AppendLooseLEntry); /* loose ANY */
- }
- }
- }
- /* now look for matching leaf nodes */
- entry = table->next;
- if (!entry)
- return False;
- if (entry->leaf) {
- if (entry->tight && !table->tight)
- entry = entry->next;
- } else {
- entry = entry->next;
- if (!entry || !entry->tight)
- return False;
- }
- if (!entry || entry->name != table->name)
- return False;
- /* found one */
- if (entry->hasloose &&
- AppendLooseLEntry((LTable)entry, names, classes, closure))
- return True;
- if (entry->tight && entry == table->next && (entry = entry->next) &&
- entry->name == table->name && entry->hasloose)
- return AppendLooseLEntry((LTable)entry, names, classes, closure);
- return False;
-}
-
-Bool XrmQGetSearchList(
- XrmDatabase db,
- XrmNameList names,
- XrmClassList classes,
- XrmSearchList searchList, /* RETURN */
- int listLength)
-{
- register NTable table;
- SClosureRec closure;
-
- if (listLength <= 0)
- return False;
- closure.list = (LTable *)searchList;
- closure.idx = -1;
- closure.limit = listLength - 2;
- if (db) {
- _XLockMutex(&db->linfo);
- table = db->table;
- if (*names) {
- if (table && !table->leaf) {
- if (SearchNEntry(table, names, classes, &closure)) {
- _XUnlockMutex(&db->linfo);
- return False;
- }
- } else if (table && table->hasloose &&
- AppendLooseLEntry((LTable)table, names, classes,
- &closure)) {
- _XUnlockMutex(&db->linfo);
- return False;
- }
- } else {
- if (table && !table->leaf)
- table = table->next;
- if (table &&
- AppendLEntry((LTable)table, names, classes, &closure)) {
- _XUnlockMutex(&db->linfo);
- return False;
- }
- }
- _XUnlockMutex(&db->linfo);
- }
- closure.list[closure.idx + 1] = (LTable)NULL;
- return True;
-}
-
-Bool XrmQGetSearchResource(
- XrmSearchList searchList,
- register XrmName name,
- register XrmClass class,
- XrmRepresentation *pType, /* RETURN */
- XrmValue *pValue) /* RETURN */
-{
- register LTable *list;
- register LTable table;
- register VEntry entry = NULL;
- int flags;
-
-/* find tight or loose entry */
-#define VTIGHTLOOSE(q) \
- entry = LeafHash(table, q); \
- while (entry && entry->name != q) \
- entry = entry->next; \
- if (entry) \
- break
-
-/* find loose entry */
-#define VLOOSE(q) \
- entry = LeafHash(table, q); \
- while (entry && entry->name != q) \
- entry = entry->next; \
- if (entry) { \
- if (!entry->tight) \
- break; \
- if ((entry = entry->next) && entry->name == q) \
- break; \
- }
-
- list = (LTable *)searchList;
- /* figure out which combination of name and class we need to search for */
- flags = 0;
- if (IsResourceQuark(name))
- flags = 2;
- if (IsResourceQuark(class))
- flags |= 1;
- if (!flags) {
- /* neither name nor class has ever been used to name a resource */
- table = (LTable)NULL;
- } else if (flags == 3) {
- /* both name and class */
- while ((table = *list++)) {
- if (table != LOOSESEARCH) {
- VTIGHTLOOSE(name); /* do name, tight and loose */
- VTIGHTLOOSE(class); /* do class, tight and loose */
- } else {
- table = *list++;
- VLOOSE(name); /* do name, loose only */
- VLOOSE(class); /* do class, loose only */
- }
- }
- } else {
- /* just one of name or class */
- if (flags == 1)
- name = class;
- while ((table = *list++)) {
- if (table != LOOSESEARCH) {
- VTIGHTLOOSE(name); /* tight and loose */
- } else {
- table = *list++;
- VLOOSE(name); /* loose only */
- }
- }
- }
- if (table) {
- /* found a match */
- if (entry->string) {
- *pType = XrmQString;
- pValue->addr = StringValue(entry);
- } else {
- *pType = RepType(entry);
- pValue->addr = DataValue(entry);
- }
- pValue->size = entry->size;
- return True;
- }
- *pType = NULLQUARK;
- pValue->addr = (XPointer)NULL;
- pValue->size = 0;
- return False;
-
-#undef VTIGHTLOOSE
-#undef VLOOSE
-}
-
-/* look for a tight/loose value */
-static Bool GetVEntry(
- LTable table,
- XrmNameList names,
- XrmClassList classes,
- VClosure closure)
-{
- register VEntry entry;
- register XrmQuark q;
-
- /* try name first */
- q = *names;
- entry = LeafHash(table, q);
- while (entry && entry->name != q)
- entry = entry->next;
- if (!entry) {
- /* not found, try class */
- q = *classes;
- entry = LeafHash(table, q);
- while (entry && entry->name != q)
- entry = entry->next;
- if (!entry)
- return False;
- }
- if (entry->string) {
- *closure->type = XrmQString;
- closure->value->addr = StringValue(entry);
- } else {
- *closure->type = RepType(entry);
- closure->value->addr = DataValue(entry);
- }
- closure->value->size = entry->size;
- return True;
-}
-
-/* look for a loose value */
-static Bool GetLooseVEntry(
- LTable table,
- XrmNameList names,
- XrmClassList classes,
- VClosure closure)
-{
- register VEntry entry;
- register XrmQuark q;
-
-#define VLOOSE(ename) \
- q = ename; \
- entry = LeafHash(table, q); \
- while (entry && entry->name != q) \
- entry = entry->next; \
- if (entry && entry->tight && (entry = entry->next) && entry->name != q) \
- entry = (VEntry)NULL;
-
- /* bump to last component */
- while (names[1]) {
- names++;
- classes++;
- }
- VLOOSE(*names); /* do name, loose only */
- if (!entry) {
- VLOOSE(*classes); /* do class, loose only */
- if (!entry)
- return False;
- }
- if (entry->string) {
- *closure->type = XrmQString;
- closure->value->addr = StringValue(entry);
- } else {
- *closure->type = RepType(entry);
- closure->value->addr = DataValue(entry);
- }
- closure->value->size = entry->size;
- return True;
-
-#undef VLOOSE
-}
-
-/* recursive search for a value */
-static Bool GetNEntry(
- NTable table,
- XrmNameList names,
- XrmClassList classes,
- VClosure closure)
-{
- register NTable entry;
- register XrmQuark q;
- register unsigned int leaf;
- Bool (*get)(
- NTable table,
- XrmNameList names,
- XrmClassList classes,
- VClosure closure);
- NTable otable;
-
- if (names[2]) {
- get = GetNEntry; /* recurse */
- leaf = 0;
- } else {
- get = (getNTableVProcp)GetVEntry; /* bottom of recursion */
- leaf = 1;
- }
- GTIGHTLOOSE(*names, GetLooseVEntry); /* do name, tight and loose */
- GTIGHTLOOSE(*classes, GetLooseVEntry); /* do class, tight and loose */
- if (table->hasany) {
- GTIGHTLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, tight and loose */
- }
- if (table->hasloose) {
- while (1) {
- names++;
- classes++;
- if (!names[1])
- break;
- if (!names[2]) {
- get = (getNTableVProcp)GetVEntry; /* bottom of recursion */
- leaf = 1;
- }
- GLOOSE(*names, GetLooseVEntry); /* do name, loose only */
- GLOOSE(*classes, GetLooseVEntry); /* do class, loose only */
- if (table->hasany) {
- GLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, loose only */
- }
- }
- }
- /* look for matching leaf tables */
- otable = table;
- table = table->next;
- if (!table)
- return False;
- if (table->leaf) {
- if (table->tight && !otable->tight)
- table = table->next;
- } else {
- table = table->next;
- if (!table || !table->tight)
- return False;
- }
- if (!table || table->name != otable->name)
- return False;
- /* found one */
- if (table->hasloose &&
- GetLooseVEntry((LTable)table, names, classes, closure))
- return True;
- if (table->tight && table == otable->next) {
- table = table->next;
- if (table && table->name == otable->name && table->hasloose)
- return GetLooseVEntry((LTable)table, names, classes, closure);
- }
- return False;
-}
-
-Bool XrmQGetResource(
- XrmDatabase db,
- XrmNameList names,
- XrmClassList classes,
- XrmRepresentation *pType, /* RETURN */
- XrmValuePtr pValue) /* RETURN */
-{
- register NTable table;
- VClosureRec closure;
-
- if (db && *names) {
- _XLockMutex(&db->linfo);
- closure.type = pType;
- closure.value = pValue;
- table = db->table;
- if (names[1]) {
- if (table && !table->leaf) {
- if (GetNEntry(table, names, classes, &closure)) {
- _XUnlockMutex(&db->linfo);
- return True;
- }
- } else if (table && table->hasloose &&
- GetLooseVEntry((LTable)table, names, classes, &closure)) {
- _XUnlockMutex (&db->linfo);
- return True;
- }
- } else {
- if (table && !table->leaf)
- table = table->next;
- if (table && GetVEntry((LTable)table, names, classes, &closure)) {
- _XUnlockMutex(&db->linfo);
- return True;
- }
- }
- _XUnlockMutex(&db->linfo);
- }
- *pType = NULLQUARK;
- pValue->addr = (XPointer)NULL;
- pValue->size = 0;
- return False;
-}
-
-Bool
-XrmGetResource(XrmDatabase db, _Xconst char *name_str, _Xconst char *class_str,
- XrmString *pType_str, XrmValuePtr pValue)
-{
- XrmName names[MAXDBDEPTH+1];
- XrmClass classes[MAXDBDEPTH+1];
- XrmRepresentation fromType;
- Bool result;
-
- XrmStringToNameList(name_str, names);
- XrmStringToClassList(class_str, classes);
- result = XrmQGetResource(db, names, classes, &fromType, pValue);
- (*pType_str) = XrmQuarkToString(fromType);
- return result;
-}
-
-/* destroy all values, plus table itself */
-static void DestroyLTable(
- LTable table)
-{
- register int i;
- register VEntry *buckets;
- register VEntry entry, next;
-
- buckets = table->buckets;
- for (i = table->table.mask; i >= 0; i--, buckets++) {
- for (next = *buckets; (entry = next); ) {
- next = entry->next;
- Xfree((char *)entry);
- }
- }
- Xfree((char *)table->buckets);
- Xfree((char *)table);
-}
-
-/* destroy all contained tables, plus table itself */
-static void DestroyNTable(
- NTable table)
-{
- register int i;
- register NTable *buckets;
- register NTable entry, next;
-
- buckets = NodeBuckets(table);
- for (i = table->mask; i >= 0; i--, buckets++) {
- for (next = *buckets; (entry = next); ) {
- next = entry->next;
- if (entry->leaf)
- DestroyLTable((LTable)entry);
- else
- DestroyNTable(entry);
- }
- }
- Xfree((char *)table);
-}
-
-const char *
-XrmLocaleOfDatabase(
- XrmDatabase db)
-{
- const char* retval;
- _XLockMutex(&db->linfo);
- retval = (*db->methods->lcname)(db->mbstate);
- _XUnlockMutex(&db->linfo);
- return retval;
-}
-
-void XrmDestroyDatabase(
- XrmDatabase db)
-{
- register NTable table, next;
-
- if (db) {
- _XLockMutex(&db->linfo);
- for (next = db->table; (table = next); ) {
- next = table->next;
- if (table->leaf)
- DestroyLTable((LTable)table);
- else
- DestroyNTable(table);
- }
- _XUnlockMutex(&db->linfo);
- _XFreeMutex(&db->linfo);
- (*db->methods->destroy)(db->mbstate);
- Xfree((char *)db);
- }
-}
+
+/***********************************************************
+Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard
+
+ 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 name Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/*
+
+Copyright 1987, 1988, 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include "Xlibint.h"
+#include <X11/Xresource.h>
+#include "Xlcint.h"
+#ifdef XTHREADS
+#include "locking.h"
+#endif
+#include <X11/Xos.h>
+#include <sys/stat.h>
+#include "Xresinternal.h"
+#include "Xresource.h"
+
+/*
+
+These Xrm routines allow very fast lookup of resources in the resource
+database. Several usage patterns are exploited:
+
+(1) Widgets get a lot of resources at one time. Rather than look up each from
+scratch, we can precompute the prioritized list of database levels once, then
+search for each resource starting at the beginning of the list.
+
+(2) Many database levels don't contain any leaf resource nodes. There is no
+point in looking for resources on a level that doesn't contain any. This
+information is kept on a per-level basis.
+
+(3) Sometimes the widget instance tree is structured such that you get the same
+class name repeated on the fully qualified widget name. This can result in the
+same database level occuring multiple times on the search list. The code below
+only checks to see if you get two identical search lists in a row, rather than
+look back through all database levels, but in practice this removes all
+duplicates I've ever observed.
+
+Joel McCormack
+
+*/
+
+/*
+
+The Xrm representation has been completely redesigned to substantially reduce
+memory and hopefully improve performance.
+
+The database is structured into two kinds of tables: LTables that contain
+only values, and NTables that contain only other tables.
+
+Some invariants:
+
+The next pointer of the top-level node table points to the top-level leaf
+table, if any.
+
+Within an LTable, for a given name, the tight value always precedes the
+loose value, and if both are present the loose value is always right after
+the tight value.
+
+Within an NTable, all of the entries for a given name are contiguous,
+in the order tight NTable, loose NTable, tight LTable, loose LTable.
+
+Bob Scheifler
+
+*/
+
+static XrmQuark XrmQString, XrmQANY;
+
+typedef Bool (*DBEnumProc)(
+ XrmDatabase* /* db */,
+ XrmBindingList /* bindings */,
+ XrmQuarkList /* quarks */,
+ XrmRepresentation* /* type */,
+ XrmValue* /* value */,
+ XPointer /* closure */
+);
+
+typedef struct _VEntry {
+ struct _VEntry *next; /* next in chain */
+ XrmQuark name; /* name of this entry */
+ unsigned int tight:1; /* 1 if it is a tight binding */
+ unsigned int string:1; /* 1 if type is String */
+ unsigned int size:30; /* size of value */
+} VEntryRec, *VEntry;
+
+
+typedef struct _DEntry {
+ VEntryRec entry; /* entry */
+ XrmRepresentation type; /* representation type */
+} DEntryRec, *DEntry;
+
+/* the value is right after the structure */
+#define StringValue(ve) (XPointer)((ve) + 1)
+#define RepType(ve) ((DEntry)(ve))->type
+/* the value is right after the structure */
+#define DataValue(ve) (XPointer)(((DEntry)(ve)) + 1)
+#define RawValue(ve) (char *)((ve)->string ? StringValue(ve) : DataValue(ve))
+
+typedef struct _NTable {
+ struct _NTable *next; /* next in chain */
+ XrmQuark name; /* name of this entry */
+ unsigned int tight:1; /* 1 if it is a tight binding */
+ unsigned int leaf:1; /* 1 if children are values */
+ unsigned int hasloose:1; /* 1 if has loose children */
+ unsigned int hasany:1; /* 1 if has ANY entry */
+ unsigned int pad:4; /* unused */
+ unsigned int mask:8; /* hash size - 1 */
+ unsigned int entries:16; /* number of children */
+} NTableRec, *NTable;
+
+/* the buckets are right after the structure */
+#define NodeBuckets(ne) ((NTable *)((ne) + 1))
+#define NodeHash(ne,q) NodeBuckets(ne)[(q) & (ne)->mask]
+
+/* leaf tables have an extra level of indirection for the buckets,
+ * so that resizing can be done without invalidating a search list.
+ * This is completely ugly, and wastes some memory, but the Xlib
+ * spec doesn't really specify whether invalidation is OK, and the
+ * old implementation did not invalidate.
+ */
+typedef struct _LTable {
+ NTableRec table;
+ VEntry *buckets;
+} LTableRec, *LTable;
+
+#define LeafHash(le,q) (le)->buckets[(q) & (le)->table.mask]
+
+/* An XrmDatabase just holds a pointer to the first top-level table.
+ * The type name is no longer descriptive, but better to not change
+ * the Xresource.h header file. This type also gets used to define
+ * XrmSearchList, which is a complete crock, but we'll just leave it
+ * and caste types as required.
+ */
+typedef struct _XrmHashBucketRec {
+ NTable table;
+ XPointer mbstate;
+ XrmMethods methods;
+#ifdef XTHREADS
+ LockInfoRec linfo;
+#endif
+} XrmHashBucketRec;
+
+/* closure used in get/put resource */
+typedef struct _VClosure {
+ XrmRepresentation *type; /* type of value */
+ XrmValuePtr value; /* value itself */
+} VClosureRec, *VClosure;
+
+/* closure used in get search list */
+typedef struct _SClosure {
+ LTable *list; /* search list */
+ int idx; /* index of last filled element */
+ int limit; /* maximum index */
+} SClosureRec, *SClosure;
+
+/* placed in XrmSearchList to indicate next table is loose only */
+#define LOOSESEARCH ((LTable)1)
+
+/* closure used in enumerate database */
+typedef struct _EClosure {
+ XrmDatabase db; /* the database */
+ DBEnumProc proc; /* the user proc */
+ XPointer closure; /* the user closure */
+ XrmBindingList bindings; /* binding list */
+ XrmQuarkList quarks; /* quark list */
+ int mode; /* XrmEnum<kind> */
+} EClosureRec, *EClosure;
+
+/* types for typecasting ETable based functions to NTable based functions */
+typedef Bool (*getNTableSProcp)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ SClosure closure);
+typedef Bool (*getNTableVProcp)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure);
+typedef Bool (*getNTableEProcp)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register int level,
+ EClosure closure);
+
+/* predicate to determine when to resize a hash table */
+#define GrowthPred(n,m) ((unsigned)(n) > (((m) + 1) << 2))
+
+#define GROW(prev) \
+ if (GrowthPred((*prev)->entries, (*prev)->mask)) \
+ GrowTable(prev)
+
+/* pick a reasonable value for maximum depth of resource database */
+#define MAXDBDEPTH 100
+
+/* macro used in get/search functions */
+
+/* find an entry named ename, with leafness given by leaf */
+#define NFIND(ename) \
+ q = ename; \
+ entry = NodeHash(table, q); \
+ while (entry && entry->name != q) \
+ entry = entry->next; \
+ if (leaf && entry && !entry->leaf) { \
+ entry = entry->next; \
+ if (entry && !entry->leaf) \
+ entry = entry->next; \
+ if (entry && entry->name != q) \
+ entry = (NTable)NULL; \
+ }
+
+/* resourceQuarks keeps track of what quarks have been associated with values
+ * in all LTables. If a quark has never been used in an LTable, we don't need
+ * to bother looking for it.
+ */
+
+static unsigned char *resourceQuarks = (unsigned char *)NULL;
+static XrmQuark maxResourceQuark = -1;
+
+/* determines if a quark has been used for a value in any database */
+#define IsResourceQuark(q) ((q) > 0 && (q) <= maxResourceQuark && \
+ resourceQuarks[(q) >> 3] & (1 << ((q) & 7)))
+
+typedef unsigned char XrmBits;
+
+#define BSLASH ((XrmBits) (1 << 5))
+#define NORMAL ((XrmBits) (1 << 4))
+#define EOQ ((XrmBits) (1 << 3))
+#define SEP ((XrmBits) (1 << 2))
+#define ENDOF ((XrmBits) (1 << 1))
+#define SPACE (NORMAL|EOQ|SEP|(XrmBits)0)
+#define RSEP (NORMAL|EOQ|SEP|(XrmBits)1)
+#define EOS (EOQ|SEP|ENDOF|(XrmBits)0)
+#define EOL (EOQ|SEP|ENDOF|(XrmBits)1)
+#define BINDING (NORMAL|EOQ)
+#define ODIGIT (NORMAL|(XrmBits)1)
+
+#define next_char(ch,str) xrmtypes[(unsigned char)((ch) = *(++(str)))]
+#define next_mbchar(ch,len,str) xrmtypes[(unsigned char)(ch = (*db->methods->mbchar)(db->mbstate, str, &len), str += len, ch)]
+
+#define is_space(bits) ((bits) == SPACE)
+#define is_EOQ(bits) ((bits) & EOQ)
+#define is_EOF(bits) ((bits) == EOS)
+#define is_EOL(bits) ((bits) & ENDOF)
+#define is_binding(bits) ((bits) == BINDING)
+#define is_odigit(bits) ((bits) == ODIGIT)
+#define is_separator(bits) ((bits) & SEP)
+#define is_nonpcs(bits) (!(bits))
+#define is_normal(bits) ((bits) & NORMAL)
+#define is_simple(bits) ((bits) & (NORMAL|BSLASH))
+#define is_special(bits) ((bits) & (ENDOF|BSLASH))
+
+/* parsing types */
+static XrmBits const xrmtypes[256] = {
+ EOS,0,0,0,0,0,0,0,
+ 0,SPACE,EOL,0,0,
+#if defined(WIN32) || defined(__UNIXOS2__)
+ EOL, /* treat CR the same as LF, just in case */
+#else
+ 0,
+#endif
+ 0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ SPACE,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,BINDING,NORMAL,NORMAL,NORMAL,BINDING,NORMAL,
+ ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,ODIGIT,
+ NORMAL,NORMAL,RSEP,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,BSLASH,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,
+ NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,NORMAL,0
+ /* The rest will be automatically initialized to zero. */
+};
+
+void XrmInitialize(void)
+{
+ XrmQString = XrmPermStringToQuark("String");
+ XrmQANY = XrmPermStringToQuark("?");
+}
+
+XrmDatabase XrmGetDatabase(
+ Display *display)
+{
+ XrmDatabase retval;
+ LockDisplay(display);
+ retval = display->db;
+ UnlockDisplay(display);
+ return retval;
+}
+
+void XrmSetDatabase(
+ Display *display,
+ XrmDatabase database)
+{
+ LockDisplay(display);
+ /* destroy database if set up imlicitely by XGetDefault() */
+ if (display->db && (display->flags & XlibDisplayDfltRMDB)) {
+ XrmDestroyDatabase(display->db);
+ display->flags &= ~XlibDisplayDfltRMDB;
+ }
+ display->db = database;
+ UnlockDisplay(display);
+}
+
+void
+XrmStringToQuarkList(
+ register _Xconst char *name,
+ register XrmQuarkList quarks) /* RETURN */
+{
+ register XrmBits bits;
+ register Signature sig = 0;
+ register char ch, *tname;
+ register int i = 0;
+
+ if ((tname = (char *)name)) {
+ tname--;
+ while (!is_EOF(bits = next_char(ch, tname))) {
+ if (is_binding (bits)) {
+ if (i) {
+ /* Found a complete name */
+ *quarks++ = _XrmInternalStringToQuark(name,tname - name,
+ sig, False);
+ i = 0;
+ sig = 0;
+ }
+ name = tname+1;
+ }
+ else {
+ sig = (sig << 1) + ch; /* Compute the signature. */
+ i++;
+ }
+ }
+ *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False);
+ }
+ *quarks = NULLQUARK;
+}
+
+void
+XrmStringToBindingQuarkList(
+ register _Xconst char *name,
+ register XrmBindingList bindings, /* RETURN */
+ register XrmQuarkList quarks) /* RETURN */
+{
+ register XrmBits bits;
+ register Signature sig = 0;
+ register char ch, *tname;
+ register XrmBinding binding;
+ register int i = 0;
+
+ if ((tname = (char *)name)) {
+ tname--;
+ binding = XrmBindTightly;
+ while (!is_EOF(bits = next_char(ch, tname))) {
+ if (is_binding (bits)) {
+ if (i) {
+ /* Found a complete name */
+ *bindings++ = binding;
+ *quarks++ = _XrmInternalStringToQuark(name, tname - name,
+ sig, False);
+
+ i = 0;
+ sig = 0;
+ binding = XrmBindTightly;
+ }
+ name = tname+1;
+
+ if (ch == '*')
+ binding = XrmBindLoosely;
+ }
+ else {
+ sig = (sig << 1) + ch; /* Compute the signature. */
+ i++;
+ }
+ }
+ *bindings = binding;
+ *quarks++ = _XrmInternalStringToQuark(name, tname - name, sig, False);
+ }
+ *quarks = NULLQUARK;
+}
+
+#ifdef DEBUG
+
+static void PrintQuarkList(
+ XrmQuarkList quarks,
+ FILE *stream)
+{
+ Bool firstNameSeen;
+
+ for (firstNameSeen = False; *quarks; quarks++) {
+ if (firstNameSeen) {
+ (void) fprintf(stream, ".");
+ }
+ firstNameSeen = True;
+ (void) fputs(XrmQuarkToString(*quarks), stream);
+ }
+} /* PrintQuarkList */
+
+#endif /* DEBUG */
+
+
+/*
+ * Fallback methods for Xrm parsing.
+ * Simulate a C locale. No state needed here.
+ */
+
+static void
+c_mbnoop(
+ XPointer state)
+{
+}
+
+static char
+c_mbchar(
+ XPointer state,
+ const char *str,
+ int *lenp)
+{
+ *lenp = 1;
+ return *str;
+}
+
+static const char *
+c_lcname(
+ XPointer state)
+{
+ return "C";
+}
+
+static const XrmMethodsRec mb_methods = {
+ c_mbnoop, /* mbinit */
+ c_mbchar, /* mbchar */
+ c_mbnoop, /* mbfinish */
+ c_lcname, /* lcname */
+ c_mbnoop /* destroy */
+};
+
+
+static XrmDatabase NewDatabase(void)
+{
+ register XrmDatabase db;
+
+ db = (XrmDatabase) Xmalloc(sizeof(XrmHashBucketRec));
+ if (db) {
+ _XCreateMutex(&db->linfo);
+ db->table = (NTable)NULL;
+ db->mbstate = (XPointer)NULL;
+ db->methods = _XrmInitParseInfo(&db->mbstate);
+ if (!db->methods)
+ db->methods = &mb_methods;
+ }
+ return db;
+}
+
+/* move all values from ftable to ttable, and free ftable's buckets.
+ * ttable is quaranteed empty to start with.
+ */
+static void MoveValues(
+ LTable ftable,
+ register LTable ttable)
+{
+ register VEntry fentry, nfentry;
+ register VEntry *prev;
+ register VEntry *bucket;
+ register VEntry tentry;
+ register int i;
+
+ for (i = ftable->table.mask, bucket = ftable->buckets; i >= 0; i--) {
+ for (fentry = *bucket++; fentry; fentry = nfentry) {
+ prev = &LeafHash(ttable, fentry->name);
+ tentry = *prev;
+ *prev = fentry;
+ /* chain on all with same name, to preserve invariant order */
+ while ((nfentry = fentry->next) && nfentry->name == fentry->name)
+ fentry = nfentry;
+ fentry->next = tentry;
+ }
+ }
+ Xfree((char *)ftable->buckets);
+}
+
+/* move all tables from ftable to ttable, and free ftable.
+ * ttable is quaranteed empty to start with.
+ */
+static void MoveTables(
+ NTable ftable,
+ register NTable ttable)
+{
+ register NTable fentry, nfentry;
+ register NTable *prev;
+ register NTable *bucket;
+ register NTable tentry;
+ register int i;
+
+ for (i = ftable->mask, bucket = NodeBuckets(ftable); i >= 0; i--) {
+ for (fentry = *bucket++; fentry; fentry = nfentry) {
+ prev = &NodeHash(ttable, fentry->name);
+ tentry = *prev;
+ *prev = fentry;
+ /* chain on all with same name, to preserve invariant order */
+ while ((nfentry = fentry->next) && nfentry->name == fentry->name)
+ fentry = nfentry;
+ fentry->next = tentry;
+ }
+ }
+ Xfree((char *)ftable);
+}
+
+/* grow the table, based on current number of entries */
+static void GrowTable(
+ NTable *prev)
+{
+ register NTable table;
+ register int i;
+
+ table = *prev;
+ i = table->mask;
+ if (i == 255) /* biggest it gets */
+ return;
+ while (i < 255 && GrowthPred(table->entries, i))
+ i = (i << 1) + 1;
+ i++; /* i is now the new size */
+ if (table->leaf) {
+ register LTable ltable;
+ LTableRec otable;
+
+ ltable = (LTable)table;
+ /* cons up a copy to make MoveValues look symmetric */
+ otable = *ltable;
+ ltable->buckets = (VEntry *)Xmalloc(i * sizeof(VEntry));
+ if (!ltable->buckets) {
+ ltable->buckets = otable.buckets;
+ return;
+ }
+ ltable->table.mask = i - 1;
+ bzero((char *)ltable->buckets, i * sizeof(VEntry));
+ MoveValues(&otable, ltable);
+ } else {
+ register NTable ntable;
+
+ ntable = (NTable)Xmalloc(sizeof(NTableRec) + i * sizeof(NTable));
+ if (!ntable)
+ return;
+ *ntable = *table;
+ ntable->mask = i - 1;
+ bzero((char *)NodeBuckets(ntable), i * sizeof(NTable));
+ *prev = ntable;
+ MoveTables(table, ntable);
+ }
+}
+
+/* merge values from ftable into *pprev, destroy ftable in the process */
+static void MergeValues(
+ LTable ftable,
+ NTable *pprev,
+ Bool override)
+{
+ register VEntry fentry, tentry;
+ register VEntry *prev;
+ register LTable ttable;
+ VEntry *bucket;
+ int i;
+ register XrmQuark q;
+
+ ttable = (LTable)*pprev;
+ if (ftable->table.hasloose)
+ ttable->table.hasloose = 1;
+ for (i = ftable->table.mask, bucket = ftable->buckets;
+ i >= 0;
+ i--, bucket++) {
+ for (fentry = *bucket; fentry; ) {
+ q = fentry->name;
+ prev = &LeafHash(ttable, q);
+ tentry = *prev;
+ while (tentry && tentry->name != q)
+ tentry = *(prev = &tentry->next);
+ /* note: test intentionally uses fentry->name instead of q */
+ /* permits serendipitous inserts */
+ while (tentry && tentry->name == fentry->name) {
+ /* if tentry is earlier, skip it */
+ if (!fentry->tight && tentry->tight) {
+ tentry = *(prev = &tentry->next);
+ continue;
+ }
+ if (fentry->tight != tentry->tight) {
+ /* no match, chain in fentry */
+ *prev = fentry;
+ prev = &fentry->next;
+ fentry = *prev;
+ *prev = tentry;
+ ttable->table.entries++;
+ } else if (override) {
+ /* match, chain in fentry, splice out and free tentry */
+ *prev = fentry;
+ prev = &fentry->next;
+ fentry = *prev;
+ *prev = tentry->next;
+ /* free the overridden entry */
+ Xfree((char *)tentry);
+ /* get next tentry */
+ tentry = *prev;
+ } else {
+ /* match, discard fentry */
+ prev = &tentry->next;
+ tentry = fentry; /* use as a temp var */
+ fentry = fentry->next;
+ /* free the overpowered entry */
+ Xfree((char *)tentry);
+ /* get next tentry */
+ tentry = *prev;
+ }
+ if (!fentry)
+ break;
+ }
+ /* at this point, tentry cannot match any fentry named q */
+ /* chain in all bindings together, preserve invariant order */
+ while (fentry && fentry->name == q) {
+ *prev = fentry;
+ prev = &fentry->next;
+ fentry = *prev;
+ *prev = tentry;
+ ttable->table.entries++;
+ }
+ }
+ }
+ Xfree((char *)ftable->buckets);
+ Xfree((char *)ftable);
+ /* resize if necessary, now that we're all done */
+ GROW(pprev);
+}
+
+/* merge tables from ftable into *pprev, destroy ftable in the process */
+static void MergeTables(
+ NTable ftable,
+ NTable *pprev,
+ Bool override)
+{
+ register NTable fentry, tentry;
+ NTable nfentry;
+ register NTable *prev;
+ register NTable ttable;
+ NTable *bucket;
+ int i;
+ register XrmQuark q;
+
+ ttable = *pprev;
+ if (ftable->hasloose)
+ ttable->hasloose = 1;
+ if (ftable->hasany)
+ ttable->hasany = 1;
+ for (i = ftable->mask, bucket = NodeBuckets(ftable);
+ i >= 0;
+ i--, bucket++) {
+ for (fentry = *bucket; fentry; ) {
+ q = fentry->name;
+ prev = &NodeHash(ttable, q);
+ tentry = *prev;
+ while (tentry && tentry->name != q)
+ tentry = *(prev = &tentry->next);
+ /* note: test intentionally uses fentry->name instead of q */
+ /* permits serendipitous inserts */
+ while (tentry && tentry->name == fentry->name) {
+ /* if tentry is earlier, skip it */
+ if ((fentry->leaf && !tentry->leaf) ||
+ (!fentry->tight && tentry->tight &&
+ (fentry->leaf || !tentry->leaf))) {
+ tentry = *(prev = &tentry->next);
+ continue;
+ }
+ nfentry = fentry->next;
+ if (fentry->leaf != tentry->leaf ||
+ fentry->tight != tentry->tight) {
+ /* no match, just chain in */
+ *prev = fentry;
+ *(prev = &fentry->next) = tentry;
+ ttable->entries++;
+ } else {
+ if (fentry->leaf)
+ MergeValues((LTable)fentry, prev, override);
+ else
+ MergeTables(fentry, prev, override);
+ /* bump to next tentry */
+ tentry = *(prev = &(*prev)->next);
+ }
+ /* bump to next fentry */
+ fentry = nfentry;
+ if (!fentry)
+ break;
+ }
+ /* at this point, tentry cannot match any fentry named q */
+ /* chain in all bindings together, preserve invariant order */
+ while (fentry && fentry->name == q) {
+ *prev = fentry;
+ prev = &fentry->next;
+ fentry = *prev;
+ *prev = tentry;
+ ttable->entries++;
+ }
+ }
+ }
+ Xfree((char *)ftable);
+ /* resize if necessary, now that we're all done */
+ GROW(pprev);
+}
+
+void XrmCombineDatabase(
+ XrmDatabase from, XrmDatabase *into,
+ Bool override)
+{
+ register NTable *prev;
+ register NTable ftable, ttable, nftable;
+
+ if (!*into) {
+ *into = from;
+ } else if (from) {
+ _XLockMutex(&from->linfo);
+ _XLockMutex(&(*into)->linfo);
+ if ((ftable = from->table)) {
+ prev = &(*into)->table;
+ ttable = *prev;
+ if (!ftable->leaf) {
+ nftable = ftable->next;
+ if (ttable && !ttable->leaf) {
+ /* both have node tables, merge them */
+ MergeTables(ftable, prev, override);
+ /* bump to into's leaf table, if any */
+ ttable = *(prev = &(*prev)->next);
+ } else {
+ /* into has no node table, link from's in */
+ *prev = ftable;
+ *(prev = &ftable->next) = ttable;
+ }
+ /* bump to from's leaf table, if any */
+ ftable = nftable;
+ } else {
+ /* bump to into's leaf table, if any */
+ if (ttable && !ttable->leaf)
+ ttable = *(prev = &ttable->next);
+ }
+ if (ftable) {
+ /* if into has a leaf, merge, else insert */
+ if (ttable)
+ MergeValues((LTable)ftable, prev, override);
+ else
+ *prev = ftable;
+ }
+ }
+ (from->methods->destroy)(from->mbstate);
+ _XUnlockMutex(&from->linfo);
+ _XFreeMutex(&from->linfo);
+ Xfree((char *)from);
+ _XUnlockMutex(&(*into)->linfo);
+ }
+}
+
+void XrmMergeDatabases(
+ XrmDatabase from, XrmDatabase *into)
+{
+ XrmCombineDatabase(from, into, True);
+}
+
+/* store a value in the database, overriding any existing entry */
+static void PutEntry(
+ XrmDatabase db,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ XrmRepresentation type,
+ XrmValuePtr value)
+{
+ register NTable *pprev, *prev;
+ register NTable table;
+ register XrmQuark q;
+ register VEntry *vprev;
+ register VEntry entry;
+ NTable *nprev, *firstpprev;
+
+#define NEWTABLE(q,i) \
+ table = (NTable)Xmalloc(sizeof(LTableRec)); \
+ if (!table) \
+ return; \
+ table->name = q; \
+ table->hasloose = 0; \
+ table->hasany = 0; \
+ table->mask = 0; \
+ table->entries = 0; \
+ if (quarks[i]) { \
+ table->leaf = 0; \
+ nprev = NodeBuckets(table); \
+ } else { \
+ table->leaf = 1; \
+ if (!(nprev = (NTable *)Xmalloc(sizeof(VEntry *)))) {\
+ Xfree(table); \
+ return; \
+ } \
+ ((LTable)table)->buckets = (VEntry *)nprev; \
+ } \
+ *nprev = (NTable)NULL; \
+ table->next = *prev; \
+ *prev = table
+
+ if (!db || !*quarks)
+ return;
+ table = *(prev = &db->table);
+ /* if already at leaf, bump to the leaf table */
+ if (!quarks[1] && table && !table->leaf)
+ table = *(prev = &table->next);
+ pprev = prev;
+ if (!table || (quarks[1] && table->leaf)) {
+ /* no top-level node table, create one and chain it in */
+ NEWTABLE(NULLQUARK,1);
+ table->tight = 1; /* arbitrary */
+ prev = nprev;
+ } else {
+ /* search along until we need a value */
+ while (quarks[1]) {
+ q = *quarks;
+ table = *(prev = &NodeHash(table, q));
+ while (table && table->name != q)
+ table = *(prev = &table->next);
+ if (!table)
+ break; /* not found */
+ if (quarks[2]) {
+ if (table->leaf)
+ break; /* not found */
+ } else {
+ if (!table->leaf) {
+ /* bump to leaf table, if any */
+ table = *(prev = &table->next);
+ if (!table || table->name != q)
+ break; /* not found */
+ if (!table->leaf) {
+ /* bump to leaf table, if any */
+ table = *(prev = &table->next);
+ if (!table || table->name != q)
+ break; /* not found */
+ }
+ }
+ }
+ if (*bindings == XrmBindTightly) {
+ if (!table->tight)
+ break; /* not found */
+ } else {
+ if (table->tight) {
+ /* bump to loose table, if any */
+ table = *(prev = &table->next);
+ if (!table || table->name != q ||
+ !quarks[2] != table->leaf)
+ break; /* not found */
+ }
+ }
+ /* found that one, bump to next quark */
+ pprev = prev;
+ quarks++;
+ bindings++;
+ }
+ if (!quarks[1]) {
+ /* found all the way to a leaf */
+ q = *quarks;
+ entry = *(vprev = &LeafHash((LTable)table, q));
+ while (entry && entry->name != q)
+ entry = *(vprev = &entry->next);
+ /* if want loose and have tight, bump to next entry */
+ if (entry && *bindings == XrmBindLoosely && entry->tight)
+ entry = *(vprev = &entry->next);
+ if (entry && entry->name == q &&
+ (*bindings == XrmBindTightly) == entry->tight) {
+ /* match, need to override */
+ if ((type == XrmQString) == entry->string &&
+ entry->size == value->size) {
+ /* update type if not String, can be different */
+ if (!entry->string)
+ RepType(entry) = type;
+ /* identical size, just overwrite value */
+ memcpy(RawValue(entry), (char *)value->addr, value->size);
+ return;
+ }
+ /* splice out and free old entry */
+ *vprev = entry->next;
+ Xfree((char *)entry);
+ (*pprev)->entries--;
+ }
+ /* this is where to insert */
+ prev = (NTable *)vprev;
+ }
+ }
+ /* keep the top table, because we may have to grow it */
+ firstpprev = pprev;
+ /* iterate until we get to the leaf */
+ while (quarks[1]) {
+ /* build a new table and chain it in */
+ NEWTABLE(*quarks,2);
+ if (*quarks++ == XrmQANY)
+ (*pprev)->hasany = 1;
+ if (*bindings++ == XrmBindTightly) {
+ table->tight = 1;
+ } else {
+ table->tight = 0;
+ (*pprev)->hasloose = 1;
+ }
+ (*pprev)->entries++;
+ pprev = prev;
+ prev = nprev;
+ }
+ /* now allocate the value entry */
+ entry = (VEntry)Xmalloc(((type == XrmQString) ?
+ sizeof(VEntryRec) : sizeof(DEntryRec)) +
+ value->size);
+ if (!entry)
+ return;
+ entry->name = q = *quarks;
+ if (*bindings == XrmBindTightly) {
+ entry->tight = 1;
+ } else {
+ entry->tight = 0;
+ (*pprev)->hasloose = 1;
+ }
+ /* chain it in, with a bit of type cast ugliness */
+ entry->next = *((VEntry *)prev);
+ *((VEntry *)prev) = entry;
+ entry->size = value->size;
+ if (type == XrmQString) {
+ entry->string = 1;
+ } else {
+ entry->string = 0;
+ RepType(entry) = type;
+ }
+ /* save a copy of the value */
+ memcpy(RawValue(entry), (char *)value->addr, value->size);
+ (*pprev)->entries++;
+ /* this is a new leaf, need to remember it for search lists */
+ if (q > maxResourceQuark) {
+ unsigned oldsize = (maxResourceQuark + 1) >> 3;
+ unsigned size = ((q | 0x7f) + 1) >> 3; /* reallocate in chunks */
+ if (resourceQuarks) {
+ unsigned char *prevQuarks = resourceQuarks;
+
+ resourceQuarks = (unsigned char *)Xrealloc((char *)resourceQuarks,
+ size);
+ if (!resourceQuarks) {
+ Xfree(prevQuarks);
+ }
+ } else
+ resourceQuarks = (unsigned char *)Xmalloc(size);
+ if (resourceQuarks) {
+ bzero((char *)&resourceQuarks[oldsize], size - oldsize);
+ maxResourceQuark = (size << 3) - 1;
+ } else {
+ maxResourceQuark = -1;
+ }
+ }
+ if (q > 0 && resourceQuarks)
+ resourceQuarks[q >> 3] |= 1 << (q & 0x7);
+ GROW(firstpprev);
+
+#undef NEWTABLE
+}
+
+void XrmQPutResource(
+ XrmDatabase *pdb,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ XrmRepresentation type,
+ XrmValuePtr value)
+{
+ if (!*pdb) *pdb = NewDatabase();
+ _XLockMutex(&(*pdb)->linfo);
+ PutEntry(*pdb, bindings, quarks, type, value);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+void
+XrmPutResource(
+ XrmDatabase *pdb,
+ _Xconst char *specifier,
+ _Xconst char *type,
+ XrmValuePtr value)
+{
+ XrmBinding bindings[MAXDBDEPTH+1];
+ XrmQuark quarks[MAXDBDEPTH+1];
+
+ if (!*pdb) *pdb = NewDatabase();
+ _XLockMutex(&(*pdb)->linfo);
+ XrmStringToBindingQuarkList(specifier, bindings, quarks);
+ PutEntry(*pdb, bindings, quarks, XrmStringToQuark(type), value);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+void
+XrmQPutStringResource(
+ XrmDatabase *pdb,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ _Xconst char *str)
+{
+ XrmValue value;
+
+ if (!*pdb) *pdb = NewDatabase();
+ value.addr = (XPointer) str;
+ value.size = strlen(str)+1;
+ _XLockMutex(&(*pdb)->linfo);
+ PutEntry(*pdb, bindings, quarks, XrmQString, &value);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+/* Function Name: GetDatabase
+ * Description: Parses a string and stores it as a database.
+ * Arguments: db - the database.
+ * str - a pointer to the string containing the database.
+ * filename - source filename, if any.
+ * doall - whether to do all lines or just one
+ */
+
+/*
+ * This function is highly optimized to inline as much as possible.
+ * Be very careful with modifications, or simplifications, as they
+ * may adversely affect the performance.
+ *
+ * Chris Peterson, MIT X Consortium 5/17/90.
+ */
+
+/*
+ * Xlib spec says max 100 quarks in a lookup, will stop and return if
+ * return if any single production's lhs has more than 100 components.
+ */
+#define QLIST_SIZE 100
+
+/*
+ * This should be big enough to handle things like the XKeysymDB or biggish
+ * ~/.Xdefaults or app-defaults files. Anything bigger will be allocated on
+ * the heap.
+ */
+#define DEF_BUFF_SIZE 8192
+
+static void GetIncludeFile(
+ XrmDatabase db,
+ _Xconst char *base,
+ _Xconst char *fname,
+ int fnamelen);
+
+static void GetDatabase(
+ XrmDatabase db,
+ _Xconst register char *str,
+ _Xconst char *filename,
+ Bool doall)
+{
+ char *rhs;
+ char *lhs, lhs_s[DEF_BUFF_SIZE];
+ XrmQuark quarks[QLIST_SIZE + 1]; /* allow for a terminal NullQuark */
+ XrmBinding bindings[QLIST_SIZE + 1];
+
+ register char *ptr;
+ register XrmBits bits = 0;
+ register char c;
+ register Signature sig;
+ register char *ptr_max;
+ register int num_quarks;
+ register XrmBindingList t_bindings;
+
+ int len, alloc_chars;
+ unsigned long str_len;
+ XrmValue value;
+ Bool only_pcs;
+ Bool dolines;
+
+ if (!db)
+ return;
+
+ /*
+ * if strlen (str) < DEF_BUFF_SIZE allocate buffers on the stack for
+ * speed otherwise malloc the buffer. From a buffer overflow standpoint
+ * we can be sure that neither: a) a component on the lhs, or b) a
+ * value on the rhs, will be longer than the overall length of str,
+ * i.e. strlen(str).
+ *
+ * This should give good performance when parsing "*foo: bar" type
+ * databases as might be passed with -xrm command line options; but
+ * with larger databases, e.g. .Xdefaults, app-defaults, or KeysymDB
+ * files, the size of the buffers will be overly large. One way
+ * around this would be to double-parse each production with a resulting
+ * performance hit. In any event we can be assured that a lhs component
+ * name or a rhs value won't be longer than str itself.
+ */
+
+ str_len = strlen (str);
+ if (DEF_BUFF_SIZE > str_len) lhs = lhs_s;
+ else if ((lhs = (char*) Xmalloc (str_len)) == NULL)
+ return;
+
+ alloc_chars = DEF_BUFF_SIZE < str_len ? str_len : DEF_BUFF_SIZE;
+ if ((rhs = (char*) Xmalloc (alloc_chars)) == NULL) {
+ if (lhs != lhs_s) Xfree (lhs);
+ return;
+ }
+
+ (*db->methods->mbinit)(db->mbstate);
+ str--;
+ dolines = True;
+ while (!is_EOF(bits) && dolines) {
+ dolines = doall;
+
+ /*
+ * First: Remove extra whitespace.
+ */
+
+ do {
+ bits = next_char(c, str);
+ } while is_space(bits);
+
+ /*
+ * Ignore empty lines.
+ */
+
+ if (is_EOL(bits))
+ continue; /* start a new line. */
+
+ /*
+ * Second: check the first character in a line to see if it is
+ * "!" signifying a comment, or "#" signifying a directive.
+ */
+
+ if (c == '!') { /* Comment, spin to next newline */
+ while (is_simple(bits = next_char(c, str))) {}
+ if (is_EOL(bits))
+ continue;
+ while (!is_EOL(bits = next_mbchar(c, len, str))) {}
+ str--;
+ continue; /* start a new line. */
+ }
+
+ if (c == '#') { /* Directive */
+ /* remove extra whitespace */
+ only_pcs = True;
+ while (is_space(bits = next_char(c, str))) {};
+ /* only "include" directive is currently defined */
+ if (!strncmp(str, "include", 7)) {
+ str += (7-1);
+ /* remove extra whitespace */
+ while (is_space(bits = next_char(c, str))) {};
+ /* must have a starting " */
+ if (c == '"') {
+ _Xconst char *fname = str+1;
+ len = 0;
+ do {
+ if (only_pcs) {
+ bits = next_char(c, str);
+ if (is_nonpcs(bits))
+ only_pcs = False;
+ }
+ if (!only_pcs)
+ bits = next_mbchar(c, len, str);
+ } while (c != '"' && !is_EOL(bits));
+ /* must have an ending " */
+ if (c == '"')
+ GetIncludeFile(db, filename, fname, str - len - fname);
+ }
+ }
+ /* spin to next newline */
+ if (only_pcs) {
+ while (is_simple(bits))
+ bits = next_char(c, str);
+ if (is_EOL(bits))
+ continue;
+ }
+ while (!is_EOL(bits))
+ bits = next_mbchar(c, len, str);
+ str--;
+ continue; /* start a new line. */
+ }
+
+ /*
+ * Third: loop through the LHS of the resource specification
+ * storing characters and converting this to a Quark.
+ */
+
+ num_quarks = 0;
+ t_bindings = bindings;
+
+ sig = 0;
+ ptr = lhs;
+ *t_bindings = XrmBindTightly;
+ for(;;) {
+ if (!is_binding(bits)) {
+ while (!is_EOQ(bits)) {
+ *ptr++ = c;
+ sig = (sig << 1) + c; /* Compute the signature. */
+ bits = next_char(c, str);
+ }
+
+ quarks[num_quarks++] =
+ _XrmInternalStringToQuark(lhs, ptr - lhs, sig, False);
+
+ if (num_quarks > QLIST_SIZE) {
+ Xfree(rhs);
+ if (lhs != lhs_s) Xfree (lhs);
+ (*db->methods->mbfinish)(db->mbstate);
+ return;
+ }
+
+ if (is_separator(bits)) {
+ if (!is_space(bits))
+ break;
+
+ /* Remove white space */
+ do {
+ *ptr++ = c;
+ sig = (sig << 1) + c; /* Compute the signature. */
+ } while (is_space(bits = next_char(c, str)));
+
+ /*
+ * The spec doesn't permit it, but support spaces
+ * internal to resource name/class
+ */
+
+ if (is_separator(bits))
+ break;
+ num_quarks--;
+ continue;
+ }
+
+ if (c == '.')
+ *(++t_bindings) = XrmBindTightly;
+ else
+ *(++t_bindings) = XrmBindLoosely;
+
+ sig = 0;
+ ptr = lhs;
+ }
+ else {
+ /*
+ * Magic unspecified feature #254.
+ *
+ * If two separators appear with no Text between them then
+ * ignore them.
+ *
+ * If anyone of those separators is a '*' then the binding
+ * will be loose, otherwise it will be tight.
+ */
+
+ if (c == '*')
+ *t_bindings = XrmBindLoosely;
+ }
+
+ bits = next_char(c, str);
+ }
+
+ quarks[num_quarks] = NULLQUARK;
+
+ /*
+ * Make sure that there is a ':' in this line.
+ */
+
+ if (c != ':') {
+ char oldc;
+
+ /*
+ * A parsing error has occured, toss everything on the line
+ * a new_line can still be escaped with a '\'.
+ */
+
+ while (is_normal(bits))
+ bits = next_char(c, str);
+ if (is_EOL(bits))
+ continue;
+ bits = next_mbchar(c, len, str);
+ do {
+ oldc = c;
+ bits = next_mbchar(c, len, str);
+ } while (c && (c != '\n' || oldc == '\\'));
+ str--;
+ continue;
+ }
+
+ /*
+ * I now have a quark and binding list for the entire left hand
+ * side. "c" currently points to the ":" separating the left hand
+ * side for the right hand side. It is time to begin processing
+ * the right hand side.
+ */
+
+ /*
+ * Fourth: Remove more whitespace
+ */
+
+ for(;;) {
+ if (is_space(bits = next_char(c, str)))
+ continue;
+ if (c != '\\')
+ break;
+ bits = next_char(c, str);
+ if (c == '\n')
+ continue;
+ str--;
+ bits = BSLASH;
+ c = '\\';
+ break;
+ }
+
+ /*
+ * Fifth: Process the right hand side.
+ */
+
+ ptr = rhs;
+ ptr_max = ptr + alloc_chars - 4;
+ only_pcs = True;
+ len = 1;
+
+ for(;;) {
+
+ /*
+ * Tight loop for the normal case: Non backslash, non-end of value
+ * character that will fit into the allocated buffer.
+ */
+
+ if (only_pcs) {
+ while (is_normal(bits) && ptr < ptr_max) {
+ *ptr++ = c;
+ bits = next_char(c, str);
+ }
+ if (is_EOL(bits))
+ break;
+ if (is_nonpcs(bits)) {
+ only_pcs = False;
+ bits = next_mbchar(c, len, str);
+ }
+ }
+ while (!is_special(bits) && ptr + len <= ptr_max) {
+ len = -len;
+ while (len)
+ *ptr++ = str[len++];
+ if (*str == '\0') {
+ bits = EOS;
+ break;
+ }
+ bits = next_mbchar(c, len, str);
+ }
+
+ if (is_EOL(bits)) {
+ str--;
+ break;
+ }
+
+ if (c == '\\') {
+ /*
+ * We need to do some magic after a backslash.
+ */
+ Bool read_next = True;
+
+ if (only_pcs) {
+ bits = next_char(c, str);
+ if (is_nonpcs(bits))
+ only_pcs = False;
+ }
+ if (!only_pcs)
+ bits = next_mbchar(c, len, str);
+
+ if (is_EOL(bits)) {
+ if (is_EOF(bits))
+ continue;
+ } else if (c == 'n') {
+ /*
+ * "\n" means insert a newline.
+ */
+ *ptr++ = '\n';
+ } else if (c == '\\') {
+ /*
+ * "\\" completes to just one backslash.
+ */
+ *ptr++ = '\\';
+ } else {
+ /*
+ * pick up to three octal digits after the '\'.
+ */
+ char temp[3];
+ int count = 0;
+ while (is_odigit(bits) && count < 3) {
+ temp[count++] = c;
+ if (only_pcs) {
+ bits = next_char(c, str);
+ if (is_nonpcs(bits))
+ only_pcs = False;
+ }
+ if (!only_pcs)
+ bits = next_mbchar(c, len, str);
+ }
+
+ /*
+ * If we found three digits then insert that octal code
+ * into the value string as a character.
+ */
+
+ if (count == 3) {
+ *ptr++ = (unsigned char) ((temp[0] - '0') * 0100 +
+ (temp[1] - '0') * 010 +
+ (temp[2] - '0'));
+ }
+ else {
+ int tcount;
+
+ /*
+ * Otherwise just insert those characters into the
+ * string, since no special processing is needed on
+ * numerics we can skip the special processing.
+ */
+
+ for (tcount = 0; tcount < count; tcount++) {
+ *ptr++ = temp[tcount]; /* print them in
+ the correct order */
+ }
+ }
+ read_next = False;
+ }
+ if (read_next) {
+ if (only_pcs) {
+ bits = next_char(c, str);
+ if (is_nonpcs(bits))
+ only_pcs = False;
+ }
+ if (!only_pcs)
+ bits = next_mbchar(c, len, str);
+ }
+ }
+
+ /*
+ * It is important to make sure that there is room for at least
+ * four more characters in the buffer, since I can add that
+ * many characters into the buffer after a backslash has occured.
+ */
+
+ if (ptr + len > ptr_max) {
+ char * temp_str;
+
+ alloc_chars += BUFSIZ/10;
+ temp_str = Xrealloc(rhs, sizeof(char) * alloc_chars);
+
+ if (!temp_str) {
+ Xfree(rhs);
+ if (lhs != lhs_s) Xfree (lhs);
+ (*db->methods->mbfinish)(db->mbstate);
+ return;
+ }
+
+ ptr = temp_str + (ptr - rhs); /* reset pointer. */
+ rhs = temp_str;
+ ptr_max = rhs + alloc_chars - 4;
+ }
+ }
+
+ /*
+ * Lastly: Terminate the value string, and store this entry
+ * into the database.
+ */
+
+ *ptr++ = '\0';
+
+ /* Store it in database */
+ value.size = ptr - rhs;
+ value.addr = (XPointer) rhs;
+
+ PutEntry(db, bindings, quarks, XrmQString, &value);
+ }
+
+ if (lhs != lhs_s) Xfree (lhs);
+ Xfree (rhs);
+
+ (*db->methods->mbfinish)(db->mbstate);
+}
+
+void
+XrmPutStringResource(
+ XrmDatabase *pdb,
+ _Xconst char*specifier,
+ _Xconst char*str)
+{
+ XrmValue value;
+ XrmBinding bindings[MAXDBDEPTH+1];
+ XrmQuark quarks[MAXDBDEPTH+1];
+
+ if (!*pdb) *pdb = NewDatabase();
+ XrmStringToBindingQuarkList(specifier, bindings, quarks);
+ value.addr = (XPointer) str;
+ value.size = strlen(str)+1;
+ _XLockMutex(&(*pdb)->linfo);
+ PutEntry(*pdb, bindings, quarks, XrmQString, &value);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+
+void
+XrmPutLineResource(
+ XrmDatabase *pdb,
+ _Xconst char*line)
+{
+ if (!*pdb) *pdb = NewDatabase();
+ _XLockMutex(&(*pdb)->linfo);
+ GetDatabase(*pdb, line, (char *)NULL, False);
+ _XUnlockMutex(&(*pdb)->linfo);
+}
+
+XrmDatabase
+XrmGetStringDatabase(
+ _Xconst char *data)
+{
+ XrmDatabase db;
+
+ db = NewDatabase();
+ _XLockMutex(&db->linfo);
+ GetDatabase(db, data, (char *)NULL, True);
+ _XUnlockMutex(&db->linfo);
+ return db;
+}
+
+/* Function Name: ReadInFile
+ * Description: Reads the file into a buffer.
+ * Arguments: filename - the name of the file.
+ * Returns: An allocated string containing the contents of the file.
+ */
+
+static char *
+ReadInFile(_Xconst char *filename)
+{
+ register int fd, size;
+ char * filebuf;
+
+#ifdef __UNIXOS2__
+ filename = __XOS2RedirRoot(filename);
+#endif
+
+ /*
+ * MS-Windows and OS/2 note: Default open mode includes O_TEXT
+ */
+ if ( (fd = _XOpenFile (filename, O_RDONLY)) == -1 )
+ return (char *)NULL;
+
+ /*
+ * MS-Windows and OS/2 note: depending on how the sources are
+ * untarred, the newlines in resource files may or may not have
+ * been expanded to CRLF. Either way the size returned by fstat
+ * is sufficient to read the file into because in text-mode any
+ * CRLFs in a file will be converted to newlines (LF) with the
+ * result that the number of bytes actually read with be <=
+ * to the size returned by fstat.
+ */
+ {
+ struct stat status_buffer;
+ if ( (fstat(fd, &status_buffer)) == -1 ) {
+ close (fd);
+ return (char *)NULL;
+ } else
+ size = status_buffer.st_size;
+ }
+
+ if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */
+ close(fd);
+ return (char *)NULL;
+ }
+ size = read (fd, filebuf, size);
+
+#ifdef __UNIXOS2__
+ { /* kill CRLF */
+ int i,k;
+ for (i=k=0; i<size; i++)
+ if (filebuf[i] != 0x0d) {
+ filebuf[k++] = filebuf[i];
+ }
+ filebuf[k] = 0;
+ }
+#endif
+
+ if (size < 0) {
+ close (fd);
+ Xfree(filebuf);
+ return (char *)NULL;
+ }
+ close (fd);
+
+ filebuf[size] = '\0'; /* NULL terminate it. */
+ return filebuf;
+}
+
+static void
+GetIncludeFile(
+ XrmDatabase db,
+ _Xconst char *base,
+ _Xconst char *fname,
+ int fnamelen)
+{
+ int len;
+ char *str;
+ char realfname[BUFSIZ];
+
+ if (fnamelen <= 0 || fnamelen >= BUFSIZ)
+ return;
+ if (*fname != '/' && base && (str = strrchr(base, '/'))) {
+ len = str - base + 1;
+ if (len + fnamelen >= BUFSIZ)
+ return;
+ strncpy(realfname, base, len);
+ strncpy(realfname + len, fname, fnamelen);
+ realfname[len + fnamelen] = '\0';
+ } else {
+ strncpy(realfname, fname, fnamelen);
+ realfname[fnamelen] = '\0';
+ }
+ if (!(str = ReadInFile(realfname)))
+ return;
+ GetDatabase(db, str, realfname, True);
+ Xfree(str);
+}
+
+XrmDatabase
+XrmGetFileDatabase(
+ _Xconst char *filename)
+{
+ XrmDatabase db;
+ char *str;
+
+ if (!(str = ReadInFile(filename)))
+ return (XrmDatabase)NULL;
+
+ db = NewDatabase();
+ _XLockMutex(&db->linfo);
+ GetDatabase(db, str, filename, True);
+ _XUnlockMutex(&db->linfo);
+ Xfree(str);
+ return db;
+}
+
+Status
+XrmCombineFileDatabase(
+ _Xconst char *filename,
+ XrmDatabase *target,
+ Bool override)
+{
+ XrmDatabase db;
+ char *str;
+
+ if (!(str = ReadInFile(filename)))
+ return 0;
+ if (override) {
+ db = *target;
+ if (!db)
+ *target = db = NewDatabase();
+ } else
+ db = NewDatabase();
+ _XLockMutex(&db->linfo);
+ GetDatabase(db, str, filename, True);
+ _XUnlockMutex(&db->linfo);
+ Xfree(str);
+ if (!override)
+ XrmCombineDatabase(db, target, False);
+ return 1;
+}
+
+/* call the user proc for every value in the table, arbitrary order.
+ * stop if user proc returns True. level is current depth in database.
+ */
+/*ARGSUSED*/
+static Bool EnumLTable(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register int level,
+ register EClosure closure)
+{
+ register VEntry *bucket;
+ register int i;
+ register VEntry entry;
+ XrmValue value;
+ XrmRepresentation type;
+ Bool tightOk;
+
+ closure->bindings[level] = (table->table.tight ?
+ XrmBindTightly : XrmBindLoosely);
+ closure->quarks[level] = table->table.name;
+ level++;
+ tightOk = !*names;
+ closure->quarks[level + 1] = NULLQUARK;
+ for (i = table->table.mask, bucket = table->buckets;
+ i >= 0;
+ i--, bucket++) {
+ for (entry = *bucket; entry; entry = entry->next) {
+ if (entry->tight && !tightOk)
+ continue;
+ closure->bindings[level] = (entry->tight ?
+ XrmBindTightly : XrmBindLoosely);
+ closure->quarks[level] = entry->name;
+ value.size = entry->size;
+ if (entry->string) {
+ type = XrmQString;
+ value.addr = StringValue(entry);
+ } else {
+ type = RepType(entry);
+ value.addr = DataValue(entry);
+ }
+ if ((*closure->proc)(&closure->db, closure->bindings+1,
+ closure->quarks+1, &type, &value,
+ closure->closure))
+ return True;
+ }
+ }
+ return False;
+}
+
+static Bool EnumAllNTable(
+ NTable table,
+ register int level,
+ register EClosure closure)
+{
+ register NTable *bucket;
+ register int i;
+ register NTable entry;
+ XrmQuark empty = NULLQUARK;
+
+ if (level >= MAXDBDEPTH)
+ return False;
+ for (i = table->mask, bucket = NodeBuckets(table);
+ i >= 0;
+ i--, bucket++) {
+ for (entry = *bucket; entry; entry = entry->next) {
+ if (entry->leaf) {
+ if (EnumLTable((LTable)entry, &empty, &empty, level, closure))
+ return True;
+ } else {
+ closure->bindings[level] = (entry->tight ?
+ XrmBindTightly : XrmBindLoosely);
+ closure->quarks[level] = entry->name;
+ if (EnumAllNTable(entry, level+1, closure))
+ return True;
+ }
+ }
+ }
+ return False;
+}
+
+/* recurse on every table in the table, arbitrary order.
+ * stop if user proc returns True. level is current depth in database.
+ */
+static Bool EnumNTable(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register int level,
+ register EClosure closure)
+{
+ register NTable entry;
+ register XrmQuark q;
+ register unsigned int leaf;
+ Bool (*get)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register int level,
+ EClosure closure);
+ Bool bilevel;
+
+/* find entries named ename, leafness leaf, tight or loose, and call get */
+#define ITIGHTLOOSE(ename) \
+ NFIND(ename); \
+ if (entry) { \
+ if (leaf == entry->leaf) { \
+ if (!leaf && !entry->tight && entry->next && \
+ entry->next->name == q && entry->next->tight && \
+ (bilevel || entry->next->hasloose) && \
+ EnumLTable((LTable)entry->next, names+1, classes+1, \
+ level, closure)) \
+ return True; \
+ if ((*get)(entry, names+1, classes+1, level, closure)) \
+ return True; \
+ if (entry->tight && (entry = entry->next) && \
+ entry->name == q && leaf == entry->leaf && \
+ (*get)(entry, names+1, classes+1, level, closure)) \
+ return True; \
+ } else if (entry->leaf) { \
+ if ((bilevel || entry->hasloose) && \
+ EnumLTable((LTable)entry, names+1, classes+1, level, closure))\
+ return True; \
+ if (entry->tight && (entry = entry->next) && \
+ entry->name == q && (bilevel || entry->hasloose) && \
+ EnumLTable((LTable)entry, names+1, classes+1, level, closure))\
+ return True; \
+ } \
+ }
+
+/* find entries named ename, leafness leaf, loose only, and call get */
+#define ILOOSE(ename) \
+ NFIND(ename); \
+ if (entry && entry->tight && (entry = entry->next) && entry->name != q) \
+ entry = (NTable)NULL; \
+ if (entry) { \
+ if (leaf == entry->leaf) { \
+ if ((*get)(entry, names+1, classes+1, level, closure)) \
+ return True; \
+ } else if (entry->leaf && (bilevel || entry->hasloose)) { \
+ if (EnumLTable((LTable)entry, names+1, classes+1, level, closure))\
+ return True; \
+ } \
+ }
+
+ if (level >= MAXDBDEPTH)
+ return False;
+ closure->bindings[level] = (table->tight ?
+ XrmBindTightly : XrmBindLoosely);
+ closure->quarks[level] = table->name;
+ level++;
+ if (!*names) {
+ if (EnumAllNTable(table, level, closure))
+ return True;
+ } else {
+ if (names[1] || closure->mode == XrmEnumAllLevels) {
+ get = EnumNTable; /* recurse */
+ leaf = 0;
+ bilevel = !names[1];
+ } else {
+ get = (getNTableEProcp)EnumLTable; /* bottom of recursion */
+ leaf = 1;
+ bilevel = False;
+ }
+ if (table->hasloose && closure->mode == XrmEnumAllLevels) {
+ NTable *bucket;
+ int i;
+ XrmQuark empty = NULLQUARK;
+
+ for (i = table->mask, bucket = NodeBuckets(table);
+ i >= 0;
+ i--, bucket++) {
+ q = NULLQUARK;
+ for (entry = *bucket; entry; entry = entry->next) {
+ if (!entry->tight && entry->name != q &&
+ entry->name != *names && entry->name != *classes) {
+ q = entry->name;
+ if (entry->leaf) {
+ if (EnumLTable((LTable)entry, &empty, &empty,
+ level, closure))
+ return True;
+ } else {
+ if (EnumNTable(entry, &empty, &empty,
+ level, closure))
+ return True;
+ }
+ }
+ }
+ }
+ }
+
+ ITIGHTLOOSE(*names); /* do name, tight and loose */
+ ITIGHTLOOSE(*classes); /* do class, tight and loose */
+ if (table->hasany) {
+ ITIGHTLOOSE(XrmQANY); /* do ANY, tight and loose */
+ }
+ if (table->hasloose) {
+ while (1) {
+ names++;
+ classes++;
+ if (!*names)
+ break;
+ if (!names[1] && closure->mode != XrmEnumAllLevels) {
+ get = (getNTableEProcp)EnumLTable; /* bottom of recursion */
+ leaf = 1;
+ }
+ ILOOSE(*names); /* loose names */
+ ILOOSE(*classes); /* loose classes */
+ if (table->hasany) {
+ ILOOSE(XrmQANY); /* loose ANY */
+ }
+ }
+ names--;
+ classes--;
+ }
+ }
+ /* now look for matching leaf nodes */
+ entry = table->next;
+ if (!entry)
+ return False;
+ if (entry->leaf) {
+ if (entry->tight && !table->tight)
+ entry = entry->next;
+ } else {
+ entry = entry->next;
+ if (!entry || !entry->tight)
+ return False;
+ }
+ if (!entry || entry->name != table->name)
+ return False;
+ /* found one */
+ level--;
+ if ((!*names || entry->hasloose) &&
+ EnumLTable((LTable)entry, names, classes, level, closure))
+ return True;
+ if (entry->tight && entry == table->next && (entry = entry->next) &&
+ entry->name == table->name && (!*names || entry->hasloose))
+ return EnumLTable((LTable)entry, names, classes, level, closure);
+ return False;
+
+#undef ITIGHTLOOSE
+#undef ILOOSE
+}
+
+/* call the proc for every value in the database, arbitrary order.
+ * stop if the proc returns True.
+ */
+Bool XrmEnumerateDatabase(
+ XrmDatabase db,
+ XrmNameList names,
+ XrmClassList classes,
+ int mode,
+ DBEnumProc proc,
+ XPointer closure)
+{
+ XrmBinding bindings[MAXDBDEPTH+2];
+ XrmQuark quarks[MAXDBDEPTH+2];
+ register NTable table;
+ EClosureRec eclosure;
+ Bool retval = False;
+
+ if (!db)
+ return False;
+ _XLockMutex(&db->linfo);
+ eclosure.db = db;
+ eclosure.proc = proc;
+ eclosure.closure = closure;
+ eclosure.bindings = bindings;
+ eclosure.quarks = quarks;
+ eclosure.mode = mode;
+ table = db->table;
+ if (table && !table->leaf && !*names && mode == XrmEnumOneLevel)
+ table = table->next;
+ if (table) {
+ if (!table->leaf)
+ retval = EnumNTable(table, names, classes, 0, &eclosure);
+ else
+ retval = EnumLTable((LTable)table, names, classes, 0, &eclosure);
+ }
+ _XUnlockMutex(&db->linfo);
+ return retval;
+}
+
+static void PrintBindingQuarkList(
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ FILE *stream)
+{
+ Bool firstNameSeen;
+
+ for (firstNameSeen = False; *quarks; bindings++, quarks++) {
+ if (*bindings == XrmBindLoosely) {
+ (void) fprintf(stream, "*");
+ } else if (firstNameSeen) {
+ (void) fprintf(stream, ".");
+ }
+ firstNameSeen = True;
+ (void) fputs(XrmQuarkToString(*quarks), stream);
+ }
+}
+
+/* output out the entry in correct file syntax */
+/*ARGSUSED*/
+static Bool DumpEntry(
+ XrmDatabase *db,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ XrmRepresentation *type,
+ XrmValuePtr value,
+ XPointer data)
+{
+ FILE *stream = (FILE *)data;
+ register unsigned int i;
+ register char *s;
+ register char c;
+
+ if (*type != XrmQString)
+ (void) putc('!', stream);
+ PrintBindingQuarkList(bindings, quarks, stream);
+ s = value->addr;
+ i = value->size;
+ if (*type == XrmQString) {
+ (void) fputs(":\t", stream);
+ if (i)
+ i--;
+ }
+ else
+ (void) fprintf(stream, "=%s:\t", XrmRepresentationToString(*type));
+ if (i && (*s == ' ' || *s == '\t'))
+ (void) putc('\\', stream); /* preserve leading whitespace */
+ while (i--) {
+ c = *s++;
+ if (c == '\n') {
+ if (i)
+ (void) fputs("\\n\\\n", stream);
+ else
+ (void) fputs("\\n", stream);
+ } else if (c == '\\')
+ (void) fputs("\\\\", stream);
+ else if ((c < ' ' && c != '\t') ||
+ ((unsigned char)c >= 0x7f && (unsigned char)c < 0xa0))
+ (void) fprintf(stream, "\\%03o", (unsigned char)c);
+ else
+ (void) putc(c, stream);
+ }
+ (void) putc('\n', stream);
+ return ferror(stream) != 0;
+}
+
+#ifdef DEBUG
+
+void PrintTable(
+ NTable table,
+ FILE *file)
+{
+ XrmBinding bindings[MAXDBDEPTH+1];
+ XrmQuark quarks[MAXDBDEPTH+1];
+ EClosureRec closure;
+ XrmQuark empty = NULLQUARK;
+
+ closure.db = (XrmDatabase)NULL;
+ closure.proc = DumpEntry;
+ closure.closure = (XPointer)file;
+ closure.bindings = bindings;
+ closure.quarks = quarks;
+ closure.mode = XrmEnumAllLevels;
+ if (table->leaf)
+ EnumLTable((LTable)table, &empty, &empty, 0, &closure);
+ else
+ EnumNTable(table, &empty, &empty, 0, &closure);
+}
+
+#endif /* DEBUG */
+
+void
+XrmPutFileDatabase(
+ XrmDatabase db,
+ _Xconst char *fileName)
+{
+ FILE *file;
+ XrmQuark empty = NULLQUARK;
+
+ if (!db) return;
+ if (!(file = fopen(fileName, "w"))) return;
+ if (XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels,
+ DumpEntry, (XPointer) file))
+ unlink((char *)fileName);
+ fclose(file);
+}
+
+/* macros used in get/search functions */
+
+/* find entries named ename, leafness leaf, tight or loose, and call get */
+#define GTIGHTLOOSE(ename,looseleaf) \
+ NFIND(ename); \
+ if (entry) { \
+ if (leaf == entry->leaf) { \
+ if (!leaf && !entry->tight && entry->next && \
+ entry->next->name == q && entry->next->tight && \
+ entry->next->hasloose && \
+ looseleaf((LTable)entry->next, names+1, classes+1, closure)) \
+ return True; \
+ if ((*get)(entry, names+1, classes+1, closure)) \
+ return True; \
+ if (entry->tight && (entry = entry->next) && \
+ entry->name == q && leaf == entry->leaf && \
+ (*get)(entry, names+1, classes+1, closure)) \
+ return True; \
+ } else if (entry->leaf) { \
+ if (entry->hasloose && \
+ looseleaf((LTable)entry, names+1, classes+1, closure)) \
+ return True; \
+ if (entry->tight && (entry = entry->next) && \
+ entry->name == q && entry->hasloose && \
+ looseleaf((LTable)entry, names+1, classes+1, closure)) \
+ return True; \
+ } \
+ }
+
+/* find entries named ename, leafness leaf, loose only, and call get */
+#define GLOOSE(ename,looseleaf) \
+ NFIND(ename); \
+ if (entry && entry->tight && (entry = entry->next) && entry->name != q) \
+ entry = (NTable)NULL; \
+ if (entry) { \
+ if (leaf == entry->leaf) { \
+ if ((*get)(entry, names+1, classes+1, closure)) \
+ return True; \
+ } else if (entry->leaf && entry->hasloose) { \
+ if (looseleaf((LTable)entry, names+1, classes+1, closure)) \
+ return True; \
+ } \
+ }
+
+/* add tight/loose entry to the search list, return True if list is full */
+/*ARGSUSED*/
+static Bool AppendLEntry(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register SClosure closure)
+{
+ /* check for duplicate */
+ if (closure->idx >= 0 && closure->list[closure->idx] == table)
+ return False;
+ if (closure->idx == closure->limit)
+ return True;
+ /* append it */
+ closure->idx++;
+ closure->list[closure->idx] = table;
+ return False;
+}
+
+/* add loose entry to the search list, return True if list is full */
+/*ARGSUSED*/
+static Bool AppendLooseLEntry(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ register SClosure closure)
+{
+ /* check for duplicate */
+ if (closure->idx >= 0 && closure->list[closure->idx] == table)
+ return False;
+ if (closure->idx >= closure->limit - 1)
+ return True;
+ /* append it */
+ closure->idx++;
+ closure->list[closure->idx] = LOOSESEARCH;
+ closure->idx++;
+ closure->list[closure->idx] = table;
+ return False;
+}
+
+/* search for a leaf table */
+static Bool SearchNEntry(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ SClosure closure)
+{
+ register NTable entry;
+ register XrmQuark q;
+ register unsigned int leaf;
+ Bool (*get)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ SClosure closure);
+
+ if (names[1]) {
+ get = SearchNEntry; /* recurse */
+ leaf = 0;
+ } else {
+ get = (getNTableSProcp)AppendLEntry; /* bottom of recursion */
+ leaf = 1;
+ }
+ GTIGHTLOOSE(*names, AppendLooseLEntry); /* do name, tight and loose */
+ GTIGHTLOOSE(*classes, AppendLooseLEntry); /* do class, tight and loose */
+ if (table->hasany) {
+ GTIGHTLOOSE(XrmQANY, AppendLooseLEntry); /* do ANY, tight and loose */
+ }
+ if (table->hasloose) {
+ while (1) {
+ names++;
+ classes++;
+ if (!*names)
+ break;
+ if (!names[1]) {
+ get = (getNTableSProcp)AppendLEntry; /* bottom of recursion */
+ leaf = 1;
+ }
+ GLOOSE(*names, AppendLooseLEntry); /* loose names */
+ GLOOSE(*classes, AppendLooseLEntry); /* loose classes */
+ if (table->hasany) {
+ GLOOSE(XrmQANY, AppendLooseLEntry); /* loose ANY */
+ }
+ }
+ }
+ /* now look for matching leaf nodes */
+ entry = table->next;
+ if (!entry)
+ return False;
+ if (entry->leaf) {
+ if (entry->tight && !table->tight)
+ entry = entry->next;
+ } else {
+ entry = entry->next;
+ if (!entry || !entry->tight)
+ return False;
+ }
+ if (!entry || entry->name != table->name)
+ return False;
+ /* found one */
+ if (entry->hasloose &&
+ AppendLooseLEntry((LTable)entry, names, classes, closure))
+ return True;
+ if (entry->tight && entry == table->next && (entry = entry->next) &&
+ entry->name == table->name && entry->hasloose)
+ return AppendLooseLEntry((LTable)entry, names, classes, closure);
+ return False;
+}
+
+Bool XrmQGetSearchList(
+ XrmDatabase db,
+ XrmNameList names,
+ XrmClassList classes,
+ XrmSearchList searchList, /* RETURN */
+ int listLength)
+{
+ register NTable table;
+ SClosureRec closure;
+
+ if (listLength <= 0)
+ return False;
+ closure.list = (LTable *)searchList;
+ closure.idx = -1;
+ closure.limit = listLength - 2;
+ if (db) {
+ _XLockMutex(&db->linfo);
+ table = db->table;
+ if (*names) {
+ if (table && !table->leaf) {
+ if (SearchNEntry(table, names, classes, &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return False;
+ }
+ } else if (table && table->hasloose &&
+ AppendLooseLEntry((LTable)table, names, classes,
+ &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return False;
+ }
+ } else {
+ if (table && !table->leaf)
+ table = table->next;
+ if (table &&
+ AppendLEntry((LTable)table, names, classes, &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return False;
+ }
+ }
+ _XUnlockMutex(&db->linfo);
+ }
+ closure.list[closure.idx + 1] = (LTable)NULL;
+ return True;
+}
+
+Bool XrmQGetSearchResource(
+ XrmSearchList searchList,
+ register XrmName name,
+ register XrmClass class,
+ XrmRepresentation *pType, /* RETURN */
+ XrmValue *pValue) /* RETURN */
+{
+ register LTable *list;
+ register LTable table;
+ register VEntry entry = NULL;
+ int flags;
+
+/* find tight or loose entry */
+#define VTIGHTLOOSE(q) \
+ entry = LeafHash(table, q); \
+ while (entry && entry->name != q) \
+ entry = entry->next; \
+ if (entry) \
+ break
+
+/* find loose entry */
+#define VLOOSE(q) \
+ entry = LeafHash(table, q); \
+ while (entry && entry->name != q) \
+ entry = entry->next; \
+ if (entry) { \
+ if (!entry->tight) \
+ break; \
+ if ((entry = entry->next) && entry->name == q) \
+ break; \
+ }
+
+ list = (LTable *)searchList;
+ /* figure out which combination of name and class we need to search for */
+ flags = 0;
+ if (IsResourceQuark(name))
+ flags = 2;
+ if (IsResourceQuark(class))
+ flags |= 1;
+ if (!flags) {
+ /* neither name nor class has ever been used to name a resource */
+ table = (LTable)NULL;
+ } else if (flags == 3) {
+ /* both name and class */
+ while ((table = *list++)) {
+ if (table != LOOSESEARCH) {
+ VTIGHTLOOSE(name); /* do name, tight and loose */
+ VTIGHTLOOSE(class); /* do class, tight and loose */
+ } else {
+ table = *list++;
+ VLOOSE(name); /* do name, loose only */
+ VLOOSE(class); /* do class, loose only */
+ }
+ }
+ } else {
+ /* just one of name or class */
+ if (flags == 1)
+ name = class;
+ while ((table = *list++)) {
+ if (table != LOOSESEARCH) {
+ VTIGHTLOOSE(name); /* tight and loose */
+ } else {
+ table = *list++;
+ VLOOSE(name); /* loose only */
+ }
+ }
+ }
+ if (table) {
+ /* found a match */
+ if (entry->string) {
+ *pType = XrmQString;
+ pValue->addr = StringValue(entry);
+ } else {
+ *pType = RepType(entry);
+ pValue->addr = DataValue(entry);
+ }
+ pValue->size = entry->size;
+ return True;
+ }
+ *pType = NULLQUARK;
+ pValue->addr = (XPointer)NULL;
+ pValue->size = 0;
+ return False;
+
+#undef VTIGHTLOOSE
+#undef VLOOSE
+}
+
+/* look for a tight/loose value */
+static Bool GetVEntry(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure)
+{
+ register VEntry entry;
+ register XrmQuark q;
+
+ /* try name first */
+ q = *names;
+ entry = LeafHash(table, q);
+ while (entry && entry->name != q)
+ entry = entry->next;
+ if (!entry) {
+ /* not found, try class */
+ q = *classes;
+ entry = LeafHash(table, q);
+ while (entry && entry->name != q)
+ entry = entry->next;
+ if (!entry)
+ return False;
+ }
+ if (entry->string) {
+ *closure->type = XrmQString;
+ closure->value->addr = StringValue(entry);
+ } else {
+ *closure->type = RepType(entry);
+ closure->value->addr = DataValue(entry);
+ }
+ closure->value->size = entry->size;
+ return True;
+}
+
+/* look for a loose value */
+static Bool GetLooseVEntry(
+ LTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure)
+{
+ register VEntry entry;
+ register XrmQuark q;
+
+#define VLOOSE(ename) \
+ q = ename; \
+ entry = LeafHash(table, q); \
+ while (entry && entry->name != q) \
+ entry = entry->next; \
+ if (entry && entry->tight && (entry = entry->next) && entry->name != q) \
+ entry = (VEntry)NULL;
+
+ /* bump to last component */
+ while (names[1]) {
+ names++;
+ classes++;
+ }
+ VLOOSE(*names); /* do name, loose only */
+ if (!entry) {
+ VLOOSE(*classes); /* do class, loose only */
+ if (!entry)
+ return False;
+ }
+ if (entry->string) {
+ *closure->type = XrmQString;
+ closure->value->addr = StringValue(entry);
+ } else {
+ *closure->type = RepType(entry);
+ closure->value->addr = DataValue(entry);
+ }
+ closure->value->size = entry->size;
+ return True;
+
+#undef VLOOSE
+}
+
+/* recursive search for a value */
+static Bool GetNEntry(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure)
+{
+ register NTable entry;
+ register XrmQuark q;
+ register unsigned int leaf;
+ Bool (*get)(
+ NTable table,
+ XrmNameList names,
+ XrmClassList classes,
+ VClosure closure);
+ NTable otable;
+
+ if (names[2]) {
+ get = GetNEntry; /* recurse */
+ leaf = 0;
+ } else {
+ get = (getNTableVProcp)GetVEntry; /* bottom of recursion */
+ leaf = 1;
+ }
+ GTIGHTLOOSE(*names, GetLooseVEntry); /* do name, tight and loose */
+ GTIGHTLOOSE(*classes, GetLooseVEntry); /* do class, tight and loose */
+ if (table->hasany) {
+ GTIGHTLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, tight and loose */
+ }
+ if (table->hasloose) {
+ while (1) {
+ names++;
+ classes++;
+ if (!names[1])
+ break;
+ if (!names[2]) {
+ get = (getNTableVProcp)GetVEntry; /* bottom of recursion */
+ leaf = 1;
+ }
+ GLOOSE(*names, GetLooseVEntry); /* do name, loose only */
+ GLOOSE(*classes, GetLooseVEntry); /* do class, loose only */
+ if (table->hasany) {
+ GLOOSE(XrmQANY, GetLooseVEntry); /* do ANY, loose only */
+ }
+ }
+ }
+ /* look for matching leaf tables */
+ otable = table;
+ table = table->next;
+ if (!table)
+ return False;
+ if (table->leaf) {
+ if (table->tight && !otable->tight)
+ table = table->next;
+ } else {
+ table = table->next;
+ if (!table || !table->tight)
+ return False;
+ }
+ if (!table || table->name != otable->name)
+ return False;
+ /* found one */
+ if (table->hasloose &&
+ GetLooseVEntry((LTable)table, names, classes, closure))
+ return True;
+ if (table->tight && table == otable->next) {
+ table = table->next;
+ if (table && table->name == otable->name && table->hasloose)
+ return GetLooseVEntry((LTable)table, names, classes, closure);
+ }
+ return False;
+}
+
+Bool XrmQGetResource(
+ XrmDatabase db,
+ XrmNameList names,
+ XrmClassList classes,
+ XrmRepresentation *pType, /* RETURN */
+ XrmValuePtr pValue) /* RETURN */
+{
+ register NTable table;
+ VClosureRec closure;
+
+ if (db && *names) {
+ _XLockMutex(&db->linfo);
+ closure.type = pType;
+ closure.value = pValue;
+ table = db->table;
+ if (names[1]) {
+ if (table && !table->leaf) {
+ if (GetNEntry(table, names, classes, &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return True;
+ }
+ } else if (table && table->hasloose &&
+ GetLooseVEntry((LTable)table, names, classes, &closure)) {
+ _XUnlockMutex (&db->linfo);
+ return True;
+ }
+ } else {
+ if (table && !table->leaf)
+ table = table->next;
+ if (table && GetVEntry((LTable)table, names, classes, &closure)) {
+ _XUnlockMutex(&db->linfo);
+ return True;
+ }
+ }
+ _XUnlockMutex(&db->linfo);
+ }
+ *pType = NULLQUARK;
+ pValue->addr = (XPointer)NULL;
+ pValue->size = 0;
+ return False;
+}
+
+Bool
+XrmGetResource(XrmDatabase db, _Xconst char *name_str, _Xconst char *class_str,
+ XrmString *pType_str, XrmValuePtr pValue)
+{
+ XrmName names[MAXDBDEPTH+1];
+ XrmClass classes[MAXDBDEPTH+1];
+ XrmRepresentation fromType;
+ Bool result;
+
+ XrmStringToNameList(name_str, names);
+ XrmStringToClassList(class_str, classes);
+ result = XrmQGetResource(db, names, classes, &fromType, pValue);
+ (*pType_str) = XrmQuarkToString(fromType);
+ return result;
+}
+
+/* destroy all values, plus table itself */
+static void DestroyLTable(
+ LTable table)
+{
+ register int i;
+ register VEntry *buckets;
+ register VEntry entry, next;
+
+ buckets = table->buckets;
+ for (i = table->table.mask; i >= 0; i--, buckets++) {
+ for (next = *buckets; (entry = next); ) {
+ next = entry->next;
+ Xfree((char *)entry);
+ }
+ }
+ Xfree((char *)table->buckets);
+ Xfree((char *)table);
+}
+
+/* destroy all contained tables, plus table itself */
+static void DestroyNTable(
+ NTable table)
+{
+ register int i;
+ register NTable *buckets;
+ register NTable entry, next;
+
+ buckets = NodeBuckets(table);
+ for (i = table->mask; i >= 0; i--, buckets++) {
+ for (next = *buckets; (entry = next); ) {
+ next = entry->next;
+ if (entry->leaf)
+ DestroyLTable((LTable)entry);
+ else
+ DestroyNTable(entry);
+ }
+ }
+ Xfree((char *)table);
+}
+
+const char *
+XrmLocaleOfDatabase(
+ XrmDatabase db)
+{
+ const char* retval;
+ _XLockMutex(&db->linfo);
+ retval = (*db->methods->lcname)(db->mbstate);
+ _XUnlockMutex(&db->linfo);
+ return retval;
+}
+
+void XrmDestroyDatabase(
+ XrmDatabase db)
+{
+ register NTable table, next;
+
+ if (db) {
+ _XLockMutex(&db->linfo);
+ for (next = db->table; (table = next); ) {
+ next = table->next;
+ if (table->leaf)
+ DestroyLTable((LTable)table);
+ else
+ DestroyNTable(table);
+ }
+ _XUnlockMutex(&db->linfo);
+ _XFreeMutex(&db->linfo);
+ (*db->methods->destroy)(db->mbstate);
+ Xfree((char *)db);
+ }
+}
diff --git a/libX11/src/config.h b/libX11/src/config.h
new file mode 100644
index 000000000..abbac6e3b
--- /dev/null
+++ b/libX11/src/config.h
@@ -0,0 +1,243 @@
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if `struct sockaddr_in' has a `sin_len' member */
+/* #undef BSD44SOCKETS */
+
+/* Include compose table cache support */
+#define COMPOSECACHE 1
+
+/* Has getresuid() & getresgid() functions */
+/* #undef HASGETRESUID */
+
+/* Has issetugid() function */
+/* #undef HASSETUGID */
+
+/* Has shm*() functions */
+//MH#define HAS_SHM 1
+
+/* Define to 1 if you have the `authdes_create' function. */
+/* #undef HAVE_AUTHDES_CREATE */
+
+/* Define to 1 if you have the `authdes_seccreate' function. */
+/* #undef HAVE_AUTHDES_SECCREATE */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <endian.h> header file. */
+#define HAVE_ENDIAN_H 1
+
+/* Use dlopen to load shared libraries */
+#define HAVE_DLOPEN 1
+
+/* Define to 1 if you have the <dl.h> header file. */
+/* #undef HAVE_DL_H */
+
+/* Define to 1 if you have the `getpagesize' function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* launchd support available */
+/* #undef HAVE_LAUNCHD */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `poll' function. */
+#define HAVE_POLL 1
+
+/* Define to 1 if you have a working `mmap' system call. */
+#define HAVE_MMAP 1
+
+/* Use shl_load to load shared libraries */
+/* #undef HAVE_SHL_LOAD */
+
+/* Define to 1 if the system has the type `socklen_t'. */
+#define HAVE_SOCKLEN_T 0
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the `strtol' function. */
+#define HAVE_STRTOL 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Support IPv6 for TCP connections */
+/* #undef IPv6 */
+
+/* Support dynamically loaded font modules */
+#define LOADABLEFONTS 1
+
+/* Support os-specific local connections */
+/* #undef LOCALCONN */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Disable XLOCALEDIR environment variable */
+#define NO_XLOCALEDIR 1
+
+/* Name of package */
+#define PACKAGE "libX11"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://bugs.freedesktop.org/enter_bug.cgi?product=xorg"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libX11"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libX11 1.1.5"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libX11"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.1.5"
+
+/* Major version of this package */
+#define PACKAGE_VERSION_MAJOR 1
+
+/* Minor version of this package */
+#define PACKAGE_VERSION_MINOR 1
+
+/* Patch version of this package */
+#define PACKAGE_VERSION_PATCHLEVEL 5
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+/* #undef RETSIGTYPE */
+
+/* Support Secure RPC ("SUN-DES-1") authentication for X11 clients */
+/* #undef SECURE_RPC */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Support TCP socket connections */
+#define TCPCONN 1
+
+/* launchd support available */
+/* #undef TRANS_REOPEN */
+
+/* Support UNIX socket connections */
+#define UNIXCONN 1
+
+/* Split some i18n functions into loadable modules */
+/* #undef USE_DYNAMIC_LC */
+
+/* Use the X cursor library to load cursors */
+#define USE_DYNAMIC_XCURSOR 1
+
+/* poll() function is available */
+#define USE_POLL 1
+
+/* Use XCB for low-level protocol implementation */
+#define USE_XCB 1
+
+/* Version number of package */
+#define VERSION "1.1.5"
+
+/* Support bdf format bitmap font files */
+#define XFONT_BDFFORMAT 1
+
+/* Location of libX11 data */
+#define X11_DATADIR "/usr/share/X11"
+
+/* Location of libX11 library data */
+#define X11_LIBDIR "/usr/lib/X11"
+
+/* Include support for XCMS */
+#define XCMS 1
+
+/* Location of error message database */
+#define XERRORDB "XErrorDB"
+
+/* Enable XF86BIGFONT extension */
+/* #undef XF86BIGFONT */
+
+/* Use XKB */
+#define XKB 1
+
+/* Location of keysym database */
+#define XKEYSYMDB "XKeysymDB"
+
+/* support for X Locales */
+#define XLOCALE 1
+
+/* Location of libX11 locale data */
+#define XLOCALEDATADIR "locale"
+
+/* Location of libX11 locale data */
+#define XLOCALEDIR "locale"
+
+/* Location of libX11 locale libraries */
+#define XLOCALELIBDIR "locale"
+
+/* Whether libX11 is compiled with thread support */
+#define XTHREADS /**/
+
+/* Whether libX11 needs to use MT safe API's */
+#define XUSE_MTSAFE_API /**/
+
+/* Enable GNU and other extensions to the C environment for glibc */
+/* #undef _GNU_SOURCE */
+
+/* Support bitmap font files */
+#define XFONT_BITMAP 1
+
+/* Support built-in fonts */
+#define XFONT_BUILTINS 1
+
+/* Support the X Font Services Protocol */
+#define XFONT_FC 1
+
+/* Support fonts in files */
+#define XFONT_FONTFILE 1
+
+/* Support FreeType rasterizer for nearly all font file formats */
+#define XFONT_FREETYPE 1
+
+/* Support pcf format bitmap font files */
+#define XFONT_PCFFORMAT 1
+
+/* Support snf format bitmap font files */
+#define XFONT_SNFFORMAT 1
+
+/* Support Speedo font files */
+#define XFONT_SPEEDO 1
+
+/* Support IBM Type 1 rasterizer for Type1 font files */
+#define XFONT_TYPE1 1
+
+/* Support bzip2 for bitmap fonts */
+/* #undef X_BZIP2_FONT_COMPRESSION */
+
+/* Support gzip for bitmap fonts */
+#define X_GZIP_FONT_COMPRESSION 1
+
+#define INCL_WINSOCK_API_TYPEDEFS 1
+#include <X11/Xwinsock.h>
+#include <X11/Xwindows.h>
diff --git a/libX11/src/genhextable.py b/libX11/src/genhextable.py
new file mode 100644
index 000000000..2a45a9e83
--- /dev/null
+++ b/libX11/src/genhextable.py
@@ -0,0 +1,39 @@
+import sys
+
+HexTable={
+ '0' : 0, '1' : 1,
+ '2' : 2, '3' : 3,
+ '4' : 4, '5' : 5,
+ '6' : 6, '7' : 7,
+ '8' : 8, '9' : 9,
+ 'A' : 10, 'B' : 11,
+ 'C' : 12, 'D' : 13,
+ 'E' : 14, 'F' : 15,
+ 'a' : 10, 'b' : 11,
+ 'c' : 12, 'd' : 13,
+ 'e' : 14, 'f' : 15,
+
+ ' ' : -1, ',' : -1,
+ '}' : -1, '\n' : -1,
+ '\t' : -1
+}
+
+OutHexTable=[0]*256
+
+for Char,Val in HexTable.iteritems():
+ OutHexTable[ord(Char)]=Val
+
+print "static const short hexTable[256] = {"
+i=0
+for Item in OutHexTable:
+ if i==0:
+ PreFix=" "
+ elif i%16 == 0:
+ PreFix="\n ,"
+ else:
+ PreFix=", "
+ i+=1
+ Val="%d"%Item
+ if len(Val)==1: Val = " "+Val
+ sys.stdout.write("%s%s"%(PreFix,Val))
+print "\n};" \ No newline at end of file
diff --git a/libX11/src/makefile b/libX11/src/makefile
new file mode 100644
index 000000000..e89f573c7
--- /dev/null
+++ b/libX11/src/makefile
@@ -0,0 +1,278 @@
+LIBRARY=libx11
+
+DEFINES += X11_t TRANS_CLIENT
+
+CSRCS = \
+ AllCells.c \
+ AllowEv.c \
+ AllPlanes.c \
+ AutoRep.c \
+ Backgnd.c \
+ BdrWidth.c \
+ Bell.c \
+ Border.c \
+ ChAccCon.c \
+ ChActPGb.c \
+ ChClMode.c \
+ ChCmap.c \
+ ChGC.c \
+ ChKeyCon.c \
+ ChkIfEv.c \
+ ChkMaskEv.c \
+ ChkTypEv.c \
+ ChkTypWEv.c \
+ ChkWinEv.c \
+ ChPntCon.c \
+ ChProp.c \
+ ChSaveSet.c \
+ ChWAttrs.c \
+ ChWindow.c \
+ CirWin.c \
+ CirWinDn.c \
+ CirWinUp.c \
+ ClDisplay.c \
+ ClearArea.c \
+ Clear.c \
+ ConfWind.c \
+ Context.c \
+ ConvSel.c \
+ CopyArea.c \
+ CopyCmap.c \
+ CopyGC.c \
+ CopyPlane.c \
+ CrBFData.c \
+ CrCmap.c \
+ CrCursor.c \
+ CrGC.c \
+ CrGlCur.c \
+ CrPFBData.c \
+ CrPixmap.c \
+ CrWindow.c \
+ Cursor.c \
+ DefCursor.c \
+ DelProp.c \
+ Depths.c \
+ DestSubs.c \
+ DestWind.c \
+ DisName.c \
+ DrArc.c \
+ DrArcs.c \
+ DrLine.c \
+ DrLines.c \
+ DrPoint.c \
+ DrPoints.c \
+ DrRect.c \
+ DrRects.c \
+ DrSegs.c \
+ ErrDes.c \
+ ErrHndlr.c \
+ evtomask.c \
+ EvToWire.c \
+ FetchName.c \
+ FillArc.c \
+ FillArcs.c \
+ FillPoly.c \
+ FillRct.c \
+ FillRcts.c \
+ FilterEv.c \
+ Flush.c \
+ Font.c \
+ FontInfo.c \
+ FontNames.c \
+ FreeCmap.c \
+ FreeCols.c \
+ FreeCurs.c \
+ FreeEData.c \
+ FreeEventData.c \
+ FreeGC.c \
+ FreePix.c \
+ FSSaver.c \
+ FSWrap.c \
+ GCMisc.c \
+ Geom.c \
+ GetAtomNm.c \
+ GetColor.c \
+ GetDflt.c \
+ GetEventData.c \
+ GetFPath.c \
+ GetFProp.c \
+ GetGCVals.c \
+ GetGeom.c \
+ GetHColor.c \
+ GetHints.c \
+ GetIFocus.c \
+ GetImage.c \
+ GetKCnt.c \
+ GetMoEv.c \
+ GetNrmHint.c \
+ GetPCnt.c \
+ GetPntMap.c \
+ GetProp.c \
+ GetRGBCMap.c \
+ GetSOwner.c \
+ GetSSaver.c \
+ GetStCmap.c \
+ GetTxtProp.c \
+ GetWAttrs.c \
+ GetWMCMapW.c \
+ GetWMProto.c \
+ globals.c \
+ GrButton.c \
+ GrKeybd.c \
+ GrKey.c \
+ GrPointer.c \
+ GrServer.c \
+ Host.c \
+ Iconify.c \
+ IfEvent.c \
+ imConv.c \
+ ImText16.c \
+ ImText.c \
+ ImUtil.c \
+ InitExt.c \
+ InsCmap.c \
+ IntAtom.c \
+ KeyBind.c \
+ KeysymStr.c \
+ KillCl.c \
+ LiHosts.c \
+ LiICmaps.c \
+ LiProps.c \
+ ListExt.c \
+ LoadFont.c \
+ LockDis.c \
+ locking.c \
+ LookupCol.c \
+ LowerWin.c \
+ Macros.c \
+ MapRaised.c \
+ MapSubs.c \
+ MapWindow.c \
+ MaskEvent.c \
+ Misc.c \
+ ModMap.c \
+ MoveWin.c \
+ NextEvent.c \
+ OCWrap.c \
+ OMWrap.c \
+ OpenDis.c \
+ ParseCmd.c \
+ ParseCol.c \
+ ParseGeom.c \
+ PeekEvent.c \
+ PeekIfEv.c \
+ Pending.c \
+ PixFormats.c \
+ PmapBgnd.c \
+ PmapBord.c \
+ PolyReg.c \
+ PolyTxt16.c \
+ PolyTxt.c \
+ PropAlloc.c \
+ PutBEvent.c \
+ PutImage.c \
+ Quarks.c \
+ QuBest.c \
+ QuColor.c \
+ QuColors.c \
+ QuCurShp.c \
+ QuExt.c \
+ QuKeybd.c \
+ QuPntr.c \
+ QuStipShp.c \
+ QuTextE16.c \
+ QuTextExt.c \
+ QuTileShp.c \
+ QuTree.c \
+ RaiseWin.c \
+ RdBitF.c \
+ RecolorC.c \
+ ReconfWin.c \
+ ReconfWM.c \
+ Region.c \
+ RegstFlt.c \
+ RepWindow.c \
+ RestackWs.c \
+ RotProp.c \
+ ScrResStr.c \
+ SelInput.c \
+ SendEvent.c \
+ SetBack.c \
+ SetClMask.c \
+ SetClOrig.c \
+ SetCRects.c \
+ SetDashes.c \
+ SetFont.c \
+ SetFore.c \
+ SetFPath.c \
+ SetFunc.c \
+ SetHints.c \
+ SetIFocus.c \
+ SetLocale.c \
+ SetLStyle.c \
+ SetNrmHint.c \
+ SetPMask.c \
+ SetPntMap.c \
+ SetRGBCMap.c \
+ SetSOwner.c \
+ SetSSaver.c \
+ SetState.c \
+ SetStCmap.c \
+ SetStip.c \
+ SetTile.c \
+ SetTSOrig.c \
+ SetTxtProp.c \
+ SetWMCMapW.c \
+ SetWMProto.c \
+ StBytes.c \
+ StColor.c \
+ StColors.c \
+ StName.c \
+ StNColor.c \
+ StrKeysym.c \
+ StrToText.c \
+ Sync.c \
+ Synchro.c \
+ Text16.c \
+ Text.c \
+ TextExt16.c \
+ TextExt.c \
+ TextToStr.c \
+ TrCoords.c \
+ UndefCurs.c \
+ UngrabBut.c \
+ UngrabKbd.c \
+ UngrabKey.c \
+ UngrabPtr.c \
+ UngrabSvr.c \
+ UninsCmap.c \
+ UnldFont.c \
+ UnmapSubs.c \
+ UnmapWin.c \
+ VisUtil.c \
+ WarpPtr.c \
+ Window.c \
+ WinEvent.c \
+ Withdraw.c \
+ WMGeom.c \
+ WMProps.c \
+ WrBitF.c \
+ xcb_disp.c \
+ xcb_io.c \
+ XlibAsync.c \
+ XlibInt.c \
+ Xrm.c \
+
+
+INCLUDES := . xcms xlibi18n xkb $(MHMAKECONF)\X11 $(OBJDIR) $(INCLUDES)
+
+KEYSYMDEF = $(MHMAKECONF)/X11/keysymdef.h
+
+$(OBJDIR)\$(LIBRARY).lib: $(OBJDIR)\ks_tables.h
+
+load_makefile util\makefile MAKESERVER=$(MAKESERVER) DEBUG=$(DEBUG)
+
+$(OBJDIR)\ks_tables.h: $(KEYSYMDEF) util\$(OBJDIR)\makekeys.exe
+ util\$(OBJDIR)\makekeys $(relpath $<) > $(relpath $@)
+
+
diff --git a/libX11/src/util/makefile b/libX11/src/util/makefile
new file mode 100644
index 000000000..27da68335
--- /dev/null
+++ b/libX11/src/util/makefile
@@ -0,0 +1,6 @@
+TTYAPP=makekeys
+
+DEFINES += X11_t TRANS_CLIENT
+
+CSRCS = makekeys.c
+
diff --git a/libX11/src/util/makekeys.c b/libX11/src/util/makekeys.c
index 85ce75268..fb758b9cb 100644
--- a/libX11/src/util/makekeys.c
+++ b/libX11/src/util/makekeys.c
@@ -33,6 +33,7 @@ from The Open Group.
#include <X11/keysymdef.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
typedef unsigned long Signature;
@@ -157,7 +158,7 @@ main(int argc, char *argv[])
num_found = 0;
for (z = ksnum; z < KTNUM; z++) {
max_rehash = 0;
- for (name = tab, i = z; --i >= 0;)
+ for (name = &tab[0], i = z; --i >= 0;)
*name++ = 0;
for (i = 0; i < ksnum; i++) {
name = info[i].name;
diff --git a/libX11/src/xcb_io.c b/libX11/src/xcb_io.c
index 13c709f2f..6a2172bdb 100644
--- a/libX11/src/xcb_io.c
+++ b/libX11/src/xcb_io.c
@@ -21,6 +21,9 @@
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
+#include <sys/time.h>
+
+#include <X11/Xtrans/Xtrans.h>
static void return_socket(void *closure)
{
diff --git a/libX11/src/xcms/config.h b/libX11/src/xcms/config.h
new file mode 100644
index 000000000..a01921855
--- /dev/null
+++ b/libX11/src/xcms/config.h
@@ -0,0 +1,2 @@
+#include <string.h>
+#include <unistd.h>
diff --git a/libX11/src/xcms/makefile b/libX11/src/xcms/makefile
new file mode 100644
index 000000000..00fab124a
--- /dev/null
+++ b/libX11/src/xcms/makefile
@@ -0,0 +1,71 @@
+LIBRARY = libxcms
+
+DEFINES += HAVE_CONFIG_H
+
+CSRCS = \
+ AddDIC.c \
+ AddSF.c \
+ CCC.c \
+ CvColW.c \
+ CvCols.c \
+ HVC.c \
+ HVCGcC.c \
+ HVCGcV.c \
+ HVCGcVC.c \
+ HVCMnV.c \
+ HVCMxC.c \
+ HVCMxV.c \
+ HVCMxVC.c \
+ HVCMxVs.c \
+ HVCWpAj.c \
+ IdOfPr.c \
+ LRGB.c \
+ Lab.c \
+ LabGcC.c \
+ LabGcL.c \
+ LabGcLC.c \
+ LabMnL.c \
+ LabMxC.c \
+ LabMxL.c \
+ LabMxLC.c \
+ LabWpAj.c \
+ Luv.c \
+ LuvGcC.c \
+ LuvGcL.c \
+ LuvGcLC.c \
+ LuvMnL.c \
+ LuvMxC.c \
+ LuvMxL.c \
+ LuvMxLC.c \
+ LuvWpAj.c \
+ OfCCC.c \
+ PrOfId.c \
+ QBlack.c \
+ QBlue.c \
+ QGreen.c \
+ QRed.c \
+ QWhite.c \
+ QuCol.c \
+ QuCols.c \
+ SetCCC.c \
+ SetGetCols.c \
+ StCol.c \
+ StCols.c \
+ UNDEFINED.c \
+ XRGB.c \
+ XYZ.c \
+ cmsAllCol.c \
+ cmsAllNCol.c \
+ cmsCmap.c \
+ cmsColNm.c \
+ cmsGlobls.c \
+ cmsInt.c \
+ cmsLkCol.c \
+ cmsMath.c \
+ cmsProp.c \
+ cmsTrig.c \
+ uvY.c \
+ xyY.c
+
+INCLUDES += ..\..\include\X11 ..\..\src\xlibi18n ..\..\src
+
diff --git a/libX11/src/xkb/Makefile b/libX11/src/xkb/Makefile
new file mode 100644
index 000000000..0f6b7e859
--- /dev/null
+++ b/libX11/src/xkb/Makefile
@@ -0,0 +1,27 @@
+LIBRARY = libxkb
+
+CSRCS = \
+ XKB.c \
+ XKBBind.c \
+ XKBCompat.c \
+ XKBCtrls.c \
+ XKBCvt.c \
+ XKBGetMap.c \
+ XKBGetByName.c \
+ XKBNames.c \
+ XKBRdBuf.c \
+ XKBSetMap.c \
+ XKBUse.c \
+ XKBleds.c \
+ XKBBell.c \
+ XKBGeom.c \
+ XKBSetGeom.c \
+ XKBExtDev.c \
+ XKBList.c \
+ XKBMisc.c \
+ XKBMAlloc.c \
+ XKBGAlloc.c \
+ XKBAlloc.c
+
+INCLUDES += ..\..\include\X11 ..\..\src\xlibi18n
+
diff --git a/libX11/src/xkb/XKB.c b/libX11/src/xkb/XKB.c
index f926cb997..374e27d2d 100644
--- a/libX11/src/xkb/XKB.c
+++ b/libX11/src/xkb/XKB.c
@@ -28,6 +28,11 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#endif
#include <stdio.h>
+
+#ifdef XKB_IN_SERVER
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#endif
+
#include "Xlibint.h"
#include <X11/extensions/XKBproto.h>
#include "XKBlibint.h"
diff --git a/libX11/src/xkb/XKBBind.c b/libX11/src/xkb/XKBBind.c
index 2e4b1fe68..4904b461f 100644
--- a/libX11/src/xkb/XKBBind.c
+++ b/libX11/src/xkb/XKBBind.c
@@ -31,6 +31,34 @@ from The Open Group.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+
+#ifdef XKB_IN_SERVER
+#define XkbAllocClientMap SrvXkbAllocClientMap
+#define XkbAllocServerMap SrvXkbAllocServerMap
+#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey
+#define XkbCopyKeyTypes SrvXkbCopyKeyTypes
+#define XkbFreeClientMap SrvXkbFreeClientMap
+#define XkbFreeServerMap SrvXkbFreeServerMap
+#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols
+#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey
+#define XkbResizeKeyActions SrvXkbResizeKeyActions
+#define XkbResizeKeySyms SrvXkbResizeKeySyms
+#define XkbResizeKeyType SrvXkbResizeKeyType
+#define XkbAllocCompatMap SrvXkbAllocCompatMap
+#define XkbAllocControls SrvXkbAllocControls
+#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps
+#define XkbAllocKeyboard SrvXkbAllocKeyboard
+#define XkbAllocNames SrvXkbAllocNames
+#define XkbFreeCompatMap SrvXkbFreeCompatMap
+#define XkbFreeKeyboard SrvXkbFreeKeyboard
+#define XkbFreeNames SrvXkbFreeNames
+#define XkbLatchModifiers SrvXkbLatchModifiers
+#define XkbLatchGroup SrvXkbLatchGroup
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange
+#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges
+#endif
+
#include "XKBlib.h"
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
diff --git a/libX11/src/xkb/XKBGeom.c b/libX11/src/xkb/XKBGeom.c
index 2572b9964..065285fcb 100644
--- a/libX11/src/xkb/XKBGeom.c
+++ b/libX11/src/xkb/XKBGeom.c
@@ -37,12 +37,8 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <X11/extensions/XKBproto.h>
#include "XKBlibint.h"
-#ifndef MINSHORT
#define MINSHORT -32768
-#endif
-#ifndef MAXSHORT
#define MAXSHORT 32767
-#endif
/***====================================================================***/
diff --git a/libX11/src/xkb/XKBGetMap.c b/libX11/src/xkb/XKBGetMap.c
index eff088341..96370c6d3 100644
--- a/libX11/src/xkb/XKBGetMap.c
+++ b/libX11/src/xkb/XKBGetMap.c
@@ -28,6 +28,34 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+
+#ifdef XKB_IN_SERVER
+#define XkbAllocClientMap SrvXkbAllocClientMap
+#define XkbAllocServerMap SrvXkbAllocServerMap
+#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey
+#define XkbCopyKeyTypes SrvXkbCopyKeyTypes
+#define XkbFreeClientMap SrvXkbFreeClientMap
+#define XkbFreeServerMap SrvXkbFreeServerMap
+#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols
+#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey
+#define XkbResizeKeyActions SrvXkbResizeKeyActions
+#define XkbResizeKeySyms SrvXkbResizeKeySyms
+#define XkbResizeKeyType SrvXkbResizeKeyType
+#define XkbAllocCompatMap SrvXkbAllocCompatMap
+#define XkbAllocControls SrvXkbAllocControls
+#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps
+#define XkbAllocKeyboard SrvXkbAllocKeyboard
+#define XkbAllocNames SrvXkbAllocNames
+#define XkbFreeCompatMap SrvXkbFreeCompatMap
+#define XkbFreeKeyboard SrvXkbFreeKeyboard
+#define XkbFreeNames SrvXkbFreeNames
+#define XkbLatchModifiers SrvXkbLatchModifiers
+#define XkbLatchGroup SrvXkbLatchGroup
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange
+#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges
+#endif
+
#include "Xlibint.h"
#include <X11/extensions/XKBproto.h>
#include "XKBlibint.h"
diff --git a/libX11/src/xkb/XKBMisc.c b/libX11/src/xkb/XKBMisc.c
index 4aa1f733a..ac1e8c062 100644
--- a/libX11/src/xkb/XKBMisc.c
+++ b/libX11/src/xkb/XKBMisc.c
@@ -42,6 +42,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <stdio.h>
#include <X11/X.h>
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
#include <X11/Xproto.h>
#include "misc.h"
#include "inputstr.h"
diff --git a/libX11/src/xkb/XKBSetGeom.c b/libX11/src/xkb/XKBSetGeom.c
index 439b75e01..5b9f5887c 100644
--- a/libX11/src/xkb/XKBSetGeom.c
+++ b/libX11/src/xkb/XKBSetGeom.c
@@ -36,12 +36,8 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <X11/extensions/XKBgeom.h>
#include <X11/extensions/XKBproto.h>
-#ifndef MINSHORT
#define MINSHORT -32768
-#endif
-#ifndef MAXSHORT
#define MAXSHORT 32767
-#endif
/***====================================================================***/
diff --git a/libX11/src/xkb/XKBUse.c b/libX11/src/xkb/XKBUse.c
index efca018f6..a16d6963a 100644
--- a/libX11/src/xkb/XKBUse.c
+++ b/libX11/src/xkb/XKBUse.c
@@ -29,6 +29,34 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif
#include <stdio.h>
#include <ctype.h>
+
+#ifdef XKB_IN_SERVER
+#define XkbAllocClientMap SrvXkbAllocClientMap
+#define XkbAllocServerMap SrvXkbAllocServerMap
+#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey
+#define XkbCopyKeyTypes SrvXkbCopyKeyTypes
+#define XkbFreeClientMap SrvXkbFreeClientMap
+#define XkbFreeServerMap SrvXkbFreeServerMap
+#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols
+#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey
+#define XkbResizeKeyActions SrvXkbResizeKeyActions
+#define XkbResizeKeySyms SrvXkbResizeKeySyms
+#define XkbResizeKeyType SrvXkbResizeKeyType
+#define XkbAllocCompatMap SrvXkbAllocCompatMap
+#define XkbAllocControls SrvXkbAllocControls
+#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps
+#define XkbAllocKeyboard SrvXkbAllocKeyboard
+#define XkbAllocNames SrvXkbAllocNames
+#define XkbFreeCompatMap SrvXkbFreeCompatMap
+#define XkbFreeKeyboard SrvXkbFreeKeyboard
+#define XkbFreeNames SrvXkbFreeNames
+#define XkbLatchModifiers SrvXkbLatchModifiers
+#define XkbLatchGroup SrvXkbLatchGroup
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange
+#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges
+#endif
+
#include "Xlibint.h"
#include <X11/extensions/XKBproto.h>
#include "XKBlibint.h"
diff --git a/libX11/src/xlibi18n/XDefaultOMIF.c b/libX11/src/xlibi18n/XDefaultOMIF.c
index ae8ac79e4..1821e6459 100644
--- a/libX11/src/xlibi18n/XDefaultOMIF.c
+++ b/libX11/src/xlibi18n/XDefaultOMIF.c
@@ -69,6 +69,7 @@ Sun Microsystems, Inc. or its licensors is granted.
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <stdio.h>
+#include <stdint.h>
#define MAXFONTS 100
diff --git a/libX11/src/xlibi18n/XimProto.h b/libX11/src/xlibi18n/XimProto.h
index 6b0096dd6..9551301a2 100644
--- a/libX11/src/xlibi18n/XimProto.h
+++ b/libX11/src/xlibi18n/XimProto.h
@@ -143,6 +143,13 @@ PERFORMANCE OF THIS SOFTWARE.
/*
* byte order
*/
+#ifdef BIGENDIAN
+#undef BIGENDIAN
+#endif
+#ifdef LITTLEENDIAN
+#undef LITTLEENDIAN
+#endif
+
#define BIGENDIAN (CARD8)0x42 /* MSB first */
#define LITTLEENDIAN (CARD8)0x6c /* LSB first */
diff --git a/libX11/src/xlibi18n/lcDB.c b/libX11/src/xlibi18n/lcDB.c
index afff17455..4a25ae69d 100644
--- a/libX11/src/xlibi18n/lcDB.c
+++ b/libX11/src/xlibi18n/lcDB.c
@@ -48,6 +48,8 @@
#endif /* NOT_X_ENV */
+#include <stdint.h>
+
/* specifying NOT_X_ENV allows users to just use
the database parsing routine. */
/* For UDC/VW */
diff --git a/libX11/src/xlibi18n/lcDynamic.c b/libX11/src/xlibi18n/lcDynamic.c
index f6df94cbb..8d022d885 100644
--- a/libX11/src/xlibi18n/lcDynamic.c
+++ b/libX11/src/xlibi18n/lcDynamic.c
@@ -51,7 +51,7 @@ from The Open Group.
#include "Xlcint.h"
#ifndef XLOCALEDIR
-#define XLOCALEDIR "/usr/lib/X11/locale"
+#define XLOCALEDIR "locale"
#endif
#define LCLIBNAME "xi18n.so"
diff --git a/libX11/src/xlibi18n/lcFile.c b/libX11/src/xlibi18n/lcFile.c
index 18756c1ca..167943d3c 100644
--- a/libX11/src/xlibi18n/lcFile.c
+++ b/libX11/src/xlibi18n/lcFile.c
@@ -214,7 +214,7 @@ _XlcParsePath(
}
#ifndef XLOCALEDIR
-#define XLOCALEDIR "/usr/lib/X11/locale"
+#define XLOCALEDIR "locale"
#endif
void
diff --git a/libX11/src/xlibi18n/makefile b/libX11/src/xlibi18n/makefile
new file mode 100644
index 000000000..5be81d350
--- /dev/null
+++ b/libX11/src/xlibi18n/makefile
@@ -0,0 +1,80 @@
+#AM_CFLAGS= \
+# -I$(top_srcdir)/include \
+# -I$(top_srcdir)/include/X11 \
+# -I$(top_builddir)/include \
+# -I$(top_builddir)/include/X11 \
+# -I$(top_srcdir)/src/xcms \
+# -I$(top_srcdir)/src/xkb \
+# -I$(top_srcdir)/src/xlibi18n \
+# -I$(top_srcdir)/src \
+# $(X11_CFLAGS) \
+# $(BIGFONT_CFLAGS) \
+# $(XDMCP_CFLAGS) \
+# -D_BSD_SOURCE \
+# $(XMALLOC_ZERO_CFLAGS)
+
+LIBRARY = libi18n
+
+
+#
+# Dynamic loading code for i18n modules
+#
+#if XLIB_LOADABLE_I18N
+#XI18N_DL_SOURCES = \
+# XlcDL.c \
+# XlcSL.c
+#else
+#
+# Static interfaces to input/output methods
+#
+#IM_LIBS = \
+# ${top_builddir}/modules/im/ximcp/libximcp.la
+
+#LC_LIBS = \
+# ${top_builddir}/modules/lc/def/libxlcDef.la \
+# ${top_builddir}/modules/lc/gen/libxlibi18n.la \
+# ${top_builddir}/modules/lc/Utf8/libxlcUTF8Load.la \
+# ${top_builddir}/modules/lc/xlocale/libxlocale.la
+
+#OM_LIBS = \
+# ${top_builddir}/modules/om/generic/libxomGeneric.la
+#endif
+
+#libi18n_la_LIBADD = \
+# $(IM_LIBS) $(LC_LIBS) $(OM_LIBS)
+
+INCLUDES += ..\..\include\X11
+DEFINES += XLOCALELIBDIR="\".\""
+
+CSRCS = \
+ $(XI18N_DL_SOURCES) \
+ XDefaultIMIF.c \
+ XDefaultOMIF.c \
+ xim_trans.c\
+ ICWrap.c\
+ IMWrap.c\
+ imKStoUCS.c\
+ lcCT.c\
+ lcCharSet.c\
+ lcConv.c\
+ lcDB.c\
+ lcDynamic.c\
+ lcFile.c\
+ lcGeneric.c\
+ lcInit.c\
+ lcPrTxt.c\
+ lcPubWrap.c\
+ lcPublic.c\
+ lcRM.c\
+ lcStd.c\
+ lcTxtPr.c\
+ lcUTF8.c\
+ lcUtil.c\
+ lcWrap.c\
+ mbWMProps.c\
+ mbWrap.c\
+ utf8WMProps.c\
+ utf8Wrap.c\
+ wcWrap.c
+
+