/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */

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

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

#ifndef _XEMACS_DEVICE_H_
#define _XEMACS_DEVICE_H_

struct redisplay_info;
struct device;
struct Lisp_Face;
struct display_line;
struct font_metric_info;
struct window_mirror;
struct scrollbar_instance;

/* 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;
  Bufpos bufpos;
  Bufpos closest;
  Lisp_Object obj;
  int retval;
};

struct device_methods
{
  CONST char *name;	/* Used by print_device */
  Lisp_Object symbol;
  Lisp_Object predicate_symbol;

  /* device methods */
  void (*init_device_method) (struct device *, Lisp_Object data);
  void (*delete_device_method) (struct device *);
  int (*initially_selected_for_input_method) (struct device *);
  void (*mark_device_method) (struct device *, void (*)(Lisp_Object));
  void (*asynch_device_change_method) ();
  int (*device_pixel_width_method) (struct device *);
  int (*device_pixel_height_method) (struct device *);
  int (*device_mm_width_method) (struct device *);
  int (*device_mm_height_method) (struct device *);
  int (*device_bitplanes_method) (struct device *);
  int (*device_color_cells_method) (struct device *);

  /* frame methods */
  Lisp_Object *device_specific_frame_params;
  void (*init_frame_method) (struct frame *, Lisp_Object parameters);
  void (*finish_init_frame_method) (struct frame *, Lisp_Object parameters);
  void (*mark_frame_method) (struct frame *, void (*)(Lisp_Object));
  void (*delete_frame_method) (struct frame *);
  void (*focus_on_frame_method) (struct frame *);
  void (*raise_frame_method) (struct frame *);
  void (*lower_frame_method) (struct frame *);
  int (*get_mouse_position_method) (struct device *, struct window **,
				    int *x, int *y);
  void (*set_mouse_position_method) (struct window *w, int x, int y);
  void (*make_frame_visible_method) (struct frame *f);
  void (*make_frame_invisible_method) (struct frame *f);
  void (*iconify_frame_method) (struct frame *f);
  void (*get_frame_params_method) (struct frame *f, Lisp_Object *alistptr);
  void (*set_frame_params_method) (struct frame *f, Lisp_Object alist);
  void (*set_frame_size_method) (struct frame *f, int width, int height);
  void (*set_frame_position_method) (struct frame *f, int xoff, int yoff);
  int (*frame_totally_visible_p_method) (struct frame *f);
  int (*frame_iconified_p_method) (struct frame *f);
  void (*set_title_from_char_method) (struct frame *f, char *title);
  void (*set_icon_name_from_char_method) (struct frame *f, char *title);

  /* color methods */
  int (*initialize_color_instance_method) (struct Lisp_Color_Instance *,
					   Lisp_Object name,
					   Lisp_Object device,
					   int no_error);
  void (*mark_color_instance_method) (struct Lisp_Color_Instance *,
				      void (*)(Lisp_Object));
  void (*print_color_instance_method) (struct Lisp_Color_Instance *,
				       Lisp_Object printcharfun,
				       int escapeflag);
  void (*finalize_color_instance_method) (struct Lisp_Color_Instance *);
  int (*color_instance_equal_method) (struct Lisp_Color_Instance *,
				      struct Lisp_Color_Instance *,
				      int depth);
  unsigned long (*color_instance_hash_method) (struct Lisp_Color_Instance *,
					       int depth);
  Lisp_Object (*color_instance_rgb_components_method)
    (struct Lisp_Color_Instance *);
  int (*valid_color_name_p_method) (struct device *, Lisp_Object color);

  /* font methods */
  int (*initialize_font_instance_method) (struct Lisp_Font_Instance *,
					  Lisp_Object name,
					  Lisp_Object device,
					  int no_error);
  void (*mark_font_instance_method) (struct Lisp_Font_Instance *,
				     void (*)(Lisp_Object));
  void (*print_font_instance_method) (struct Lisp_Font_Instance *,
				      Lisp_Object printcharfun,
				      int escapeflag);
  void (*finalize_font_instance_method) (struct Lisp_Font_Instance *);
  Lisp_Object (*font_instance_truename_method) (struct Lisp_Font_Instance *,
						int no_error);
  Lisp_Object (*font_instance_properties_method) (struct Lisp_Font_Instance *);
  Lisp_Object (*list_fonts_method) (Lisp_Object pattern,
				    Lisp_Object device);

  /* image methods */
  void (*mark_image_instance_method) (struct Lisp_Image_Instance *,
				      void (*)(Lisp_Object));
  void (*print_image_instance_method) (struct Lisp_Image_Instance *,
				       Lisp_Object printcharfun,
				       int escapeflag);
  void (*finalize_image_instance_method) (struct Lisp_Image_Instance *);
  int (*image_instance_equal_method) (struct Lisp_Image_Instance *,
				      struct Lisp_Image_Instance *,
				      int depth);
  unsigned long (*image_instance_hash_method) (struct Lisp_Image_Instance *,
					       int depth);
  Lisp_Object image_conversion_list;

  /* toolbar methods */
  void (*toolbar_size_changed_in_frame_method) (Lisp_Object specifier,
						struct frame *f,
						Lisp_Object oldval);
  void (*output_frame_toolbars_method) (struct frame *);
  void (*initialize_frame_toolbars_method) (struct frame *);
  void (*free_frame_toolbars_method) (struct frame *);
  void (*output_toolbar_button_method) (struct frame *, Lisp_Object);
  void (*redraw_frame_toolbars_method) (struct frame *);

  /* scrollbar methods */
  int (*inhibit_scrollbar_thumb_size_change_method) (void);
  void (*free_scrollbar_instance_method) (struct scrollbar_instance *);
  void (*release_scrollbar_instance_method) (struct scrollbar_instance *);
  void (*create_scrollbar_instance_method) (struct frame *, int,
					    struct scrollbar_instance *);
  void (*scrollbar_width_changed_in_frame_method) (Lisp_Object, struct frame *,
						   Lisp_Object);
  void (*scrollbar_height_changed_in_frame_method) (Lisp_Object,
						    struct frame *,
						   Lisp_Object);
  void (*update_scrollbar_instance_values_method) (struct window *,
						   struct scrollbar_instance *,
						   int, int, int, int, int,
						   int, int, int, int, int);
  void (*update_scrollbar_instance_status_method) (struct window *, int, int,
						   struct scrollbar_instance *);

  /* redisplay methods */
  void (*update_frame_menubars_method) (struct frame *);
  int (*left_margin_width_method) (struct window *);
  int (*right_margin_width_method) (struct window *);
  int (*text_width_method) (struct window *w, Lisp_Object font,
			    CONST Emchar *, int);
  void (*font_metric_info_method) (struct device *, Lisp_Object font,
				   struct font_metric_info *);
  void (*output_display_block_method) (struct window *, struct display_line *,
				       int, int, int, int, int, int, int);
  int (*divider_width_method) (void);
  int (*divider_height_method) (void);
  int (*eol_cursor_width_method) (void);
  void (*output_vertical_divider_method) (struct window *, int);
  void (*clear_to_window_end_method) (struct window *, int, int);
  void (*clear_region_method) (Lisp_Object, face_index, int, int, int, int);
  void (*clear_frame_method) (struct frame *);
  void (*output_begin_method) (struct device *);
  void (*output_end_method) (struct device *);
  int (*flash_method) (struct device *);
  void (*ring_bell_method) (struct device *, int volume, int pitch,
			    int duration);
  void (*frame_redraw_cursor_method) (struct frame *f);
};

