/* Functions for the X window system.
   Copyright (C) 1988 Free Software Foundation.

This file is part of GNU Emacs.

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the GNU Emacs General Public
License for full details.

Everyone is granted permission to copy, modify and redistribute
GNU Emacs, but only under the conditions described in the
GNU Emacs General Public License.   A copy of this license is
supposed to have been given to you along with GNU Emacs so you
can know your rights and responsibilities.  It should be in a
file named COPYING.  Among other things, the copyright notice
and this notice must be preserved on all copies.  */

/* Written by Yakim Martillo; rearranged by Richard Stallman.  */
/* Color and other features added by Robert Krawitz*/
/* Converted to X11 by Robert French */

#include <stdio.h>
#ifdef NULL
#undef NULL
#endif
#include <signal.h>
#include "config.h"
#include "lisp.h"
#include "window.h"
#include "x11term.h"
#include "dispextern.h"
#include "termchar.h"
#if defined(USG) && ! defined(OS_386ix)
#include <time.h>
#else
#include <sys/time.h>
#endif
#include <fcntl.h>
#include <setjmp.h>

#include "screen.h"
#include "screenW.h"		/* [amc] */
#include "screenX.h"		/* [amc] */
#include "xresource.h"

#ifdef HAVE_X_WINDOWS

#define abs(x) ((x < 0) ? ((x)) : (x))
#define sgn(x) ((x < 0) ? (-1) : (1))
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
  
/* Non-nil if Emacs is running with an X window for display.
   Nil if Emacs is run on an ordinary terminal.  */

Lisp_Object Vxterm;

Lisp_Object Vx_mouse_pos;
Lisp_Object Vx_mouse_abs_pos;

Lisp_Object Vx_mouse_item;

extern struct Lisp_Vector *MouseMap;

extern XEvent *XXm_queue[XMOUSEBUFSIZE];
extern int XXm_queue_num;
extern int XXm_queue_in;
extern int XXm_queue_out;

extern Display *XD_display;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

check_xterm ()
{
	if (NULL (Vxterm))
		error ("Terminal does not understand X protocol.");
}


DEFUN ("epoch::store-cut-buffer", Fx_store_cut_buffer, Sx_store_cut_buffer,
       1, 1, "sSend string to X:",
       "Store contents of STRING into the cut buffer of the X window system.")
     (string)
     register Lisp_Object string;
{
  BLOCK_INPUT_DECLARE ();

  CHECK_STRING (string, 1);
  check_xterm ();

  BLOCK_INPUT ();
  XStoreBytes (XD_display, XSTRING (string)->data,
	       XSTRING (string)->size);
  UNBLOCK_INPUT ();

  return Qnil;
}

