view src/device.h @ 826:6728e641994e

[xemacs-hg @ 2002-05-05 11:30:15 by ben] syntax cache, 8-bit-format, lots of code cleanup README.packages: Update info about --package-path. i.c: Create an inheritable event and pass it on to XEmacs, so that ^C can be handled properly. Intercept ^C and signal the event. "Stop Build" in VC++ now works. bytecomp-runtime.el: Doc string changes. compat.el: Some attempts to redo this to make it truly useful and fix the "multiple versions interacting with each other" problem. Not yet done. Currently doesn't work. files.el: Use with-obsolete-variable to avoid warnings in new revert-buffer code. xemacs.mak: Split up CFLAGS into a version without flags specifying the C library. The problem seems to be that minitar depends on zlib, which depends specifically on libc.lib, not on any of the other C libraries. Unless you compile with libc.lib, you get errors -- specifically, no _errno in the other libraries, which must make it something other than an int. (#### But this doesn't seem to obtain in XEmacs, which also uses zlib, and can be linked with any of the C libraries. Maybe zlib is used differently and doesn't need errno, or maybe XEmacs provides an int errno; ... I don't understand. Makefile.in.in: Fix so that packages are around when testing. abbrev.c, alloc.c, buffer.c, buffer.h, bytecode.c, callint.c, casefiddle.c, casetab.c, casetab.h, charset.h, chartab.c, chartab.h, cmds.c, console-msw.h, console-stream.c, console-x.c, console.c, console.h, data.c, device-msw.c, device.c, device.h, dialog-msw.c, dialog-x.c, dired-msw.c, dired.c, doc.c, doprnt.c, dumper.c, editfns.c, elhash.c, emacs.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, events.c, events.h, extents.c, extents.h, faces.c, file-coding.c, file-coding.h, fileio.c, fns.c, font-lock.c, frame-gtk.c, frame-msw.c, frame-x.c, frame.c, frame.h, glade.c, glyphs-gtk.c, glyphs-msw.c, glyphs-msw.h, glyphs-x.c, glyphs.c, glyphs.h, gui-msw.c, gui-x.c, gui.h, gutter.h, hash.h, indent.c, insdel.c, intl-win32.c, intl.c, keymap.c, lisp-disunion.h, lisp-union.h, lisp.h, lread.c, lrecord.h, lstream.c, lstream.h, marker.c, menubar-gtk.c, menubar-msw.c, menubar-x.c, menubar.c, minibuf.c, mule-ccl.c, mule-charset.c, mule-coding.c, mule-wnnfns.c, nas.c, objects-msw.c, objects-x.c, opaque.c, postgresql.c, print.c, process-nt.c, process-unix.c, process.c, process.h, profile.c, rangetab.c, redisplay-gtk.c, redisplay-msw.c, redisplay-output.c, redisplay-x.c, redisplay.c, redisplay.h, regex.c, regex.h, scrollbar-msw.c, search.c, select-x.c, specifier.c, specifier.h, symbols.c, symsinit.h, syntax.c, syntax.h, syswindows.h, tests.c, text.c, text.h, tooltalk.c, ui-byhand.c, ui-gtk.c, unicode.c, win32.c, window.c: Another big Ben patch. -- FUNCTIONALITY CHANGES: add partial support for 8-bit-fixed, 16-bit-fixed, and 32-bit-fixed formats. not quite done yet. (in particular, needs functions to actually convert the buffer.) NOTE: lots of changes to regex.c here. also, many new *_fmt() inline funs that take an Internal_Format argument. redo syntax cache code. make the cache per-buffer; keep the cache valid across calls to functions that use it. also keep it valid across insertions/deletions and extent changes, as much as is possible. eliminate the junky regex-reentrancy code by passing in the relevant lisp info to the regex routines as local vars. add general mechanism in extents code for signalling extent changes. fix numerous problems with the case-table implementation; yoshiki never properly transferred many algorithms from old-style to new-style case tables. redo char tables to support a default argument, so that mapping only occurs over changed args. change many chartab functions to accept Lisp_Object instead of Lisp_Char_Table *. comment out the code in font-lock.c by default, because font-lock.el no longer uses it. we should consider eliminating it entirely. Don't output bell as ^G in console-stream when not a TTY. add -mswindows-termination-handle to interface with i.c, so we can properly kill a build. add more error-checking to buffer/string macros. add some additional buffer_or_string_() funs. -- INTERFACE CHANGES AFFECTING MORE CODE: switch the arguments of write_c_string and friends to be consistent with write_fmt_string, which must have printcharfun first. change BI_* macros to BYTE_* for increased clarity; similarly for bi_* local vars. change VOID_TO_LISP to be a one-argument function. eliminate no-longer-needed CVOID_TO_LISP. -- char/string macro changes: rename MAKE_CHAR() to make_emchar() for slightly less confusion with make_char(). (The former generates an Emchar, the latter a Lisp object. Conceivably we should rename make_char() -> wrap_char() and similarly for make_int(), make_float().) Similar changes for other *CHAR* macros -- we now consistently use names with `emchar' whenever we are working with Emchars. Any remaining name with just `char' always refers to a Lisp object. rename macros with XSTRING_* to string_* except for those that reference actual fields in the Lisp_String object, following conventions used elsewhere. rename set_string_{data,length} macros (the only ones to work with a Lisp_String_* instead of a Lisp_Object) to set_lispstringp_* to make the difference clear. try to be consistent about caps vs. lowercase in macro/inline-fun names for chars and such, which wasn't the case before. we now reserve caps either for XFOO_ macros that reference object fields (e.g. XSTRING_DATA) or for things that have non-function semantics, e.g. directly modifying an arg (BREAKUP_EMCHAR) or evaluating an arg (any arg) more than once. otherwise, use lowercase. here is a summary of most of the macros/inline funs changed by all of the above changes: BYTE_*_P -> byte_*_p XSTRING_BYTE -> string_byte set_string_data/length -> set_lispstringp_data/length XSTRING_CHAR_LENGTH -> string_char_length XSTRING_CHAR -> string_emchar INTBYTE_FIRST_BYTE_P -> intbyte_first_byte_p INTBYTE_LEADING_BYTE_P -> intbyte_leading_byte_p charptr_copy_char -> charptr_copy_emchar LEADING_BYTE_* -> leading_byte_* CHAR_* -> EMCHAR_* *_CHAR_* -> *_EMCHAR_* *_CHAR -> *_EMCHAR CHARSET_BY_ -> charset_by_* BYTE_SHIFT_JIS* -> byte_shift_jis* BYTE_BIG5* -> byte_big5* REP_BYTES_BY_FIRST_BYTE -> rep_bytes_by_first_byte char_to_unicode -> emchar_to_unicode valid_char_p -> valid_emchar_p Change intbyte_strcmp -> qxestrcmp_c (duplicated functionality). -- INTERFACE CHANGES AFFECTING LESS CODE: use DECLARE_INLINE_HEADER in various places. remove '#ifdef emacs' from XEmacs-only files. eliminate CHAR_TABLE_VALUE(), which duplicated the functionality of get_char_table(). add BUFFER_TEXT_LOOP to simplify iterations over buffer text. define typedefs for signed and unsigned types of fixed sizes (INT_32_BIT, UINT_32_BIT, etc.). create ALIGN_FOR_TYPE as a higher-level interface onto ALIGN_SIZE; fix code to use it. add charptr_emchar_len to return the text length of the character pointed to by a ptr; use it in place of charcount_to_bytecount(..., 1). add emchar_len to return the text length of a given character. add types Bytexpos and Charxpos to generalize Bytebpos/Bytecount and Charbpos/Charcount, in code (particularly, the extents code and redisplay code) that works with either kind of index. rename redisplay struct params with names such as `charbpos' to e.g. `charpos' when they are e.g. a Charxpos, not a Charbpos. eliminate xxDEFUN in place of DEFUN; no longer necessary with changes awhile back to doc.c. split up big ugly combined list of EXFUNs in lisp.h on a file-by-file basis, since other prototypes are similarly split. rewrite some "*_UNSAFE" macros as inline funs and eliminate the _UNSAFE suffix. move most string code from lisp.h to text.h; the string code and text.h code is now intertwined in such a fashion that they need to be in the same place and partially interleaved. (you can't create forward references for inline funs) automated/lisp-tests.el, automated/symbol-tests.el, automated/test-harness.el: Fix test harness to output FAIL messages to stderr when in batch mode. Fix up some problems in lisp-tests/symbol-tests that were causing spurious failures.
author ben
date Sun, 05 May 2002 11:33:57 +0000
parents a5954632b187
children 84762348c6f9
line wrap: on
line source

/* Define device-object for XEmacs.
   Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
   Copyright (C) 1995 Ben Wing
   Copyright (C) 1995 Sun Microsystems

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.  */

/* Synched up with: Not in FSF. */

/* Written by Chuck Thompson and Ben Wing. */

#ifndef INCLUDED_device_h_
#define INCLUDED_device_h_

#include "console.h"

/* This should really be in redisplay.h but by putting it here we
   won't have to ensure that redisplay.h is always included before
   this file. */
struct pixel_to_glyph_translation_cache
{
  unsigned int valid :1;
  struct frame *frame;
  int low_x_coord, high_x_coord, col, obj_x;
  int low_y_coord, high_y_coord, row, obj_y;
  struct window *w;
  Charbpos charpos;
  Charbpos closest;
  Charcount modeline_closest;
  Lisp_Object obj1, obj2;
  int retval;
};

#define DEVICE_TYPE_NAME(d) ((d)->devmeths->name)
#define DEVICE_TYPE(d) ((d)->devmeths->symbol)
#define DEVICE_IMPL_FLAG(d, f) CONMETH_IMPL_FLAG ((d)->devmeths, (f))
#define DEVICE_SPECIFIC_FRAME_PROPS(d) \
  ((d)->devmeths->device_specific_frame_props)

/******** Accessing / calling a device method *********/

#define HAS_DEVMETH_P(d, m) HAS_CONTYPE_METH_P ((d)->devmeths, m)
#define DEVMETH(d, m, args) CONTYPE_METH ((d)->devmeths, m, args)
#define MAYBE_DEVMETH(d, m, args) MAYBE_CONTYPE_METH ((d)->devmeths, m, args)
#define DEVMETH_OR_GIVEN(d, m, args, given) \
  CONTYPE_METH_OR_GIVEN((d)->devmeths, m, args, given)
#define MAYBE_INT_DEVMETH(d, m, args) \
  MAYBE_INT_CONTYPE_METH ((d)->devmeths, m, args)
#define MAYBE_LISP_DEVMETH(d, m, args) \
  MAYBE_LISP_CONTYPE_METH ((d)->devmeths, m, args)

struct device
{
  struct lcrecord_header header;

  /* Methods for this device's console.  This can also be retrieved
     through device->console, but it's faster this way. */
  struct console_methods *devmeths;

  /* A structure of auxiliary data specific to the device type.
     struct x_device is used for X window frames; defined in console-x.h
     struct tty_device is used to TTY's; defined in console-tty.h */
  void *device_data;

  /* redisplay flags */
  unsigned int buffers_changed :1;
  unsigned int clip_changed :1;
  unsigned int extents_changed :1;
  unsigned int faces_changed :1;
  unsigned int frame_changed :1;
  unsigned int glyphs_changed :1;
  unsigned int subwindows_changed :1;
  unsigned int subwindows_state_changed :1;
  unsigned int icon_changed :1;
  unsigned int menubar_changed :1;
  unsigned int modeline_changed :1;
  unsigned int point_changed :1;
  unsigned int size_changed :1;
  unsigned int gutter_changed :1;
  unsigned int toolbar_changed :1;
  unsigned int windows_changed :1;
  unsigned int windows_structure_changed :1;

  unsigned int locked :1;

  /* Cache information about last pixel position translated to a
     glyph.  The law of locality applies very heavily here so caching
     the value leads to a significant win.  At the moment this is
     really X specific but once we have generic mouse support it won't
     be. */
  struct pixel_to_glyph_translation_cache pixel_to_glyph_cache;

  /* Output baud rate of device; used for redisplay decisions.  */
  int baud_rate;

  /* sound flags */
  unsigned int on_console_p :1;
  unsigned int connected_to_nas_p :1;

#define MARKED_SLOT(x) Lisp_Object x
#include "devslots.h"

  /* File descriptors for input and output.  Much of the time
     (but not always) these will be the same.  For an X device,
     these both hold the file descriptor of the socket used
     to communicate with the X server.  For a TTY device, these
     may or may not be the same and point to the terminal that
     is used for I/O. */
  int infd, outfd;

  /* infd and outfd are moved outside HAVE_UNIXOID_EVENT_LOOP conditionals,
     because Win32, presumably the first port which does not use select()
     polling, DOES have handles for a console device. -- kkm */

#ifdef HAVE_UNIXOID_EVENT_LOOP
  /* holds some data necessary for SIGIO control.  Perhaps this should
     be inside of device_data; but it is used for both TTY's and X
     device.  Perhaps it should be conditionalized on SIGIO; but
     this requires including syssignal.h and systty.h. */
  int old_fcntl_owner;
#endif
};

DECLARE_LRECORD (device, struct device);
#define XDEVICE(x) XRECORD (x, device, struct device)
#define wrap_device(p) wrap_record (p, device)
#define DEVICEP(x) RECORDP (x, device)
#define CHECK_DEVICE(x) CHECK_RECORD (x, device)
#define CONCHECK_DEVICE(x) CONCHECK_RECORD (x, device)

#define CHECK_LIVE_DEVICE(x) do {			\
  CHECK_DEVICE (x);					\
  if (! DEVICE_LIVE_P (XDEVICE (x)))			\
    dead_wrong_type_argument (Qdevice_live_p, (x));	\
} while (0)
#define CONCHECK_LIVE_DEVICE(x) do {			\
  CONCHECK_DEVICE (x);					\
  if (! DEVICE_LIVE_P (XDEVICE (x)))			\
    x = wrong_type_argument (Qdevice_live_p, (x));	\
} while (0)