#define DEVICE_TYPE_NAME(d) ((d)->methods->name)
#define DEVICE_TYPE(d) ((d)->methods->symbol)
#define DEVICE_SPECIFIC_FRAME_PARAMS(d) \
  ((d)->methods->device_specific_frame_params)

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

#define HAS_DEVTYPE_METH_P(meth, m) ((meth)->m##_method)
#define DEVTYPE_METH(meth, m, args) (((meth)->m##_method) args)

/* Call a void-returning device method, if it exists */
#define MAYBE_DEVTYPE_METH(meth, m, args)			\
do {								\
  struct device_methods *_maybe_devtype_meth_meth = (meth);	\
  if (HAS_DEVTYPE_METH_P (_maybe_devtype_meth_meth, m))		\
    DEVTYPE_METH (_maybe_devtype_meth_meth, m, args);		\
} while (0)

MAC_DECLARE_EXTERN (struct device_methods *, mactemp_devtype_meth_or_given)

/* Call a device method, if it exists; otherwise return
   the specified value */
#define DEVTYPE_METH_OR_GIVEN(meth, m, args, given)			\
MAC_BEGIN								\
  MAC_DECLARE (struct device_methods *,					\
	       mactemp_devtype_meth_or_given, meth)			\
  HAS_DEVTYPE_METH_P (mactemp_devtype_meth_or_given, m) ?		\
    DEVTYPE_METH (mactemp_devtype_meth_or_given, m, args) : (given)	\