DEFUN ("epoch::get-cut-buffer", Fx_get_cut_buffer, Sx_get_cut_buffer, 0, 0, 0,
  "Return contents of cut buffer of the X window system, as a string.")
     ()
{
  int len;
  register Lisp_Object string;
  BLOCK_INPUT_DECLARE ();
  register char *d;

  BLOCK_INPUT ();
  d = XFetchBytes (XD_display, &len);
  string = make_string (d, len);
  UNBLOCK_INPUT ();

  return string;
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
unsigned int
ElispSymbolToShiftBit(sym) Lisp_Object sym;
{
  
  if (EQ(sym,intern("shift"))) return 1;
  if (EQ(sym,intern("lock"))) return 2;
  if (EQ(sym,intern("control"))) return 4;
  if (EQ(sym,intern("meta"))) return 8;
  if (EQ(sym,intern("mod1"))) return 8;
  if (EQ(sym,intern("mod2"))) return 0x10;
  if (EQ(sym,intern("mod3"))) return 0x20;
  if (EQ(sym,intern("mod4"))) return 0x40;
  if (EQ(sym,intern("mod5"))) return 0x80;
  return 0;
}
  
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Re-written version of x-rebind-key [AMC] */

DEFUN ("epoch::rebind-key", Fx_rebind_key, Sx_rebind_key, 3, 3, 0,
       "Rebind KEYCODE, with MODIFIERS, to new string NEWSTRING.\n\
KEYCODE should be the string name of an X KeySym\n\
MODIFIERS should be a list of symbols, specifying the keyboard modifers.\n\
The valid ones are 'shift, 'lock, 'control, 'meta, 'mod1, 'mod2, 'mod3,\n\
'mod4 and 'mod5. 'mod1 and 'meta are equivalent.\n\
MODIFIERS can also be a shift mask, as defined by the X window system.\n\
NEWSTRING should be a key sequence string." ) (keycode, modifiers, newstring)
     Lisp_Object keycode;
     Lisp_Object modifiers;
     Lisp_Object newstring;
{
  KeySym xkey,mkey,*modlist;
  int imod = 0;
  int modrequest;
  int i,j,mod_set = 0;
  unsigned int mmask = 0;
  XModifierKeymap *xkmap;
  KeyCode *map;
  Lisp_Object result = Qt;
  BLOCK_INPUT_DECLARE();

  /* check arguments */
  CHECK_STRING(keycode,0);
  CHECK_STRING(newstring,2);

  if (INTEGERP(modifiers))
      mod_set = mmask = XFASTINT(modifiers);
  else if (CONSP(modifiers) || SYMBOLP(modifiers))
    {
      mod_set = 1;
      while (!NULL(modifiers))
	{
	  if (SYMBOLP(modifiers)) mmask |= ElispSymbolToShiftBit(modifiers);
	  if (CONSP(modifiers))
	    {
	      mmask |= ElispSymbolToShiftBit(XCONS(modifiers)->car);
	      modifiers = XCONS(modifiers)->cdr;
	    }
	  else modifiers = Qnil;
	}
    }
  else error("Modifiers must be int, symbol, or symbol list");

  BLOCK_INPUT();
  xkey = XStringToKeysym(XSTRING(keycode)->data);
  if (xkey == NoSymbol)
    {
      UNBLOCK_INPUT();
      error("Invalid X-key name");
    }
 
  xkmap = XGetModifierMapping(XD_display);

  modlist = (KeySym *) alloca(xkmap->max_keypermod * 8 * sizeof(KeySym));

  for ( i = 0 ; i < 8 ; ++i, mmask >>= 1 ) /* step through the bits */
    {
      if (mmask & 1)
	{
	  for ( j = 0, map = xkmap->modifiermap + xkmap->max_keypermod * i ;
	       j < xkmap->max_keypermod ; ++j, ++map )
	    if ( *map 
		&& NoSymbol != (mkey = XKeycodeToKeysym(XD_display,*map,0)))
	      modlist[imod++] = mkey;
	}
    }

  XFreeModifiermap(xkmap);
  if (imod || !mod_set)
    XRebindKeysym(XD_display,xkey,modlist,imod,
		  XSTRING(newstring)->data,XSTRING(newstring)->size);
  else result = Qnil;

  UNBLOCK_INPUT();

  return result;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
DEFUN ("epoch::mod-to-shiftmask",Fx_mod_to_shiftmask,Sx_mod_to_shiftmask,1,1,0,
"OBSOLETE. Do not use.\n\
 Given an index from 0..7, returns the shift mask corresponding to that\n\
 modifier under X windows. Indices are Shift, Lock, Control, Mod1, Mod2,\n\
 Mod3, Mod4, Mod5")
        (mod) Lisp_Object mod;
{
  int i,index,result;
  XModifierKeymap *xkmap;
  KeyCode *map;

  CHECK_NUMBER(mod,0);
  index = XFASTINT(mod);
  if (index < 0 || index > 7) return make_number(0);
  return make_number(1<<index);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* [amc] */
FlashScreen (dpy,win,fg,bg,width,height)
     Display *dpy;
     Window win;
     unsigned long fg,bg;
     unsigned width,height;
{
#ifdef HAVE_TIMEVAL
  struct timeval to;
#endif
  XGCValues gcv;
  GC thegc;
  BLOCK_INPUT_DECLARE ();
    
#ifdef XDEBUG
  fprintf (stderr, "XTflash\n");
#endif

  gcv.function = GXxor;
  gcv.foreground = fg ^ bg;
  gcv.fill_style = FillSolid;

  BLOCK_INPUT ();

  thegc = XCreateGC(dpy, win, GCFunction|GCForeground|GCFillStyle, &gcv);
  XFillRectangle (dpy, win, thegc, 0, 0, width, height);
  XFlush (dpy);
    
  UNBLOCK_INPUT ();
#ifdef HAVE_TIMEVAL
  to.tv_sec = 0;
  to.tv_usec = 250000;
    
  select(0, 0, 0, 0, &to);
#endif
  BLOCK_INPUT ();
    
  XFillRectangle (dpy, win, thegc, 0, 0, width, height);
  XFreeGC (dpy, thegc);
  XFlush (dpy);
  
  UNBLOCK_INPUT ();
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
DEFUN ("epoch::flash-screen", Fepoch_flash_screen, Sepoch_flash_screen,
       0, 1, "",
       "Flash the SCREEN-OR-XWIN. If omitted, flashes the current screen.")
     (screen) Lisp_Object screen;
{
  struct Lisp_Xresource *xr;
  struct Root_Block *rb;
  Lisp_Object result = screen;

  if (! (xr = ResourceOrScreen(screen,&rb))) return Qnil;

  if (rb)
    {
      XS_DEF;

      FlashScreen(xr->dpy, xr->id, xs->foreground, xs->background,
		  xs->pixwidth, xs->pixheight);
      XSET(result, Lisp_Root_Block, rb);
    }
  else
    {
      XWindowAttributes data;
      Status zret;

      HOLD_INPUT(zret = XGetWindowAttributes(xr->dpy,xr->id,&data));

      if (zret == True)
	FlashScreen(xr->dpy, xr->id, AllPlanes, 0, data.width, data.height);
      else
	result = Qnil;
    }
  return result;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
DEFUN ("epoch::set-bell", Fepoch_set_bell, Sepoch_set_bell, 1, 1, "",
       "With non-nil argument, sets Epoch to use a visual bell, otherwise to use an audible bell.")
     (arg) Lisp_Object arg;
{
  BLOCK_INPUT_DECLARE ();

  check_xterm ();
  BLOCK_INPUT ();
  if (!NULL (arg)) XSetFlash ();
  else XSetFeep ();
  UNBLOCK_INPUT ();
  return arg;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifdef NO_COED
DEFUN ("x-flip-color", Fx_flip_color, Sx_flip_color, 0, 0, "",
  "Toggle the background and foreground colors")
  ()
{
	check_xterm ();
	XFlipColor ();
	return Qt;
}

DEFUN ("x-set-foreground-color", Fx_set_foreground_color,
       Sx_set_foreground_color, 1, 1, "sSet foregroud color:  ",
       "Set foreground (text) color to COLOR.")
  (arg)
     Lisp_Object arg;
{
	XColor cdef;
	BLOCK_INPUT_DECLARE ();
	char *save_color;

	save_color = fore_color;
	check_xterm ();
	CHECK_STRING (arg,1);
	fore_color = (char *) xmalloc (XSTRING (arg)->size + 1);
	bcopy (XSTRING (arg)->data, fore_color, XSTRING (arg)->size + 1);

	BLOCK_INPUT ();

	if (fore_color && XXisColor &&
	    XParseColor (XXdisplay, XXColorMap, fore_color, &cdef) &&
	    XAllocColor(XXdisplay, XXColorMap, &cdef))
		fore = cdef.pixel;
	else
		if (fore_color && !strcmp (fore_color, "black"))
			fore = BlackPixel (XXdisplay, XXscreen);
		else
			if (fore_color && !strcmp (fore_color, "white"))
				fore = WhitePixel (XXdisplay, XXscreen);
			else
				fore_color = save_color;

	XSetForeground(XXdisplay, XXgc_norm, fore);
	XSetBackground(XXdisplay, XXgc_rev, fore);
	
	Fredraw_display ();
	UNBLOCK_INPUT ();

	XFlush (XXdisplay);
	return Qt;
}

DEFUN ("x-set-background-color", Fx_set_background_color,
       Sx_set_background_color, 1, 1, "sSet background color: ",
       "Set background color to COLOR.")
  (arg)
     Lisp_Object arg;
{
	XColor cdef;
	BLOCK_INPUT_DECLARE ();
	char *save_color;

	check_xterm ();
	CHECK_STRING (arg,1);
	save_color = back_color;
	back_color = (char *) xmalloc (XSTRING (arg)->size + 1);
	bcopy (XSTRING (arg)->data, back_color, XSTRING (arg)->size + 1);

	BLOCK_INPUT ();

	if (back_color && XXisColor &&
	    XParseColor (XXdisplay, XXColorMap, back_color, &cdef) &&
	    XAllocColor(XXdisplay, XXColorMap, &cdef))
		back = cdef.pixel;
	else
		if (back_color && !strcmp (back_color, "white"))
			back = WhitePixel (XXdisplay, XXscreen);
		else
			if (back_color && !strcmp (back_color, "black"))
				back = BlackPixel (XXdisplay, XXscreen);
			else
				back_color = save_color;

	XSetBackground (XXdisplay, XXgc_norm, back);
	XSetForeground (XXdisplay, XXgc_rev, back);
	XSetWindowBackground(XXdisplay, XXwindow, back);
	XClearArea (XXdisplay, XXwindow, 0, 0,
		    SCREEN_WIDTH*XXfontw+2*XXInternalBorder,
		    SCREEN_HEIGHT*XXfonth+2*XXInternalBorder, 0);
	
	UNBLOCK_INPUT ();
	Fredraw_display ();

	XFlush (XXdisplay);
	return Qt;
}

DEFUN ("x-set-border-color", Fx_set_border_color, Sx_set_border_color, 1, 1,
       "sSet border color: ",
       "Set border color to COLOR.")
  (arg)
     Lisp_Object arg;
{
	XColor cdef;
	BLOCK_INPUT_DECLARE ();

	check_xterm ();
	CHECK_STRING (arg,1);
	brdr_color= (char *) xmalloc (XSTRING (arg)->size + 1);
	bcopy (XSTRING (arg)->data, brdr_color, XSTRING (arg)->size + 1);

	BLOCK_INPUT ();

	if (brdr_color && XXisColor &&
	    XParseColor (XXdisplay, XXColorMap, brdr_color, &cdef) &&
	    XAllocColor(XXdisplay, XXColorMap, &cdef))
		brdr = cdef.pixel;
	else
		if (brdr_color && !strcmp (brdr_color, "black"))
			brdr = BlackPixel (XXdisplay, XXscreen);
		else
			if (brdr_color && !strcmp (brdr_color, "white"))
				brdr = WhitePixel (XXdisplay, XXscreen);
			else {
				brdr_color = "black";
				brdr = BlackPixel (XXdisplay, XXscreen);
			}

	if (XXborder) {
		XSetWindowBorder(XXdisplay, XXwindow, brdr);
		XFlush (XXdisplay);
	}
	
	UNBLOCK_INPUT ();

	return Qt;
}

DEFUN ("x-set-cursor-color", Fx_set_cursor_color, Sx_set_cursor_color, 1, 1,
       "sSet text cursor color: ",
       "Set text cursor color to COLOR.")
  (arg)
     Lisp_Object arg;
{
	XColor cdef;
	BLOCK_INPUT_DECLARE ();
	char *save_color;

	check_xterm ();
	CHECK_STRING (arg,1);
	save_color = curs_color;
	curs_color = (char *) xmalloc (XSTRING (arg)->size + 1);
	bcopy (XSTRING (arg)->data, curs_color, XSTRING (arg)->size + 1);

	BLOCK_INPUT ();

	if (curs_color && XXisColor &&
	    XParseColor (XXdisplay, XXColorMap, curs_color, &cdef) &&
	    XAllocColor(XXdisplay, XXColorMap, &cdef))
		curs = cdef.pixel;
	else
		if (curs_color && !strcmp (curs_color, "black"))
			curs = BlackPixel (XXdisplay, XXscreen);
		else
			if (curs_color && !strcmp (curs_color, "white"))
				curs = WhitePixel (XXdisplay, XXscreen);
			else
				curs_color = save_color;

	XSetBackground(XXdisplay, XXgc_curs, curs);
	
	CursorToggle ();
	CursorToggle ();

	UNBLOCK_INPUT ();
	return Qt;
}

DEFUN ("x-set-mouse-color", Fx_set_mouse_color, Sx_set_mouse_color, 1, 1,
       "sSet mouse cursor color: ",
       "Set mouse cursor color to COLOR.")
  (arg)
     Lisp_Object arg;
{
  BLOCK_INPUT_DECLARE ();
  char *save_color;

  check_xterm ();
  CHECK_STRING (arg,1);
  save_color = mous_color;
  mous_color = (char *) xmalloc (XSTRING (arg)->size + 1);
  bcopy (XSTRING (arg)->data, mous_color, XSTRING (arg)->size + 1);

  BLOCK_INPUT ();

  if (! x_set_cursor_colors ())
    mous_color = save_color;

  XFlush (XXdisplay);
	
  UNBLOCK_INPUT ();
  return Qt;
}   

/* Set the actual X cursor colors from `mous_color' and `back_color'.  */

int
x_set_cursor_colors ()
{
  XColor forec, backc;

  if (XXisColor && mous_color
      && XParseColor (XXdisplay, XXColorMap, mous_color, &forec)
      && XParseColor (XXdisplay, XXColorMap, back_color, &backc))
    {
      XRecolorCursor (XXdisplay, EmacsCursor, &forec, &backc);
      return 1;
    }
  else return 0;
}

DEFUN ("x-color-p", Fx_color_p, Sx_color_p, 0, 0, 0,
       "Returns t if the display is a color X terminal.")
  ()
{
	check_xterm ();

	if (XXisColor)
		return Qt;
	else
		return Qnil;
}
	
DEFUN ("x-get-foreground-color", Fx_get_foreground_color,
       Sx_get_foreground_color, 0, 0, 0,
       "Returns the color of the foreground, as a string.")
  ()
{
	Lisp_Object string;

	string = build_string (fore_color);
	return string;
}

DEFUN ("x-get-background-color", Fx_get_background_color,
       Sx_get_background_color, 0, 0, 0,
       "Returns the color of the background, as a string.")
  ()
{
	Lisp_Object string;

	string = build_string (back_color);
	return string;
}

DEFUN ("x-get-border-color", Fx_get_border_color,
       Sx_get_border_color, 0, 0, 0,
       "Returns the color of the border, as a string.")
  ()
{
	Lisp_Object string;

	string = build_string (brdr_color);
	return string;
}

DEFUN ("x-get-cursor-color", Fx_get_cursor_color,
       Sx_get_cursor_color, 0, 0, 0,
       "Returns the color of the cursor, as a string.")
  ()
{
	Lisp_Object string;

	string = build_string (curs_color);
	return string;
}

DEFUN ("x-get-mouse-color", Fx_get_mouse_color,
       Sx_get_mouse_color, 0, 0, 0,
       "Returns the color of the mouse cursor, as a string.")
  ()
{
	Lisp_Object string;

	string = build_string (mous_color);
	return string;
}

DEFUN ("x-get-default", Fx_get_default, Sx_get_default, 1, 1, 0,
       "Get default for X-window attribute ATTRIBUTE from the system.\n\
ATTRIBUTE must be a string.\n\
Returns nil if attribute default isn't specified.")
  (arg)
     Lisp_Object arg;
{
	char *default_name, *value;

	check_xterm ();
	CHECK_STRING (arg, 1);
	default_name = (char *) XSTRING (arg)->data;

	if (XXidentity)
		value = XGetDefault (XXdisplay, XXidentity, default_name);
	else
		value = XGetDefault (XXdisplay, CLASS, default_name);
 	
	if (value)
		return build_string (value);
	return (Qnil);
}

DEFUN ("x-set-baud", Fx_set_baud, Sx_set_baud, 1, 1, "nBaud Rate: ",
       "Sets the apparent baud rate to influence the refresh algorithm")
     (new_baud_rate)
{
    CHECK_NUMBER (new_baud_rate, 1);
    check_xterm ();
    baud_rate = XINT (new_baud_rate);
    return (Qnil);
}

DEFUN ("x-set-font", Fx_set_font, Sx_set_font, 1, 1, "sFont Name: ",
      "Sets the font to be used for the X window.")
  (arg)
     Lisp_Object arg;
{
	register char *newfontname;
	
	CHECK_STRING (arg, 1);
	check_xterm ();

	newfontname = (char *) xmalloc (XSTRING (arg)->size + 1);
	bcopy (XSTRING (arg)->data, newfontname, XSTRING (arg)->size + 1);
	if (XSTRING (arg)->size == 0)
		goto badfont;

	if (!XNewFont (newfontname)) {
		free (XXcurrentfont);
		XXcurrentfont = newfontname;
		return Qt;
	}
badfont:
	error ("Font \"%s\" is not defined", newfontname);
	free (newfontname);

	return Qnil;
}

DEFUN ("x-set-border-width", Fx_set_border_width, Sx_set_border_width,
  1, 1, "nBorder width: ",
  "Set width of border to WIDTH, in the X window system.")
  (borderwidth)
     register Lisp_Object borderwidth;
{
	BLOCK_INPUT_DECLARE ();

	CHECK_NUMBER (borderwidth, 0);

	check_xterm ();
  
	if (XINT (borderwidth) < 0)
		XSETINT (borderwidth, 0);
  
	BLOCK_INPUT ();
	XSetWindowBorderWidth(XXdisplay, XXwindow, XINT(borderwidth));
	XFlush(XXdisplay);
	UNBLOCK_INPUT ();

	return Qt;
}


DEFUN ("x-set-internal-border-width", Fx_set_internal_border_width,
       Sx_set_internal_border_width, 1, 1, "nInternal border width: ",
  "Set width of internal border to WIDTH, in the X window system.")
  (internalborderwidth)
     register Lisp_Object internalborderwidth;
{
	BLOCK_INPUT_DECLARE ();

	CHECK_NUMBER (internalborderwidth, 0);

	check_xterm ();
  
	if (XINT (internalborderwidth) < 0)
		XSETINT (internalborderwidth, 0);

	BLOCK_INPUT ();
	XXInternalBorder = XINT(internalborderwidth);
	XSetWindowSize(SCREEN_HEIGHT,SCREEN_WIDTH);
	UNBLOCK_INPUT ();

	return Qt;
}

#endif /* NO_COED */

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

XExitWithCoreDump ()
{
	XCleanUp ();
	abort ();
}

DEFUN ("x-debug", Fx_debug, Sx_debug, 1, 1, 0,
  "ARG non-nil means that X errors should generate a coredump.")
  (arg)
     register Lisp_Object arg;
{
	int (*handler)();

	if (!NULL (arg))
		handler = XExitWithCoreDump;
	else
	{
		extern int XIgnoreError ();
		handler = XIgnoreError;
	}
	XSetErrorHandler(handler);
	XSetIOErrorHandler(handler);
	return (Qnil);
}

XRedrawDisplay ()
{
	Fredraw_display ();
}

XCleanUp ()
{
	Fdo_auto_save (Qt);

#ifdef subprocesses
	kill_buffer_processes (Qnil);
#endif				/* subprocesses */
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

syms_of_xfns ()
{
  /* If not dumping, init_display ran before us, so don't override it.  */
#ifdef CANNOT_DUMP
  if (noninteractive)
#endif
    Vxterm = Qnil;

  syms_of_mouse();		/* set up mouse handling stuff */

  defsubr (&Sx_store_cut_buffer);
  defsubr (&Sx_get_cut_buffer);
  defsubr (&Sx_rebind_key);
  defsubr (&Sx_mod_to_shiftmask);
  defsubr (&Sepoch_flash_screen);
  defsubr (&Sepoch_set_bell);

#ifdef NO_COED
  defsubr (&Sx_set_bell);
  defsubr (&Sx_flip_color);
  defsubr (&Sx_set_font);
#ifdef notdef
  defsubr (&Sx_set_icon);
#endif /* notdef */
  defsubr (&Sx_set_border_width);
  defsubr (&Sx_set_internal_border_width);
  defsubr (&Sx_set_foreground_color);
  defsubr (&Sx_set_background_color);
  defsubr (&Sx_set_border_color);
  defsubr (&Sx_set_cursor_color);
  defsubr (&Sx_set_mouse_color);
  defsubr (&Sx_get_foreground_color);
  defsubr (&Sx_get_background_color);
  defsubr (&Sx_get_border_color);
  defsubr (&Sx_get_cursor_color);
  defsubr (&Sx_get_mouse_color);
  defsubr (&Sx_color_p);
  defsubr (&Sx_get_default);
  defsubr (&Sx_debug);
  defsubr (&Sx_set_baud);
#endif
}

#endif /* HAVE_X_WINDOWS */