#define DEVICE_TYPE_P(d, type)	EQ (DEVICE_TYPE (d), Q##type)

#ifdef ERROR_CHECK_TYPES
DECLARE_INLINE_HEADER (
struct device *
error_check_device_type (struct device *d, Lisp_Object sym)
)
{
  assert (EQ (DEVICE_TYPE (d), sym));
  return d;
}
# define DEVICE_TYPE_DATA(d, type)			\
  ((struct type##_device *) error_check_device_type (d, Q##type)->device_data)
#else
# define DEVICE_TYPE_DATA(d, type)			\
  ((struct type##_device *) (d)->device_data)
#endif

#define CHECK_DEVICE_TYPE(x, type)			\
  do {							\
    CHECK_DEVICE (x);					\
    if (!(DEVICEP (x) && DEVICE_TYPE_P (XDEVICE (x),	\
					 type)))	\
      dead_wrong_type_argument				\
	(type##_console_methods->predicate_symbol, x);	\
  } while (0)
#define CONCHECK_DEVICE_TYPE(x, type)			\
  do {							\
    CONCHECK_DEVICE (x);				\
    if (!(DEVICEP (x) && DEVICE_TYPE_P (XDEVICE (x),	\
					 type)))	\
      x = wrong_type_argument				\
	(type##_console_methods->predicate_symbol, x);	\
  } while (0)

#define DEVICE_DISPLAY_P(dev)				\
  (DEVICE_LIVE_P (dev) &&				\
    !DEVICE_IMPL_FLAG (dev, XDEVIMPF_IS_A_PRINTER))

#define CHECK_DISPLAY_DEVICE(dev)			\
  do {							\
    CHECK_DEVICE (dev);					\
    if (!(DEVICEP (dev)					\
          && DEVICE_DISPLAY_P (XDEVICE (dev))))		\
      dead_wrong_type_argument (Qdisplay, dev);		\
  } while (0)

#define CONCHECK_DISPLAY_DEVICE(dev)			\
  do {							\
    CONCHECK_DEVICE (dev);				\
    if (!(DEVICEP (dev)					\
          && DEVICE_DISPLAY_P (XDEVICE (dev))))		\
      wrong_type_argument (Qdisplay, dev);		\
  } while (0)

#define DEVICE_PRINTER_P(dev)				\
  (DEVICE_LIVE_P (dev) && !DEVICE_DISPLAY_P (dev))

#define CHECK_PRINTER_DEVICE(dev)			\
  do {							\
    CHECK_DEVICE (dev);					\
    if (!(DEVICEP (dev)					\
          && DEVICE_PRINTER_P (XDEVICE (dev))))		\
      dead_wrong_type_argument (Qprinter, dev);		\
  } while (0)

#define CONCHECK_PRINTER_DEVICE(dev)			\
  do {							\
    CONCHECK_DEVICE (dev);				\
    if (!(DEVICEP (dev)					\
          && DEVICE_PRINTER_P (XDEVICE (dev))))		\
      wrong_type_argument (Qprinter, dev);		\
  } while (0)

/* #### These should be in the device-*.h files but there are
   too many places where the abstraction is broken.  Need to
   fix. */

#define DEVICE_X_P(dev) CONSOLE_TYPESYM_X_P (DEVICE_TYPE (dev))
#define CHECK_X_DEVICE(z) CHECK_DEVICE_TYPE (z, x)
#define CONCHECK_X_DEVICE(z) CONCHECK_DEVICE_TYPE (z, x)

#define DEVICE_GTK_P(dev) CONSOLE_TYPESYM_GTK_P (DEVICE_TYPE (dev))
#define CHECK_GTK_DEVICE(z) CHECK_DEVICE_TYPE (z, gtk)
#define CONCHECK_GTK_DEVICE(z) CONCHECK_DEVICE_TYPE (z, gtk)

#define DEVICE_MSWINDOWS_P(dev) CONSOLE_TYPESYM_MSWINDOWS_P (DEVICE_TYPE (dev))
#define CHECK_MSWINDOWS_DEVICE(z) CHECK_DEVICE_TYPE (z, mswindows)
#define CONCHECK_MSWINDOWS_DEVICE(z) CONCHECK_DEVICE_TYPE (z, mswindows)

#define DEVICE_TTY_P(dev) CONSOLE_TYPESYM_TTY_P (DEVICE_TYPE (dev))
#define CHECK_TTY_DEVICE(z) CHECK_DEVICE_TYPE (z, tty)
#define CONCHECK_TTY_DEVICE(z) CONCHECK_DEVICE_TYPE (z, tty)

#define DEVICE_STREAM_P(dev) CONSOLE_TYPESYM_STREAM_P (DEVICE_TYPE (dev))
#define CHECK_STREAM_DEVICE(z) CHECK_DEVICE_TYPE (z, stream)
#define CONCHECK_STREAM_DEVICE(z) CONCHECK_DEVICE_TYPE (z, stream)

#define DEVICE_WIN_P(dev) CONSOLE_TYPESYM_WIN_P (DEVICE_TYPE (dev))

EXFUN (Fdevice_console, 1);
EXFUN (Fdevice_name, 1);
EXFUN (Ffind_device, 2);
EXFUN (Fmake_device, 3);
EXFUN (Fselected_device, 1);

extern Lisp_Object Qcreate_device_hook, Qdelete_device_hook, Qgrayscale;
extern Lisp_Object Qinit_post_tty_win, Qmono, Vdefault_x_device, Vdefault_gtk_device;
extern Lisp_Object Vdevice_class_list;

int valid_device_class_p (Lisp_Object class);

#define DEVICE_LIVE_P(d) (!EQ (DEVICE_TYPE (d), Qdead))

#define DEVICE_REDISPLAY_INFO(d) ((d)->redisplay_info)

#define DEVICE_NAME(d) ((d)->name)
#define DEVICE_CLASS(d) ((d)->device_class)
/* Catch people attempting to set this. */
#define DEVICE_SELECTED_FRAME(d) NON_LVALUE ((d)->selected_frame)
#define DEVICE_FRAME_WITH_FOCUS_REAL(d) ((d)->frame_with_focus_real)
#define DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS(d) ((d)->frame_with_focus_for_hooks)
#define DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS(d)			\
  ((d)->frame_that_ought_to_have_focus)
#define DEVICE_USER_DEFINED_TAGS(d) ((d)->user_defined_tags)
#define DEVICE_FRAME_LIST(d) ((d)->frame_list)
#define DEVICE_CONNECTION(d) ((d)->connection)
#define DEVICE_CANON_CONNECTION(d) ((d)->canon_connection)
#define DEVICE_CONSOLE(d) ((d)->console)
#define DEVICE_BAUD_RATE(d) ((d)->baud_rate)
#define DEVICE_INFD(d) ((d)->infd)
#define DEVICE_OUTFD(d) ((d)->outfd)
#define DEVICE_OLD_FCNTL_OWNER(d) ((d)->old_fcntl_owner)
#define DEVICE_ON_CONSOLE_P(d) ((d)->on_console_p)
#define DEVICE_CONNECTED_TO_NAS_P(d) ((d)->connected_to_nas_p)

#define LOCK_DEVICE(d) ((void) ((d)->locked = 1))
#define UNLOCK_DEVICE(d) ((void) ((d)->locked = 0))

#define INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE(d)			\
  ((void) ((d)->pixel_to_glyph_cache.valid = 0))

#define INVALIDATE_PIXEL_TO_GLYPH_CACHE do {					\
  Lisp_Object IPTGC_devcons, IPTGC_concons;					\
  DEVICE_LOOP_NO_BREAK (IPTGC_devcons, IPTGC_concons)				\
    INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (XDEVICE (XCAR (IPTGC_devcons)));	\
} while (0)

#define MARK_DEVICE_FACES_CHANGED(d)			\
  ((void) (faces_changed = (d)->faces_changed = 1))

#define MARK_DEVICE_GLYPHS_CHANGED(d)			\
  ((void) (glyphs_changed = (d)->glyphs_changed = 1))

#define MARK_DEVICE_SUBWINDOWS_CHANGED(d)			\
  ((void) (subwindows_changed = (d)->subwindows_changed = 1))

#define MARK_DEVICE_SUBWINDOWS_STATE_CHANGED(d)		\
  ((void) (subwindows_state_changed = (d)->subwindows_state_changed = 1))

#define MARK_DEVICE_TOOLBARS_CHANGED(d)			\
  ((void) (toolbar_changed = (d)->toolbar_changed = 1))

#define MARK_DEVICE_GUTTERS_CHANGED(d)		\
  ((void) (gutter_changed = (d)->gutter_changed = 1))

#define MARK_DEVICE_SIZE_CHANGED(d)			\
  ((void) (size_changed = (d)->size_changed = 1))

#define MARK_DEVICE_FRAMES_FACES_CHANGED(d) do {	\
  struct device *mdffc_d = (d);				\
  Lisp_Object frmcons;					\
  DEVICE_FRAME_LOOP (frmcons, mdffc_d)			\
    XFRAME (XCAR (frmcons))->faces_changed = 1;		\
  MARK_DEVICE_FACES_CHANGED (mdffc_d);			\
} while (0)

#define MARK_DEVICE_FRAMES_GLYPHS_CHANGED(d) do {	\
  struct device *mdffc_d = (d);				\
  Lisp_Object frmcons;					\
  DEVICE_FRAME_LOOP (frmcons, mdffc_d)			\
    XFRAME (XCAR (frmcons))->glyphs_changed = 1;		\
  MARK_DEVICE_GLYPHS_CHANGED (mdffc_d);		\
} while (0)

#define MARK_DEVICE_FRAME_CHANGED(d)			\
  ((void) (frame_changed = (d)->frame_changed = 1))

#define MARK_DEVICE_WINDOWS_CHANGED(d)			\
  ((void) (windows_changed = (d)->windows_changed = 1))

#define MARK_DEVICE_WINDOWS_STRUCTURE_CHANGED(d)	\
  ((void) (windows_structure_changed = (d)->windows_structure_changed = 1))

/* #### unify this with DOMAIN_DEVICE once the latter has image instances
   expunged from it. */
/* This turns out to be used heavily so we make it a macro to make it
   inline.  Also, the majority of the time the object will turn out to
   be a window so we move it from being checked last to being checked
   first. */
#define DFW_DEVICE(obj)					\
   (WINDOWP (obj) ? WINDOW_DEVICE (XWINDOW (obj))	\
 : (FRAMEP  (obj) ? FRAME_DEVICE (XFRAME (obj))		\
 : (DEVICEP (obj) ? obj					\
 : Qnil)))

/* NO_BREAK means that "break" doesn't do what you think it does!
   Use goto instead.  "continue" is OK, though. */
#define DEVICE_LOOP_NO_BREAK(devcons, concons)			\
  CONSOLE_LOOP (concons)					\
    CONSOLE_DEVICE_LOOP (devcons, XCONSOLE (XCAR (concons)))
#define DEVICE_FRAME_LOOP(frmcons, d) \
  LIST_LOOP (frmcons, DEVICE_FRAME_LIST (d))
#define CONSOLE_FRAME_LOOP_NO_BREAK(frmcons, devcons, con) \
  CONSOLE_DEVICE_LOOP (devcons, con) 			   \
    DEVICE_FRAME_LOOP (frmcons, XDEVICE (XCAR (devcons)))

void select_device_1 (Lisp_Object);
struct device *decode_device (Lisp_Object);
void handle_asynch_device_change (void);
void call_critical_lisp_code (struct device *d, Lisp_Object function,
			      Lisp_Object object);
void delete_device_internal (struct device *d, int force,
			     int called_from_delete_console,
			     int from_io_error);
void io_error_delete_device (Lisp_Object device);
Lisp_Object find_nonminibuffer_frame_not_on_device (Lisp_Object device);
void set_device_selected_frame (struct device *d, Lisp_Object frame);
Lisp_Object domain_device_type (Lisp_Object domain);
int window_system_pixelated_geometry (Lisp_Object domain);

#endif /* INCLUDED_device_h_ */