view src/lisp-union.h @ 4917:fce43cb76a1c

xlike cleanup, documentation -------------------- ChangeLog entries follow: -------------------- man/ChangeLog addition: 2010-02-03 Ben Wing <ben@xemacs.org> * internals/internals.texi (Top): * internals/internals.texi (Evaluation; Stack Frames; Bindings): * internals/internals.texi (Ben's README): * internals/internals.texi (Consoles; Devices; Frames; Windows): * internals/internals.texi (Window Hierarchy): * internals/internals.texi (The Window Object): * internals/internals.texi (Modules for the Basic Displayable Lisp Objects): * internals/internals.texi (Window-System Support): * internals/internals.texi (Creating a Window-System Type): * internals/internals.texi (Discussion -- Garbage Collection): Update the part at the top about how to maintain the file with more tips. Add a chapter on "window-system support" describing in a general way how the support for different window systems/device types works, including the separation between device-independent and device-dependent parts, device methods, the specific device types and the "xlike" pseudo-type. src/ChangeLog addition: 2010-02-03 Ben Wing <ben@xemacs.org> * Makefile.in.in: * Makefile.in.in (x_objs): * Makefile.in.in (gtk_gui_objs): * console-xlike-inc.h: * depend: * device-x.c: * emacs.c: * gccache-gtk.h: * gccache-gtk.h (gc_cache_lookup): * gccache-x.c: * gccache-x.c (GCCACHE_HASH): * gccache-x.h: * toolbar-gtk.c: * toolbar-gtk.c (gtk_initialize_frame_toolbars): * toolbar-x.c: * toolbar-x.c (x_initialize_frame_toolbars): * toolbar-xlike.c: * toolbar-xlike.c (xlike_draw_blank_toolbar_button): * toolbar-xlike.c (xlike_output_toolbar_button): * toolbar-xlike.c (xlike_get_button_size): * toolbar-xlike.c (XLIKE_OUTPUT_BUTTONS_LOOP): * toolbar-xlike.c (xlike_output_toolbar): * toolbar-xlike.c (xlike_clear_toolbar): * toolbar-xlike.c (xlike_output_frame_toolbars): * toolbar-xlike.c (xlike_clear_frame_toolbars): * toolbar-xlike.c (xlike_redraw_exposed_toolbar): * toolbar-xlike.c (xlike_redraw_exposed_toolbars): * toolbar-xlike.c (xlike_redraw_frame_toolbars): * toolbar-xlike.h: * toolbar-xlike.h (xlike_clear_frame_toolbars): Rename some files to make them consistent with general naming rules: xgccache.c -> gccache-x.c xgccache.h -> gccache-x.h toolbar-common.c -> toolbar-xlike.c toolbar-common.h -> toolbar-xlike.h Fix include-file references. Also change the names of functions in now-named toolbar-xlike.c to be xlike_foo() instead of common_foo(). Add a longish comment in console-xlike-inc.h describing the "xlike" system, how it works and what the various files are used for.
author Ben Wing <ben@xemacs.org>
date Wed, 03 Feb 2010 02:46:50 -0600
parents 78507f684253
children ae48681c47fa
line wrap: on
line source

/* Fundamental definitions for XEmacs Lisp interpreter -- union objects.
   Copyright (C) 1985, 1986, 1987, 1992, 1993, 1994
   Free Software Foundation, Inc.
   Copyright (C) 2002, 2005 Ben Wing.

This file is part of XEmacs.

XEmacs is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.

XEmacs is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with XEmacs; see the file COPYING.  If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

/* Divergent from FSF.  */

/* Definition of Lisp_Object type as a union.
   The declaration order of the objects within the struct members
   of the union is dependent on ENDIAN-ness.
   See lisp-disunion.h for more details.  */

typedef
union Lisp_Object
{
  /* if non-valbits are at lower addresses */
#ifdef WORDS_BIGENDIAN
  struct
  {
    EMACS_UINT val : VALBITS;
    enum_field (Lisp_Type) type : GCTYPEBITS;
  } gu;

  struct
  {
    signed EMACS_INT val : INT_VALBITS;
    unsigned int bits : INT_GCBITS;
  } s;

  struct
  {
    EMACS_UINT val : INT_VALBITS;
    unsigned int bits : INT_GCBITS;
  } u;
#else /* non-valbits are at higher addresses */
  struct
  {
    enum_field (Lisp_Type) type : GCTYPEBITS;
    EMACS_UINT val : VALBITS;
  } gu;

  struct
  {
    unsigned int bits : INT_GCBITS;
    signed EMACS_INT val : INT_VALBITS;
  } s;

  struct
  {
    unsigned int bits : INT_GCBITS;
    EMACS_UINT val : INT_VALBITS;
  } u;

#endif /* non-valbits are at higher addresses */

  EMACS_UINT ui;
  signed EMACS_INT i;

  /* This was formerly declared `void *v' etc. but that causes
     GCC to accept any (yes, any) pointer as the argument of
     a function declared to accept a Lisp_Object. */
  struct nosuchstruct *v;
}
Lisp_Object;

#define XCHARVAL(x) ((EMACS_INT)(x).gu.val)
#define XPNTRVAL(x) ((x).ui)

#define XREALINT(x) ((EMACS_INT)(x).s.val)
#define XUINT(x) ((EMACS_UINT)(x).u.val)
#define XTYPE(x) ((x).gu.type)
#define EQ(x,y) ((x).v == (y).v)

DECLARE_INLINE_HEADER (
Lisp_Object
make_int_verify (EMACS_INT val)
)
{
  Lisp_Object obj;
  obj.s.bits = 1;
  obj.s.val = val;
  type_checking_assert (XREALINT (obj) == val);
  return obj;
}

DECLARE_INLINE_HEADER (
Lisp_Object
make_int (EMACS_INT val)
)
{
  Lisp_Object obj;
  obj.s.bits = 1;
  obj.s.val = val;
  return obj;
}

DECLARE_INLINE_HEADER (
Lisp_Object
make_char_1 (Ichar val)
)
{
  Lisp_Object obj;
  obj.gu.type = Lisp_Type_Char;
  obj.gu.val = val;
  return obj;
}

DECLARE_INLINE_HEADER (
Lisp_Object
wrap_pointer_1 (const void *ptr)
)
{
  Lisp_Object obj;
  obj.ui = (EMACS_UINT) ptr;
  return obj;
}

extern MODULE_API Lisp_Object Qnull_pointer, Qzero;

#define INTP(x) ((x).s.bits)
#define INT_PLUS(x,y)  make_int (XINT (x) + XINT (y))
#define INT_MINUS(x,y) make_int (XINT (x) - XINT (y))
#define INT_PLUS1(x)   make_int (XINT (x) + 1)
#define INT_MINUS1(x)  make_int (XINT (x) - 1)

/* WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

   You can only VOID_TO_LISP something that had previously been
   LISP_TO_VOID'd.  You cannot go the other way, i.e. create a bogus
   Lisp_Object.  If you want to stuff a void * into a Lisp_Object, use
   make_opaque_ptr(). */

/* Convert between a (void *) and a Lisp_Object, as when the
   Lisp_Object is passed to a toolkit callback function */
DECLARE_INLINE_HEADER (
Lisp_Object
VOID_TO_LISP (const void *arg)
)
{
  Lisp_Object larg;
  larg.v = (struct nosuchstruct *) arg;
  return larg;
}

#define LISP_TO_VOID(larg) ((void *) ((larg).v))

/* Convert a Lisp_Object into something that can't be used as an
   lvalue.  Useful for type-checking. */
#if (__GNUC__ > 1)
#define NON_LVALUE(larg) ({ (larg); })
#else
/* Well, you can't really do it without using a function call, and
   there's no real point in that; no-union-type is the rule, and that
   will catch errors. */
#define NON_LVALUE(larg) (larg)
#endif