MAC_END

/* Call an int-returning device method, if it exists; otherwise
   return 0 */
#define MAYBE_INT_DEVTYPE_METH(meth, m, args) \
  DEVTYPE_METH_OR_GIVEN (meth, m, args, 0)

/* Call an Lisp-Object-returning device method, if it exists;
   otherwise return Qnil */
#define MAYBE_LISP_DEVTYPE_METH(meth, m, args) \
  DEVTYPE_METH_OR_GIVEN (meth, m, args, Qnil)

/******** Same functions, operating on a device instead of a
          struct device_methods ********/

#define HAS_DEVMETH_P(d, m) HAS_DEVTYPE_METH_P ((d)->methods, m)
#define DEVMETH(d, m, args) DEVTYPE_METH ((d)->methods, m, args)
#define MAYBE_DEVMETH(d, m, args) MAYBE_DEVTYPE_METH ((d)->methods, m, args)
#define DEVMETH_OR_GIVEN(d, m, args, given) \
  DEVTYPE_METH_OR_GIVEN((d)->methods, m, args, given)
#define MAYBE_INT_DEVMETH(d, m, args) \
  MAYBE_INT_DEVTYPE_METH ((d)->methods, m, args)
#define MAYBE_LISP_DEVMETH(d, m, args) \
  MAYBE_LISP_DEVTYPE_METH ((d)->methods, m, args)

/******** Defining new device types ********/

#define DECLARE_DEVICE_TYPE(type)				\
extern struct device_methods * type##_device_methods

#define DEFINE_DEVICE_TYPE(type)		\
struct device_methods * type##_device_methods;	\
Lisp_Object Q##type

