/modules/clx/new-clx/clx.f
FORTRAN Legacy | 8276 lines | 7155 code | 885 blank | 236 comment | 487 complexity | eebc37146486bb3f5d8a83c02c77d45a MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0, BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- /* -*- C -*- vim:filetype=c
- Copyright (c) 1996-1999 by Gilbert Baumann, distributed under GPL
- Bruno Haible 1998-2000
- Sam Steingold 2001-2008
- ----------------------------------------------------------------------------
- Title: C implementation of CLX utilizing the Xlib
- Created: Sat Dec 2 18:04:51 1995
- Author: Gilbert Baumann <unk6@rz.uni-karlsruhe.de>
- Copying: (c) copyright 1996 by Gilbert Baumann distributed under GPL.
- ----------------------------------------------------------------------------
- Revision 1.24 1999-10-17 bruno
- - Use allocate_bit_vector in place of allocate_byte_vector. Remove ->data
- indirection.
- Revision 1.23 1999-10-11 gilbert
- - get_font_info_and_display: XGetAtomNames is a new X11R6 addition, use
- XGetAtomName instead.
- Revision 1.22 1999-06-06 bruno
- - get_font_info_and_display now optionally returns the Lisp font.
- It also fills in the font's encoding.
- - New function to_XChar2b, used to convert a character sequence to a font
- index sequence. Works for linear non-iso8859-1 fonts (unlike Motif!).
- Still needs work for chinese or japanese fonts.
- Revision 1.21 1999-05-30 bruno
- - Add missing begin_callback() in `xlib_io_error_handler'.
- - Save subr_self during some calls in xlib:change-property.
- - Fix some obvious typos in `font_char_info'.
- - Call XFree() when done with the result of XGetAtomName().
- - Improved error handling in `get_font_info_and_display'.
- Revision 1.20 1999-04-04 bruno
- - Modifications for UNICODE.
- Revision 1.19 1998-10-19 bruno
- - Use the macro `nonreturning_function', not `nonreturning'.
- Revision 1.18 1997-06-22 bruno
- - replace first preprocessing with CCMP2C; then only comments need to be
- stripped before e2d can be applied.
- - compilation in WIDE mode works now (use `eq', not `==' to compare objects)
- - fixed buggy ESLOT4 macro (make_xatom wants a `Display*', not an `object')
- - DYNAMIC_ARRAY has 3 arguments since 1996-07-22
- - allocate_byte_array is now exported from array.d
- - typos and spaces here and there
- Revision 1.18 1997/06/12 00:23:35 gilbert
- - nothing special
- Revision 1.17 1997/06/02 16:19:27 gilbert
- - Lots of minor tweeks here and there
- - First attempt to get the IMAGE implementation right
- - Found memory leak in font handling code
- - fixed bug in xpm::read-pixmap-from-file occured when shape-mask-p = t
- - (xlib:open-display "localhost") works now
- Revision 1.16 1996/10/11 14:18:03 gilbert
- - Some tweakings to get it smoother compiled under 07-22
- Revision 1.15 1996/10/11 10:15:52 gilbert
- - removed all GETTEXTs because it does not compile on 07-22
- - error hander now calls the Lisp error handler
- - fixed invokation of DYNAMIC_ARRAY
- - removed all 'reg?' decls
- - lots of bug fixes
- - changed outlook of xlib:%restore-gcontext-components.
- - the clip mask and the dash list are now retrievable from a gcontext
- So the gcontext chapter should be complete now. [sans cache-p]
- Revision 1.14 1996/10/09 09:03:42 gilbert
- - lots of bug fixes
- - changed outlook of xlib:%restore-gcontext-components.
- - the clip mask and the dash list are now retrievable from a gcontext
- So the gcontext chapter should be complete now. [sans cache-p]
- Revision 1.13 1996/10/05 01:00:50 gilbert
- - begin_call / end_call should be finally added everwhere..
- - fixed some serve bugs in XLIB:CHANGE-PROPERTY.
- - providing {WINDOW,PIXMAP,DRAWABLE,FONT,COLORMAP}-LOOKUP
- Revision 1.12 1996/10/04 03:14:53 gilbert
- - Introduced new macro 'STANDARD_XID_OBJECT_LOOK'.
- - The {WINDOW,PIXMAP,DRAWABLE,FONT,COLORMAP}-{DISPLAY,PLIST,PLIST-SETTER,ID}
- functions now do proper type checking.
- The corresponding xx-EQUAL functions are based on the XID alone.
- Same needs to be done for PTR objects.
- - The silly (and ineffient) 'general_p' function vanished.
- Revision 1.11 1996/10/03 03:37:12 gilbert
- - all invocations of "TheFpointer()->fp_pointer"
- are now guarded by "fp_validp".
- Revision 1.10 1996/10/03 02:45:00 gilbert
- - made the get_[su]int?? functions do type checking
- - Got rid of get_string and get_stringable.
- Revision 1.9 1996/10/02 10:39:45 gilbert
- - eliminated get_xatom_name due to GC vulnerability.
- - got rid of most get_string due to the same reason
- - as always some begin/end_calls added.
- Revision 1.8 1996/09/28 21:59:02 gilbert
- - Only lots of code movements to gather stuff which belongs together
- also to appear together for better maintainability.
- Revision 1.7 1996/09/28 20:52:24 gilbert
- - Redone the invoke stuff, because
- YOU HAVE TO SAVE YOUR FILE BEFORE YOU CHECK IT IN!
- [Emacs does not check this 8-{ Realy angry! $%^#@#%$@ ]
- Revision 1.6 1996/09/28 20:41:23 gilbert
- - added type checking to get_{xid,ptr}_object
- - got rid of display_of all now done with the get_foo_and_display
- functions, so get_font_info is now called get_font_info_and_display.
- - also get rid of the 'invoke' function, it was considered too
- unportable.
- Revision 1.5 1996/09/28 01:45:06 gilbert
- Converted all enum definitions into the DEF_ENUM macro for code size.
- Revision 1.4 1996/09/27 12:48:33 gilbert
- Cleaned up event disassembling code
- Revision 1.3 1996/08/02 10:51:40 gilbert
- Only for Bruno.
- Revision 1.2 1996/07/27 02:25:31 gilbert
- *** empty log message ***
- Revision 1.1 1996/07/08 15:47:43 gilbert
- Initial revision
- ^^^ That is not true! Coding this started actually in Dec 1995.
- (Just around a couple of days befor chrismas?)
- */
- /* --- TODO ---
- - fake the REPORT-ASYNCHRONOUS-ERRORS slot on displays.
- - Garnet seems to loose exposure events from time to time, I do not know
- if it is my fault or a garnet bug? This thing is hard to trace, since
- it seems to depend on how fast the window gets mapped, or how fast the
- garnet code is!
- - the get_XXX functions *all* should do type checking
- - Most uses of 'fixnum' are wrong, since the actual type is somewhat more
- precise known. fixnums are only correct as indexes into sequences and
- such!
- -------
- When passing #<XLIB:GCONTEXT #x00000160> to FONT-ASCENT it says:
- "Error: XLIB:FONT-ASCENT: NIL is not of type XLIB:FONT"
- Why is two way wrong:
- a. A gcontext should be ok where a font is
- b. Why is dumped NIL and not the gcontext?
- O.k. this was due to the fact that the font was actually never set.
- fix that!
- (Maybe we just pass the gcontext down to Xlib, since Xlib is supposed
- to do the same here.)
- -------
- When a display is closed the host name and such sould not
- be available any longer
- -------
- - there should be a function called closed-p, which checks wether an given
- xid or ptr object is closed or not. When re-incarnating CLISP all CLX
- objects should get closed. get_xxx functions should check on that. But
- there a some nasty problems:
- a.) when I setup the XFree... request it is not yet at the server
- b.) There may be additional references in the servers queque.
- Maybe I open a pseudo window, just for sneeking for destruction events?
- - XLIB:TEXT-EXTENTS and XLIB:TEXT-WIDTH needs fixing for non simple
- string arguments.
- - Garnet accidentally used :on/:off for save under values
- [But only sometimes]
- - Scan for all funcalls and save subr_self prior to call.
- - Is it right that we make the list of displays public?
- - we should rethink a bit more the font handling stuff, because several
- situations could arise:
- . A font may not have an fid, this implies, that the font could not be
- hashed, furthermore we should init a finializer to discard also the
- fontinfo when the font object becomes inaccessible.
- . A font may come without per-character information.
- (But only when it has a 0 font id, hence a pseudo font)
- . If we open a pseudo font, we should then enter it into the hash table.
- . ensure that the font-name slot has some valid value.
- (It is even not guaranteed to be available.)
- - go thru' the whole source and find all error messages and check that they
- are given right. [error wants its arguments backwards!]
- - since some make_xxx functions use value1, I should generally push the
- return values onto the stack before actually returning.
- - since somebody could now create classes on top of window, check the xid we
- want to read, if it is unbound emit some reasonable error message. [If it
- is unbound the slot-value function returns an error on its own already.]
- - What about the plist slot? (Should we bind it to a useful value?)
- - maybe we make the clos-instance representation optional? Since it eats
- some speed. (Fetching a slot value is not the fastest operation.)
- - several X11 functions, which return lists may actually pass NULL as the
- empty sequence?!
- - some of the enumerating functions (list XListDepths etc) do not set the
- count_return on failure, so set it yourself to 0 before you make the call,
- so that we do not run into difficulties.
- - Maybe we dont put all those symbols in the XLIB package to be able to
- include the MIT-CLX also. (Generally CLISP lacks some of the nice package
- features Symbolics Common LISP provided. There were also anonymous or
- invisible packages.)
- - errors should be reported in a much more meaningful way.
- - the big export list in clx.lisp seems to export some superfluous symbols.
- - put also ptr objects into the hashtable.
- Is there any way to get 'em anyhow back?
- - the xlib:free-xxx routines should remove that object from the hashtable.
- (or shouldn`t they?) What does the Xserver with free`ed objects?
- And also they might be still alive, if some other application uses it.
- [Well simply take a look at the MIT code.] [What about GC?!]
- - should DISPLAY be a class? What with VISUAL-INFO, COLOR an so on ...
- - We should really make DISPLAY-AFTER-FUNCTION to live.
- The is also a XAfterFunction or something like that on the C side of life.
- - What exactly is a drawable? a type? a class?
- - We should insert a lot more type checks?
- - Since type checks are rather expensive think about listening to SAFTY and
- SPEED ...
- */
- /* --- DONE ----
- - some functions emit errors saying #xDDD using decimal notation!
- - upon disconnection we simply get a broken pipe message and exit
- [This is not the disired way, since we want to handle such an error.]
- - with-gcontext !!!
- - rename the 'font-name' slot of font to 'name'.
- - take a look at the CLUE code, what it does with the :xxx option to
- create-xxx functions?!
- - DISPLAY-AFTER-FUNCTION setter is needed.
- - make display/window/pixmap clos-instances (see the CLUE patches for that)
- - put xids into the hashtable and do not build the object new on each
- request.
- - plists (partly done)
- - get_visual
- - how to proceed with visuals? In CLX a visual is just a card29 in CLX it is
- a pointer to a structure.
- - Together with the CLX implementation should go a wholine implementation.
- (partly there)
- */
- /* --- NOTE ---
- This package is not actually optimized for speed, since my intent and BTW
- the overall intent of CLISP is to make the whole beast small.
- (Actually you gain speed due to reduced paging).
- Also this code is at some places BFI!
- The general idea behind writing this bunch of code, is to provide a CLX
- implementation for CLISP, which is feasible of both speed and space. I
- actually use the libX library, because if you want to do graphics on your
- machine, you will already have it in memory, so it adds no extra cost. [One
- disadvantage is that I am forced in some places to go into the internals of
- the libX, since the CLX specification is more powerful at some places than
- the libX implementation. This add another source of in-portability of CLISP,
- so *please*, if you encounter compilation problems mail me,
- so I could adjust the code ...]
- CLX adds on my machines another ~700k of memory needs for CLISP, but this
- implementation add only 70k [*I* know that I am telling lies here, since the
- libX11 itself has a size of ~500k; But as long as I have no pure LISP OS but
- need the UNIX to boot it ...] and a great bunch of speed.
- Also having this implemenation should gain a big plus against GCL. (IMHO
- gcl is very bad code compared to CLISP! [gcl is actually akcl]) flame,flame.
- BTW It should be fun to write the graph.d routines on top of CLX!
- */
- /* --- FUTURE ---
- Xpm Support?
- We should also include support for the xpm library to have a nice access to
- .xpm files, which is hardly needed, since I do not want to duplicate this
- non-trivial code in Lisp. But we have to think about a Lisp representation
- for pixmaps. I could also imagine a `defpixmap` macro. Just another
- question is if we want to put the xpm routines into another package. (called
- `x-pixmap` or just 'xpm'). I want also to write some documentation for the
- then Lisp xpm routines. But since the xpm library seems to be a changing
- thing it is also a question, how we cope with them.
- Incorporation into the FFI?
- Since we use could convert now a WINDOW object into a libX11 Window object,
- it may be worth offer this also to the FFI. When I finished this work I
- should take a look at the FFI.
- */
- /* --- IMPLEMENTATION NOTES ---------------------------------------------------
- The following types are only XID`s:
- window, drawable, font, pixmap, cursor, colormap, GContext, keysym
- No XID, but data-structures:
- color, display, screen, GC
- First I define some data types by providing get_xxx, make_xxx and xxx_p
- functions. Note that this set is not complete, since not all functions are
- actually needed. The consistent name is crucial, since some macros I define
- later take a "type" argument, which is concatenated with 'make_' or 'get_'.
- This is done to make this file more dense; (Thus save me a lot of redundant
- typing.)
- type | dpy? | XID-P | hashed-p | Note
- ----------+------+-------+----------+------------------------------
- GCONTEXT | T | NIL | NIL | Is really a pointer
- WINDOW | T | T | T |
- PIXMAP | T | T | T |
- CURSOR | T | T | T |
- COLORMAP | T | T | T |
- FONT | T | T/NIL | T/NIL |
- SCREEN | T | NIL | (should | Could also been represented as index?
- | | | be) |
- DISPLAY | NIL | NIL | NIL |
- Class Hierarchy
- --------------------
- xlib-object --+--> xid-object --+--> DRAWABLE -+--> WINDOW
- | | +--> PIXMAP
- | |--> CURSOR
- | +--> COLORMAP
- | +--> FONT
- |
- +--> ptr-object --+--> GCONTEXT
- |
- +--> DISPLAY
- Just in case you prefer a textual representation:
- (defclass xlib-object () (plist display))
- (defclass xid-object (xlib-object) (xid))
- (defclass ptr-object (xlib-object) (ptr))
- (defclass drawable (xid-object) ())
- (defclass window (drawable) ())
- (defclass pixmap (drawable) ())
- (defclass cursor (xid-object) ())
- (defclass colormap (xid-object) ())
- (defclass gcontext (ptr-object) ())
- (defclass display (ptr-object) ())
- (defclass font (xid-object) (font-info name))
- */
- /* -- NOTE --
- For further for grepability I use the following tags in comments:
- XXX - really bad and a major risk to safety/usability.
- FIXME - just fix me, something that ought to be done
- before next release.
- TODO - something, which should be done and is already
- considered useful.
- FUTURE - something which is just an idea and it is not yet
- decided, if I ever implement it; It may also later
- be considered silly.
- I welcome discussion about those items.
- OK - the opposite of XXX. Functions which are
- considered to be totally finished and
- had undergone a test are marked with this.
- UNDEFINED - this is thought for undefined functions at whole
- NOTIMPLEMENTED - is thought for not implemented features
- in an partly defined function.
- */
- /* enough bla bla, let's start coding, we have a long long way before us ...*/
- #include "clisp.h"
- #include <X11/Xlib.h>
- #include <X11/Xutil.h> /* XGetVisualInfo */
- #include <X11/Xcms.h> /* forXcmsCCCOfColormap() & XcmsVisualOfCCC() */
- #include <X11/Xauth.h>
- /* #include <X11/Xresource.h> */
- #include <stdio.h> /* sprintf() */
- #include <string.h> /* memcpy(), strchr(), strcpy() */
- #include "config.h"
- #if defined(TIME_WITH_SYS_TIME)
- # include <sys/time.h>
- # include <time.h>
- #else
- # if defined(HAVE_SYS_TIME_H)
- # include <sys/time.h>
- # elif defined(HAVE_TIME_H)
- # include <time.h>
- # endif
- #endif
- #if defined(HAVE_SYS_SOCKET_H)
- # include <sys/socket.h>
- #endif
- #if defined(HAVE_NETDB_H)
- # include <netdb.h>
- #endif
- #if defined(HAVE_NETINET_IN_H)
- # include <netinet/in.h>
- #endif
- ##if WANT_XSHAPE
- /* must include this before DEFMODULE so that DEFCHECKER will work */
- #include <X11/extensions/shape.h>
- ##endif
- #define DEBUG_CLX 0
- #ifndef FOREIGN
- #error FOREIGN is not defined.
- #error CLX needs a CLISP built with the foreign pointer datatype support.
- #error Go into the main CLISP makefile and add a -DFOREIGN=void*
- #error to CFLAGS make variable and rebuild CLISP before coming back here.
- #endif
- DEFMODULE(clx,"XLIB")
- /* ... But first we provide some prototypes for functions, which maybe worth
- included in libX11 and are defined at the end of this file. */
- /* might also been called XVisualIDFromVisual**(-1) : */
- static Visual *XVisualIDToVisual (Display *dpy, VisualID vid);
- /* Find the screen index from a Screen* : */
- static int XScreenNo (Display *dpy, Screen *screen);
- /* our own forward declaration */
- static Display *pop_display (void);
- static inline Display *get_display (object dpy)
- { pushSTACK(dpy); return pop_display(); }
- /* Some fix-ups: */
- #define NOTIMPLEMENTED NOTREACHED
- #define UNDEFINED NOTIMPLEMENTED
- /* debug */
- #if DEBUG_CLX
- #define dprintf(x) do{ printf x; fflush(stdout); }while(0)
- #else
- #define dprintf(x) do{}while(0)
- #endif
- /* it is not clear whether we can rely on `writing_to_subprocess' or
- must actually disable SIGPIPE - see src/spvw_sigpipe.d */
- #define RELY_ON_WRITING_TO_SUBPROCESS
- #if defined(RELY_ON_WRITING_TO_SUBPROCESS)
- /* including <signal.h> just for the sake of SIGPIPE
- (which is always there anyway) is a total waste */
- # if defined(HAVE_SIGNALS) /* && defined(SIGPIPE) */
- extern
- # endif
- bool writing_to_subprocess;
- # define begin_x_call() writing_to_subprocess=true;begin_call()
- # define end_x_call() end_call();writing_to_subprocess=false
- #else
- # define begin_x_call() begin_call()
- # define end_x_call() end_call()
- extern void disable_sigpipe(void);
- #endif
- #define X_CALL(f) do{ begin_x_call(); f; end_x_call(); }while(0)
- /* -------------------------------------------------------------------------
- * General purpose utilities
- * ------------------------------------------------------------------------- */
- /* sugar for funcall (used in macros, so not a macro) */
- static inline object funcall1 (object fun, object arg)
- { pushSTACK(arg); funcall(fun,1); return value1; }
- nonreturning_function(static,my_type_error,(object type, object datum))
- {
- pushSTACK(datum); /* TYPE-ERROR slot DATUM */
- pushSTACK(type); /* TYPE-ERROR slot TYPE */
- pushSTACK(type); pushSTACK(datum); pushSTACK(TheSubr(subr_self)->name);
- error (type_error, ("~S: ~S is not of type ~S"));
- }
- nonreturning_function (static, error_closed_display,
- (object caller, object dpy)) {
- pushSTACK(`XLIB::CLOSED-DISPLAY`);
- pushSTACK(`:DISPLAY`); pushSTACK(dpy);
- pushSTACK(`:CALLER`); pushSTACK(caller);
- funcall(L(error),5);
- abort(); /* ERROR does not return: avoid a compiler warning */
- }
- /* with_stringable_0 is much like with_string_0, but a symbol is also
- allowed as argument. This macro does type checking and may raise an error. */
- #define with_stringable_0_tc(obj, encoding, cvar, body) \
- do { \
- object wsa0_temp = \
- (symbolp(obj) ? (object)Symbol_name (obj) : (object)(obj)); \
- if (stringp (wsa0_temp)) { \
- with_string_0 (wsa0_temp, encoding, cvar, body); \
- } else my_type_error(`(OR STRING SYMBOL)`,obj); \
- } while(0)
- /* -----------------------------------------------------------------------
- * Integer data types
- * ----------------------------------------------------------------------- */
- /* Huh?! These functions do not check the type?! */
- #define make_uint8(i) uint8_to_I (i)
- #define make_uint16(i) uint16_to_I (i)
- #define make_uint29(ul) UL_to_I (ul)
- #define make_uint32(ul) UL_to_I (ul)
- #define make_sint8(i) sint8_to_I (i)
- #define make_sint16(i) sint16_to_I (i)
- #define make_sint32(i) L_to_I (i)
- #define get_bool(obj) (!nullp(obj))
- #define make_bool(b) ((b)?(T):(NIL))
- #define pixel_p(obj) integerp (obj)
- #define get_pixel(obj) get_uint32(obj)
- #define make_pixel(obj) make_uint32(obj)
- #define get_fixnum(obj) fixnum_to_V (obj) /* WARNING: obj should be a variable (evaluated multiple), and no range check is performed */
- #if 0
- #define get_uint8(obj) I_to_uint8(obj)
- #define get_uint16(obj) I_to_uint16(obj)
- #define get_uint29(obj) I_to_UL (obj)
- #define get_uint32(obj) I_to_UL (obj)
- #define get_sint8(obj) I_to_sint8(obj)
- #define get_sint16(obj) I_to_sint16(obj)
- #define get_sint32(obj) I_to_sint32(obj)
- #else
- #define uint29_p uint32_p /* XXX the actual type checking code is just too weird! */
- #define I_to_uint29 I_to_UL /* XXX ditto */
- #define DEFINE_INTEGER_GETTER(type, lspnam) \
- static inline type get_##type (object obj) { \
- if (type##_p (obj)) \
- return I_to_##type (obj); \
- else my_type_error(lspnam,obj); \
- } \
- static inline type get_##type##_0 (object obj) { \
- return missingp(obj) ? 0 : get_##type(obj); \
- }
- DEFINE_INTEGER_GETTER (uint8, `XLIB::CARD8`)
- DEFINE_INTEGER_GETTER (uint16, `XLIB::CARD16`)
- DEFINE_INTEGER_GETTER (uint29, `XLIB::CARD29`)
- DEFINE_INTEGER_GETTER (uint32, `XLIB::CARD32`)
- DEFINE_INTEGER_GETTER (sint8, `XLIB::INT8`)
- DEFINE_INTEGER_GETTER (sint16, `XLIB::INT16`)
- DEFINE_INTEGER_GETTER (sint32, `XLIB::INT32`)
- #endif
- static uint32 get_aint32 (object obj)
- { /* This is special routine, which accepts either an uint32 or a sint32.
- However returned is an uint32.
- Used by XLIB:CHANGE-PROPERTY */
- if (uint32_p (obj))
- return I_to_uint32 (obj);
- if (sint32_p (obj))
- return (uint32)I_to_sint32 (obj);
- else my_type_error(`(OR XLIB::INT32 XLIB::CARD32)`,obj);
- }
- /* -----------------------------------------------------------------------
- * Displays
- * ----------------------------------------------------------------------- */
- /* Objects of type DISPLAY are currently represented as structure; here are the
- slots: The actual defstruct definition in clx.lisp must match. There is a
- warning in the code. */
- enum {
- slot_DISPLAY_FOREIGN_POINTER=1,
- slot_DISPLAY_HASH_TABLE,
- slot_DISPLAY_PLIST,
- slot_DISPLAY_AFTER_FUNCTION,
- slot_DISPLAY_ERROR_HANDLER,
- slot_DISPLAY_DISPLAY,
- display_structure_size
- };
- /* The display contains a hash table. All XID objects are entered there, so
- that two XID objects, with equal XID are actually eq. */
- static object make_display (Display *dpy, int display_number)
- { /* Given the C representation of a display create the Lisp one and
- initialize it. The newly created display is added to XLIB:*DISPLAYS*. */
- pushSTACK(`(XLIB::DISPLAY)`); pushSTACK(fixnum(display_structure_size));
- funcall(L(make_structure),2); pushSTACK(value1);
- TheStructure(STACK_0)->recdata[slot_DISPLAY_FOREIGN_POINTER]
- = allocate_fpointer (dpy);
- #if oint_data_len<29
- pushSTACK(S(Ktest)); pushSTACK(S(stablehash_equal)); /* key is a cons */
- #else
- pushSTACK(S(Ktest)); pushSTACK(S(stablehash_eq)); /* key is a fixnum */
- #endif
- funcall (L(make_hash_table), 2);
- TheStructure(STACK_0)->recdata[slot_DISPLAY_HASH_TABLE] = value1;
- TheStructure(STACK_0)->recdata[slot_DISPLAY_PLIST] = NIL;
- TheStructure(STACK_0)->recdata[slot_DISPLAY_AFTER_FUNCTION] = NIL;
- TheStructure(STACK_0)->recdata[slot_DISPLAY_ERROR_HANDLER] = NIL;
- TheStructure(STACK_0)->recdata[slot_DISPLAY_DISPLAY] =
- make_uint8 (display_number);
- /* Now enter the display into the list of all displays: */
- pushSTACK(STACK_0);
- pushSTACK(Symbol_value(`XLIB::*DISPLAYS*`));
- funcall (L(cons), 2);
- Symbol_value(`XLIB::*DISPLAYS*`) = value1;
- return value1 = popSTACK();
- }
- static object find_display (Display *display)
- { /* Searched the XLIB:*DISPLAY* variable for `display',
- return NIL, if display was not found.
- Used by the error handler, the only callback code here. */
- pushSTACK(Symbol_value (`XLIB::*DISPLAYS*`));
- for (;consp (STACK_0); STACK_0 = Cdr (STACK_0)) {
- if (get_display(Car(STACK_0)) == display)
- return Car(popSTACK());
- }
- skipSTACK(1);
- return NIL;
- }
- static Bool ensure_living_display (gcv_object_t *objf)
- { /* ensures that the object pointed to by 'objf' is really a display.
- Also the display must be 'alive', meaning that it does not contain
- a fptr from an previous incarnation of CLISP.
- If all that does not hold an error is signaled.
- Finally, returns an indicator of whether the display has been closed.
- 'objf' should point into the stack due to GC. */
- if (typep_classname (*objf, `XLIB::DISPLAY`)) { /* Is it a display at all? */
- object fptr = TheStructure(*objf)->recdata[slot_DISPLAY_FOREIGN_POINTER];
- return (fpointerp(fptr) && fp_validp(TheFpointer(fptr))
- && (TheFpointer(fptr)->fp_pointer != NULL));
- }
- /* Fall through -- raise type error */
- my_type_error(`XLIB::DISPLAY`,*(objf));
- }
- DEFUN(XLIB:CLOSED-DISPLAY-P, display)
- {
- VALUES_IF(!ensure_living_display(&STACK_0));
- skipSTACK(1);
- }
- /* display_hash_table -- return the hashtable of a display object
- > the display object
- < its hash table
- This function is somewhat silly, since it introduces double type checking! */
- static object display_hash_table (object dpy)
- {
- pushSTACK(dpy);
- if (!ensure_living_display(&(STACK_0)))
- error_closed_display(TheSubr(subr_self)->name,STACK_0);
- return TheStructure (popSTACK())->recdata[slot_DISPLAY_HASH_TABLE];
- }
- /* pop_display --- return the C Display* of an display object
- > STACK_0: the Lisp DISPLAY object */
- static Display *pop_display (void)
- {
- if (!ensure_living_display(&(STACK_0)))
- error_closed_display(TheSubr(subr_self)->name,STACK_0);
- STACK_0 = TheStructure (STACK_0)->recdata[slot_DISPLAY_FOREIGN_POINTER];
- return (Display*) TheFpointer(popSTACK())->fp_pointer;
- }
- /* -----------------------------------------------------------------------
- * PTR and XID objects
- * ----------------------------------------------------------------------- */
- /* First the ptr ones.
- ptr_objs are screens and gcontexts, these objects are not hashed.
- (which is a bad idea btw). But on the other hand for gcontexts it is
- not too bad, since you get `em only once.
- Another story are the screen, these could be cached. Or we do not give the
- actual screen structure, but pass simply the index? */
- static object make_ptr_obj (object type, object dpy, void *ptr)
- { /* (make-instance type :display dpy :ptr ptr) */
- pushSTACK(type);
- pushSTACK(`:DISPLAY`); pushSTACK(dpy);
- pushSTACK(`:PTR`); pushSTACK(allocate_fpointer (ptr));
- funcall(S(make_instance),5);
- return value1;
- }
- /* return the fp_pointer of the foreign slot
- value1 is set the slot value
- can trigger GC */
- static void* foreign_slot (object obj, object slot) {
- pushSTACK(obj); pushSTACK(slot); funcall(L(slot_value), 2);
- return TheFpointer(value1 = check_fpointer(value1,false))->fp_pointer;
- }
- static void *get_ptr_object_and_display (object type, object obj,
- Display **dpyf)
- { /* 'obj' is the lisp object, whose C representation is returned.
- When 'dpyf' is non-0, the display of 'obj' is also returned and it is
- ensured that it lives. [Otherwise an error is signaled.]
- If 'obj' is not of type 'type', a symbol naming the desired class,
- an error is issued.
- Hence this function ensures, that a proper object is returned, or nothing. */
- pushSTACK(type);
- pushSTACK(obj);
- if (typep_classname (STACK_0, STACK_1)) {
- if (dpyf) { /* do we want the display? */
- pushSTACK(STACK_0); pushSTACK(`XLIB::DISPLAY`);
- funcall(L(slot_value), 2); pushSTACK(value1);
- *dpyf = pop_display ();
- }
- { void * ret = foreign_slot(STACK_0/* 'obj' */,`XLIB::PTR`);
- skipSTACK(2); /* clean up */
- return ret;
- }
- } else my_type_error(STACK_1/*type*/,STACK_0/*obj*/);
- }
- /* Now the XID objects */
- static object make_xid_obj_low (gcv_object_t *prealloc, gcv_object_t *type,
- gcv_object_t *dpy, XID xid)
- {
- if (nullp (*prealloc)) {
- /* (make-instance type :display dpy :id xid) */
- pushSTACK(*type);
- pushSTACK(`:DISPLAY`); pushSTACK(*dpy);
- pushSTACK(`:ID`); pushSTACK(make_uint29 (xid));
- funcall(S(make_instance),5);
- return value1;
- } else {
- /* TODO: We should check the type of the preallocated object?!
- [Is is a bug or a feature?] */
- pushSTACK(*prealloc);
- pushSTACK(`XLIB::DISPLAY`);
- pushSTACK(*dpy);
- funcall (L(set_slot_value), 3);
- pushSTACK(*prealloc);
- pushSTACK(`XLIB::ID`);
- pushSTACK(make_uint29 (xid));
- funcall (L(set_slot_value), 3);
- return *prealloc;
- }
- }
- #if oint_data_len<29
- DEFVAR(xlib_a_cons,allocate_cons());
- /* return the XID object for lookup (old) */
- static inline object XID_to_object_old (XID xid) {
- Car (O(xlib_a_cons)) = make_uint16 (xid & 0xFFFF); /* lower halfword */
- Cdr (O(xlib_a_cons)) = make_uint16 (xid >> 16); /* upper halfword */
- return O(xlib_a_cons);
- }
- /* return the XID object for creation (new) */
- static inline object XID_to_object_new (XID xid) {
- pushSTACK(make_uint16 (xid & 0xFFFF)); /* lower halfword */
- pushSTACK(make_uint16 (xid >> 16)); /* upper halfword */
- funcall(L(cons),2); /* cons them */
- return value1;
- }
- #else
- #define XID_to_object_old(xid) fixnum(xid)
- #define XID_to_object_new(xid) fixnum(xid)
- #endif
- /* find the resource in the display hash table
- < display object, XID number
- > returns dpy->hash-table if NOT found
- nullobj if found, in which case the object found is in value1 */
- static object lookup_xid (object dpy, XID xid) {
- if (xid == 0) { /* This is trivial, but is it also right?! */
- VALUES1(NIL);
- return nullobj;
- } else {
- object ht = display_hash_table(dpy);
- value1 = gethash(XID_to_object_old(xid),ht,false); /* look it up */
- if (!eq(value1,nullobj)) { /* something found? */
- mv_count = 1; /* simply return what we found */
- return nullobj;
- } else
- return ht; /* return the hash-table */
- }
- }
- /* set the ID to map to RESOURCE on display
- < display hash-table object, XID number, resource object
- can trigger GC */
- static void set_resource_id (gcv_object_t *ht, XID xid,
- gcv_object_t *resource) {
- value1 = XID_to_object_new(xid);
- pushSTACK(value1); /* key for puthash */
- pushSTACK(*ht); /* hashtable */
- pushSTACK(*resource); /* value */
- funcall (L(puthash), 3); /* put it into the hashtable */
- }
- /* delete the resource ID from the display
- < display hash-table object, XID number */
- static Values delete_resource_id (gcv_object_t *ht, XID xid) {
- pushSTACK(XID_to_object_old(xid)); pushSTACK(*ht); funcall(L(remhash),2);
- }
- static object make_xid_obj_2 (object type, object dpy, XID xid,
- object prealloc)
- { /* NOTE: - This code is not reentrant :-( But hence it saves consing
- - may be we want to check the most significant 3 bits in xid, since
- GC inquiry functions return those values, if slot has an unknown
- value.
- - We could add even more safty here
- 1. bark if lookup succeed and prealloc was specified.
- [But this situation should not be able to occurr, since a
- prealloc is only given upon creation requests.] However MIT-CLX
- does this check and raises a hash-error, if something is not
- o.k. with the hash table. [But only if you set a debug flag
- somewhere].
- 2. If lookup succeeds we could also check the type.
- 3. We should check the type of the preallocated object?!
- [Compare to make_ptr_obj] */
- object ht = lookup_xid(dpy,xid);
- if (!eq(ht,nullobj)) { /* allocate and enter object into the hashtable */
- pushSTACK(prealloc); /* save is save */
- pushSTACK(type); /* ditto */
- pushSTACK(dpy); /* ditto */
- pushSTACK(ht); /* hashtable */
- pushSTACK(make_xid_obj_low (&STACK_3, &STACK_2, &STACK_1, xid));
- set_resource_id(&STACK_1,xid,&STACK_0); /* enter it into the hashtable */
- VALUES1(popSTACK()); /* return freshly allocated structure */
- skipSTACK(4); /* remove saved prealloc, type, dpy, ht */
- }
- return value1;
- }
- static XID get_xid_object_and_display (object type, object obj, Display **dpyf)
- {
- pushSTACK(type);
- pushSTACK(obj);
- if (typep_classname (STACK_0, STACK_1)) {
- if (dpyf) { /* do we want the display? */
- pushSTACK(STACK_0); pushSTACK(`XLIB::DISPLAY`);
- funcall(L(slot_value), 2); pushSTACK(value1);
- *dpyf = pop_display();
- }
- pushSTACK(STACK_0); /* obj already on stack */ pushSTACK(`XLIB::ID`);
- funcall(L(slot_value), 2);
- ASSERT(integerp (value1)); /* FIXME */
- skipSTACK(2); /* clean up */
- return (XID)(get_uint29 (value1)); /* all done */
- } else my_type_error(STACK_1/*type*/,STACK_0/*obj*/);
- }
- static object get_display_obj_tc (object type, object obj)
- {
- if (typep_classname (obj, type)) {
- pushSTACK(obj); pushSTACK(`XLIB::DISPLAY`);
- funcall(L(slot_value), 2); return value1;
- } else my_type_error(type,obj);
- }
- static object get_display_obj (object obj)
- { /* XXX type checking [Well on the other hand is it really necessary?]
- I want to use the combined function above. */
- pushSTACK(obj); pushSTACK(`XLIB::DISPLAY`);
- funcall(L(slot_value), 2); return value1;
- }
- /* -----------------------------------------------------------------------
- * Specializied getters/makers/predicates
- * ----------------------------------------------------------------------- */
- /* Simple Getters */
- #define get_xid_object(type,obj) get_xid_object_and_display(type,obj,0)
- #define get_ptr_object(type,obj) get_ptr_object_and_display(type,obj,0)
- #define get_gcontext(obj) ((GC) get_ptr_object (`XLIB::GCONTEXT`, obj))
- #define get_screen(obj) ((Screen*) get_ptr_object (`XLIB::SCREEN`, obj))
- #define get_image(obj) ((XImage*) get_ptr_object (`XLIB::IMAGE`, obj))
- #define get_window(obj) ((Window) get_xid_object (`XLIB::WINDOW`, obj))
- #define get_pixmap(obj) ((Pixmap) get_xid_object (`XLIB::PIXMAP`, obj))
- #define get_cursor(obj) ((Cursor) get_xid_object (`XLIB::CURSOR`, obj))
- #define get_colormap(obj) ((Colormap)get_xid_object (`XLIB::COLORMAP`, obj))
- #define get_drawable(obj) ((Drawable)get_xid_object (`XLIB::DRAWABLE`, obj))
- /* Combined getters */
- #define get_drawable_and_display(obj, dpyf) ((Drawable)get_xid_object_and_display (`XLIB::DRAWABLE`, obj, dpyf))
- #define get_window_and_display(obj, dpyf) ((Window) get_xid_object_and_display (`XLIB::WINDOW`, obj, dpyf))
- #define get_pixmap_and_display(obj, dpyf) ((Pixmap) get_xid_object_and_display (`XLIB::PIXMAP`, obj, dpyf))
- #define get_cursor_and_display(obj, dpyf) ((Cursor) get_xid_object_and_display (`XLIB::CURSOR`, obj, dpyf))
- #define get_colormap_and_display(obj, dpyf) ((Colormap)get_xid_object_and_display (`XLIB::COLORMAP`, obj, dpyf))
- #define get_gcontext_and_display(obj,dpyf) ((GC) get_ptr_object_and_display (`XLIB::GCONTEXT`, obj, dpyf))
- #define get_screen_and_display(obj,dpyf) ((Screen*) get_ptr_object_and_display (`XLIB::SCREEN`, obj, dpyf))
- #define get_font_and_display(obj, dpyf) ((Font) get_xid_object_and_display (`XLIB::FONT`, obj, dpyf))
- /* Predicates */
- #define drawable_p(obj) (typep_classname (obj, `XLIB::DRAWABLE`))
- #define window_p(obj) (typep_classname (obj, `XLIB::WINDOW`))
- #define pixmap_p(obj) (typep_classname (obj, `XLIB::PIXMAP`))
- #define cursor_p(obj) (typep_classname (obj, `XLIB::CURSOR`))
- #define colormap_p(obj) (typep_classname (obj, `XLIB::COLORMAP`))
- #define font_p(obj) (typep_classname (obj, `XLIB::FONT`))
- #define gcontext_p(obj) (typep_classname (obj, `XLIB::GCONTEXT`))
- #define screen_p(obj) (typep_classname (obj, `XLIB::SCREEN`))
- #define display_p(obj) (typep_classname (obj, `XLIB::DISPLAY`))
- #define color_p(obj) (typep_classname (obj, `XLIB::COLOR`))
- /* Simple Makers */
- #define make_xid_obj(a,b,c) make_xid_obj_2(a,b,c,NIL)
- #define make_window(dpy,win) (make_window_2(dpy,win,NIL))
- #define make_pixmap(dpy,pix) (make_pixmap_2(dpy,pix,NIL))
- #define make_drawable(dpy,da) (make_window (dpy, da))
- #define make_cursor(dpy,cur) (make_xid_obj (`XLIB::CURSOR`, dpy, cur))
- #define make_colormap(dpy,cm) (make_xid_obj (`XLIB::COLORMAP`, dpy, cm))
- #define make_gcontext(dpy,gc) (make_ptr_obj (`XLIB::GCONTEXT`, dpy, gc))
- #define make_screen(dpy, srcn) (make_ptr_obj (`XLIB::SCREEN`, dpy, srcn))
- /* Makers with prealloc */
- #define make_window_2(dpy, win, prealloc) (make_xid_obj_2 (`XLIB::WINDOW`, dpy, win, prealloc))
- #define make_pixmap_2(dpy, pm, prealloc) (make_xid_obj_2 (`XLIB::PIXMAP`, dpy, pm, prealloc))
- static object make_font (object dpy, Font fn, object name)
- { /* This looks much more like assembler, doesn't it? */
- pushSTACK(name); /* save the name */
- pushSTACK(make_xid_obj (`XLIB::FONT`, dpy, fn)); /* make the xid-object and save it */
- /* fetch old FONT-INFO slot */
- pushSTACK(STACK_0); /* xid-object */
- pushSTACK(`XLIB::FONT-INFO`); /* slot */
- funcall(L(slot_value), 2); /* (slot-value new-xid-object `font-info) */
- /* do not overwrite any already fetched font info */
- if (!fpointerp (value1)) { /* allocate a new fpointer */
- pushSTACK(STACK_0); /* the new xid-object */
- pushSTACK(`XLIB::FONT-INFO`); /* the slot */
- pushSTACK(allocate_fpointer (NULL)); /* new value */
- funcall (L(set_slot_value), 3); /* update the :font-info slot */
- }
- if (!nullp (STACK_1)) { /* name */
- pushSTACK(STACK_0); /* the new xid-object */
- pushSTACK(`XLIB::NAME`); /* the :name slot */
- pushSTACK(STACK_3); /* [name] new value */
- funcall (L(set_slot_value), 3); /* update the :name slot */
- }
- value1 = STACK_0; /* return value = new xid-object */
- skipSTACK(2); /* clean up */
- return value1;
- }
- static Font get_font (object obj);
- static XFontStruct *get_font_info_and_display (object obj, object* fontf,
- Display **dpyf)
- { /* Fetches the font information from a font, if it isn't there
- already, query the server for it.
- Further more if a gcontext is passed in, fetch its font slot instead.
- Does type checking and raises error if unappropriate object passed in.
- If 'fontf' is non-0, also the font as a Lisp object is returned.
- If 'dpyf' is non-0, also the display of the font is returned and it is
- ensured that the display actually lives. */
- XFontStruct *info;
- Display *dpy;
- Font font;
- if (gcontext_p (obj)) {
- /* In all places where a font object is required, a gcontext should
- be accepted too, so fetch the font slot and go on ... */
- pushSTACK(obj); pushSTACK(NIL);
- funcall(``XLIB:GCONTEXT-FONT``,2);
- obj = value1; /* Now we have the font [or nothing] */
- }
- if (!font_p (obj)) my_type_error(`XLIB::FONT`,obj);
- pushSTACK(obj); /* save */
- info = (XFontStruct*) foreign_slot(obj,`XLIB::FONT-INFO`);
- if (!info) {
- /* We have no font information already, so go and ask the server for it. */
- pushSTACK(value1); /* but first save what we found. */
- font = get_font_and_display (STACK_1, &dpy);
- X_CALL(info = XQueryFont (dpy, font));
- if (!info) {
- pushSTACK(STACK_1); pushSTACK(TheSubr (subr_self)->name);
- error(error_condition,"~S: Font ~S does not exist");
- }
- if (dpyf) *dpyf = dpy;
- /* Store it in the foreign pointer
- (foreign_slot ensures that STACK_0 is a foreign pointer) */
- TheFpointer(STACK_0)->fp_pointer = info;
- skipSTACK(1);
- # ifdef UNICODE
- { /* Determine the font's encoding, so we can correctly convert
- characters to indices.
- Call (XLIB:FONT-PROPERTY font "CHARSET_REGISTRY")
- and (XLIB:FONT-PROPERTY font "CHARSET_ENCODING")
- and translate the resulting pairs to CLISP encodings. */
- Atom xatom;
- unsigned long rgstry;
- unsigned long encdng;
- begin_x_call();
- xatom = XInternAtom (dpy, "CHARSET_REGISTRY", 0);
- if (XGetFontProperty (info, xatom, &rgstry)) {
- xatom = XInternAtom (dpy, "CHARSET_ENCODING", 0);
- if (XGetFontProperty (info, xatom, &encdng)) {
- Atom xatoms[2];
- char* names[2];
- int status;
- xatoms[0] = rgstry;
- xatoms[1] = encdng;
- names[0] = NULL;
- names[1] = NULL;
- # if !defined(HAVE_XGETATOMNAMES)
- names[0] = XGetAtomName (dpy, xatoms[0]);
- names[1] = XGetAtomName (dpy, xatoms[1]);
- status = names[0] && names[1];
- # else
- status = XGetAtomNames (dpy, xatoms, 2, names); /* X11R6 */
- # endif
- if (status) {
- /* this encoding canonicalization was requested by
- Pascal J.Bourguignon <pjb@informatimago.com>
- in <http://article.gmane.org/gmane.lisp.clisp.general:7794> */
- char* whole = (char*) alloca(strlen(names[0])+strlen(names[1])+3);
- if (!strncasecmp(names[0],"iso",3) && names[0][3] != '-') {
- strcpy(whole,"ISO-");
- strcat(whole,names[0]+3);
- } else strcpy(whole,names[0]);
- strcat(whole,"-");
- strcat(whole,names[1]);
- end_x_call();
- pushSTACK(S(Kcharset));
- pushSTACK(asciz_to_string(whole,GLO(misc_encoding)));
- pushSTACK(S(Koutput_error_action));
- pushSTACK(fixnum(info->default_char));
- funcall(L(make_encoding),4);
- pushSTACK(STACK_0); /* obj */
- pushSTACK(`XLIB::ENCODING`);
- pushSTACK(value1);
- funcall(L(set_slot_value),3);
- begin_x_call();
- }
- if (names[0])
- XFree (names[0]);
- if (names[1])
- XFree (names[1]);
- }
- }
- end_x_call();
- }
- # endif
- } else if (dpyf) /* caller wants the display, so get it! */
- unused get_font_and_display (STACK_0, dpyf);
- if (fontf) *fontf = STACK_0;
- skipSTACK(1);
- return info; /* all done */
- }
- static object get_font_name (object obj)
- {
- pushSTACK(obj); /* the instance */
- pushSTACK(`XLIB::NAME`); /* slot */
- funcall(L(slot_value), 2); /* lookup the slot */
- return value1;
- }
- #define ENSURE_TYPE(datum,booli,type) if (!booli) my_type_error(type,datum)
- static object get_slot (object obj, object slot)
- { /* like gethash(): return nullobj on unbound slot and slot value otherwise */
- pushSTACK(obj); pushSTACK(slot); /* save for SLOT-VALUE */
- pushSTACK(obj); pushSTACK(slot); funcall(L(slot_boundp),2);
- if (nullp(value1)) { skipSTACK(2); return nullobj; }
- funcall(L(slot_value),2); return value1;
- }
- static Font get_font (object self)
- { /* Does type-checking. */
- object font_id;
- pushSTACK(self); /* save */
- ENSURE_TYPE (STACK_0, font_p(STACK_0), `XLIB::FONT`);
- font_id = get_slot(STACK_0,`XLIB::ID`);
- if (!eq(font_id,nullobj)) { /* We have already a fid, so return it. */
- skipSTACK(1); /* clean up */
- ASSERT(integerp(font_id));
- return (XID)(get_uint29(font_id));
- } else { /* No font id => lookup the name & open that font */
- object name = get_font_name(STACK_0/*self*/);
- if (boundp(name)) { /* Ok there is a name ... so try to open the font */
- Font font; Display *dpy = get_display(STACK_0);
- with_string_0 (name, GLO(misc_encoding), namez, { /* XXX */
- X_CALL(font = XLoadFont(dpy,namez));
- });
- if (font) { /* Hurra! We got a font id, so enter it */
- pushSTACK(`XLIB::ID`); pushSTACK(make_uint29(font));
- funcall(L(set_slot_value),3);
- /* XXX -- We should enter it also into the hash table! */
- return font; /* all done */
- } else { /* We could not open the font, so emit an error message */
- pushSTACK(TheSubr(subr_self)->name); /* function name */
- error(error_condition,"~S: Cannot open pseudo font ~S");
- }
- } else { /* We have no name, tell that the luser. */
- pushSTACK(TheSubr(subr_self)->name); /* function name */
- error(error_condition,"~S: Cannot open pseudo font ~S, since it has no name associated with it.");
- }
- }
- }
- static Atom get_xatom_general (Display *dpy, object obj, int internp)
- { /* Converts a symbol or a string to an xatom. If 'obj' is no symbol
- nor a string, an error is raised. if 'internp' is non-0 the atom
- is interned on the server. */
- Atom xatom;
- with_stringable_0_tc (obj, GLO(misc_encoding), atom_name, {
- X_CALL(xatom = XInternAtom (dpy, atom_name, !internp));
- });
- return xatom;
- }
- #define get_xatom(dpy,obj) get_xatom_general (dpy, obj, 1) /* interning version */
- #define get_xatom_nointern(dpy,obj) get_xatom_general (dpy, obj, 0) /* non-interning version */
- static object make_visual (Visual *visual)
- {
- XID id;
- X_CALL(id = XVisualIDFromVisual (visual));
- return make_uint29 (id);
- }
- static Visual *get_visual (Display *dpy, object vid)
- {
- /* no begin/end_call here XVisualIDToVisual is defined by us. */
- return XVisualIDToVisual (dpy, get_uint29 (vid));
- }
- /* -----------------------------------------------------------------------
- * Lots of enums
- * ----------------------------------------------------------------------- */
- DEFCHECKER(get_map_state,default=,UNMAPPED=IsUnmapped \
- UNVIEWABLE=IsUnviewable VIEWABLE=IsViewable)
- #define make_map_state get_map_state_reverse
- DEFCHECKER(get_shape,default=,COMPLEX=Complex CONVEX=Convex \
- NON-CONVEX=Nonconvex)
- DEFCHECKER(get_W_class,default=,:COPY=CopyFromParent INPUT-OUTPUT=InputOutput \
- INPUT-ONLY=InputOnly)
- #define make_W_class get_W_class_reverse
- DEFCHECKER(get_stack_mode,default=,ABOVE=Above BELOW=Below TOP-IF=TopIf \
- BOTTOM-IF=BottomIf OPPOSITE=Opposite)
- #define make_stack_mode get_stack_mode_reverse
- DEFCHECKER(get_arc_mode,default=,CHORD=ArcChord PIE-SLICE=ArcPieSlice)
- #define make_arc_mode get_arc_mode_reverse
- DEFCHECKER(get_line_style,default=,SOLID=LineSolid DASH=LineOnOffDash \
- DOUBLE-DASH=LineDoubleDash)
- #define make_line_style get_line_style_reverse
- DEFCHECKER(get_cap_style,default=,NOT-LAST=CapNotLast BUTT=CapButt \
- ROUND=CapRound PROJECTING=CapProjecting)
- #define make_cap_style get_cap_style_reverse
- DEFCHECKER(get_join_style,default=, \
- MITER=JoinMiter ROUND=JoinRound BEVEL=JoinBevel)
- #define make_join_style get_join_style_reverse
- DEFCHECKER(get_fill_style,default=,SOLID=FillSolid TILED=FillTiled \
- STIPPLED=FillStippled OPAQUE-STIPPLED=FillOpaqueStippled)
- #define make_fill_style get_fill_style_reverse
- DEFCHECKER(get_fill_rule,default=, EVEN-ODD=EvenOddRule WINDING=WindingRule)
- #define make_fill_rule get_fill_rule_reverse
- DEFCHECKER(get_subwindow_mode,default=, \
- CLIP-BY-CHILDREN=ClipByChildren INCLUDE-INFERIORS=IncludeInferiors)
- #define make_subwindow_mode get_subwindow_mode_reverse
- DEFCHECKER(get_gravity,default=,FORGET=ForgetGravity \
- NORTH-WEST=NorthWestGravity NORTH=NorthGravity \
- NORTH-EAST=NorthEastGravity WEST=WestGravity CENTER=CenterGravity \
- EAST=EastGravity SOUTH-WEST=SouthWestGravity SOUTH=SouthGravity \
- SOUTH-EAST=SouthEastGravity STATIC=StaticGravity)
- #define make_gravity get_gravity_reverse
- /* NIM: the :static gravity is not mentioned in the CLX manual. */
- DEFCHECKER(get_visibility_state,default=, UNOBSCURED=VisibilityUnobscured \
- PARTLY-OBSCURED=VisibilityPartiallyObscured \
- FULLY-OBSCURED=VisibilityFullyObscured)
- #define make_visibility_state get_visibility_state_reverse
- DEFCHECKER(get_top_or_bottom,default=,TOP=PlaceOnTop BOTTOM=PlaceOnBottom)
- #define make_top_or_bottom get_top_or_bottom_reverse
- DEFCHECKER(get_new_value_or_deleted,default=, \
- NEW-VALUE=PropertyNewValue DELETED=PropertyDelete)
- #define make_new_value_or_deleted get_new_value_or_deleted_reverse
- DEFCHECKER(get_ordering,default=Unsorted, UNSORTED=Unsorted Y-SORTED=YSorted \
- YX-SORTED=YXSorted YX-BANDED=YXBanded)
- DEFCHECKER(get_mapping_request…
Large files files are truncated, but you can click here to view the full file