home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / lemacs-19.6 / src / xfns.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-24  |  67.4 KB  |  2,357 lines

  1. /* Functions for the X window system.
  2.    Copyright (C) 1989, 1992, 1993 Free Software Foundation.
  3.  
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* Substantially rewritten for Lucid GNU Emacs.  */
  21.  
  22. #include "config.h"
  23.  
  24. #include <stdio.h>
  25. #include <signal.h>
  26.  
  27. #include <X11/IntrinsicP.h>    /* CoreP.h needs this */
  28. #include <X11/CoreP.h>        /* foul, but we need this to use our own
  29.                    window inside a widget instead of one 
  30.                    that Xt creates... */
  31. #include <X11/StringDefs.h>
  32. #include <X11/Xresource.h>
  33. #include <X11/Shell.h>
  34.  
  35. #include <X11/Xaw/Paned.h>
  36. #include <X11/Xaw/Label.h>
  37.  
  38. #include <X11/Xos.h>
  39.  
  40. #include "ScreenWidgetP.h"
  41.  
  42. #ifdef LINE_INFO_WIDGET
  43. # include "LineInfoWidget.h"
  44. # include "LineInfoWidgetP.h"
  45. #endif
  46.  
  47. #include "EmacsShell.h"
  48. #include "EmacsShellP.h"
  49.  
  50. #if (XtSpecificationRelease >= 5)    /* Do the EDITRES protocol */
  51. #define HACK_EDITRES
  52. extern void _XEditResCheckMessages();
  53. #endif /* R5 */
  54.  
  55. #ifdef USE_SOUND
  56. # include <netdb.h>
  57. #endif
  58.  
  59. #include "lisp.h"
  60. #include "xterm.h"
  61. #include "window.h"
  62. #include "buffer.h"
  63. #include "extents.h"
  64. #include "screen.h"
  65. #include "events.h"
  66. #include "faces.h"
  67.  
  68. #ifdef HAVE_X_WINDOWS
  69.  
  70. #define min(a,b) ((a) < (b) ? (a) : (b))
  71. #define max(a,b) ((a) > (b) ? (a) : (b))
  72. #define COLOR_SCREEN_P(d) (XCellsOfScreen (DefaultScreenOfDisplay (d)) > 2)
  73.  
  74. Lisp_Object Vx_gc_pointer_shape;
  75.  
  76. /* If non-nil, use vertical bar cursor. */
  77. Lisp_Object Vbar_cursor;
  78.  
  79. /* Where bitmaps are; initialized from resource database */
  80. Lisp_Object Vx_bitmap_file_path;
  81.  
  82. /* The application class of Emacs. */
  83. Lisp_Object Vx_emacs_application_class;
  84.  
  85. /* The screen on which we have placed a WM_COMMAND property.  Only one. */
  86. Lisp_Object WM_COMMAND_screen;
  87.  
  88. Atom Xatom_WM_TAKE_FOCUS, Xatom_WM_SAVE_YOURSELF, Xatom_WM_DELETE_WINDOW,
  89.  Xatom_WM_PROTOCOLS;
  90.  
  91. Lisp_Object Qundefined_color;
  92. Lisp_Object Qx_resource_name;
  93.  
  94. extern Lisp_Object Vwindow_system_version;
  95.  
  96. /* Default parameters to use when creating screens.  */
  97. Lisp_Object Vx_screen_defaults;
  98.  
  99. /* Do we accept events send by other clients? */
  100. int x_allow_sendevents;
  101.  
  102. extern Lisp_Object Qmouse_enter_screen_hook, Qmouse_leave_screen_hook;
  103. extern Lisp_Object Qmap_screen_hook, Qunmap_screen_hook;
  104. extern Lisp_Object Qcreate_screen_hook;
  105.  
  106.  
  107. /* Return the Emacs screen-object corresponding to an X window */
  108. struct screen *
  109. x_window_to_screen (wdesc)
  110.      Window wdesc;
  111. {
  112.   Lisp_Object tail, screen;
  113.   struct screen *s;
  114.  
  115.   for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
  116.     {
  117.       screen = XCONS (tail)->car;
  118.       if (!SCREENP (screen))
  119.         continue;
  120.       s = XSCREEN (screen);
  121.       if (SCREEN_IS_X (s) && XtWindow (s->display.x->edit_widget) == wdesc)
  122.         return s;
  123.     }
  124.   return 0;
  125. }
  126.  
  127. /* Like x_window_to_screen but also compares the window with the widget's
  128.    widows */
  129. struct screen *
  130. x_any_window_to_screen (wdesc)
  131.      Window wdesc;
  132. {
  133.   Lisp_Object tail, screen;
  134.   struct screen *s;
  135.   struct x_display *x;
  136.  
  137.   for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
  138.     {
  139.       screen = XCONS (tail)->car;
  140.       if (!SCREENP (screen))
  141.         continue;
  142.       s = XSCREEN (screen);
  143.       if (!SCREEN_IS_X (s))
  144.     continue;
  145.       x = s->display.x;
  146.       /* This screen matches if the window is any of its widgets. */
  147.       if (wdesc == XtWindow (x->widget) ||
  148.       wdesc == XtWindow (x->column_widget) ||
  149.       wdesc == XtWindow (x->edit_widget))
  150.     return s;
  151.       /* Match if the window is this screen's menubar. */
  152.       if (x->menubar_widget &&
  153.       wdesc == XtWindow (x->menubar_widget))
  154.     return s;
  155.       /* Do *not* match if the window is this screen's psheet. */
  156.     }
  157.   return 0;
  158. }
  159.  
  160. Lisp_Object text_part_sym;
  161. Lisp_Object modeline_part_sym;
  162.  
  163.  
  164. /* Connect the screen-parameter names (symbols) to the corresponding
  165.    X Resource Manager names.  The name of a parameter, as a Lisp symbol,
  166.    has an `x-resource-name' property which is a Lisp_String. */
  167.  
  168. static void
  169. init_x_parm_symbols ()
  170. {
  171.   register Lisp_Object propname;
  172.   Qx_resource_name = propname = intern ("x-resource-name");
  173.  
  174. #define def(sym, rsrc) \
  175.   Fput (intern (sym), propname, build_string (rsrc))
  176. #define defi(sym,rsrc) \
  177.     def (sym, rsrc); Fput (intern (sym), Qintegerp, Qt)
  178.  
  179.   def ("cursor-color", XtNcursorColor);
  180.   def ("border-color", XtNborderColor);
  181.   defi("border-width", XtNborderWidth);
  182.   defi("internal-border-width", XtNinternalBorderWidth);
  183.   defi("width", XtNwidth);
  184.   defi("height", XtNheight);
  185.   defi("x", XtNx);
  186.   defi("y", XtNy);
  187. /*  def ("icon-type", "iconType"); */
  188. #ifdef LINE_INFO_COLUMN
  189.   defi("line-info-column-width", XtNlineInfoColumnWidth);
  190.   def ("line-info-column-foreground-color", XtNlineInfoColumnForeground);
  191.   def ("line-info-column-background-color", XtNlineInfoColumnBackground);
  192. #endif
  193. /*  def ("vertical-scroll-bar", XtNverticalScrollBar); */
  194. /*  def ("horizontal-scroll-bar", XtNhorizontalScrollBar); */
  195.   def ("minibuffer", XtNminibuffer);
  196.   def ("unsplittable", XtNunsplittable);
  197.   defi("inter-line-space", XtNinterline);
  198. /*  def ("bar-cursor", XtNbarCursor); */
  199. /*  def ("visual-bell", XtNvisualBell); */
  200. /*  defi("bell-volume", XtNbellVolume); */
  201.   
  202. #undef def
  203. }
  204.  
  205.  
  206. /* Insert a description of internally-recorded parameters of screen X
  207.    into the parameter alist *ALISTPTR that is to be given to the user.
  208.    Only parameters that are specific to the X window system
  209.    and whose values are not correctly recorded in the screen's
  210.    param_alist need to be considered here.  */
  211.  
  212. extern Lisp_Object Vinvocation_name;
  213.  
  214. static void
  215. color_to_string (w, pixel, buf)
  216.      Widget w;
  217.      unsigned long pixel;
  218.      char *buf;
  219. {
  220.   XColor color;
  221.   color.pixel = pixel;
  222.   BLOCK_INPUT;
  223.   XQueryColor (XtDisplay (w), w->core.colormap, &color);
  224.   UNBLOCK_INPUT;
  225.   sprintf (buf, "#%04x%04x%04x", color.red, color.green, color.blue);
  226. }
  227.  
  228.  
  229. extern void store_in_alist (Lisp_Object *, char *, Lisp_Object);
  230.  
  231. void
  232. x_report_screen_params (s, alistptr)
  233.      struct screen *s;
  234.      Lisp_Object *alistptr;
  235. {
  236.   TopLevelShellWidget shell = (TopLevelShellWidget)s->display.x->widget;
  237.   EmacsScreenWidget w = (EmacsScreenWidget)s->display.x->edit_widget;
  238.   char buf [255];
  239.  
  240. #define store_int(sym, slot) \
  241.   store_in_alist (alistptr, sym, make_number (slot))
  242. #define store_str(sym, slot) \
  243.   store_in_alist (alistptr, sym, build_string (slot))
  244. #define store_bool(sym, slot) \
  245.   store_in_alist (alistptr, sym, (slot) ? Qt : Qnil)
  246. #define store_color(sym, slot) \
  247.   color_to_string ((Widget) w, slot, buf); \
  248.   store_in_alist (alistptr, sym, build_string (buf))
  249. #define store_curs(sym, slot) /* #### don't have the strings any more... */
  250.  
  251.   store_color ("cursor-color", w->emacs_screen.cursor_color);
  252.   store_color ("border-color", w->core.border_pixel);
  253.   store_int ("left", shell->core.x);
  254.   store_int ("top", shell->core.y);
  255.   store_int ("border-width", w->core.border_width);
  256.   store_int ("internal-border-width", w->emacs_screen.internal_border_width);
  257.   store_int ("inter-line-space", w->emacs_screen.interline);
  258.   store_bool ("minibuffer", w->emacs_screen.minibuffer);
  259.   store_bool ("unsplittable", w->emacs_screen.minibuffer);
  260. /*  store_bool ("visual-bell", w->emacs_screen.visual_bell); */
  261. /*  store_bool ("bar-cursor",  w->emacs_screen.bar_cursor); */
  262.   sprintf (buf, "0x%x", XtWindow (w));
  263.   store_str ("window-id", buf);
  264. }
  265.  
  266.  
  267. /* Functions called only from `x_set_screen_param' to set
  268. ** individual parameters. */
  269.  
  270. void 
  271. x_set_title_from_char (struct screen* s, char* name)
  272. {
  273.   char *old_name = 0;
  274.   Arg av [1];
  275.   BLOCK_INPUT;
  276.   XtSetArg (av[0], XtNtitle, &old_name);
  277.   XtGetValues (s->display.x->widget, av, 1);
  278.   if (!old_name || strcmp (name, old_name))
  279.     {
  280.       XtSetArg (av[0], XtNtitle, name);
  281.       XtSetValues (s->display.x->widget, av, 1);
  282.     }
  283.   UNBLOCK_INPUT;
  284. }
  285.  
  286. void
  287. x_set_icon_name_from_char (struct screen* s, char* name)
  288. {
  289.   char *old_name = 0;
  290.   Arg av [1];
  291.   BLOCK_INPUT;
  292.   XtSetArg (av[0], XtNiconName, &old_name);
  293.   XtGetValues (s->display.x->widget, av, 1);
  294.   if (!old_name || strcmp (name, old_name))
  295.     {
  296.       XtSetArg (av[0], XtNiconName, name);
  297.       XtSetValues (s->display.x->widget, av, 1);
  298.     }
  299.   UNBLOCK_INPUT;
  300. }
  301.  
  302. /* Report to X that a screen parameter of screen S is being set or changed.
  303.    If the parameter is not specially recognized, do nothing.
  304.  */
  305.  
  306. extern void store_screen_param (struct screen *s, Lisp_Object, Lisp_Object);
  307.  
  308. void
  309. x_set_screen_values (s, alist)
  310.      struct screen *s;
  311.      Lisp_Object alist;
  312. {
  313.   int x, y;
  314.   Dimension width = 0, height = 0;
  315.   Bool size_specified_p = False;
  316.   Bool x_specified_p = False;
  317.   Bool y_specified_p = False;
  318.   Lisp_Object tail;
  319.   Widget w = s->display.x->edit_widget;
  320.   
  321.   for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
  322.     {
  323.       Lisp_Object elt = Fcar (tail);
  324.       Lisp_Object prop = Fcar (elt);
  325.       Lisp_Object val = Fcdr (elt);
  326.       
  327.       if (STRINGP (prop))
  328.     {
  329.       if (XSTRING (prop)->size == 0)
  330.         continue;
  331.  
  332.       BLOCK_INPUT;
  333.       if (STRINGP (val))
  334.         XtVaSetValues (w, XtVaTypedArg, XSTRING (prop)->data, XtRString,
  335.                XSTRING (val)->data, XSTRING (val)->size + 1,
  336.                0);
  337.       else
  338.         XtVaSetValues (w, XtVaTypedArg,
  339.                XSTRING (prop)->data, XtRInt, XINT (val),
  340.                sizeof (int),
  341.                0);
  342.       UNBLOCK_INPUT;
  343.     }
  344.       else
  345.     {
  346.       Lisp_Object str = Fget (prop, Qx_resource_name);
  347.       int int_p = !NILP (Fget (prop, Qintegerp));
  348.       if (NILP (prop) || NILP (str))
  349.         continue;
  350.       CHECK_STRING (str, 0);
  351.  
  352.       /* Kludge the width/height so that we interpret them in characters
  353.          instead of pixels.  Yuck yuck yuck. */
  354.       if (!strcmp ((char *) XSTRING (str)->data, "width"))
  355.         {
  356.           CHECK_FIXNUM (val, 0);
  357.           width = XINT (val);
  358.           size_specified_p = True;
  359.           continue;
  360.         }
  361.       if (!strcmp ((char *) XSTRING (str)->data, "height"))
  362.         {
  363.           CHECK_FIXNUM (val, 0);
  364.           height = XINT (val);
  365.           size_specified_p = True;
  366.           continue;
  367.         }
  368.       /* Further kludge the x/y to call set-screen-position instead. */
  369. #if 0
  370.       /* this doesn't work because the window isn't around yet,.
  371.          I guess we really need to cons up a geometry spec. */
  372.       if (!strcmp ((char *) XSTRING (str)->data, "x"))
  373.         {
  374.           CHECK_FIXNUM (val, 0);
  375.           x = XINT (val);
  376.           x_specified_p = True;
  377.           continue;
  378.         }
  379.       if (!strcmp ((char *) XSTRING (str)->data, "y"))
  380.         {
  381.           CHECK_FIXNUM (val, 0);
  382.           y = XINT (val);
  383.           y_specified_p = True;
  384.           continue;
  385.         }
  386. #endif
  387.  
  388.       BLOCK_INPUT;
  389.       if (int_p)
  390.         {
  391.           CHECK_FIXNUM (val, 0);
  392.           XtVaSetValues (w, (char *) XSTRING (str)->data, XINT (val),
  393.                  0);
  394.         }
  395.       else if (EQ (val, Qt))
  396.         XtVaSetValues (w, (char *) XSTRING (str)->data, /* XtN... */
  397.                True,
  398.                0);
  399.       else if (EQ (val, Qnil))
  400.         XtVaSetValues (w, (char *) XSTRING (str)->data, /* XtN... */
  401.                False,
  402.                0);
  403.       else
  404.         {
  405.           CHECK_STRING (val, 0);
  406.           XtVaSetValues (w, XtVaTypedArg,
  407.                  (char *) XSTRING (str)->data, /* XtN... */
  408.                  XtRString,
  409.                  XSTRING (val)->data, XSTRING (val)->size + 1,
  410.                  0);
  411.         }
  412.       UNBLOCK_INPUT;
  413.     }
  414.     }
  415.  
  416.   /* Kludge kludge kludge. */
  417.   if (size_specified_p)
  418.     {
  419.       Lisp_Object screen;
  420.       XSET (screen, Lisp_Screen, s);
  421.       if (width == 0) width = SCREEN_WIDTH (s);
  422.       if (height == 0) height = SCREEN_HEIGHT (s);
  423.       Fset_screen_size (screen, make_number (width), make_number (height),
  424.             Qnil);
  425.     }
  426.   /* Kludge kludge kludge kludge. */
  427.   if (x_specified_p || y_specified_p)
  428.     {
  429.       Lisp_Object screen;
  430.       XSET (screen, Lisp_Screen, s);
  431.       if (!x_specified_p) x = s->display.x->widget->core.x;
  432.       if (!y_specified_p) y = s->display.x->widget->core.y;
  433.       Fset_screen_position (screen, make_number (x), make_number (y));
  434.     }
  435. }
  436.  
  437. void
  438. fix_pane_constraints (w)
  439.   Widget w;
  440. {
  441.   BLOCK_INPUT;
  442.   XtVaSetValues (w, XtNshowGrip, 0, XtNresizeToPreferred, 1,
  443.          XtNallowResize, 1, 0);
  444.   UNBLOCK_INPUT;
  445. }
  446.  
  447. #ifdef ENERGIZE
  448.  
  449. /* #### remove this when we do not use uilib anymore */
  450. void sheet_callback () {}
  451.  
  452. extern int *get_psheets_for_buffer ();
  453.  
  454. void
  455. recompute_screen_menubar (screen)
  456.      struct screen *screen;
  457. {
  458.   /* #### This shouldn't be necessary any more */
  459. }
  460.  
  461.  
  462. /* This function is invoked by each menu item which Energize should handle.
  463.    Defined in xterm.c.
  464.  */
  465. extern void client_menu_item_cb ();
  466.  
  467. void
  468. make_psheets_desired (s, buffer)
  469.      struct screen* s;
  470.      Lisp_Object buffer;
  471. {
  472.   struct x_display *x = s->display.x;
  473.   int count;
  474.   int *psheets;
  475.  
  476.   if (NILP (buffer) || !(psheets = get_psheets_for_buffer (buffer, &count)))
  477.     {
  478.       x->desired_psheets = 0;
  479.       x->desired_psheet_count = 0;
  480.       x->desired_psheet_buffer = Qnil;
  481.     }
  482.   else
  483.     {
  484.       /* Do not show the debugger panel in this function.  The
  485.        * debugger panel should never be listed in the visible psheets. */
  486.       extern int debuggerpanel_sheet;
  487.       
  488.       if (count == 1 && psheets [0] == debuggerpanel_sheet)
  489.     return;
  490.  
  491.       x->desired_psheets = psheets;
  492.       x->desired_psheet_count = count;
  493.       x->desired_psheet_buffer = buffer;
  494.     }
  495. }
  496.  
  497. Lisp_Object
  498. desired_psheet_buffer (struct screen* s)
  499. {
  500.   return s->display.x->desired_psheet_buffer;
  501. }
  502.  
  503. /* This function is invoked when the user clicks on the "sheet" button.
  504.  */
  505. DEFUN ("energize-toggle-psheet", Fenergize_toggle_psheet,
  506.        Senergize_toggle_psheet, 0, 0, "",
  507.        "")
  508.      ()
  509. {
  510.   struct screen *screen = selected_screen;
  511.   Lisp_Object buffer = Fwindow_buffer (Fselected_window ());
  512.   if (EQ (buffer, desired_psheet_buffer (screen)))
  513.     make_psheets_desired (screen, Qnil);
  514.   else
  515.     make_psheets_desired (screen, buffer);
  516.   return Qnil;
  517. }
  518.  
  519.  
  520. void energize_show_menubar_of_buffer ();
  521.  
  522. /* This is called when a buffer becomes visible in some window.
  523.  
  524.    Show the menubar associated with this buffer, and show the psheets as
  525.    well if this buffer is the last buffer whose psheets were visible in
  526.    this screen.
  527.  */
  528. void energize_buffer_shown_hook (window)
  529.      struct window *window;
  530. {
  531.   struct screen* screen = XSCREEN (window->screen);
  532.   Lisp_Object buffer = window->buffer;
  533.   Lisp_Object pbuf;
  534.  
  535.   if (! SCREEN_IS_X (screen)) return;
  536.   pbuf = desired_psheet_buffer (screen);
  537.  
  538.   if (!MINI_WINDOW_P (window))
  539.     energize_show_menubar_of_buffer (window->screen, buffer,
  540.                      (EQ (buffer, pbuf) ? Qt : Qnil));
  541. }
  542.  
  543.  
  544. static int
  545. find_buffer_in_different_window (window, buffer, not_in)
  546.      struct window* window;
  547.      Lisp_Object buffer;
  548.      struct window* not_in;
  549. {
  550.   Lisp_Object child;
  551.   if (!NILP (window->buffer))
  552.     {
  553.       /* a leaf window */
  554.       return window->buffer == buffer && window != not_in;
  555.     }
  556.   else
  557.     {
  558.       /* a non leaf window, visit either the hchild or the vchild */
  559.       for (child = !NILP (window->vchild) ? window->vchild : window->hchild;
  560.        !NILP (child);
  561.        child = XWINDOW (child)->next)
  562.     {
  563.       if (find_buffer_in_different_window (XWINDOW (child), buffer,
  564.                            not_in))
  565.         return 1;
  566.     }
  567.       return 0;
  568.     }
  569. }
  570.  
  571. /* returns 1 if the buffer is only visible in window on screen s */
  572. static int
  573. buffer_only_visible_in_this_window_p (buffer, s, window)
  574.      Lisp_Object buffer;
  575.      struct screen* s;
  576.      struct window* window;
  577. {
  578.   return !find_buffer_in_different_window (XWINDOW (s->root_window), buffer,
  579.                        window);
  580. }
  581.  
  582. /* This is called just before a buffer which is visible becomes invisible,
  583.    either because some other buffer is about to be made visible in its window,
  584.    or because that window is being deleted.
  585.  
  586.    If this buffer's psheets are visible, hide them.
  587.  */
  588. void energize_buffer_hidden_hook (window)
  589.      struct window *window;
  590. {
  591.   struct screen *s;
  592.   s = XSCREEN (window->screen);
  593.  
  594.   if (! SCREEN_IS_X (s)) return;
  595.  
  596.   /* hides the p_sheet if we are changing the buffer of the
  597.    * selected window of the screen and the p_sheet where displayed */
  598.   if (EQ (window->buffer, desired_psheet_buffer (s))
  599.       && buffer_only_visible_in_this_window_p (window->buffer, s, window))
  600.     make_psheets_desired (s, Qnil);
  601. }
  602.  
  603.  
  604. /* This is called just before the selected window is no longer the selected
  605.    window because some other window is being selected.  The given window is
  606.    not being deleted, it is merely no longer the selected one.
  607.  
  608.    This doesn't do anything right now.
  609.  */
  610. void energize_window_deselected_hook (window)
  611.      struct window *window;
  612. {
  613. }
  614.  
  615.  
  616. /* This is called just after a window has been selected.
  617.  
  618.    Show the menubar associated with this buffer; leave the psheets as
  619.    they are.
  620.  */
  621. void energize_window_selected_hook (window)
  622.      struct window *window;
  623. {
  624.   struct screen* screen = XSCREEN (window->screen);
  625.   Lisp_Object buffer = window->buffer;
  626.  
  627.   if (SCREEN_IS_X (screen) && !MINI_WINDOW_P (window))
  628.     energize_show_menubar_of_buffer (window->screen, buffer, Qnil);
  629. }
  630.  
  631.  
  632.  
  633. int current_debuggerpanel_exposed_p;
  634. int desired_debuggerpanel_exposed_p;
  635. int debuggerpanel_sheet;
  636.  
  637. void
  638. energize_show_menubar_of_buffer (screen, buffer, psheets_too)
  639.      Lisp_Object screen, buffer, psheets_too;
  640. {
  641.   struct screen* s;
  642.   struct x_display *x;
  643.   
  644.   if (NILP (screen))
  645.     s = selected_screen;
  646.   else {
  647.     CHECK_SCREEN (screen, 0);
  648.     s = XSCREEN (screen);
  649.   }
  650.  
  651.   if (! SCREEN_IS_X (s)) error ("not an X screen");
  652.   x = s->display.x;
  653.  
  654.   if (! NILP (psheets_too))
  655.     {
  656.       Lisp_Object buffer;
  657.       XSET (buffer, Lisp_Buffer, current_buffer);
  658.       make_psheets_desired (s, buffer);
  659.     }
  660. }
  661.  
  662.  
  663. #endif /* ENERGIZE */
  664.  
  665. /* The one and only application context associated with the connection
  666. ** to the one and only X display that Emacs uses. */
  667. XtAppContext Xt_app_con;
  668.  
  669. /* The one and only application shell.  Emacs screens are popup shells of this
  670. ** application. */
  671. Widget Xt_app_shell;
  672.  
  673. extern Lisp_Object Vscreen_title_format, Vscreen_icon_title_format;
  674. extern Lisp_Object Vscreen_list;
  675.  
  676. static void
  677. maybe_set_screen_title_format (shell)
  678.      Widget shell;
  679. {
  680.   BLOCK_INPUT;
  681.  
  682.   if (NILP (Vscreen_list) ||
  683.       (NILP (Fcdr (Vscreen_list)) &&
  684.        XSCREEN (Fcar (Vscreen_list))->display.nothing == 1))
  685.     /* Only do this if this is the first X screen we're creating.
  686.        If the *title resource (or -title option) was specified, then
  687.        set screen-title-format to its value.
  688.      */
  689.     {
  690.       /* No doubt there's a less stupid way to do this. */
  691.       char *results [2];
  692.       XtResource resources [2];
  693.       results [0] = results [1] = 0;
  694.       resources [0].resource_name = XtNtitle;
  695.       resources [0].resource_class = XtCTitle;
  696.       resources [0].resource_type = XtRString;
  697.       resources [0].resource_size = sizeof (String);
  698.       resources [0].resource_offset = 0;
  699.       resources [0].default_type = XtRString;
  700.       resources [0].default_addr = 0;
  701.       resources [1].resource_name = XtNiconName;
  702.       resources [1].resource_class = XtCIconName;
  703.       resources [1].resource_type = XtRString;
  704.       resources [1].resource_size = sizeof (String);
  705.       resources [1].resource_offset = sizeof (char *);
  706.       resources [1].default_type = XtRString;
  707.       resources [1].default_addr = 0;
  708.       XtGetSubresources (XtParent(shell), (XtPointer)results, shell->core.name,
  709.              shell->core.widget_class->core_class.class_name,
  710.              resources, XtNumber (resources), 0, 0);
  711.       if (results[0])
  712.     Vscreen_title_format = build_string (results[0]);
  713.       if (results[1])
  714.     Vscreen_icon_title_format = build_string (results[1]);
  715.     }
  716.   UNBLOCK_INPUT;
  717. }
  718.  
  719.  
  720. /* Creates the widgets for a screen.  Parms is an alist of
  721. resources/values to use for the screen.  (ignored right now).
  722. reslisp_window_id is a Lisp description of an X window or Xt widget to
  723. resParse.  (ignored right now).  */
  724.  
  725. extern void maybe_store_wm_command (struct screen *);
  726.  
  727. static void hack_wm_protocols (Widget);
  728.  
  729. static void
  730. x_create_widgets (s, parms, lisp_window_id)
  731.      struct screen *s;
  732.      Lisp_Object parms;
  733.      Lisp_Object lisp_window_id;
  734. {
  735.   Widget shell_widget;
  736.   Widget pane_widget;
  737.   Widget screen_widget;
  738.   char* name;
  739.   Arg al [25];
  740.   int ac = 0;
  741.  
  742.   BLOCK_INPUT;
  743.  
  744.   if (STRINGP (s->name))
  745.      name = (char*)XSTRING (s->name)->data;
  746.   else
  747.     name = "emacs";
  748.        
  749.   ac = 0;
  750.   XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
  751.   XtSetArg (al[ac], XtNinput, 1); ac++;
  752.   shell_widget = XtCreatePopupShell (name, emacsShellWidgetClass, Xt_app_shell,
  753.                      al, ac);
  754.   maybe_set_screen_title_format (shell_widget);
  755.  
  756.   ac = 0;
  757.   XtSetArg (al[ac], XtNborderWidth, 0); ac++;
  758.   pane_widget = XtCreateWidget ("pane", panedWidgetClass, shell_widget, al,
  759.                 ac);
  760.  
  761.   /* mappedWhenManaged to false tells to the paned window to not map/unmap 
  762.    * the emacs screen when changing menubar.  This reduces flickering a lot.
  763.    */
  764.   ac = 0;
  765.   XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
  766.   XtSetArg (al[ac], XtNshowGrip, 0); ac++;
  767.   XtSetArg (al[ac], XtNallowResize, 1); ac++;
  768.   XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
  769.   XtSetArg (al[ac], XtNemacsScreen, s); ac++;
  770.   screen_widget = XtCreateWidget ("screen", emacsScreenWidgetClass,
  771.                   pane_widget, al, ac);
  772.  
  773.   s->display.x->widget = shell_widget;
  774.   s->display.x->column_widget = pane_widget;
  775.   s->display.x->edit_widget = screen_widget;
  776.  
  777.   if (NILP (Vx_screen_defaults))
  778.     x_set_screen_values (s, parms);
  779.   else
  780.     x_set_screen_values (s, nconc2 (Fcopy_sequence (parms),
  781.                     Vx_screen_defaults));
  782.  
  783.   XtManageChild (screen_widget);
  784.   XtManageChild (pane_widget);
  785.   XtRealizeWidget (shell_widget);
  786.   maybe_store_wm_command (s);
  787.   hack_wm_protocols (shell_widget);
  788.  
  789. #ifdef HACK_EDITRES
  790.   XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
  791. #endif
  792.  
  793.   /* Do a stupid property change to force the server to generate a
  794.      propertyNotify event so that the event_stream server timestamp will
  795.      be initialized to something relevant to the time we created the window.
  796.      */
  797.   XChangeProperty (XtDisplay (screen_widget), XtWindow (screen_widget),
  798.            Xatom_WM_PROTOCOLS, XA_ATOM, 32, PropModeAppend,
  799.            (unsigned char*) NULL, 0);
  800.  
  801.   XtMapWidget (screen_widget);
  802.  
  803.   XtPopup (shell_widget, XtGrabNone);
  804.   UNBLOCK_INPUT;
  805.  
  806. #if 0
  807.  * Forget this for now
  808.  *  if (NILP(lisp_window_id))
  809.  *     window_id = 0;
  810.  *  else
  811.  *    { CHECK_STRING(lisp_window_id, 0);
  812.  *      string = (char *) (XSTRING(lisp_window_id)->data);
  813.  *      if (string[0] == '0' && (string[1] == 'x' || string[1] == 'X'))
  814.  *         sscanf(string+2, "%xu", &window_id);
  815.  *#ifdef ENERGIZE
  816.  *      else if (string[0] == 'w'){
  817.  *    sscanf (string+1, "%x", &parent_widget);
  818.  *    if (parent_widget)
  819.  *      window_id = XtWindow (parent_widget);
  820.  *      }
  821.  *#endif
  822.  *      else
  823.  *         sscanf (string, "%lu", &window_id);
  824.  *    }
  825. #endif
  826. }
  827.  
  828.  
  829. /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS
  830.    and WM_DELETE_WINDOW, then add them.  (They may already be present
  831.    because of the toolkit (Motif adds them, for example, but Xt doesn't.)
  832.  */
  833. static void hack_wm_protocols (Widget widget)
  834. {
  835.   Display *dpy = XtDisplay (widget);
  836.   Window w = XtWindow (widget);
  837.   int need_delete = 1;
  838.   int need_focus = 1;
  839.   BLOCK_INPUT;
  840.   {
  841.     Atom type, *atoms = 0;
  842.     int format = 0;
  843.     unsigned long nitems = 0;
  844.     unsigned long bytes_after;
  845.  
  846.     if (Success == XGetWindowProperty (dpy, w, Xatom_WM_PROTOCOLS,
  847.                        0, 100, False, XA_ATOM,
  848.                        &type, &format, &nitems, &bytes_after,
  849.                        (unsigned char **) &atoms)
  850.     && format == 32 && type == XA_ATOM)
  851.       while (nitems > 0)
  852.     {
  853.       nitems--;
  854.       if (atoms [nitems] == Xatom_WM_DELETE_WINDOW)   need_delete = 0;
  855.       else if (atoms [nitems] == Xatom_WM_TAKE_FOCUS) need_focus = 0;
  856.     }
  857.     if (atoms) XFree ((char *) atoms);
  858.   }
  859.   {
  860.     Atom props [10];
  861.     int count = 0;
  862.     if (need_delete) props [count++] = Xatom_WM_DELETE_WINDOW;
  863.     if (need_focus)  props [count++] = Xatom_WM_TAKE_FOCUS;
  864.     if (count)
  865.       XChangeProperty (dpy, w, Xatom_WM_PROTOCOLS, XA_ATOM, 32, PropModeAppend,
  866.                (unsigned char *) props, count);
  867.   }
  868.   UNBLOCK_INPUT;
  869. }
  870.  
  871.  
  872. static void
  873. allocate_x_display_struct (s)
  874.      struct screen* s;
  875. {
  876.   s->output_method = output_x_window;
  877.   s->display.x = (struct x_display *)xmalloc (sizeof (struct x_display));
  878.  
  879.   /* zero out all slots. */
  880.   memset (s->display.x, 0, sizeof (struct x_display));
  881. }
  882.  
  883. Lisp_Object Vdefault_screen_name;
  884.  
  885. extern void x_format_screen_title (struct screen *);
  886.  
  887. extern void run_hooks_1_arg (Lisp_Object, Lisp_Object);
  888.  
  889. DEFUN ("x-create-screen", Fx_create_screen, Sx_create_screen,
  890.        1, 2, 0,
  891.   "Make a new X window, which is considered a \"screen\" in Emacs terms.\n\
  892. Return an Emacs screen object representing the X window.\n\
  893. ALIST is an alist of screen parameters.\n\
  894. The value of `x-screen-defaults' is an additional alist\n\
  895. of default parameters which apply when not overridden by ALIST.\n\
  896. Optional second argument is the numerical ID of the X window to use for this\n\
  897. screen (in order to run Emacs on a window created by some other program).\n\
  898. Since this ID number is an unsigned long, you must pass it as a string.\n\
  899. It may be a string of decimal numbers, or a string of hex numbers beginning\n\
  900. with \"0x\".")
  901.   (parms, lisp_window_id)
  902.      Lisp_Object parms, lisp_window_id;
  903. {
  904.   struct screen *s;
  905.   Lisp_Object screen = Qnil;
  906.   Lisp_Object name = Qnil;
  907.   struct gcpro gcpro1;
  908.   struct gcpro gcpro2;
  909.   GCPRO2 (screen, name);
  910.   
  911.   if (x_current_display == 0)
  912.     error ("X windows are not in use or not initialized");
  913.   
  914.   s = make_screen (1);
  915.   
  916.   allocate_x_display_struct (s);
  917.   name = Fassq (intern ("name"), parms);
  918.   if (!NILP (name))
  919.     {
  920.       name = Fcdr (name);
  921.       CHECK_STRING (name, 0);
  922.     }
  923.   else if (STRINGP (Vdefault_screen_name))
  924.     name = Vdefault_screen_name;
  925.   else
  926.     name = build_string ("emacs");
  927.  
  928.   s->name = name;
  929.  
  930.   XSET (screen, Lisp_Screen, s);
  931.  
  932.   x_create_widgets (s, parms, lisp_window_id);
  933.   
  934.   /* do this after anything that might call Fsignal() before the screen
  935.    * is in a usable state. */
  936.   Vscreen_list = Fcons (screen, Vscreen_list);
  937.  
  938.   /* This runs lisp code, and thus might GC.  If the selected screen is still
  939.      the terminal screen (meaning that we're in the middle of creating the
  940.      initial X screen) then select the X screen now, so that GC messages don't
  941.      get written on the terminal screen.  This is kind of a hack...
  942.    */
  943.   if (selected_screen == XSCREEN (Vterminal_screen))
  944.     select_screen_internal (s);
  945.   init_screen_faces (s);
  946.   x_format_screen_title (s);
  947.   run_hooks_1_arg (Qcreate_screen_hook, screen);
  948.   UNGCPRO;
  949.   return screen;
  950. }
  951.  
  952.  
  953. DEFUN ("x-show-lineinfo-column",
  954.        Fx_show_lineinfo_column, Sx_show_lineinfo_column, 0, 1, 0,
  955.        "Make the current emacs screen have a lineinfo column.")
  956.      (screen)
  957.      Lisp_Object screen;
  958. {
  959.   struct screen* s;
  960.   struct x_display *x;
  961. #ifdef LINE_INFO_WIDGET
  962.   int just_created;
  963. #endif
  964.   
  965.   if (NILP (screen))
  966.     s = selected_screen;
  967.   else {
  968.     CHECK_SCREEN (screen, 0);
  969.     s = XSCREEN (screen);
  970.   }
  971.   if (! SCREEN_IS_X (s)) error ("not an X screen");
  972.  
  973.   x = s->display.x;
  974.  
  975. #ifdef LINE_INFO_WIDGET
  976.   
  977.   BLOCK_INPUT;
  978.   XawPanedSetRefigureMode (x->row_widget, 0);
  979.   
  980.   /* the order in which children are managed is the top to
  981.      bottom order in which they are displayed in the paned window. */
  982.   
  983.   XtUnmanageChild (x->edit_widget);
  984.   if (x->lineinfo_widget)
  985.     XtUnmanageChild (x->lineinfo_widget);
  986.   else {
  987.     x->lineinfo_widget =
  988.       XtVaCreateWidget ("lineinfo_widget", lineInfoWidgetClass,
  989.             x->row_widget,
  990.             XtNwidth,  50,
  991.             XtNheight, s->display.x->pixel_height,
  992.             XtNmappedWhenManaged, 0,
  993.             XtNshowGrip, 0,
  994.             0);
  995.     ((LineInfoWidget) x->lineinfo_widget)->lineInfo.screen = s;
  996.     just_created = 1;
  997.   }
  998.   XtManageChild (x->lineinfo_widget);
  999.   XtManageChild (x->edit_widget);
  1000.  
  1001.   if (just_created)
  1002.     XStoreName (x_current_display, XtWindow(x->lineinfo_widget), "lineinfo_widget");
  1003.  
  1004.   XawPanedSetRefigureMode (x->row_widget, 1);
  1005.  
  1006.   UNBLOCK_INPUT;
  1007.  
  1008. #else
  1009. #ifdef LINE_INFO_COLUMN
  1010.  
  1011.   s->display.x->line_info_column_width =
  1012.     s->display.x->default_line_info_column_width;
  1013.  
  1014. #else
  1015.   error("support for the lineinfo column was not compiled into emacs.");
  1016.  
  1017. #endif
  1018. #endif
  1019.   return Qnil;
  1020. }
  1021.  
  1022.  
  1023. DEFUN ("x-hide-lineinfo-column",
  1024.        Fx_hide_lineinfo_column, Sx_hide_lineinfo_column, 0, 1, 0,
  1025.        "Make the given emacs screen not have a lineinfo column.")
  1026.      (screen)
  1027.      Lisp_Object screen;
  1028. {
  1029.   struct screen *s;
  1030.   
  1031.   if (NILP (screen))
  1032.     s = selected_screen;
  1033.   else {
  1034.     CHECK_SCREEN (screen, 0);
  1035.     s = XSCREEN (screen);
  1036.   }
  1037.   if (! SCREEN_IS_X (s)) error ("not an X screen");
  1038.  
  1039. #ifdef LINE_INFO_WIDGET
  1040.   if (! s->display.x->lineinfo_widget) return Qnil;
  1041.   XtUnmanageChild (s->display.x->lineinfo_widget);
  1042.  
  1043. #else
  1044. #ifdef LINE_INFO_COLUMN
  1045.   s->display.x->line_info_column_width = 0;
  1046.  
  1047. #else
  1048.   error("support for the lineinfo column was not compiled into emacs.");
  1049. #endif
  1050. #endif
  1051.   return Qnil;
  1052. }
  1053.  
  1054.  
  1055. #define GET_X_SCREEN(s, screen) { \
  1056.   if (NILP (screen))         \
  1057.     s = selected_screen;     \
  1058.   else                 \
  1059.     {                 \
  1060.       CHECK_SCREEN (screen, 0);     \
  1061.       s = XSCREEN (screen);     \
  1062.     }                 \
  1063.   if (!SCREEN_IS_X (s))         \
  1064.     error ("not an X display"); }
  1065.  
  1066.  
  1067. DEFUN ("x-display-visual-class", Fx_display_visual_class,
  1068.        Sx_display_visual_class, 0, 1, 0,
  1069.        "Returns the visual class of the display `screen' is on.\n\
  1070. The returned value will be one of the symbols StaticGray, GrayScale,\n\
  1071. StaticColor, PseudoColor, TrueColor, or DirectColor.")
  1072.     (screen)
  1073.      Lisp_Object screen;
  1074. {
  1075.   struct screen *s;
  1076.   Display *dpy;
  1077.   GET_X_SCREEN (s, screen);
  1078.   dpy = XtDisplay (s->display.x->widget);
  1079.   switch (DefaultVisual (dpy, DefaultScreen (dpy))->class)
  1080.     {
  1081.     case StaticGray:  return (intern ("StaticGray"));
  1082.     case GrayScale:   return (intern ("GrayScale"));
  1083.     case StaticColor: return (intern ("StaticColor"));
  1084.     case PseudoColor: return (intern ("PseudoColor"));
  1085.     case TrueColor:   return (intern ("TrueColor"));
  1086.     case DirectColor: return (intern ("DirectColor"));
  1087.     default:
  1088.       error ("display has an unknown visual class");
  1089.     }
  1090. }
  1091.  
  1092. DEFUN ("x-color-display-p", Fx_color_display_p, Sx_color_display_p, 0, 1, 0,
  1093.        "Returns t if the X display of the given screen supports color.")
  1094.      (screen)
  1095.      Lisp_Object screen;
  1096. {
  1097.   struct screen *s;
  1098.   Display *dpy;
  1099.   GET_X_SCREEN (s, screen);
  1100.   dpy = XtDisplay (s->display.x->widget);
  1101.   if (DisplayCells (dpy, DefaultScreen (dpy)) <= 2)
  1102.     return Qnil;
  1103.   switch (DefaultVisual (dpy, DefaultScreen (dpy))->class)
  1104.     {
  1105.     case StaticColor:
  1106.     case PseudoColor:
  1107.     case TrueColor:
  1108.     case DirectColor:
  1109.       return Qt;
  1110.     default:
  1111.       return Qnil;
  1112.     }
  1113. }
  1114.  
  1115. DEFUN ("x-pixel-width", Fx_pixel_width, Sx_pixel_width, 0, 1, 0,
  1116.   "Returns the width in pixels of the given screen.")
  1117.   (screen)
  1118.      Lisp_Object screen;
  1119. {
  1120.   struct screen *s;
  1121.   GET_X_SCREEN (s, screen);
  1122.   return make_number (PIXEL_WIDTH (s));
  1123. }
  1124.  
  1125. DEFUN ("x-pixel-height", Fx_pixel_height, Sx_pixel_height, 0, 1, 0,
  1126.   "Returns the height in pixels of the given screen.")
  1127.   (screen)
  1128.      Lisp_Object screen;
  1129. {
  1130.   struct screen *s;
  1131.   GET_X_SCREEN (s, screen);
  1132.   return make_number (PIXEL_HEIGHT (s));
  1133. }
  1134.  
  1135. DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
  1136.        0, 1, 0,
  1137.        "Returns the width in pixels of the display `screen' is on.")
  1138.      (screen)
  1139. {
  1140.   struct screen *s;
  1141.   Display *dpy;
  1142.   GET_X_SCREEN (s, screen);
  1143.   dpy = XtDisplay (s->display.x->widget);
  1144.   return make_number (DisplayWidth (dpy, DefaultScreen (dpy)));
  1145. }
  1146.  
  1147. DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
  1148.        Sx_display_pixel_height,
  1149.        0, 1, 0,
  1150.        "Returns the height in pixels of the display `screen' is on.")
  1151.      (screen)
  1152. {
  1153.   struct screen *s;
  1154.   Display *dpy;
  1155.   GET_X_SCREEN (s, screen);
  1156.   dpy = XtDisplay (s->display.x->widget);
  1157.   return make_number (DisplayHeight (dpy, DefaultScreen (dpy)));
  1158. }
  1159.  
  1160. DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
  1161.        0, 1, 0,
  1162.        "Returns the number of bitplanes of the display `screen' is on.")
  1163.      (screen)
  1164. {
  1165.   struct screen *s;
  1166.   Display *dpy;
  1167.   GET_X_SCREEN (s, screen);
  1168.   dpy = XtDisplay (s->display.x->widget);
  1169.   return make_number (DisplayPlanes (dpy, DefaultScreen (dpy)));
  1170. }
  1171.  
  1172. DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
  1173.        0, 1, 0,
  1174.        "Returns the number of color cells of the display `screen' is on.")
  1175.      (screen)
  1176. {
  1177.   struct screen *s;
  1178.   Display *dpy;
  1179.   GET_X_SCREEN (s, screen);
  1180.   dpy = XtDisplay (s->display.x->widget);
  1181.   return make_number (DisplayCells (dpy, DefaultScreen (dpy)));
  1182. }
  1183.  
  1184. DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
  1185.        "Returns the vendor ID string of the X server `screen' is on.")
  1186.      (screen)
  1187. {
  1188.   struct screen *s;
  1189.   Display *dpy;
  1190.   char *vendor;
  1191.   GET_X_SCREEN (s, screen);
  1192.   dpy = XtDisplay (s->display.x->widget);
  1193.   vendor = ServerVendor (dpy);
  1194.   if (! vendor) vendor = "";
  1195.   return build_string (vendor);
  1196. }
  1197.  
  1198. DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
  1199.        "Returns the version numbers of the X server `screen' is on.\n\
  1200. The returned value is a list of three integers: the major and minor\n\
  1201. version numbers of the X Protocol in use, and the vendor-specific release\n\
  1202. number.  See also `x-server-vendor'.")
  1203.      (screen)
  1204. {
  1205.   struct screen *s;
  1206.   Display *dpy;
  1207.   GET_X_SCREEN (s, screen);
  1208.   dpy = XtDisplay (s->display.x->widget);
  1209.   return list3 (make_number (ProtocolVersion (dpy)),
  1210.         make_number (ProtocolRevision (dpy)),
  1211.         make_number (VendorRelease (dpy)));
  1212. }
  1213.  
  1214.  
  1215. DEFUN ("x-set-screen-icon-pixmap", Fx_set_screen_icon_pixmap,
  1216.        Sx_set_screen_icon_pixmap, 2, 3, 0,
  1217.        "Set the icon-pixmap of the given screen.\n\
  1218. This should be the name of a bitmap file, or a bitmap description list\n\
  1219.  of the form (width height \"bitmap-data\").\n\
  1220. If the optional third argument is specified, it is the bitmap to use for\n\
  1221.  the icon-pixmap-mask (not all window managers obey this.)  If the bitmap\n\
  1222.  is an XPM file which also contains a mask, the mask argument, if provided,\n\
  1223.  will override the mask in the file.\n\
  1224. WARNING: when you call this function, the pixmap of the previous icon\n\
  1225.  of this screen (if any) is currently not freed (this is a bug).")
  1226.   (screen, pixmap, mask)
  1227.     Lisp_Object screen, pixmap, mask;
  1228. {
  1229.   struct screen *s;
  1230.   Arg av [10];
  1231.   int ac = 0;
  1232.   unsigned int w, h, d;
  1233.   Pixmap p, m;
  1234.   if (NILP (screen))
  1235.     s = selected_screen;
  1236.   else
  1237.     {
  1238.       CHECK_SCREEN (screen, 0);
  1239.       s = XSCREEN (screen);
  1240.     }
  1241.  
  1242.   if (NILP (mask))
  1243.     m = 0;
  1244.   else
  1245.     {
  1246.       m = (Pixmap) load_pixmap (s, mask, &w, &h, &d, 0);
  1247.       if (d > 1)
  1248.     {
  1249.       BLOCK_INPUT;
  1250.       XFreePixmap (XtDisplay (s->display.x->widget), m);
  1251.       UNBLOCK_INPUT;
  1252.       m = 0;
  1253.       Fsignal (Qerror,
  1254.            list3 (build_string ("mask pixmap must be 1 plane deep"),
  1255.               mask, make_number (d)));
  1256.     }
  1257.     }
  1258.  
  1259.   if (NILP (pixmap))
  1260.     p = 0;
  1261.   else
  1262.     p = (Pixmap) load_pixmap (s, pixmap, &w, &h, &d, (m ? 0 : &m));
  1263.  
  1264.   XtSetArg (av [ac], XtNiconPixmap, p); ac++;
  1265.   XtSetArg (av [ac], XtNiconMask, m); ac++;
  1266.   XtSetValues (s->display.x->widget, av, ac);
  1267.   return pixmap;
  1268. }
  1269.  
  1270.  
  1271. static Cursor grabbed_cursor;
  1272.  
  1273. DEFUN ("x-grab-pointer", Fx_grab_pointer, Sx_grab_pointer, 0, 2, 0,
  1274.   "Grab the pointer and restrict it to its current window.  If optional\n\
  1275. SHAPE is non-nil, change the pointer shape to that.  If second optional\n\
  1276. argument MOUSE-ONLY is non-nil, ignore keyboard events during the grab.")
  1277.   (shape, ignore_keyboard)
  1278.      Lisp_Object shape, ignore_keyboard;
  1279. {
  1280.   Window w;
  1281.   int pointer_mode, result;
  1282.  
  1283.   BLOCK_INPUT;
  1284.   if (! NILP (ignore_keyboard))
  1285.     pointer_mode = GrabModeSync;
  1286.   else
  1287.     pointer_mode = GrabModeAsync;
  1288.  
  1289.   if (! NILP (shape))
  1290.     {
  1291.       CHECK_FIXNUM (shape, 0);
  1292.       grabbed_cursor = XCreateFontCursor (x_current_display, XINT (shape));
  1293.     }
  1294.  
  1295.   w = XtWindow (XSCREEN (XWINDOW (selected_window)->screen)->display.x->edit_widget);
  1296.  
  1297.   result = XGrabPointer (x_current_display, w,
  1298.              False,
  1299.              ButtonMotionMask | ButtonPressMask
  1300.              | ButtonReleaseMask | PointerMotionHintMask,
  1301.              GrabModeAsync,          /* Keep pointer events flowing */
  1302.              pointer_mode,          /* Stall keyboard events */
  1303.              w,              /* Stay in this window */
  1304.              grabbed_cursor,
  1305.              CurrentTime);
  1306.   UNBLOCK_INPUT;
  1307.   if (result == GrabSuccess)
  1308.     {
  1309.       return Qt;
  1310.     }
  1311.  
  1312.   BLOCK_INPUT;
  1313.   XFreeCursor (x_current_display, grabbed_cursor);
  1314.   UNBLOCK_INPUT;
  1315.   return Qnil;
  1316. }
  1317.  
  1318. DEFUN ("x-ungrab-pointer", Fx_ungrab_pointer, Sx_ungrab_pointer, 0, 0, 0,
  1319.   "Release the pointer.")
  1320.   ()
  1321. {
  1322.   BLOCK_INPUT;
  1323.   XUngrabPointer (x_current_display, CurrentTime);
  1324.  
  1325.   if ((int) grabbed_cursor)
  1326.     {
  1327.       XFreeCursor (x_current_display, grabbed_cursor);
  1328.       grabbed_cursor = (Cursor) 0;
  1329.     }
  1330.  
  1331.   UNBLOCK_INPUT;
  1332.   return Qnil;
  1333. }
  1334.  
  1335.  
  1336. /* handlers for the eval-events pushed on the queue by event-Xt.c */
  1337.  
  1338. Lisp_Object Qx_EnterNotify_internal, Qx_LeaveNotify_internal;
  1339. Lisp_Object Qx_FocusIn_internal, Qx_FocusOut_internal;
  1340. Lisp_Object Qx_VisibilityNotify_internal, Qx_non_VisibilityNotify_internal;
  1341. Lisp_Object Qx_MapNotify_internal, Qx_UnmapNotify_internal;
  1342.  
  1343. DEFUN ("x-EnterNotify-internal", Fx_EnterNotify_internal,
  1344.        Sx_EnterNotify_internal, 1, 1, 0, "hands off")
  1345.      (screen)
  1346.      Lisp_Object screen;
  1347. {
  1348.   CHECK_SCREEN (screen, 0);
  1349.   if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
  1350. /*  XSCREEN (screen)->display.x->mouse_p = 1; */
  1351.   run_hooks_1_arg (Qmouse_enter_screen_hook, screen);
  1352.   return Qnil;
  1353. }
  1354.  
  1355. DEFUN ("x-LeaveNotify-internal", Fx_LeaveNotify_internal,
  1356.        Sx_LeaveNotify_internal, 1, 1, 0, "hands off")
  1357.      (screen)
  1358.      Lisp_Object screen;
  1359. {
  1360.   CHECK_SCREEN (screen, 0);
  1361.   if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
  1362. /*  XSCREEN (screen)->display.x->mouse_p = 0; */
  1363.   run_hooks_1_arg (Qmouse_leave_screen_hook, screen);
  1364.   return Qnil;
  1365. }
  1366.  
  1367. /* This is true if any widget in any emacs screen has the X keyboard focus
  1368.    Flase otherwise. */
  1369. int any_screen_has_focus_p;
  1370.  
  1371. /* The select-screen-hook and deselect-screen-hook are run from the 
  1372.    select_screen_internal() function; however, we run them from the FocusIn
  1373.    and FocusOut handlers as well, because under X, the "selectedness" of a
  1374.    screen has slightly funny semantics; according to emacs, a screen is
  1375.    not "deselected" unless some other screen is selected.  This is so that
  1376.    there is always some current window and buffer, and so on.  However, it's
  1377.    useful to run the deselect-screen-hook when emacs loses the X keyboard
  1378.    focus (that is, no emacs screen is the X selected window).  Likewise,
  1379.    it's useful to run the select-screen-hook when some emacs window regains
  1380.    the focus, even if that window is already the selected screen from emacs's
  1381.    point of view.
  1382.  
  1383.    If we don't do this, then the select-screen-hook (meaning auto-raise)
  1384.    isn't run if (in a point-to-type world) the mouse moves into the same
  1385.    emacs window that it originally left.  Clearly this isn't what someone
  1386.    who would want auto-raise would want.
  1387.  
  1388.    This means that sometimes the deselect-screen-hook will be called twice.
  1389.    This kind of stinks.
  1390.  
  1391.    If there are two screens, s1, and s2, where s1 is selected:
  1392.  
  1393.     mouse moves into s1:   FocusIn s1 runs select-screen-hook, because s1
  1394.                    is the selected screen (FocusIn only does this
  1395.                for the selected screen.)
  1396.  
  1397.                    select_screen_internal doesn't run deselect-hook
  1398.                since s1 is already selected_screen, although it
  1399.                didn't have the X focus.
  1400.  
  1401.                net result: select s1 run.
  1402.  
  1403.     mouse moves into s2:   FocusOut s1 runs deselect-screen-hook, but the
  1404.                selected_screen is still s1.
  1405.  
  1406.                FocusIn s2 does not run select-screen-hook,
  1407.                because s2 is not the selected screen.
  1408.  
  1409.                select_screen_internal runs deselect-hook s1,
  1410.                then selects s2, then runs select-hook s2.
  1411.  
  1412.                net result: deselect s1, deselect s1, select s2.
  1413.                One of those deselects is superfluous.
  1414.  
  1415.     mouse moves elsewhere: FocusOut s2 runs deselect-screen-hook, but the
  1416.                selected_screen is still s2.
  1417.  
  1418.                net result: deselect s2.
  1419.  
  1420.     mouse moves into s1:   FocusIn s1 does not run select-screen-hook.
  1421.  
  1422.                    select_screen_internal runs deselect-hook s2;
  1423.                changes selected_screen, runs select-hook s1.
  1424.  
  1425.                net result: deselect s2, select s1.
  1426.                That deselect is superfluous.
  1427.  
  1428.    Things get even nastier if there is a big delay between when select-screen
  1429.    is called and when the Focus events are handled (as when lisp code calls
  1430.    select-screen and then doesn't return to top level for a while.)
  1431.  */
  1432.  
  1433. extern Lisp_Object Qselect_screen_hook, Qdeselect_screen_hook;
  1434.  
  1435. extern void x_screen_redraw_cursor (struct screen *);
  1436.  
  1437. DEFUN ("x-FocusIn-internal", Fx_FocusIn_internal,
  1438.        Sx_FocusIn_internal, 1, 1, 0, "hands off")
  1439.      (screen)
  1440.      Lisp_Object screen;
  1441. {
  1442.   int getting_focus = !any_screen_has_focus_p;
  1443.   CHECK_SCREEN (screen, 0);
  1444.   if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
  1445.   any_screen_has_focus_p = 1;
  1446.   XSCREEN (screen)->display.x->focus_p = 1;
  1447.   if (XSCREEN (screen) == selected_screen)
  1448.     {
  1449.       x_screen_redraw_cursor (XSCREEN (screen));
  1450.       /* see comment above */
  1451.       if (getting_focus)
  1452.     if (!NILP (Vrun_hooks))
  1453.       call1 (Vrun_hooks, Qselect_screen_hook);
  1454.     }
  1455.   else
  1456.     select_screen_internal (XSCREEN (screen));
  1457.   return Qnil;
  1458. }
  1459.  
  1460. DEFUN ("x-FocusOut-internal", Fx_FocusOut_internal,
  1461.        Sx_FocusOut_internal, 1, 1, 0, "hands off")
  1462.      (screen)
  1463.      Lisp_Object screen;
  1464. {
  1465.   CHECK_SCREEN (screen, 0);
  1466.   if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
  1467.   any_screen_has_focus_p = 0;
  1468.   XSCREEN (screen)->display.x->focus_p = 0;
  1469.   if (XSCREEN (screen) == selected_screen)
  1470.     {
  1471.       x_screen_redraw_cursor (XSCREEN (screen));
  1472.       /* see comment above */
  1473.       if (!NILP (Vrun_hooks))
  1474.     call1 (Vrun_hooks, Qdeselect_screen_hook);
  1475.     }
  1476.   return Qnil;
  1477. }
  1478.  
  1479. DEFUN ("x-VisibilityNotify-internal", Fx_VisibilityNotify_internal,
  1480.        Sx_VisibilityNotify_internal, 1, 1, 0, "hands off")
  1481.      (screen)
  1482.      Lisp_Object screen;
  1483. {
  1484.   CHECK_SCREEN (screen, 0);
  1485.   if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
  1486.   XSCREEN (screen)->display.x->totally_visible_p = 1;
  1487.   return Qnil;
  1488. }
  1489.  
  1490. DEFUN ("x-non-VisibilityNotify-internal", Fx_non_VisibilityNotify_internal,
  1491.        Sx_non_VisibilityNotify_internal, 1, 1, 0, "hands off")
  1492.      (screen)
  1493.      Lisp_Object screen;
  1494. {
  1495.   CHECK_SCREEN (screen, 0);
  1496.   if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
  1497.   XSCREEN (screen)->display.x->totally_visible_p = 0;
  1498.   return Qnil;
  1499. }
  1500.  
  1501. DEFUN ("x-MapNotify-internal", Fx_MapNotify_internal,
  1502.        Sx_MapNotify_internal, 1, 1, 0, "hands off")
  1503.      (screen)
  1504.      Lisp_Object screen;
  1505. {
  1506.   CHECK_SCREEN (screen, 0);
  1507.   if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
  1508.   XSCREEN (screen)->display.x->totally_visible_p = 1;
  1509.   if (! XSCREEN (screen)->visible)
  1510.     {
  1511.       XSCREEN (screen)->visible = 1;
  1512.       SET_SCREEN_GARBAGED (XSCREEN (screen));
  1513.       run_hooks_1_arg (Qmap_screen_hook, screen);
  1514.     }
  1515.   return Qnil;
  1516. }
  1517.  
  1518.  
  1519. DEFUN ("x-UnmapNotify-internal", Fx_UnmapNotify_internal,
  1520.        Sx_UnmapNotify_internal, 1, 1, 0, "hands off")
  1521.      (screen)
  1522.      Lisp_Object screen;
  1523. {
  1524.   CHECK_SCREEN (screen, 0);
  1525.   if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
  1526.   XSCREEN (screen)->display.x->totally_visible_p = 0;
  1527.   if (XSCREEN (screen)->visible)
  1528.     {
  1529.       XSCREEN (screen)->visible = 0;
  1530.       run_hooks_1_arg (Qunmap_screen_hook, screen);
  1531.     }
  1532.   return Qnil;
  1533. }
  1534.  
  1535.  
  1536. #if 0 /* #### This stuff is obsolete; with the new event model, 
  1537.           regular keyboard macros work just as well as this.
  1538.        */
  1539. DEFUN ("x-rebind-key", Fx_rebind_key, Sx_rebind_key, 3, 3, 0,
  1540. "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
  1541. KEYSYM is a string which conforms to the X keysym definitions found\n\
  1542. in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
  1543. list of strings specifying modifier keys such as Control_L, which must\n\
  1544. also be depressed for NEWSTRING to appear.")
  1545.   (x_keysym, modifiers, newstring)
  1546.      register Lisp_Object x_keysym;
  1547.      register Lisp_Object modifiers;
  1548.      register Lisp_Object newstring;
  1549. {
  1550.   char *rawstring;
  1551.   register KeySym keysym, modifier_list[16];
  1552.  
  1553.   CHECK_STRING (x_keysym, 1);
  1554.   CHECK_STRING (newstring, 3);
  1555.  
  1556.   BLOCK_INPUT;
  1557.   keysym = XStringToKeysym ((char *) XSTRING (x_keysym)->data);
  1558.   UNBLOCK_INPUT;
  1559.  
  1560.   if (keysym == NoSymbol)
  1561.     error ("Keysym does not exist");
  1562.  
  1563.   if (NILP (modifiers))
  1564.     {
  1565.       BLOCK_INPUT;
  1566.       XRebindKeysym (x_current_display, keysym, modifier_list, 0,
  1567.              XSTRING (newstring)->data, XSTRING (newstring)->size);
  1568.       UNBLOCK_INPUT;
  1569.     }
  1570.   else
  1571.     {
  1572.       register Lisp_Object rest, mod;
  1573.       register int i = 0;
  1574.  
  1575.       for (rest = modifiers; !NILP (rest); rest = Fcdr (rest))
  1576.     {
  1577.       if (i == 16)
  1578.         error ("Can't have more than 16 modifiers");
  1579.  
  1580.       mod = Fcar (rest);
  1581.       CHECK_STRING (mod, 3);
  1582.       BLOCK_INPUT;
  1583.       modifier_list[i] = XStringToKeysym ((char *) XSTRING (mod)->data);
  1584.       UNBLOCK_INPUT;
  1585.       if (modifier_list[i] == NoSymbol
  1586.           || !IsModifierKey (modifier_list[i]))
  1587.         error ("Element is not a modifier keysym");
  1588.       i++;
  1589.     }
  1590.       
  1591.       BLOCK_INPUT;
  1592.       XRebindKeysym (x_current_display, keysym, modifier_list, i,
  1593.              XSTRING (newstring)->data, XSTRING (newstring)->size);
  1594.       UNBLOCK_INPUT;
  1595.     }
  1596.  
  1597.   return Qnil;
  1598. }
  1599.   
  1600. DEFUN ("x-rebind-keys", Fx_rebind_keys, Sx_rebind_keys, 2, 2, 0,
  1601.   "Rebind KEYCODE to list of strings STRINGS.\n\
  1602. STRINGS should be a list of 16 elements, one for each shift combination.\n\
  1603. nil as element means don't change.\n\
  1604. See the documentation of `x-rebind-key' for more information.")
  1605.   (keycode, strings)
  1606.      register Lisp_Object keycode;
  1607.      register Lisp_Object strings;
  1608. {
  1609.   register Lisp_Object item;
  1610.   register unsigned char *rawstring;
  1611.   KeySym rawkey, modifier[1];
  1612.   int strsize;
  1613.   register unsigned i;
  1614.  
  1615.   CHECK_FIXNUM (keycode, 1);
  1616.   CHECK_CONS (strings, 2);
  1617.   rawkey = (KeySym) ((unsigned) (XINT (keycode))) & 255;
  1618.   for (i = 0; i <= 15; strings = Fcdr (strings), i++)
  1619.     {
  1620.       item = Fcar (strings);
  1621.       if (!NILP (item))
  1622.     {
  1623.       CHECK_STRING (item, 2);
  1624.       strsize = XSTRING (item)->size;
  1625.       rawstring = (unsigned char *) xmalloc (strsize);
  1626.       bcopy (XSTRING (item)->data, rawstring, strsize);
  1627.       modifier[1] = 1 << i;
  1628.       BLOCK_INPUT;
  1629.       XRebindKeysym (x_current_display, rawkey, modifier, 1,
  1630.              rawstring, strsize);
  1631.       UNBLOCK_INPUT;
  1632.     }
  1633.     }
  1634.   return Qnil;
  1635. }
  1636. #endif
  1637.  
  1638.  
  1639. /* This comment supplies the doc string for x-get-resource,
  1640.    for make-docfile to see.  We cannot put this in the real DEFUN
  1641.    due to limits in the Unix cpp.
  1642.  
  1643. DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 3, 4, 0,
  1644.        "Retrieve an X resource from the resource manager.\n\
  1645. The first arg is the name of the resource to retrieve, such as \"font\".\n\
  1646. The second arg is the class of the resource to retrieve, like \"Font\".\n\
  1647. The third arg should be one of the symbols string, integer, or boolean,\n\
  1648. specifying the type of object that the database is searched for.\n\
  1649. The fourth arg is the screen to search for the resources on, defaulting\n\
  1650. to the selected screen.\n\
  1651. \n\
  1652. The call\n\
  1653.     (x-get-resource \"font\" \"Font\" 'string)\n\
  1654. \n\
  1655. is an interface to the C call\n\
  1656. \n\
  1657.     XrmGetResource (db, \"emacs.this_screen_name.font\",\n\
  1658.             \"Emacs.EmacsScreen.Font\",\n\
  1659.             \"String\");\n\
  1660. \n\
  1661. Therefore if you want to retrieve a deeper resource, for example,\n\
  1662. \"Emacs.foo.foreground\", you need to specify the same number of links\n\
  1663. in the class path:\n\
  1664.     (x-get-resource \"foo.foreground\" \"Thing.Foreground\" 'string)\n\
  1665. \n\
  1666. which is equivalent to 
  1667. \n\
  1668.     XrmGetResource (db, \"emacs.screen_name.foo.foreground\",\n\
  1669.             \"Emacs.EmacsScreen.Thing.Foreground\",\n\
  1670.             \"String\");\n\
  1671.  
  1672. \n\
  1673. The returned value of this function is nil if the queried resource is not\n\
  1674. found.  If the third arg is `string', a string is returned, and if it is\n\
  1675. `integer', an integer is returned.  If the third arg is `boolean', then the\n\
  1676. returned value is the list (t) for true, (nil) for false, and is nil to\n\
  1677. mean ``unspecified.''")
  1678.      (name, class, type, screen)
  1679. */
  1680.  
  1681.  
  1682. DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 3, 4, 0, 0)
  1683.      (name, class, type, screen)
  1684.      Lisp_Object name, class, type, screen;
  1685. {
  1686.   char *name_string, *class_string;
  1687.   char *app_name, *app_class, *screen_name, *screen_class, *s;
  1688.   Widget widget;
  1689.  
  1690.   CHECK_STRING (name, 0);
  1691.   CHECK_STRING (class, 0);
  1692.   CHECK_SYMBOL (type, 0);
  1693.   if (NILP (screen))
  1694.     screen = Fselected_screen ();
  1695.   else
  1696.     CHECK_SCREEN (screen, 0);
  1697.   if (! SCREEN_IS_X (XSCREEN (screen)))
  1698. /*    error ("not an X screen"); */
  1699.     return Qnil;
  1700.  
  1701.   widget = XSCREEN (screen)->display.x->widget;
  1702.   BLOCK_INPUT;
  1703.   XtGetApplicationNameAndClass (XtDisplay (widget), &app_name, &app_class);
  1704.   UNBLOCK_INPUT;
  1705.   screen_name = widget->core.name;
  1706.   screen_class = XtClass (widget)->core_class.class_name;
  1707.   name_string = (char *) alloca (XSTRING (name)->size + strlen (app_name)
  1708.                  + strlen (screen_name) + 3);
  1709.   class_string = (char *) alloca (XSTRING (class)->size + strlen (app_class)
  1710.                   + strlen (screen_class) + 3);
  1711.   strcpy (name_string, (char *) app_name);
  1712.   for (s = name_string; *s; s++) if (*s == '.') *s = '_';
  1713.   strcat (name_string, ".");
  1714.   s++;
  1715.   strcat (name_string, (char *) screen_name);
  1716.   for (; *s; s++) if (*s == '.') *s = '_';
  1717.   strcat (name_string, ".");
  1718.   strcat (name_string, (char *) XSTRING (name)->data);
  1719.   strcpy (class_string, app_class);
  1720.   strcat (class_string, ".");
  1721.   strcat (class_string, screen_class);
  1722.   strcat (class_string, ".");
  1723.   strcat (class_string, (char *) XSTRING (class)->data);
  1724.  
  1725.   {
  1726.     XrmValue xrm_value;
  1727.     XrmName namelist [100];
  1728.     XrmClass classlist [100];
  1729.     XrmName *namerest = namelist;
  1730.     XrmClass *classrest = classlist;
  1731.     XrmRepresentation xrm_type;
  1732.     XrmRepresentation string_quark;
  1733.     int result;
  1734.     BLOCK_INPUT;
  1735.     XrmStringToNameList (name_string, namelist);
  1736.     XrmStringToClassList (class_string, classlist);
  1737.     string_quark = XrmStringToQuark ("String");
  1738.     UNBLOCK_INPUT;
  1739.  
  1740.     /* ensure that they have the same length */
  1741.     while (namerest [0] && classrest [0])
  1742.       namerest++, classrest++;
  1743.     if (namerest [0] || classrest [0])
  1744.       Fsignal (Qerror,
  1745.            Fcons (build_string
  1746.               ("class list and name list must be the same length"),
  1747.               Fcons (build_string (name_string),
  1748.                  Fcons (build_string (class_string), Qnil))));
  1749.     BLOCK_INPUT;
  1750.     result = XrmQGetResource (XtDatabase (XtDisplay (widget)),
  1751.                   namelist, classlist, &xrm_type, &xrm_value);
  1752.     UNBLOCK_INPUT;
  1753.  
  1754.     if (result != True || xrm_type != string_quark)
  1755.       return Qnil;
  1756.     s = (char *) xrm_value.addr;
  1757.   }
  1758.  
  1759.   if (EQ (type, intern ("string")))
  1760.     return build_string (s);
  1761.   else if (EQ (type, intern ("boolean")))
  1762.     {
  1763.       if (!strcasecmp (s, "off") || !strcasecmp (s, "false") ||
  1764.       !strcasecmp (s,"no"))
  1765.     return Fcons (Qnil, Qnil);
  1766.       else if (!strcasecmp (s, "on") || !strcasecmp (s, "true") ||
  1767.            !strcasecmp (s, "yes"))
  1768.     return Fcons (Qt, Qnil);
  1769.       else
  1770.     {
  1771.       char str[255];
  1772.       sprintf (str, "can't convert %s: %s to a Boolean",
  1773.            name_string, s);
  1774.       return Fsignal (Qerror, Fcons (build_string (str), Qnil));
  1775.     }
  1776.     }
  1777.   else if (EQ (type, intern ("integer")))
  1778.     {
  1779.       int i, c;
  1780.       if (1 != sscanf (s, "%d%c", &i, &c))
  1781.     {
  1782.       char str [255];
  1783.       sprintf (str, "can't convert %s: %s to an integer",
  1784.            name_string, s);
  1785.       return Fsignal (Qerror, Fcons (build_string (str), Qnil));
  1786.     }
  1787.       else
  1788.     return make_number (i);
  1789.     }
  1790.   else
  1791.     return
  1792.       Fsignal (Qwrong_type_argument,
  1793.            Fcons (build_string ("should be string, integer, or boolean"),
  1794.               Fcons (type, Qnil)));
  1795. }
  1796.  
  1797.  
  1798. #ifndef BITMAPDIR
  1799. #define BITMAPDIR "/usr/include/X11/bitmaps"
  1800. #endif
  1801.  
  1802. void
  1803. initialize_x_bitmap_file_path ()
  1804. {
  1805.   Display *dpy = x_current_display;
  1806.   char *type = 0;
  1807.   XrmValue value;
  1808.   if (XrmGetResource (XtDatabase (dpy),
  1809.               "bitmapFilePath", "BitmapFilePath", &type, &value)
  1810.       && !strcmp (type, "String"))
  1811.     {
  1812.       char *s1, *s2;
  1813.       char *p = (char *) value.addr;
  1814.       s1 = p;
  1815.       for (s2 = p; *s2; s2++)
  1816.     if (*s2 == ':' && s1 != s2)
  1817.       {
  1818.         Vx_bitmap_file_path = Fcons (make_string (s1, s2 - s1),
  1819.                      Vx_bitmap_file_path);
  1820.         s1 = s2 + 1;
  1821.       }
  1822.       if (s1 != s2)
  1823.     Vx_bitmap_file_path = Fcons (make_string (s1, s2 - s1),
  1824.                      Vx_bitmap_file_path);
  1825.     }
  1826.   Vx_bitmap_file_path = Fnreverse (Fcons (build_string (BITMAPDIR),
  1827.                       Vx_bitmap_file_path));
  1828. }
  1829.  
  1830.  
  1831. /* Cursors.  Once emacs allocates an X cursor, it never frees it.
  1832.    Presumably cursors are very lightweight, and this it ok.  If
  1833.    this turns out not to be the case, we should only cache the 
  1834.    last N cursors used (2<n<10?) and XFreeCursor() on the least
  1835.    recently used ones.
  1836.  */
  1837.  
  1838. Lisp_Object Vcursor_alist;
  1839.  
  1840. /* XmuCvtStringToCursor is a little bogus, and when it can't convert to
  1841.    a real cursor, it will sometimes return a "success" value, after 
  1842.    triggering a BadPixmap error.  It then gives you a cursor that will
  1843.    itself generate BadCursor errors.  So we install this error handler
  1844.    to catch/notice the X error and take that as meaning "couldn't convert."
  1845.  */
  1846.  
  1847. static int XmuCvtStringToCursor_got_error;
  1848. static int XmuCvtStringToCursor_error_handler (dpy, error)
  1849.      Display *dpy;
  1850.      XErrorEvent *error;
  1851. {
  1852.   XmuCvtStringToCursor_got_error = 1;
  1853.   return 0;
  1854. }
  1855.  
  1856. DEFUN ("x-valid-color-name-p", Fx_valid_color_name_p, Sx_valid_color_name_p,
  1857.        1, 2, 0,
  1858.        "Returns true if COLOR names a color that X knows about.\n\
  1859. Valid color names are listed in the file /usr/lib/X11/rgb.txt, or\n\
  1860. whatever the equivalent is on your system.")
  1861.      (color, screen)
  1862.      Lisp_Object color, screen;
  1863. {
  1864.   int ok;
  1865.   XColor c;
  1866.   Widget widget;
  1867.   if (NILP (screen))
  1868.     screen = Fselected_screen ();
  1869.   CHECK_SCREEN (screen, 0);
  1870.   if (! SCREEN_IS_X (XSCREEN (screen)))
  1871.     return Qnil;
  1872.   CHECK_STRING (color, 0);
  1873.   widget = XSCREEN (screen)->display.x->widget;
  1874.   BLOCK_INPUT;
  1875.   ok = XParseColor (XtDisplay (widget),
  1876.             DefaultColormapOfScreen (XtScreen (widget)),
  1877.             (char *) XSTRING (color)->data, &c);
  1878.   UNBLOCK_INPUT;
  1879.   return ok ? Qt : Qnil;
  1880. }
  1881.  
  1882. DEFUN ("x-valid-keysym-name-p", Fx_valid_keysym_name_p, Sx_valid_keysym_name_p,
  1883.        1, 1, 0,
  1884.   "Returns true if KEYSYM names a keysym that the X library knows about.\n\
  1885. Valid keysyms are listed in the files /usr/include/X11/keysymdef.h and in\n\
  1886. /usr/lib/X11/XKeysymDB, or whatever the equivalents are on your system.")
  1887.      (keysym)
  1888.      Lisp_Object keysym;
  1889. {
  1890.   CHECK_STRING (keysym, 0);
  1891.   if (XStringToKeysym ((char *) XSTRING (keysym)->data))
  1892.     return Qt;
  1893.   return Qnil;
  1894. }
  1895.  
  1896.  
  1897. static Cursor
  1898. x_get_cursor (s, name, fg, bg, noerror)
  1899.      struct screen *s;
  1900.      Lisp_Object name, fg, bg;
  1901.      int noerror;
  1902. {
  1903.   Cursor cursor;
  1904.   Lisp_Object cons, ofg, obg;
  1905.   if (noerror)
  1906.     {
  1907.       if ((!STRINGP (name)) ||
  1908.       (!NILP (fg) && !STRINGP (fg)) ||
  1909.       (!NILP (bg) && !STRINGP (bg)))
  1910.     return 0;
  1911.     }
  1912.   else
  1913.     {
  1914.       CHECK_STRING (name, 0);
  1915.       if (!NILP (fg)) CHECK_STRING (fg, 0);
  1916.       if (!NILP (bg)) CHECK_STRING (bg, 0);
  1917.     }
  1918.   cons = assoc_no_quit (name, Vcursor_alist);
  1919.   if (NILP (cons))
  1920.     {
  1921.       int (*old_handler) ();
  1922.       XrmValue arg, from, to;
  1923.       Cardinal nargs = 1;
  1924.       Screen *screen = XtScreen (s->display.x->widget);
  1925.       arg.addr = (XtPointer) &screen;
  1926.       arg.size = sizeof (Screen *);
  1927.       from.addr = (XtPointer) XSTRING (name)->data;
  1928.       from.size = (unsigned int) XSTRING (name)->size;
  1929.       to.addr = 0;
  1930.       to.size = 0;
  1931.       BLOCK_INPUT;
  1932.       XSync (XtDisplay (s->display.x->widget), 0);
  1933.       XmuCvtStringToCursor_got_error = 0;
  1934.       old_handler = XSetErrorHandler (XmuCvtStringToCursor_error_handler);
  1935.       XmuCvtStringToCursor (&arg, &nargs, &from, &to);
  1936.       XSync (XtDisplay (s->display.x->widget), 0);
  1937.       XSetErrorHandler (old_handler);
  1938.       UNBLOCK_INPUT;
  1939.       if (XmuCvtStringToCursor_got_error) cursor = 0;
  1940.       else if (to.addr) cursor = *((Cursor *) to.addr);
  1941.       else cursor = 0;
  1942.       if (! cursor && noerror)
  1943.     return 0;
  1944.       else if (! cursor)
  1945.     while (1)
  1946.       Fsignal (Qerror, Fcons (build_string ("unknown cursor"),
  1947.                   Fcons (name, Qnil)));
  1948.       ofg = obg = Qnil;
  1949.       cons = Fcons (name, Fcons (word_to_lisp ((int) cursor),
  1950.                  Fcons (ofg, Fcons (obg, Qnil))));
  1951.       Vcursor_alist = Fcons (cons, Vcursor_alist);
  1952.     }
  1953.   else
  1954.     {
  1955.       cursor = lisp_to_word (XCONS (XCONS (cons)->cdr)->car);
  1956.       ofg = XCONS (XCONS (XCONS (cons)->cdr)->cdr)->car;
  1957.       obg = XCONS (XCONS (XCONS (XCONS (cons)->cdr)->cdr)->cdr)->car;
  1958.     }
  1959.   if (!NILP (fg) && !NILP (bg) &&
  1960.       (NILP (Fequal (fg, ofg)) || NILP (Fequal (bg, obg))))
  1961.     {
  1962.       XColor fgc, bgc;
  1963.       int result;
  1964.       Widget widget = s->display.x->widget;
  1965.       Display *dpy = XtDisplay (widget);
  1966.       Colormap cmap = DefaultColormapOfScreen (XtScreen (widget));
  1967.  
  1968.       BLOCK_INPUT;
  1969.       result = XParseColor (dpy, cmap, (char *) XSTRING (fg)->data, &fgc);
  1970.       UNBLOCK_INPUT;
  1971.       if (! result && noerror)
  1972.     return 0;
  1973.       else if (! result)
  1974.     while (1)
  1975.       Fsignal (Qerror, Fcons (build_string ("unrecognised color"),
  1976.                   Fcons (fg, Qnil)));
  1977.       BLOCK_INPUT;
  1978.       result = XParseColor (dpy, cmap, (char *) XSTRING (bg)->data, &bgc);
  1979.       UNBLOCK_INPUT;
  1980.       if (! result && noerror)
  1981.     return 0;
  1982.       else if (! result)
  1983.     while (1)
  1984.       Fsignal (Qerror, Fcons (build_string ("unrecognised color"),
  1985.                   Fcons (bg, Qnil)));
  1986.       XCONS (XCONS (XCONS (cons)->cdr)->cdr)->car = fg;
  1987.       XCONS (XCONS (XCONS (XCONS (cons)->cdr)->cdr)->cdr)->car = bg;
  1988.       BLOCK_INPUT;
  1989.       XRecolorCursor (dpy, cursor, &fgc, &bgc);
  1990.       UNBLOCK_INPUT;
  1991.     }
  1992.   return cursor;
  1993. }
  1994.  
  1995.  
  1996. DEFUN ("x-set-screen-pointer", Fx_set_screen_pointer, Sx_set_screen_pointer,
  1997.        2, 4, 0,
  1998.        "Set the mouse cursor of SCREEN to the cursor named CURSOR-NAME,\n\
  1999. with colors FOREGROUND and BACKGROUND.  The string may be any of the\n\
  2000. standard cursor names from appendix B of the Xlib manual (also known as\n\
  2001. the file <X11/cursorfont.h>) minus the XC_ prefix, or it may be a font\n\
  2002. name and glyph index of the form \"FONT fontname index [[font] index]\",\n\
  2003. or it may be a bitmap file acceptable to XmuLocateBitmapFile().\n\
  2004. If it is a bitmap file, and if a bitmap file whose name is the name of\n\
  2005. the cursor with \"msk\" exists, then it is used as the mask.  For example,\n\
  2006. a pair of files may be named \"cursor.xbm\" and \"cursor.xbmmsk\".")
  2007.      (screen, cursor_name, fg, bg)
  2008.      Lisp_Object screen, cursor_name, fg, bg;
  2009. {
  2010.   Cursor cursor;
  2011.   CHECK_SCREEN (screen, 0);
  2012.   if (! SCREEN_IS_X (XSCREEN (screen)))
  2013.     return Qnil;
  2014.   cursor = x_get_cursor (XSCREEN (screen), cursor_name, fg, bg, 0);
  2015.   BLOCK_INPUT;
  2016.   XDefineCursor (XtDisplay (XSCREEN (screen)->display.x->edit_widget),
  2017.          XtWindow (XSCREEN (screen)->display.x->edit_widget),
  2018.          cursor);
  2019.   XFlush (XtDisplay (XSCREEN (screen)->display.x->edit_widget));
  2020.   UNBLOCK_INPUT;
  2021.   store_screen_param (XSCREEN (screen), intern ("pointer"), cursor_name);
  2022.   return Qnil;
  2023. }
  2024.  
  2025.  
  2026. /* GC calls x_show_gc_cursor() to change the mouse pointer to indicate GC.
  2027.    If this returns 0, then it couldn't change the cursor for whatever reason,
  2028.    and a minibuffer message will be output instead.  x_show_normal_cursor()
  2029.    will be called at the end.
  2030. */
  2031. static int change_cursor_for_gc ();
  2032.  
  2033. int
  2034. x_show_gc_cursor (s)
  2035.      struct screen* s;
  2036. {
  2037.   return change_cursor_for_gc (s, 1);
  2038. }
  2039.  
  2040. int
  2041. x_show_normal_cursor (s)
  2042.      struct screen* s;
  2043. {
  2044.   return change_cursor_for_gc (s, 0);
  2045. }
  2046.  
  2047.  
  2048. extern Lisp_Object get_screen_param (struct screen *, Lisp_Object);
  2049.  
  2050. static int
  2051. change_cursor_for_gc (s, gc_p)
  2052.      struct screen *s;
  2053.      int gc_p;
  2054. {
  2055.   Cursor cursor;
  2056.   static int changed;
  2057.  
  2058.   if (!s || !SCREEN_IS_X(s) || NILP (Vx_gc_pointer_shape))
  2059.     return 0;
  2060.   
  2061.   if (! gc_p && !changed)
  2062.     return 0;
  2063.  
  2064.   if (gc_p)
  2065.     cursor = x_get_cursor (s, Vx_gc_pointer_shape, Qnil, Qnil, 1);
  2066.   else
  2067.     cursor = x_get_cursor (s, get_screen_param (s, intern ("pointer")),
  2068.                Qnil, Qnil, 1);
  2069.   if (! cursor)
  2070.     {
  2071.       if (gc_p)
  2072.     message ("Garbage collecting... (x-gc-pointer-shape is bogus!)");
  2073.       changed = 0;
  2074.       return 1;
  2075.     }
  2076.  
  2077.   BLOCK_INPUT;
  2078.   XDefineCursor (XtDisplay (s->display.x->edit_widget),
  2079.          XtWindow (s->display.x->edit_widget),
  2080.          cursor);
  2081.   XFlushQueue ();
  2082.   UNBLOCK_INPUT;
  2083.   changed = 1;
  2084.   return 1;
  2085. }
  2086.  
  2087.  
  2088.  
  2089. #ifdef USE_SOUND
  2090. extern int not_on_console;  /* defined in fns.c */
  2091. #endif
  2092.  
  2093. extern Lisp_Object x_term_init (Lisp_Object);
  2094.  
  2095. DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
  2096.        1, 1, 0, "Open a connection to an X server.\n\
  2097. Argument ARGV is a list of strings describing the command line options.\n\
  2098. Returns a copy of ARGV from which the arguments used by the Xt code\n\
  2099. to open the connect have been removed.")
  2100.      (argv_list)
  2101.     Lisp_Object argv_list;
  2102. {
  2103.   Lisp_Object argv_rest;
  2104.  
  2105.   if (x_current_display != 0)
  2106.     error ("X server connection is already initialized");
  2107.  
  2108.   /* This is what sets x_current_display.  This also initializes many symbols,
  2109.      such as those used for input. */
  2110.   argv_rest = x_term_init (argv_list);
  2111.   
  2112.   text_part_sym = intern ("text-part");
  2113.   modeline_part_sym = intern ("modeline-part");
  2114.   
  2115.   XFASTINT (Vwindow_system_version) = 11;
  2116.   Xatoms_of_xfns ();
  2117.   Xatoms_of_xselect ();
  2118.  
  2119. #ifdef USE_SOUND
  2120.   /* When running on a SparcStation or SGI, we cannot use digitized sounds as
  2121.      beeps unless emacs is running on the same machine that $DISPLAY points
  2122.      to, and $DISPLAY points to screen 0 of that machine.
  2123.    */
  2124.   {
  2125.     char *dpy = x_current_display->display_name;
  2126.     char *tail = (char *) strchr (dpy, ':');
  2127.     if (! tail ||
  2128.     strncmp (tail, ":0", 2))
  2129.       not_on_console = 1;
  2130.     else {
  2131.       char dpyname[255], localname[255];
  2132.       strncpy (dpyname, dpy, tail-dpy);
  2133.       dpyname [tail-dpy] = 0;
  2134.       if (!*dpyname ||
  2135.       !strcmp(dpyname, "unix") ||
  2136.       !strcmp(dpyname, "localhost"))
  2137.     not_on_console = 0;
  2138.       else if (gethostname (localname, sizeof (localname)))
  2139.     not_on_console = 1;  /* can't find hostname? */
  2140.       else {
  2141.     /* gethostbyname() reuses the structure it returns,
  2142.        so we have to copy the string out of it. */
  2143.     struct hostent *h = gethostbyname (dpyname);
  2144.     not_on_console = !h || !!(strcmp (localname, h->h_name));
  2145.       }
  2146.     }
  2147.   }
  2148. #endif /* USE_SOUND */
  2149.  
  2150.   return argv_rest;
  2151. }
  2152.  
  2153. DEFUN ("x-window-id", Fx_window_id, Sx_window_id, 1, 1, 0,
  2154.        "Get the ID of the X11 window. This gives us a chance to manipulate\n\
  2155. the Emacs window from within a different program. Since the id is an\n\
  2156. unsigned long, we return it as a string.")
  2157.   (screen)
  2158.   Lisp_Object screen;
  2159. {
  2160.   char str[20];
  2161.  
  2162.   CHECK_SCREEN (screen, 0);
  2163.   if (! SCREEN_IS_X (XSCREEN (screen)))
  2164.     return Qnil;
  2165.   sprintf (str, "%lu", XtWindow (XSCREEN (screen)->display.x->edit_widget));
  2166.   return (make_string (str, strlen (str)));
  2167. }
  2168.  
  2169.  
  2170. DEFUN ("x-close-current-connection", Fx_close_current_connection,
  2171.        Sx_close_current_connection,
  2172.        0, 0, 0, "Close the connection to the current X server.")
  2173.   ()
  2174. {
  2175.   /* This is ONLY used when killing emacs;  For switching displays
  2176.      we'll have to take care of setting CloseDownMode elsewhere. */
  2177. #ifdef FREE_CHECKING
  2178.   extern void (*__free_hook)();
  2179.   int checking_free;
  2180. #endif
  2181.  
  2182.   if (x_current_display)
  2183.     {
  2184.       BLOCK_INPUT;
  2185. #ifdef FREE_CHECKING
  2186.       checking_free = (__free_hook != 0);
  2187.       
  2188.       /* Disable strict free checking, to avoid bug in X library */
  2189.       if (checking_free)
  2190.     disable_strict_free_check ();
  2191. #endif
  2192.       XCloseDisplay (x_current_display);
  2193.       x_current_display = 0;
  2194.       Vwindow_system = Qnil;
  2195. #ifdef FREE_CHECKING
  2196.       if (checking_free)
  2197.     enable_strict_free_check ();
  2198. #endif
  2199.       UNBLOCK_INPUT;
  2200.     }
  2201.   else
  2202.     fatal ("No current X display connection to close");
  2203.   return Qnil;
  2204. }
  2205.  
  2206. static int
  2207. emacs_safe_XSyncFunction(dpy)
  2208.      register Display *dpy;
  2209. {
  2210.   BLOCK_INPUT;
  2211.   XSync (dpy, 0);
  2212.   UNBLOCK_INPUT;
  2213.   return 0;
  2214. }
  2215.  
  2216. DEFUN ("x-debug-mode", Fx_debug_mode, Sx_debug_mode, 1, 1, 0,
  2217.        "With a true arg, put the connection to the X server in synchronous\n\
  2218. mode; this is slower.  False turns it off.\n\
  2219. Do not simply call XSynchronize() from gdb; that won't work.")
  2220.     (arg)
  2221.     Lisp_Object arg;
  2222. {
  2223.   if (!NILP (arg))
  2224.     {
  2225.       BLOCK_INPUT;
  2226.       XSetAfterFunction (x_current_display, emacs_safe_XSyncFunction);
  2227.       UNBLOCK_INPUT;
  2228.       message ("X connection is synchronous");
  2229.     }
  2230.   else
  2231.     {
  2232.       BLOCK_INPUT;
  2233.       XSetAfterFunction (x_current_display, 0);
  2234.       UNBLOCK_INPUT;
  2235.       message ("X connection is asynchronous");
  2236.     }
  2237.   return arg;
  2238. }
  2239.  
  2240.  
  2241. void
  2242. syms_of_xfns ()
  2243. {
  2244.   init_x_parm_symbols ();
  2245.  
  2246.   /* This is zero if not using X windows.  */
  2247.   x_current_display = 0;
  2248.  
  2249.   WM_COMMAND_screen = Qnil;
  2250.   staticpro (&WM_COMMAND_screen);
  2251.  
  2252.   DEFVAR_LISP ("x-gc-pointer-shape", &Vx_gc_pointer_shape,
  2253.    "The shape of the mouse-pointer during garbage collection.\n\
  2254. If this is nil, then the cursor will not be changed, and echo-area messages\n\
  2255. will be used instead.");
  2256.   Vx_gc_pointer_shape = Qnil;
  2257.  
  2258.   DEFVAR_LISP ("bar-cursor", &Vbar_cursor,
  2259.            "Use vertical bar cursor if non-nil.");
  2260.   Vbar_cursor = Qnil;
  2261.  
  2262.   DEFVAR_LISP ("x-screen-defaults", &Vx_screen_defaults,
  2263.     "Alist of default screen-creation parameters for X-window screens.\n\
  2264. These override what is specified in `~/.Xdefaults' but are overridden\n\
  2265. by the arguments to the particular call to `x-create-screen'.");
  2266.   Vx_screen_defaults = Qnil;
  2267.  
  2268.   DEFVAR_LISP ("default-screen-name", &Vdefault_screen_name,
  2269.     "The default name to assign to newly-created screens.\n\
  2270. This can be overridden by arguments to `x-create-screen'.\n\
  2271. This must be a string.");
  2272.   Vdefault_screen_name = Fpurecopy (build_string ("emacs"));
  2273.  
  2274.   DEFVAR_LISP ("x-emacs-application-class", &Vx_emacs_application_class,
  2275.            "The X application class of the Emacs process.\n\
  2276. This controls, among other things, the name of the `app-defaults' file\n\
  2277. that emacs will use.  For changes to this variable to take effect, they\n\
  2278. must be made before the connection to the X server is initialized, that is,\n\
  2279. this variable may only be changed before emacs is dumped, or by setting it\n\
  2280. in the file lisp/term/x-win.el.");
  2281.   Vx_emacs_application_class = Fpurecopy (build_string ("Emacs"));
  2282.  
  2283.   DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
  2284.        "A list of the directories in which X bitmap files may be found.\n\
  2285. If nil, this is initialized from the \"*bitmapFilePath\" resource.");
  2286.   Vx_bitmap_file_path = Qnil;
  2287.  
  2288.   DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents,
  2289.     "*Non-nil means to allow synthetic events.  Nil means they are ignored.\n\
  2290. Beware: allowing emacs to process SendEvents opens a big security hole.");
  2291.   x_allow_sendevents = 0;
  2292.  
  2293.   staticpro (&Vcursor_alist);
  2294.   Vcursor_alist = Qnil;
  2295.  
  2296.   defsubr (&Sx_display_visual_class);
  2297.   defsubr (&Sx_color_display_p);
  2298.   defsubr (&Sx_pixel_width);
  2299.   defsubr (&Sx_pixel_height);
  2300.   defsubr (&Sx_display_pixel_width);
  2301.   defsubr (&Sx_display_pixel_height);
  2302.   defsubr (&Sx_display_planes);
  2303.   defsubr (&Sx_display_color_cells);
  2304.   defsubr (&Sx_server_vendor);
  2305.   defsubr (&Sx_server_version);
  2306.   defsubr (&Sx_window_id);
  2307.   defsubr (&Sx_grab_pointer);
  2308.   defsubr (&Sx_ungrab_pointer);
  2309.   defsubr (&Sx_create_screen);
  2310.   defsubr (&Sx_open_connection);
  2311.   defsubr (&Sx_close_current_connection);
  2312. #ifdef ENERGIZE
  2313.   defsubr (&Senergize_toggle_psheet);
  2314. #endif
  2315.   defsubr (&Sx_show_lineinfo_column);
  2316.   defsubr (&Sx_hide_lineinfo_column);
  2317.   defsubr (&Sx_debug_mode);
  2318.   defsubr (&Sx_get_resource);
  2319.   defsubr (&Sx_set_screen_icon_pixmap);
  2320.   defsubr (&Sx_set_screen_pointer);
  2321.   defsubr (&Sx_valid_color_name_p);
  2322.   defsubr (&Sx_valid_keysym_name_p);
  2323.  
  2324.   defsubr (&Sx_EnterNotify_internal);
  2325.   defsubr (&Sx_LeaveNotify_internal);
  2326.   defsubr (&Sx_FocusIn_internal);
  2327.   defsubr (&Sx_FocusOut_internal);
  2328.   defsubr (&Sx_MapNotify_internal);
  2329.   defsubr (&Sx_UnmapNotify_internal);
  2330.   defsubr (&Sx_VisibilityNotify_internal);
  2331.   defsubr (&Sx_non_VisibilityNotify_internal);
  2332.  
  2333.   Qx_EnterNotify_internal = intern ("x-EnterNotify-internal");
  2334.   Qx_LeaveNotify_internal = intern ("x-LeaveNotify-internal");
  2335.   Qx_FocusIn_internal  = intern ("x-FocusIn-internal");
  2336.   Qx_FocusOut_internal = intern ("x-FocusOut-internal");
  2337.   Qx_MapNotify_internal = intern ("x-MapNotify-internal");
  2338.   Qx_UnmapNotify_internal = intern ("x-UnmapNotify-internal");
  2339.   Qx_VisibilityNotify_internal = intern ("x-VisibilityNotify-internal");
  2340.   Qx_non_VisibilityNotify_internal = intern("x-non-VisibilityNotify-internal");
  2341. }
  2342.  
  2343. void
  2344. Xatoms_of_xfns ()
  2345. {
  2346. #define ATOM(x) XInternAtom(x_current_display, (x), False)
  2347.  
  2348.   BLOCK_INPUT;
  2349.   Xatom_WM_PROTOCOLS = ATOM("WM_PROTOCOLS");
  2350.   Xatom_WM_DELETE_WINDOW = ATOM("WM_DELETE_WINDOW");
  2351.   Xatom_WM_SAVE_YOURSELF = ATOM("WM_SAVE_YOURSELF");
  2352.   Xatom_WM_TAKE_FOCUS = ATOM("WM_TAKE_FOCUS");
  2353.   UNBLOCK_INPUT;
  2354. }
  2355.  
  2356. #endif /* HAVE_X_WINDOWS */
  2357.