#define INITIALIZE_DEVICE_TYPE(type, obj_name, pred_sym)	\
  do {								\
    type##_device_methods =					\
      malloc_type_and_zero (struct device_methods);		\
    type##_device_methods->name = obj_name;			\
    defsymbol (&Q##type, obj_name);				\
    type##_device_methods->symbol = Q##type;			\
    defsymbol (&type##_device_methods->predicate_symbol,	\
	       pred_sym);					\
    add_entry_to_device_type_list (Q##type,			\
				   type##_device_methods);	\
    type##_device_methods->image_conversion_list = Qnil;	\
    staticpro (&type##_device_methods->image_conversion_list);	\
  } while (0)

/* Declare that device-type TYPE has method M; used in
   initialization routines */
#define DEVICE_HAS_METHOD(type, m) \
  (type##_device_methods->m##_method = type##_##m)

struct device
{
  struct lcrecord_header header;

  /* Name of this device, for resourcing and printing purposes.
     If not explicitly given, it's initialized in a device-specific
     manner. */
  Lisp_Object name;

  /* List of frames on this device. */
  Lisp_Object frame_list;

  /* Frame which is "currently selected".  This is what `selected-frame'
     returns and is the default frame for many operations.  This may
     not be the same as frame_with_focus; `select-frame' changes the
     selected_frame but not the frame_with_focus.  However, eventually
     either the two values will be the same, or frame_with_focus will
     be nil: right before waiting for an event, the focus is changed
     to point to the selected_frame if XEmacs currently has the focus
     on this device.  Note that frame_with_focus may be nil (none of the
     frames on this device have the window-system focus), but
     selected_frame will never be nil if there are any frames on
     the device. */
  Lisp_Object selected_frame;
  /* Frame that currently contains the window-manager focus, or none. */
  Lisp_Object frame_with_focus;
  /* If we have recently issued a request to change the focus as a
     result of select-frame having been called, the following variable
     records the frame we are trying to focus on.  The reason for this
     is that the window manager may not grant our request to change
     the focus (so we can't just change frame_with_focus), and we don't
     want to keep sending requests again and again to the window manager.
     This variable is reset whenever a focus-change event is seen. */
  Lisp_Object frame_that_ought_to_have_focus;

  /* Type of device.  All frames on a device must be of the same type. */
  struct device_methods *methods;
  Lisp_Object device_class;

  /* Really only needed for tty devices.  This maps escape sequences
     generated by function keys. */
  Lisp_Object function_key_map;

  /* Alist of values for user-defined tags in this device. */
  Lisp_Object user_defined_tags;

  /* Hash tables for device-specific objects (fonts, colors, etc).
     These are key-weak hash tables so that they disappear when the
     key goes away. */

  Lisp_Object color_instance_cache;
  Lisp_Object font_instance_cache;

  /* The image-instance cache is slightly different.  It is actually
     a bi-level cache, where the hash table in this slot here
     indexes image-instance-type masks (there are currently 6
     image-instance types and thus 64 possible masks) to
     key-weak hash tables like the ones for colors and fonts. */

  Lisp_Object image_instance_cache;

  /* A structure of auxiliary data specific to the device type.
     struct x_device is used for X window frames; defined in device-x.h
     struct tty_device is used to TTY's; defined in device-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 menubar_changed :1;
  unsigned int modeline_changed :1;
  unsigned int point_changed :1;
  unsigned int size_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 */
  int baud_rate;

  /* Character that causes a quit.  Normally C-g.
     #### Should be possible for this not to be ASCII. */
  int quit_char;

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

  /* 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
     devices.  Perhaps it should be conditionalized on SIGIO; but
     this requires including syssignal.h and systty.h. */
  int old_sigio_flag;
  int old_fcntl_owner;

  unsigned int input_enabled :1;

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

DECLARE_LRECORD (device, struct device);
#define XDEVICE(x) XRECORD (x, device, struct device)
#define XSETDEVICE(x, p) XSETRECORD (x, p, device)
#define DEVICEP(x) RECORDP (x, device)
#define CHECK_DEVICE(x, i) CHECK_RECORD (x, device)

#define CHECK_LIVE_DEVICE(x, i)						\
  do { CHECK_DEVICE (x, i);						\
       if (! DEVICEP (x)						\
	   || ! DEVICE_LIVE_P (XDEVICE (x)))				\
         x = wrong_type_argument (Qdevice_live_p, (x)); } while (0)

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

#ifdef ERROR_CHECK_TYPECHECK
MAC_DECLARE_EXTERN (struct device *, mactemp_device_data)
# define DEVICE_TYPE_DATA(d, type)				\
MAC_BEGIN							\
  MAC_DECLARE (struct device *, mactemp_device_data, d)		\
  assert (DEVICE_IS_TYPE (mactemp_device_data, type))		\
  MAC_SEP							\
  (struct type##_device *) mactemp_device_data->device_data	\
MAC_END
#else
# define DEVICE_TYPE_DATA(d, type)				\
  ((struct type##_device *) (d)->device_data)
#endif

#define CHECK_DEVICE_TYPE(x, i, type)			\
  do {							\
    CHECK_DEVICE (x, i);				\
    if (!(DEVICEP (x) && DEVICE_IS_TYPE (XDEVICE (x),	\
					 type)))	\
      x = wrong_type_argument				\
	(type##_device_methods->predicate_symbol, x);	\
  } 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_IS_X(d) DEVICE_IS_TYPE (d, x)
#define CHECK_X_DEVICE(z, i) CHECK_DEVICE_TYPE (z, i, x)

#define DEVICE_IS_NS(d) DEVICE_IS_TYPE (d, ns)
#define CHECK_NS_DEVICE(z, i) CHECK_DEVICE_TYPE (z, i, ns)

#if defined (HAVE_X_WINDOWS) && defined (HAVE_NEXTSTEP)
#define DEVICE_IS_WIN(d) (DEVICE_IS_X (d) || DEVICE_IS_NS (d))
#elif defined (HAVE_X_WINDOWS)
#define DEVICE_IS_WIN(d) DEVICE_IS_X (d)
#elif defined (HAVE_NEXTSTEP)
#define DEVICE_IS_WIN(d) DEVICE_IS_NS (d)
#else
#define DEVICE_IS_WIN(d) 0
#endif

#define DEVICE_IS_TTY(d) DEVICE_IS_TYPE (d, tty)
#define CHECK_TTY_DEVICE(x, i) CHECK_DEVICE_TYPE (x, i, tty)

#define DEVICE_IS_STREAM(d) DEVICE_IS_TYPE (d, stream)
#define CHECK_STREAM_DEVICE(x, i) CHECK_DEVICE_TYPE (x, i, stream)

extern Lisp_Object Vdevice_list, Vselected_device, Vdefault_device;
extern Lisp_Object Qdelete_device;
extern Lisp_Object Qdevice_live_p;

extern Lisp_Object Vdevice_class_list, Vdevice_type_list;

extern Lisp_Object Qtty, Qstream, Qdead;
#ifdef HAVE_X_WINDOWS
extern Lisp_Object Qx;
#endif /* HAVE_X_WINDOWS */
#ifdef HAVE_NEXTSTEP
extern Lisp_Object Qns;
#endif /* HAVE_NEXTSTEP */

extern Lisp_Object Qcolor, Qgrayscale, Qmono;
extern int valid_device_type_p (Lisp_Object type);
extern 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)
#define DEVICE_SELECTED_FRAME(d) ((d)->selected_frame)
#define DEVICE_FRAME_WITH_FOCUS(d) ((d)->frame_with_focus)
#define DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS(d)			\
  ((d)->frame_that_ought_to_have_focus)
#define DEVICE_FUNCTION_KEY_MAP(d) ((d)->function_key_map)
#define DEVICE_USER_DEFINED_TAGS(d) ((d)->user_defined_tags)
#define DEVICE_FRAME_LIST(d) ((d)->frame_list)
#define DEVICE_BAUD_RATE(d) ((d)->baud_rate)
#define DEVICE_QUIT_CHAR(d) ((d)->quit_char)
#define DEVICE_INFD(d) ((d)->infd)
#define DEVICE_OUTFD(d) ((d)->outfd)
#define DEVICE_OLD_SIGIO_FLAG(d) ((d)->old_sigio_flag)
#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) do { (d)->locked = 1; } while (0)
#define UNLOCK_DEVICE(d) do { (d)->locked = 0; } while (0)

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

#define INVALIDATE_PIXEL_TO_GLYPH_CACHE do {				\
  Lisp_Object dev;							\
  DEVICE_LOOP (dev)							\
    INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (XDEVICE (XCONS (dev)->car)); \
  } while (0)

#define MARK_DEVICE_FACES_CHANGED(d) do {				\
  faces_changed = 1;							\
  (d)->faces_changed = 1; } while (0)

#define MARK_DEVICE_TOOLBARS_CHANGED(d) do {				\
  toolbar_changed = 1;							\
  (d)->toolbar_changed = 1; } while (0)

#define MARK_DEVICE_SIZE_CHANGED(d) do {				\
  size_changed = 1;							\
  (d)->size_changed = 1; } while (0)

#define MARK_DEVICE_FRAMES_FACES_CHANGED(d) do {			\
  Lisp_Object frm;							\
  FRAME_LOOP (frm, d)							\
    XFRAME (XCONS (frm)->car)->faces_changed = 1;			\
  MARK_DEVICE_FACES_CHANGED (d); } while (0)

#define MARK_DEVICE_FRAME_CHANGED(d) do {				\
  frame_changed = 1;							\
  (d)->frame_changed = 1; } while (0)

#define MARK_DEVICE_WINDOWS_CHANGED(d) do {				\
  windows_changed = 1;							\
  (d)->windows_changed = 1; } while (0)

#define MARK_DEVICE_WINDOWS_STRUCTURE_CHANGED(d) do {			\
  windows_structure_changed = 1;					\
  (d)->windows_structure_changed = 1; } while (0)

/* 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))				\
   ? FRAME_DEVICE (XFRAME (WINDOW_FRAME (XWINDOW (obj)))) \
   : (FRAMEP (obj)				\
      ? FRAME_DEVICE (XFRAME (obj))		\
      : (DEVICEP (obj)				\
	 ? obj					\
	 : Qnil)))

#define DEVICE_LOOP(var) LIST_LOOP (var, Vdevice_list)
      
extern void select_device_1 (Lisp_Object);
extern Lisp_Object Fselected_device (void);
extern Lisp_Object Fdelete_device (Lisp_Object);
extern Lisp_Object Fdevice_type (Lisp_Object);
extern Lisp_Object Fdevice_name (Lisp_Object);
extern struct device *get_device (Lisp_Object);
extern void handle_asynch_device_change (void);
extern void call_critical_lisp_code (struct device *d, Lisp_Object function,
				     Lisp_Object object);
extern void add_entry_to_device_type_list (Lisp_Object symbol,
					   struct device_methods *type);
extern struct device_methods *decode_device_type (Lisp_Object type,
						  int no_error);

#endif /* _XEMACS_DEVICE_H_ */
