home *** CD-ROM | disk | FTP | other *** search
- /* Functions for the X window system.
- Copyright (C) 1989, 1992, 1993 Free Software Foundation.
-
- This file is part of GNU Emacs.
-
- GNU Emacs is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GNU Emacs is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU Emacs; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Substantially rewritten for Lucid GNU Emacs. */
-
- #include "config.h"
-
- #include <stdio.h>
- #include <signal.h>
-
- #include <X11/IntrinsicP.h> /* CoreP.h needs this */
- #include <X11/CoreP.h> /* foul, but we need this to use our own
- window inside a widget instead of one
- that Xt creates... */
- #include <X11/StringDefs.h>
- #include <X11/Xresource.h>
- #include <X11/Shell.h>
-
- #include <X11/Xaw/Paned.h>
- #include <X11/Xaw/Label.h>
-
- #include <X11/Xos.h>
-
- #include "ScreenWidgetP.h"
-
- #ifdef LINE_INFO_WIDGET
- # include "LineInfoWidget.h"
- # include "LineInfoWidgetP.h"
- #endif
-
- #include "EmacsShell.h"
- #include "EmacsShellP.h"
-
- #if (XtSpecificationRelease >= 5) /* Do the EDITRES protocol */
- #define HACK_EDITRES
- extern void _XEditResCheckMessages();
- #endif /* R5 */
-
- #ifdef USE_SOUND
- # include <netdb.h>
- #endif
-
- #include "lisp.h"
- #include "xterm.h"
- #include "window.h"
- #include "buffer.h"
- #include "extents.h"
- #include "screen.h"
- #include "events.h"
- #include "faces.h"
-
- #ifdef HAVE_X_WINDOWS
-
- #define min(a,b) ((a) < (b) ? (a) : (b))
- #define max(a,b) ((a) > (b) ? (a) : (b))
- #define COLOR_SCREEN_P(d) (XCellsOfScreen (DefaultScreenOfDisplay (d)) > 2)
-
- Lisp_Object Vx_gc_pointer_shape;
-
- /* If non-nil, use vertical bar cursor. */
- Lisp_Object Vbar_cursor;
-
- /* Where bitmaps are; initialized from resource database */
- Lisp_Object Vx_bitmap_file_path;
-
- /* The application class of Emacs. */
- Lisp_Object Vx_emacs_application_class;
-
- /* The screen on which we have placed a WM_COMMAND property. Only one. */
- Lisp_Object WM_COMMAND_screen;
-
- Atom Xatom_WM_TAKE_FOCUS, Xatom_WM_SAVE_YOURSELF, Xatom_WM_DELETE_WINDOW,
- Xatom_WM_PROTOCOLS;
-
- Lisp_Object Qundefined_color;
- Lisp_Object Qx_resource_name;
-
- extern Lisp_Object Vwindow_system_version;
-
- /* Default parameters to use when creating screens. */
- Lisp_Object Vx_screen_defaults;
-
- /* Do we accept events send by other clients? */
- int x_allow_sendevents;
-
- extern Lisp_Object Qmouse_enter_screen_hook, Qmouse_leave_screen_hook;
- extern Lisp_Object Qmap_screen_hook, Qunmap_screen_hook;
- extern Lisp_Object Qcreate_screen_hook;
-
-
- /* Return the Emacs screen-object corresponding to an X window */
- struct screen *
- x_window_to_screen (wdesc)
- Window wdesc;
- {
- Lisp_Object tail, screen;
- struct screen *s;
-
- for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
- {
- screen = XCONS (tail)->car;
- if (!SCREENP (screen))
- continue;
- s = XSCREEN (screen);
- if (SCREEN_IS_X (s) && XtWindow (s->display.x->edit_widget) == wdesc)
- return s;
- }
- return 0;
- }
-
- /* Like x_window_to_screen but also compares the window with the widget's
- widows */
- struct screen *
- x_any_window_to_screen (wdesc)
- Window wdesc;
- {
- Lisp_Object tail, screen;
- struct screen *s;
- struct x_display *x;
-
- for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
- {
- screen = XCONS (tail)->car;
- if (!SCREENP (screen))
- continue;
- s = XSCREEN (screen);
- if (!SCREEN_IS_X (s))
- continue;
- x = s->display.x;
- /* This screen matches if the window is any of its widgets. */
- if (wdesc == XtWindow (x->widget) ||
- wdesc == XtWindow (x->column_widget) ||
- wdesc == XtWindow (x->edit_widget))
- return s;
- /* Match if the window is this screen's menubar. */
- if (x->menubar_widget &&
- wdesc == XtWindow (x->menubar_widget))
- return s;
- /* Do *not* match if the window is this screen's psheet. */
- }
- return 0;
- }
-
- Lisp_Object text_part_sym;
- Lisp_Object modeline_part_sym;
-
-
- /* Connect the screen-parameter names (symbols) to the corresponding
- X Resource Manager names. The name of a parameter, as a Lisp symbol,
- has an `x-resource-name' property which is a Lisp_String. */
-
- static void
- init_x_parm_symbols ()
- {
- register Lisp_Object propname;
- Qx_resource_name = propname = intern ("x-resource-name");
-
- #define def(sym, rsrc) \
- Fput (intern (sym), propname, build_string (rsrc))
- #define defi(sym,rsrc) \
- def (sym, rsrc); Fput (intern (sym), Qintegerp, Qt)
-
- def ("cursor-color", XtNcursorColor);
- def ("border-color", XtNborderColor);
- defi("border-width", XtNborderWidth);
- defi("internal-border-width", XtNinternalBorderWidth);
- defi("width", XtNwidth);
- defi("height", XtNheight);
- defi("x", XtNx);
- defi("y", XtNy);
- /* def ("icon-type", "iconType"); */
- #ifdef LINE_INFO_COLUMN
- defi("line-info-column-width", XtNlineInfoColumnWidth);
- def ("line-info-column-foreground-color", XtNlineInfoColumnForeground);
- def ("line-info-column-background-color", XtNlineInfoColumnBackground);
- #endif
- /* def ("vertical-scroll-bar", XtNverticalScrollBar); */
- /* def ("horizontal-scroll-bar", XtNhorizontalScrollBar); */
- def ("minibuffer", XtNminibuffer);
- def ("unsplittable", XtNunsplittable);
- defi("inter-line-space", XtNinterline);
- /* def ("bar-cursor", XtNbarCursor); */
- /* def ("visual-bell", XtNvisualBell); */
- /* defi("bell-volume", XtNbellVolume); */
-
- #undef def
- }
-
-
- /* Insert a description of internally-recorded parameters of screen X
- into the parameter alist *ALISTPTR that is to be given to the user.
- Only parameters that are specific to the X window system
- and whose values are not correctly recorded in the screen's
- param_alist need to be considered here. */
-
- extern Lisp_Object Vinvocation_name;
-
- static void
- color_to_string (w, pixel, buf)
- Widget w;
- unsigned long pixel;
- char *buf;
- {
- XColor color;
- color.pixel = pixel;
- BLOCK_INPUT;
- XQueryColor (XtDisplay (w), w->core.colormap, &color);
- UNBLOCK_INPUT;
- sprintf (buf, "#%04x%04x%04x", color.red, color.green, color.blue);
- }
-
-
- extern void store_in_alist (Lisp_Object *, char *, Lisp_Object);
-
- void
- x_report_screen_params (s, alistptr)
- struct screen *s;
- Lisp_Object *alistptr;
- {
- TopLevelShellWidget shell = (TopLevelShellWidget)s->display.x->widget;
- EmacsScreenWidget w = (EmacsScreenWidget)s->display.x->edit_widget;
- char buf [255];
-
- #define store_int(sym, slot) \
- store_in_alist (alistptr, sym, make_number (slot))
- #define store_str(sym, slot) \
- store_in_alist (alistptr, sym, build_string (slot))
- #define store_bool(sym, slot) \
- store_in_alist (alistptr, sym, (slot) ? Qt : Qnil)
- #define store_color(sym, slot) \
- color_to_string ((Widget) w, slot, buf); \
- store_in_alist (alistptr, sym, build_string (buf))
- #define store_curs(sym, slot) /* #### don't have the strings any more... */
-
- store_color ("cursor-color", w->emacs_screen.cursor_color);
- store_color ("border-color", w->core.border_pixel);
- store_int ("left", shell->core.x);
- store_int ("top", shell->core.y);
- store_int ("border-width", w->core.border_width);
- store_int ("internal-border-width", w->emacs_screen.internal_border_width);
- store_int ("inter-line-space", w->emacs_screen.interline);
- store_bool ("minibuffer", w->emacs_screen.minibuffer);
- store_bool ("unsplittable", w->emacs_screen.minibuffer);
- /* store_bool ("visual-bell", w->emacs_screen.visual_bell); */
- /* store_bool ("bar-cursor", w->emacs_screen.bar_cursor); */
- sprintf (buf, "0x%x", XtWindow (w));
- store_str ("window-id", buf);
- }
-
-
- /* Functions called only from `x_set_screen_param' to set
- ** individual parameters. */
-
- void
- x_set_title_from_char (struct screen* s, char* name)
- {
- char *old_name = 0;
- Arg av [1];
- BLOCK_INPUT;
- XtSetArg (av[0], XtNtitle, &old_name);
- XtGetValues (s->display.x->widget, av, 1);
- if (!old_name || strcmp (name, old_name))
- {
- XtSetArg (av[0], XtNtitle, name);
- XtSetValues (s->display.x->widget, av, 1);
- }
- UNBLOCK_INPUT;
- }
-
- void
- x_set_icon_name_from_char (struct screen* s, char* name)
- {
- char *old_name = 0;
- Arg av [1];
- BLOCK_INPUT;
- XtSetArg (av[0], XtNiconName, &old_name);
- XtGetValues (s->display.x->widget, av, 1);
- if (!old_name || strcmp (name, old_name))
- {
- XtSetArg (av[0], XtNiconName, name);
- XtSetValues (s->display.x->widget, av, 1);
- }
- UNBLOCK_INPUT;
- }
-
- /* Report to X that a screen parameter of screen S is being set or changed.
- If the parameter is not specially recognized, do nothing.
- */
-
- extern void store_screen_param (struct screen *s, Lisp_Object, Lisp_Object);
-
- void
- x_set_screen_values (s, alist)
- struct screen *s;
- Lisp_Object alist;
- {
- int x, y;
- Dimension width = 0, height = 0;
- Bool size_specified_p = False;
- Bool x_specified_p = False;
- Bool y_specified_p = False;
- Lisp_Object tail;
- Widget w = s->display.x->edit_widget;
-
- for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
- {
- Lisp_Object elt = Fcar (tail);
- Lisp_Object prop = Fcar (elt);
- Lisp_Object val = Fcdr (elt);
-
- if (STRINGP (prop))
- {
- if (XSTRING (prop)->size == 0)
- continue;
-
- BLOCK_INPUT;
- if (STRINGP (val))
- XtVaSetValues (w, XtVaTypedArg, XSTRING (prop)->data, XtRString,
- XSTRING (val)->data, XSTRING (val)->size + 1,
- 0);
- else
- XtVaSetValues (w, XtVaTypedArg,
- XSTRING (prop)->data, XtRInt, XINT (val),
- sizeof (int),
- 0);
- UNBLOCK_INPUT;
- }
- else
- {
- Lisp_Object str = Fget (prop, Qx_resource_name);
- int int_p = !NILP (Fget (prop, Qintegerp));
- if (NILP (prop) || NILP (str))
- continue;
- CHECK_STRING (str, 0);
-
- /* Kludge the width/height so that we interpret them in characters
- instead of pixels. Yuck yuck yuck. */
- if (!strcmp ((char *) XSTRING (str)->data, "width"))
- {
- CHECK_FIXNUM (val, 0);
- width = XINT (val);
- size_specified_p = True;
- continue;
- }
- if (!strcmp ((char *) XSTRING (str)->data, "height"))
- {
- CHECK_FIXNUM (val, 0);
- height = XINT (val);
- size_specified_p = True;
- continue;
- }
- /* Further kludge the x/y to call set-screen-position instead. */
- #if 0
- /* this doesn't work because the window isn't around yet,.
- I guess we really need to cons up a geometry spec. */
- if (!strcmp ((char *) XSTRING (str)->data, "x"))
- {
- CHECK_FIXNUM (val, 0);
- x = XINT (val);
- x_specified_p = True;
- continue;
- }
- if (!strcmp ((char *) XSTRING (str)->data, "y"))
- {
- CHECK_FIXNUM (val, 0);
- y = XINT (val);
- y_specified_p = True;
- continue;
- }
- #endif
-
- BLOCK_INPUT;
- if (int_p)
- {
- CHECK_FIXNUM (val, 0);
- XtVaSetValues (w, (char *) XSTRING (str)->data, XINT (val),
- 0);
- }
- else if (EQ (val, Qt))
- XtVaSetValues (w, (char *) XSTRING (str)->data, /* XtN... */
- True,
- 0);
- else if (EQ (val, Qnil))
- XtVaSetValues (w, (char *) XSTRING (str)->data, /* XtN... */
- False,
- 0);
- else
- {
- CHECK_STRING (val, 0);
- XtVaSetValues (w, XtVaTypedArg,
- (char *) XSTRING (str)->data, /* XtN... */
- XtRString,
- XSTRING (val)->data, XSTRING (val)->size + 1,
- 0);
- }
- UNBLOCK_INPUT;
- }
- }
-
- /* Kludge kludge kludge. */
- if (size_specified_p)
- {
- Lisp_Object screen;
- XSET (screen, Lisp_Screen, s);
- if (width == 0) width = SCREEN_WIDTH (s);
- if (height == 0) height = SCREEN_HEIGHT (s);
- Fset_screen_size (screen, make_number (width), make_number (height),
- Qnil);
- }
- /* Kludge kludge kludge kludge. */
- if (x_specified_p || y_specified_p)
- {
- Lisp_Object screen;
- XSET (screen, Lisp_Screen, s);
- if (!x_specified_p) x = s->display.x->widget->core.x;
- if (!y_specified_p) y = s->display.x->widget->core.y;
- Fset_screen_position (screen, make_number (x), make_number (y));
- }
- }
-
- void
- fix_pane_constraints (w)
- Widget w;
- {
- BLOCK_INPUT;
- XtVaSetValues (w, XtNshowGrip, 0, XtNresizeToPreferred, 1,
- XtNallowResize, 1, 0);
- UNBLOCK_INPUT;
- }
-
- #ifdef ENERGIZE
-
- /* #### remove this when we do not use uilib anymore */
- void sheet_callback () {}
-
- extern int *get_psheets_for_buffer ();
-
- void
- recompute_screen_menubar (screen)
- struct screen *screen;
- {
- /* #### This shouldn't be necessary any more */
- }
-
-
- /* This function is invoked by each menu item which Energize should handle.
- Defined in xterm.c.
- */
- extern void client_menu_item_cb ();
-
- void
- make_psheets_desired (s, buffer)
- struct screen* s;
- Lisp_Object buffer;
- {
- struct x_display *x = s->display.x;
- int count;
- int *psheets;
-
- if (NILP (buffer) || !(psheets = get_psheets_for_buffer (buffer, &count)))
- {
- x->desired_psheets = 0;
- x->desired_psheet_count = 0;
- x->desired_psheet_buffer = Qnil;
- }
- else
- {
- /* Do not show the debugger panel in this function. The
- * debugger panel should never be listed in the visible psheets. */
- extern int debuggerpanel_sheet;
-
- if (count == 1 && psheets [0] == debuggerpanel_sheet)
- return;
-
- x->desired_psheets = psheets;
- x->desired_psheet_count = count;
- x->desired_psheet_buffer = buffer;
- }
- }
-
- Lisp_Object
- desired_psheet_buffer (struct screen* s)
- {
- return s->display.x->desired_psheet_buffer;
- }
-
- /* This function is invoked when the user clicks on the "sheet" button.
- */
- DEFUN ("energize-toggle-psheet", Fenergize_toggle_psheet,
- Senergize_toggle_psheet, 0, 0, "",
- "")
- ()
- {
- struct screen *screen = selected_screen;
- Lisp_Object buffer = Fwindow_buffer (Fselected_window ());
- if (EQ (buffer, desired_psheet_buffer (screen)))
- make_psheets_desired (screen, Qnil);
- else
- make_psheets_desired (screen, buffer);
- return Qnil;
- }
-
-
- void energize_show_menubar_of_buffer ();
-
- /* This is called when a buffer becomes visible in some window.
-
- Show the menubar associated with this buffer, and show the psheets as
- well if this buffer is the last buffer whose psheets were visible in
- this screen.
- */
- void energize_buffer_shown_hook (window)
- struct window *window;
- {
- struct screen* screen = XSCREEN (window->screen);
- Lisp_Object buffer = window->buffer;
- Lisp_Object pbuf;
-
- if (! SCREEN_IS_X (screen)) return;
- pbuf = desired_psheet_buffer (screen);
-
- if (!MINI_WINDOW_P (window))
- energize_show_menubar_of_buffer (window->screen, buffer,
- (EQ (buffer, pbuf) ? Qt : Qnil));
- }
-
-
- static int
- find_buffer_in_different_window (window, buffer, not_in)
- struct window* window;
- Lisp_Object buffer;
- struct window* not_in;
- {
- Lisp_Object child;
- if (!NILP (window->buffer))
- {
- /* a leaf window */
- return window->buffer == buffer && window != not_in;
- }
- else
- {
- /* a non leaf window, visit either the hchild or the vchild */
- for (child = !NILP (window->vchild) ? window->vchild : window->hchild;
- !NILP (child);
- child = XWINDOW (child)->next)
- {
- if (find_buffer_in_different_window (XWINDOW (child), buffer,
- not_in))
- return 1;
- }
- return 0;
- }
- }
-
- /* returns 1 if the buffer is only visible in window on screen s */
- static int
- buffer_only_visible_in_this_window_p (buffer, s, window)
- Lisp_Object buffer;
- struct screen* s;
- struct window* window;
- {
- return !find_buffer_in_different_window (XWINDOW (s->root_window), buffer,
- window);
- }
-
- /* This is called just before a buffer which is visible becomes invisible,
- either because some other buffer is about to be made visible in its window,
- or because that window is being deleted.
-
- If this buffer's psheets are visible, hide them.
- */
- void energize_buffer_hidden_hook (window)
- struct window *window;
- {
- struct screen *s;
- s = XSCREEN (window->screen);
-
- if (! SCREEN_IS_X (s)) return;
-
- /* hides the p_sheet if we are changing the buffer of the
- * selected window of the screen and the p_sheet where displayed */
- if (EQ (window->buffer, desired_psheet_buffer (s))
- && buffer_only_visible_in_this_window_p (window->buffer, s, window))
- make_psheets_desired (s, Qnil);
- }
-
-
- /* This is called just before the selected window is no longer the selected
- window because some other window is being selected. The given window is
- not being deleted, it is merely no longer the selected one.
-
- This doesn't do anything right now.
- */
- void energize_window_deselected_hook (window)
- struct window *window;
- {
- }
-
-
- /* This is called just after a window has been selected.
-
- Show the menubar associated with this buffer; leave the psheets as
- they are.
- */
- void energize_window_selected_hook (window)
- struct window *window;
- {
- struct screen* screen = XSCREEN (window->screen);
- Lisp_Object buffer = window->buffer;
-
- if (SCREEN_IS_X (screen) && !MINI_WINDOW_P (window))
- energize_show_menubar_of_buffer (window->screen, buffer, Qnil);
- }
-
-
-
- int current_debuggerpanel_exposed_p;
- int desired_debuggerpanel_exposed_p;
- int debuggerpanel_sheet;
-
- void
- energize_show_menubar_of_buffer (screen, buffer, psheets_too)
- Lisp_Object screen, buffer, psheets_too;
- {
- struct screen* s;
- struct x_display *x;
-
- if (NILP (screen))
- s = selected_screen;
- else {
- CHECK_SCREEN (screen, 0);
- s = XSCREEN (screen);
- }
-
- if (! SCREEN_IS_X (s)) error ("not an X screen");
- x = s->display.x;
-
- if (! NILP (psheets_too))
- {
- Lisp_Object buffer;
- XSET (buffer, Lisp_Buffer, current_buffer);
- make_psheets_desired (s, buffer);
- }
- }
-
-
- #endif /* ENERGIZE */
-
- /* The one and only application context associated with the connection
- ** to the one and only X display that Emacs uses. */
- XtAppContext Xt_app_con;
-
- /* The one and only application shell. Emacs screens are popup shells of this
- ** application. */
- Widget Xt_app_shell;
-
- extern Lisp_Object Vscreen_title_format, Vscreen_icon_title_format;
- extern Lisp_Object Vscreen_list;
-
- static void
- maybe_set_screen_title_format (shell)
- Widget shell;
- {
- BLOCK_INPUT;
-
- if (NILP (Vscreen_list) ||
- (NILP (Fcdr (Vscreen_list)) &&
- XSCREEN (Fcar (Vscreen_list))->display.nothing == 1))
- /* Only do this if this is the first X screen we're creating.
- If the *title resource (or -title option) was specified, then
- set screen-title-format to its value.
- */
- {
- /* No doubt there's a less stupid way to do this. */
- char *results [2];
- XtResource resources [2];
- results [0] = results [1] = 0;
- resources [0].resource_name = XtNtitle;
- resources [0].resource_class = XtCTitle;
- resources [0].resource_type = XtRString;
- resources [0].resource_size = sizeof (String);
- resources [0].resource_offset = 0;
- resources [0].default_type = XtRString;
- resources [0].default_addr = 0;
- resources [1].resource_name = XtNiconName;
- resources [1].resource_class = XtCIconName;
- resources [1].resource_type = XtRString;
- resources [1].resource_size = sizeof (String);
- resources [1].resource_offset = sizeof (char *);
- resources [1].default_type = XtRString;
- resources [1].default_addr = 0;
- XtGetSubresources (XtParent(shell), (XtPointer)results, shell->core.name,
- shell->core.widget_class->core_class.class_name,
- resources, XtNumber (resources), 0, 0);
- if (results[0])
- Vscreen_title_format = build_string (results[0]);
- if (results[1])
- Vscreen_icon_title_format = build_string (results[1]);
- }
- UNBLOCK_INPUT;
- }
-
-
- /* Creates the widgets for a screen. Parms is an alist of
- resources/values to use for the screen. (ignored right now).
- reslisp_window_id is a Lisp description of an X window or Xt widget to
- resParse. (ignored right now). */
-
- extern void maybe_store_wm_command (struct screen *);
-
- static void hack_wm_protocols (Widget);
-
- static void
- x_create_widgets (s, parms, lisp_window_id)
- struct screen *s;
- Lisp_Object parms;
- Lisp_Object lisp_window_id;
- {
- Widget shell_widget;
- Widget pane_widget;
- Widget screen_widget;
- char* name;
- Arg al [25];
- int ac = 0;
-
- BLOCK_INPUT;
-
- if (STRINGP (s->name))
- name = (char*)XSTRING (s->name)->data;
- else
- name = "emacs";
-
- ac = 0;
- XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
- XtSetArg (al[ac], XtNinput, 1); ac++;
- shell_widget = XtCreatePopupShell (name, emacsShellWidgetClass, Xt_app_shell,
- al, ac);
- maybe_set_screen_title_format (shell_widget);
-
- ac = 0;
- XtSetArg (al[ac], XtNborderWidth, 0); ac++;
- pane_widget = XtCreateWidget ("pane", panedWidgetClass, shell_widget, al,
- ac);
-
- /* mappedWhenManaged to false tells to the paned window to not map/unmap
- * the emacs screen when changing menubar. This reduces flickering a lot.
- */
- ac = 0;
- XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
- XtSetArg (al[ac], XtNshowGrip, 0); ac++;
- XtSetArg (al[ac], XtNallowResize, 1); ac++;
- XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
- XtSetArg (al[ac], XtNemacsScreen, s); ac++;
- screen_widget = XtCreateWidget ("screen", emacsScreenWidgetClass,
- pane_widget, al, ac);
-
- s->display.x->widget = shell_widget;
- s->display.x->column_widget = pane_widget;
- s->display.x->edit_widget = screen_widget;
-
- if (NILP (Vx_screen_defaults))
- x_set_screen_values (s, parms);
- else
- x_set_screen_values (s, nconc2 (Fcopy_sequence (parms),
- Vx_screen_defaults));
-
- XtManageChild (screen_widget);
- XtManageChild (pane_widget);
- XtRealizeWidget (shell_widget);
- maybe_store_wm_command (s);
- hack_wm_protocols (shell_widget);
-
- #ifdef HACK_EDITRES
- XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
- #endif
-
- /* Do a stupid property change to force the server to generate a
- propertyNotify event so that the event_stream server timestamp will
- be initialized to something relevant to the time we created the window.
- */
- XChangeProperty (XtDisplay (screen_widget), XtWindow (screen_widget),
- Xatom_WM_PROTOCOLS, XA_ATOM, 32, PropModeAppend,
- (unsigned char*) NULL, 0);
-
- XtMapWidget (screen_widget);
-
- XtPopup (shell_widget, XtGrabNone);
- UNBLOCK_INPUT;
-
- #if 0
- * Forget this for now
- * if (NILP(lisp_window_id))
- * window_id = 0;
- * else
- * { CHECK_STRING(lisp_window_id, 0);
- * string = (char *) (XSTRING(lisp_window_id)->data);
- * if (string[0] == '0' && (string[1] == 'x' || string[1] == 'X'))
- * sscanf(string+2, "%xu", &window_id);
- *#ifdef ENERGIZE
- * else if (string[0] == 'w'){
- * sscanf (string+1, "%x", &parent_widget);
- * if (parent_widget)
- * window_id = XtWindow (parent_widget);
- * }
- *#endif
- * else
- * sscanf (string, "%lu", &window_id);
- * }
- #endif
- }
-
-
- /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS
- and WM_DELETE_WINDOW, then add them. (They may already be present
- because of the toolkit (Motif adds them, for example, but Xt doesn't.)
- */
- static void hack_wm_protocols (Widget widget)
- {
- Display *dpy = XtDisplay (widget);
- Window w = XtWindow (widget);
- int need_delete = 1;
- int need_focus = 1;
- BLOCK_INPUT;
- {
- Atom type, *atoms = 0;
- int format = 0;
- unsigned long nitems = 0;
- unsigned long bytes_after;
-
- if (Success == XGetWindowProperty (dpy, w, Xatom_WM_PROTOCOLS,
- 0, 100, False, XA_ATOM,
- &type, &format, &nitems, &bytes_after,
- (unsigned char **) &atoms)
- && format == 32 && type == XA_ATOM)
- while (nitems > 0)
- {
- nitems--;
- if (atoms [nitems] == Xatom_WM_DELETE_WINDOW) need_delete = 0;
- else if (atoms [nitems] == Xatom_WM_TAKE_FOCUS) need_focus = 0;
- }
- if (atoms) XFree ((char *) atoms);
- }
- {
- Atom props [10];
- int count = 0;
- if (need_delete) props [count++] = Xatom_WM_DELETE_WINDOW;
- if (need_focus) props [count++] = Xatom_WM_TAKE_FOCUS;
- if (count)
- XChangeProperty (dpy, w, Xatom_WM_PROTOCOLS, XA_ATOM, 32, PropModeAppend,
- (unsigned char *) props, count);
- }
- UNBLOCK_INPUT;
- }
-
-
- static void
- allocate_x_display_struct (s)
- struct screen* s;
- {
- s->output_method = output_x_window;
- s->display.x = (struct x_display *)xmalloc (sizeof (struct x_display));
-
- /* zero out all slots. */
- memset (s->display.x, 0, sizeof (struct x_display));
- }
-
- Lisp_Object Vdefault_screen_name;
-
- extern void x_format_screen_title (struct screen *);
-
- extern void run_hooks_1_arg (Lisp_Object, Lisp_Object);
-
- DEFUN ("x-create-screen", Fx_create_screen, Sx_create_screen,
- 1, 2, 0,
- "Make a new X window, which is considered a \"screen\" in Emacs terms.\n\
- Return an Emacs screen object representing the X window.\n\
- ALIST is an alist of screen parameters.\n\
- The value of `x-screen-defaults' is an additional alist\n\
- of default parameters which apply when not overridden by ALIST.\n\
- Optional second argument is the numerical ID of the X window to use for this\n\
- screen (in order to run Emacs on a window created by some other program).\n\
- Since this ID number is an unsigned long, you must pass it as a string.\n\
- It may be a string of decimal numbers, or a string of hex numbers beginning\n\
- with \"0x\".")
- (parms, lisp_window_id)
- Lisp_Object parms, lisp_window_id;
- {
- struct screen *s;
- Lisp_Object screen = Qnil;
- Lisp_Object name = Qnil;
- struct gcpro gcpro1;
- struct gcpro gcpro2;
- GCPRO2 (screen, name);
-
- if (x_current_display == 0)
- error ("X windows are not in use or not initialized");
-
- s = make_screen (1);
-
- allocate_x_display_struct (s);
- name = Fassq (intern ("name"), parms);
- if (!NILP (name))
- {
- name = Fcdr (name);
- CHECK_STRING (name, 0);
- }
- else if (STRINGP (Vdefault_screen_name))
- name = Vdefault_screen_name;
- else
- name = build_string ("emacs");
-
- s->name = name;
-
- XSET (screen, Lisp_Screen, s);
-
- x_create_widgets (s, parms, lisp_window_id);
-
- /* do this after anything that might call Fsignal() before the screen
- * is in a usable state. */
- Vscreen_list = Fcons (screen, Vscreen_list);
-
- /* This runs lisp code, and thus might GC. If the selected screen is still
- the terminal screen (meaning that we're in the middle of creating the
- initial X screen) then select the X screen now, so that GC messages don't
- get written on the terminal screen. This is kind of a hack...
- */
- if (selected_screen == XSCREEN (Vterminal_screen))
- select_screen_internal (s);
- init_screen_faces (s);
- x_format_screen_title (s);
- run_hooks_1_arg (Qcreate_screen_hook, screen);
- UNGCPRO;
- return screen;
- }
-
-
- DEFUN ("x-show-lineinfo-column",
- Fx_show_lineinfo_column, Sx_show_lineinfo_column, 0, 1, 0,
- "Make the current emacs screen have a lineinfo column.")
- (screen)
- Lisp_Object screen;
- {
- struct screen* s;
- struct x_display *x;
- #ifdef LINE_INFO_WIDGET
- int just_created;
- #endif
-
- if (NILP (screen))
- s = selected_screen;
- else {
- CHECK_SCREEN (screen, 0);
- s = XSCREEN (screen);
- }
- if (! SCREEN_IS_X (s)) error ("not an X screen");
-
- x = s->display.x;
-
- #ifdef LINE_INFO_WIDGET
-
- BLOCK_INPUT;
- XawPanedSetRefigureMode (x->row_widget, 0);
-
- /* the order in which children are managed is the top to
- bottom order in which they are displayed in the paned window. */
-
- XtUnmanageChild (x->edit_widget);
- if (x->lineinfo_widget)
- XtUnmanageChild (x->lineinfo_widget);
- else {
- x->lineinfo_widget =
- XtVaCreateWidget ("lineinfo_widget", lineInfoWidgetClass,
- x->row_widget,
- XtNwidth, 50,
- XtNheight, s->display.x->pixel_height,
- XtNmappedWhenManaged, 0,
- XtNshowGrip, 0,
- 0);
- ((LineInfoWidget) x->lineinfo_widget)->lineInfo.screen = s;
- just_created = 1;
- }
- XtManageChild (x->lineinfo_widget);
- XtManageChild (x->edit_widget);
-
- if (just_created)
- XStoreName (x_current_display, XtWindow(x->lineinfo_widget), "lineinfo_widget");
-
- XawPanedSetRefigureMode (x->row_widget, 1);
-
- UNBLOCK_INPUT;
-
- #else
- #ifdef LINE_INFO_COLUMN
-
- s->display.x->line_info_column_width =
- s->display.x->default_line_info_column_width;
-
- #else
- error("support for the lineinfo column was not compiled into emacs.");
-
- #endif
- #endif
- return Qnil;
- }
-
-
- DEFUN ("x-hide-lineinfo-column",
- Fx_hide_lineinfo_column, Sx_hide_lineinfo_column, 0, 1, 0,
- "Make the given emacs screen not have a lineinfo column.")
- (screen)
- Lisp_Object screen;
- {
- struct screen *s;
-
- if (NILP (screen))
- s = selected_screen;
- else {
- CHECK_SCREEN (screen, 0);
- s = XSCREEN (screen);
- }
- if (! SCREEN_IS_X (s)) error ("not an X screen");
-
- #ifdef LINE_INFO_WIDGET
- if (! s->display.x->lineinfo_widget) return Qnil;
- XtUnmanageChild (s->display.x->lineinfo_widget);
-
- #else
- #ifdef LINE_INFO_COLUMN
- s->display.x->line_info_column_width = 0;
-
- #else
- error("support for the lineinfo column was not compiled into emacs.");
- #endif
- #endif
- return Qnil;
- }
-
-
- #define GET_X_SCREEN(s, screen) { \
- if (NILP (screen)) \
- s = selected_screen; \
- else \
- { \
- CHECK_SCREEN (screen, 0); \
- s = XSCREEN (screen); \
- } \
- if (!SCREEN_IS_X (s)) \
- error ("not an X display"); }
-
-
- DEFUN ("x-display-visual-class", Fx_display_visual_class,
- Sx_display_visual_class, 0, 1, 0,
- "Returns the visual class of the display `screen' is on.\n\
- The returned value will be one of the symbols StaticGray, GrayScale,\n\
- StaticColor, PseudoColor, TrueColor, or DirectColor.")
- (screen)
- Lisp_Object screen;
- {
- struct screen *s;
- Display *dpy;
- GET_X_SCREEN (s, screen);
- dpy = XtDisplay (s->display.x->widget);
- switch (DefaultVisual (dpy, DefaultScreen (dpy))->class)
- {
- case StaticGray: return (intern ("StaticGray"));
- case GrayScale: return (intern ("GrayScale"));
- case StaticColor: return (intern ("StaticColor"));
- case PseudoColor: return (intern ("PseudoColor"));
- case TrueColor: return (intern ("TrueColor"));
- case DirectColor: return (intern ("DirectColor"));
- default:
- error ("display has an unknown visual class");
- }
- }
-
- DEFUN ("x-color-display-p", Fx_color_display_p, Sx_color_display_p, 0, 1, 0,
- "Returns t if the X display of the given screen supports color.")
- (screen)
- Lisp_Object screen;
- {
- struct screen *s;
- Display *dpy;
- GET_X_SCREEN (s, screen);
- dpy = XtDisplay (s->display.x->widget);
- if (DisplayCells (dpy, DefaultScreen (dpy)) <= 2)
- return Qnil;
- switch (DefaultVisual (dpy, DefaultScreen (dpy))->class)
- {
- case StaticColor:
- case PseudoColor:
- case TrueColor:
- case DirectColor:
- return Qt;
- default:
- return Qnil;
- }
- }
-
- DEFUN ("x-pixel-width", Fx_pixel_width, Sx_pixel_width, 0, 1, 0,
- "Returns the width in pixels of the given screen.")
- (screen)
- Lisp_Object screen;
- {
- struct screen *s;
- GET_X_SCREEN (s, screen);
- return make_number (PIXEL_WIDTH (s));
- }
-
- DEFUN ("x-pixel-height", Fx_pixel_height, Sx_pixel_height, 0, 1, 0,
- "Returns the height in pixels of the given screen.")
- (screen)
- Lisp_Object screen;
- {
- struct screen *s;
- GET_X_SCREEN (s, screen);
- return make_number (PIXEL_HEIGHT (s));
- }
-
- DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
- 0, 1, 0,
- "Returns the width in pixels of the display `screen' is on.")
- (screen)
- {
- struct screen *s;
- Display *dpy;
- GET_X_SCREEN (s, screen);
- dpy = XtDisplay (s->display.x->widget);
- return make_number (DisplayWidth (dpy, DefaultScreen (dpy)));
- }
-
- DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
- Sx_display_pixel_height,
- 0, 1, 0,
- "Returns the height in pixels of the display `screen' is on.")
- (screen)
- {
- struct screen *s;
- Display *dpy;
- GET_X_SCREEN (s, screen);
- dpy = XtDisplay (s->display.x->widget);
- return make_number (DisplayHeight (dpy, DefaultScreen (dpy)));
- }
-
- DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
- 0, 1, 0,
- "Returns the number of bitplanes of the display `screen' is on.")
- (screen)
- {
- struct screen *s;
- Display *dpy;
- GET_X_SCREEN (s, screen);
- dpy = XtDisplay (s->display.x->widget);
- return make_number (DisplayPlanes (dpy, DefaultScreen (dpy)));
- }
-
- DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
- 0, 1, 0,
- "Returns the number of color cells of the display `screen' is on.")
- (screen)
- {
- struct screen *s;
- Display *dpy;
- GET_X_SCREEN (s, screen);
- dpy = XtDisplay (s->display.x->widget);
- return make_number (DisplayCells (dpy, DefaultScreen (dpy)));
- }
-
- DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
- "Returns the vendor ID string of the X server `screen' is on.")
- (screen)
- {
- struct screen *s;
- Display *dpy;
- char *vendor;
- GET_X_SCREEN (s, screen);
- dpy = XtDisplay (s->display.x->widget);
- vendor = ServerVendor (dpy);
- if (! vendor) vendor = "";
- return build_string (vendor);
- }
-
- DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
- "Returns the version numbers of the X server `screen' is on.\n\
- The returned value is a list of three integers: the major and minor\n\
- version numbers of the X Protocol in use, and the vendor-specific release\n\
- number. See also `x-server-vendor'.")
- (screen)
- {
- struct screen *s;
- Display *dpy;
- GET_X_SCREEN (s, screen);
- dpy = XtDisplay (s->display.x->widget);
- return list3 (make_number (ProtocolVersion (dpy)),
- make_number (ProtocolRevision (dpy)),
- make_number (VendorRelease (dpy)));
- }
-
-
- DEFUN ("x-set-screen-icon-pixmap", Fx_set_screen_icon_pixmap,
- Sx_set_screen_icon_pixmap, 2, 3, 0,
- "Set the icon-pixmap of the given screen.\n\
- This should be the name of a bitmap file, or a bitmap description list\n\
- of the form (width height \"bitmap-data\").\n\
- If the optional third argument is specified, it is the bitmap to use for\n\
- the icon-pixmap-mask (not all window managers obey this.) If the bitmap\n\
- is an XPM file which also contains a mask, the mask argument, if provided,\n\
- will override the mask in the file.\n\
- WARNING: when you call this function, the pixmap of the previous icon\n\
- of this screen (if any) is currently not freed (this is a bug).")
- (screen, pixmap, mask)
- Lisp_Object screen, pixmap, mask;
- {
- struct screen *s;
- Arg av [10];
- int ac = 0;
- unsigned int w, h, d;
- Pixmap p, m;
- if (NILP (screen))
- s = selected_screen;
- else
- {
- CHECK_SCREEN (screen, 0);
- s = XSCREEN (screen);
- }
-
- if (NILP (mask))
- m = 0;
- else
- {
- m = (Pixmap) load_pixmap (s, mask, &w, &h, &d, 0);
- if (d > 1)
- {
- BLOCK_INPUT;
- XFreePixmap (XtDisplay (s->display.x->widget), m);
- UNBLOCK_INPUT;
- m = 0;
- Fsignal (Qerror,
- list3 (build_string ("mask pixmap must be 1 plane deep"),
- mask, make_number (d)));
- }
- }
-
- if (NILP (pixmap))
- p = 0;
- else
- p = (Pixmap) load_pixmap (s, pixmap, &w, &h, &d, (m ? 0 : &m));
-
- XtSetArg (av [ac], XtNiconPixmap, p); ac++;
- XtSetArg (av [ac], XtNiconMask, m); ac++;
- XtSetValues (s->display.x->widget, av, ac);
- return pixmap;
- }
-
-
- static Cursor grabbed_cursor;
-
- DEFUN ("x-grab-pointer", Fx_grab_pointer, Sx_grab_pointer, 0, 2, 0,
- "Grab the pointer and restrict it to its current window. If optional\n\
- SHAPE is non-nil, change the pointer shape to that. If second optional\n\
- argument MOUSE-ONLY is non-nil, ignore keyboard events during the grab.")
- (shape, ignore_keyboard)
- Lisp_Object shape, ignore_keyboard;
- {
- Window w;
- int pointer_mode, result;
-
- BLOCK_INPUT;
- if (! NILP (ignore_keyboard))
- pointer_mode = GrabModeSync;
- else
- pointer_mode = GrabModeAsync;
-
- if (! NILP (shape))
- {
- CHECK_FIXNUM (shape, 0);
- grabbed_cursor = XCreateFontCursor (x_current_display, XINT (shape));
- }
-
- w = XtWindow (XSCREEN (XWINDOW (selected_window)->screen)->display.x->edit_widget);
-
- result = XGrabPointer (x_current_display, w,
- False,
- ButtonMotionMask | ButtonPressMask
- | ButtonReleaseMask | PointerMotionHintMask,
- GrabModeAsync, /* Keep pointer events flowing */
- pointer_mode, /* Stall keyboard events */
- w, /* Stay in this window */
- grabbed_cursor,
- CurrentTime);
- UNBLOCK_INPUT;
- if (result == GrabSuccess)
- {
- return Qt;
- }
-
- BLOCK_INPUT;
- XFreeCursor (x_current_display, grabbed_cursor);
- UNBLOCK_INPUT;
- return Qnil;
- }
-
- DEFUN ("x-ungrab-pointer", Fx_ungrab_pointer, Sx_ungrab_pointer, 0, 0, 0,
- "Release the pointer.")
- ()
- {
- BLOCK_INPUT;
- XUngrabPointer (x_current_display, CurrentTime);
-
- if ((int) grabbed_cursor)
- {
- XFreeCursor (x_current_display, grabbed_cursor);
- grabbed_cursor = (Cursor) 0;
- }
-
- UNBLOCK_INPUT;
- return Qnil;
- }
-
-
- /* handlers for the eval-events pushed on the queue by event-Xt.c */
-
- Lisp_Object Qx_EnterNotify_internal, Qx_LeaveNotify_internal;
- Lisp_Object Qx_FocusIn_internal, Qx_FocusOut_internal;
- Lisp_Object Qx_VisibilityNotify_internal, Qx_non_VisibilityNotify_internal;
- Lisp_Object Qx_MapNotify_internal, Qx_UnmapNotify_internal;
-
- DEFUN ("x-EnterNotify-internal", Fx_EnterNotify_internal,
- Sx_EnterNotify_internal, 1, 1, 0, "hands off")
- (screen)
- Lisp_Object screen;
- {
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
- /* XSCREEN (screen)->display.x->mouse_p = 1; */
- run_hooks_1_arg (Qmouse_enter_screen_hook, screen);
- return Qnil;
- }
-
- DEFUN ("x-LeaveNotify-internal", Fx_LeaveNotify_internal,
- Sx_LeaveNotify_internal, 1, 1, 0, "hands off")
- (screen)
- Lisp_Object screen;
- {
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
- /* XSCREEN (screen)->display.x->mouse_p = 0; */
- run_hooks_1_arg (Qmouse_leave_screen_hook, screen);
- return Qnil;
- }
-
- /* This is true if any widget in any emacs screen has the X keyboard focus
- Flase otherwise. */
- int any_screen_has_focus_p;
-
- /* The select-screen-hook and deselect-screen-hook are run from the
- select_screen_internal() function; however, we run them from the FocusIn
- and FocusOut handlers as well, because under X, the "selectedness" of a
- screen has slightly funny semantics; according to emacs, a screen is
- not "deselected" unless some other screen is selected. This is so that
- there is always some current window and buffer, and so on. However, it's
- useful to run the deselect-screen-hook when emacs loses the X keyboard
- focus (that is, no emacs screen is the X selected window). Likewise,
- it's useful to run the select-screen-hook when some emacs window regains
- the focus, even if that window is already the selected screen from emacs's
- point of view.
-
- If we don't do this, then the select-screen-hook (meaning auto-raise)
- isn't run if (in a point-to-type world) the mouse moves into the same
- emacs window that it originally left. Clearly this isn't what someone
- who would want auto-raise would want.
-
- This means that sometimes the deselect-screen-hook will be called twice.
- This kind of stinks.
-
- If there are two screens, s1, and s2, where s1 is selected:
-
- mouse moves into s1: FocusIn s1 runs select-screen-hook, because s1
- is the selected screen (FocusIn only does this
- for the selected screen.)
-
- select_screen_internal doesn't run deselect-hook
- since s1 is already selected_screen, although it
- didn't have the X focus.
-
- net result: select s1 run.
-
- mouse moves into s2: FocusOut s1 runs deselect-screen-hook, but the
- selected_screen is still s1.
-
- FocusIn s2 does not run select-screen-hook,
- because s2 is not the selected screen.
-
- select_screen_internal runs deselect-hook s1,
- then selects s2, then runs select-hook s2.
-
- net result: deselect s1, deselect s1, select s2.
- One of those deselects is superfluous.
-
- mouse moves elsewhere: FocusOut s2 runs deselect-screen-hook, but the
- selected_screen is still s2.
-
- net result: deselect s2.
-
- mouse moves into s1: FocusIn s1 does not run select-screen-hook.
-
- select_screen_internal runs deselect-hook s2;
- changes selected_screen, runs select-hook s1.
-
- net result: deselect s2, select s1.
- That deselect is superfluous.
-
- Things get even nastier if there is a big delay between when select-screen
- is called and when the Focus events are handled (as when lisp code calls
- select-screen and then doesn't return to top level for a while.)
- */
-
- extern Lisp_Object Qselect_screen_hook, Qdeselect_screen_hook;
-
- extern void x_screen_redraw_cursor (struct screen *);
-
- DEFUN ("x-FocusIn-internal", Fx_FocusIn_internal,
- Sx_FocusIn_internal, 1, 1, 0, "hands off")
- (screen)
- Lisp_Object screen;
- {
- int getting_focus = !any_screen_has_focus_p;
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
- any_screen_has_focus_p = 1;
- XSCREEN (screen)->display.x->focus_p = 1;
- if (XSCREEN (screen) == selected_screen)
- {
- x_screen_redraw_cursor (XSCREEN (screen));
- /* see comment above */
- if (getting_focus)
- if (!NILP (Vrun_hooks))
- call1 (Vrun_hooks, Qselect_screen_hook);
- }
- else
- select_screen_internal (XSCREEN (screen));
- return Qnil;
- }
-
- DEFUN ("x-FocusOut-internal", Fx_FocusOut_internal,
- Sx_FocusOut_internal, 1, 1, 0, "hands off")
- (screen)
- Lisp_Object screen;
- {
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
- any_screen_has_focus_p = 0;
- XSCREEN (screen)->display.x->focus_p = 0;
- if (XSCREEN (screen) == selected_screen)
- {
- x_screen_redraw_cursor (XSCREEN (screen));
- /* see comment above */
- if (!NILP (Vrun_hooks))
- call1 (Vrun_hooks, Qdeselect_screen_hook);
- }
- return Qnil;
- }
-
- DEFUN ("x-VisibilityNotify-internal", Fx_VisibilityNotify_internal,
- Sx_VisibilityNotify_internal, 1, 1, 0, "hands off")
- (screen)
- Lisp_Object screen;
- {
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
- XSCREEN (screen)->display.x->totally_visible_p = 1;
- return Qnil;
- }
-
- DEFUN ("x-non-VisibilityNotify-internal", Fx_non_VisibilityNotify_internal,
- Sx_non_VisibilityNotify_internal, 1, 1, 0, "hands off")
- (screen)
- Lisp_Object screen;
- {
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
- XSCREEN (screen)->display.x->totally_visible_p = 0;
- return Qnil;
- }
-
- DEFUN ("x-MapNotify-internal", Fx_MapNotify_internal,
- Sx_MapNotify_internal, 1, 1, 0, "hands off")
- (screen)
- Lisp_Object screen;
- {
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
- XSCREEN (screen)->display.x->totally_visible_p = 1;
- if (! XSCREEN (screen)->visible)
- {
- XSCREEN (screen)->visible = 1;
- SET_SCREEN_GARBAGED (XSCREEN (screen));
- run_hooks_1_arg (Qmap_screen_hook, screen);
- }
- return Qnil;
- }
-
-
- DEFUN ("x-UnmapNotify-internal", Fx_UnmapNotify_internal,
- Sx_UnmapNotify_internal, 1, 1, 0, "hands off")
- (screen)
- Lisp_Object screen;
- {
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen))) return Qnil; /* may be deleted */
- XSCREEN (screen)->display.x->totally_visible_p = 0;
- if (XSCREEN (screen)->visible)
- {
- XSCREEN (screen)->visible = 0;
- run_hooks_1_arg (Qunmap_screen_hook, screen);
- }
- return Qnil;
- }
-
-
- #if 0 /* #### This stuff is obsolete; with the new event model,
- regular keyboard macros work just as well as this.
- */
- DEFUN ("x-rebind-key", Fx_rebind_key, Sx_rebind_key, 3, 3, 0,
- "Rebind X keysym KEYSYM, with MODIFIERS, to generate NEWSTRING.\n\
- KEYSYM is a string which conforms to the X keysym definitions found\n\
- in X11/keysymdef.h, sans the initial XK_. MODIFIERS is nil or a\n\
- list of strings specifying modifier keys such as Control_L, which must\n\
- also be depressed for NEWSTRING to appear.")
- (x_keysym, modifiers, newstring)
- register Lisp_Object x_keysym;
- register Lisp_Object modifiers;
- register Lisp_Object newstring;
- {
- char *rawstring;
- register KeySym keysym, modifier_list[16];
-
- CHECK_STRING (x_keysym, 1);
- CHECK_STRING (newstring, 3);
-
- BLOCK_INPUT;
- keysym = XStringToKeysym ((char *) XSTRING (x_keysym)->data);
- UNBLOCK_INPUT;
-
- if (keysym == NoSymbol)
- error ("Keysym does not exist");
-
- if (NILP (modifiers))
- {
- BLOCK_INPUT;
- XRebindKeysym (x_current_display, keysym, modifier_list, 0,
- XSTRING (newstring)->data, XSTRING (newstring)->size);
- UNBLOCK_INPUT;
- }
- else
- {
- register Lisp_Object rest, mod;
- register int i = 0;
-
- for (rest = modifiers; !NILP (rest); rest = Fcdr (rest))
- {
- if (i == 16)
- error ("Can't have more than 16 modifiers");
-
- mod = Fcar (rest);
- CHECK_STRING (mod, 3);
- BLOCK_INPUT;
- modifier_list[i] = XStringToKeysym ((char *) XSTRING (mod)->data);
- UNBLOCK_INPUT;
- if (modifier_list[i] == NoSymbol
- || !IsModifierKey (modifier_list[i]))
- error ("Element is not a modifier keysym");
- i++;
- }
-
- BLOCK_INPUT;
- XRebindKeysym (x_current_display, keysym, modifier_list, i,
- XSTRING (newstring)->data, XSTRING (newstring)->size);
- UNBLOCK_INPUT;
- }
-
- return Qnil;
- }
-
- DEFUN ("x-rebind-keys", Fx_rebind_keys, Sx_rebind_keys, 2, 2, 0,
- "Rebind KEYCODE to list of strings STRINGS.\n\
- STRINGS should be a list of 16 elements, one for each shift combination.\n\
- nil as element means don't change.\n\
- See the documentation of `x-rebind-key' for more information.")
- (keycode, strings)
- register Lisp_Object keycode;
- register Lisp_Object strings;
- {
- register Lisp_Object item;
- register unsigned char *rawstring;
- KeySym rawkey, modifier[1];
- int strsize;
- register unsigned i;
-
- CHECK_FIXNUM (keycode, 1);
- CHECK_CONS (strings, 2);
- rawkey = (KeySym) ((unsigned) (XINT (keycode))) & 255;
- for (i = 0; i <= 15; strings = Fcdr (strings), i++)
- {
- item = Fcar (strings);
- if (!NILP (item))
- {
- CHECK_STRING (item, 2);
- strsize = XSTRING (item)->size;
- rawstring = (unsigned char *) xmalloc (strsize);
- bcopy (XSTRING (item)->data, rawstring, strsize);
- modifier[1] = 1 << i;
- BLOCK_INPUT;
- XRebindKeysym (x_current_display, rawkey, modifier, 1,
- rawstring, strsize);
- UNBLOCK_INPUT;
- }
- }
- return Qnil;
- }
- #endif
-
-
- /* This comment supplies the doc string for x-get-resource,
- for make-docfile to see. We cannot put this in the real DEFUN
- due to limits in the Unix cpp.
-
- DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 3, 4, 0,
- "Retrieve an X resource from the resource manager.\n\
- The first arg is the name of the resource to retrieve, such as \"font\".\n\
- The second arg is the class of the resource to retrieve, like \"Font\".\n\
- The third arg should be one of the symbols string, integer, or boolean,\n\
- specifying the type of object that the database is searched for.\n\
- The fourth arg is the screen to search for the resources on, defaulting\n\
- to the selected screen.\n\
- \n\
- The call\n\
- (x-get-resource \"font\" \"Font\" 'string)\n\
- \n\
- is an interface to the C call\n\
- \n\
- XrmGetResource (db, \"emacs.this_screen_name.font\",\n\
- \"Emacs.EmacsScreen.Font\",\n\
- \"String\");\n\
- \n\
- Therefore if you want to retrieve a deeper resource, for example,\n\
- \"Emacs.foo.foreground\", you need to specify the same number of links\n\
- in the class path:\n\
- (x-get-resource \"foo.foreground\" \"Thing.Foreground\" 'string)\n\
- \n\
- which is equivalent to
- \n\
- XrmGetResource (db, \"emacs.screen_name.foo.foreground\",\n\
- \"Emacs.EmacsScreen.Thing.Foreground\",\n\
- \"String\");\n\
-
- \n\
- The returned value of this function is nil if the queried resource is not\n\
- found. If the third arg is `string', a string is returned, and if it is\n\
- `integer', an integer is returned. If the third arg is `boolean', then the\n\
- returned value is the list (t) for true, (nil) for false, and is nil to\n\
- mean ``unspecified.''")
- (name, class, type, screen)
- */
-
-
- DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 3, 4, 0, 0)
- (name, class, type, screen)
- Lisp_Object name, class, type, screen;
- {
- char *name_string, *class_string;
- char *app_name, *app_class, *screen_name, *screen_class, *s;
- Widget widget;
-
- CHECK_STRING (name, 0);
- CHECK_STRING (class, 0);
- CHECK_SYMBOL (type, 0);
- if (NILP (screen))
- screen = Fselected_screen ();
- else
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen)))
- /* error ("not an X screen"); */
- return Qnil;
-
- widget = XSCREEN (screen)->display.x->widget;
- BLOCK_INPUT;
- XtGetApplicationNameAndClass (XtDisplay (widget), &app_name, &app_class);
- UNBLOCK_INPUT;
- screen_name = widget->core.name;
- screen_class = XtClass (widget)->core_class.class_name;
- name_string = (char *) alloca (XSTRING (name)->size + strlen (app_name)
- + strlen (screen_name) + 3);
- class_string = (char *) alloca (XSTRING (class)->size + strlen (app_class)
- + strlen (screen_class) + 3);
- strcpy (name_string, (char *) app_name);
- for (s = name_string; *s; s++) if (*s == '.') *s = '_';
- strcat (name_string, ".");
- s++;
- strcat (name_string, (char *) screen_name);
- for (; *s; s++) if (*s == '.') *s = '_';
- strcat (name_string, ".");
- strcat (name_string, (char *) XSTRING (name)->data);
- strcpy (class_string, app_class);
- strcat (class_string, ".");
- strcat (class_string, screen_class);
- strcat (class_string, ".");
- strcat (class_string, (char *) XSTRING (class)->data);
-
- {
- XrmValue xrm_value;
- XrmName namelist [100];
- XrmClass classlist [100];
- XrmName *namerest = namelist;
- XrmClass *classrest = classlist;
- XrmRepresentation xrm_type;
- XrmRepresentation string_quark;
- int result;
- BLOCK_INPUT;
- XrmStringToNameList (name_string, namelist);
- XrmStringToClassList (class_string, classlist);
- string_quark = XrmStringToQuark ("String");
- UNBLOCK_INPUT;
-
- /* ensure that they have the same length */
- while (namerest [0] && classrest [0])
- namerest++, classrest++;
- if (namerest [0] || classrest [0])
- Fsignal (Qerror,
- Fcons (build_string
- ("class list and name list must be the same length"),
- Fcons (build_string (name_string),
- Fcons (build_string (class_string), Qnil))));
- BLOCK_INPUT;
- result = XrmQGetResource (XtDatabase (XtDisplay (widget)),
- namelist, classlist, &xrm_type, &xrm_value);
- UNBLOCK_INPUT;
-
- if (result != True || xrm_type != string_quark)
- return Qnil;
- s = (char *) xrm_value.addr;
- }
-
- if (EQ (type, intern ("string")))
- return build_string (s);
- else if (EQ (type, intern ("boolean")))
- {
- if (!strcasecmp (s, "off") || !strcasecmp (s, "false") ||
- !strcasecmp (s,"no"))
- return Fcons (Qnil, Qnil);
- else if (!strcasecmp (s, "on") || !strcasecmp (s, "true") ||
- !strcasecmp (s, "yes"))
- return Fcons (Qt, Qnil);
- else
- {
- char str[255];
- sprintf (str, "can't convert %s: %s to a Boolean",
- name_string, s);
- return Fsignal (Qerror, Fcons (build_string (str), Qnil));
- }
- }
- else if (EQ (type, intern ("integer")))
- {
- int i, c;
- if (1 != sscanf (s, "%d%c", &i, &c))
- {
- char str [255];
- sprintf (str, "can't convert %s: %s to an integer",
- name_string, s);
- return Fsignal (Qerror, Fcons (build_string (str), Qnil));
- }
- else
- return make_number (i);
- }
- else
- return
- Fsignal (Qwrong_type_argument,
- Fcons (build_string ("should be string, integer, or boolean"),
- Fcons (type, Qnil)));
- }
-
-
- #ifndef BITMAPDIR
- #define BITMAPDIR "/usr/include/X11/bitmaps"
- #endif
-
- void
- initialize_x_bitmap_file_path ()
- {
- Display *dpy = x_current_display;
- char *type = 0;
- XrmValue value;
- if (XrmGetResource (XtDatabase (dpy),
- "bitmapFilePath", "BitmapFilePath", &type, &value)
- && !strcmp (type, "String"))
- {
- char *s1, *s2;
- char *p = (char *) value.addr;
- s1 = p;
- for (s2 = p; *s2; s2++)
- if (*s2 == ':' && s1 != s2)
- {
- Vx_bitmap_file_path = Fcons (make_string (s1, s2 - s1),
- Vx_bitmap_file_path);
- s1 = s2 + 1;
- }
- if (s1 != s2)
- Vx_bitmap_file_path = Fcons (make_string (s1, s2 - s1),
- Vx_bitmap_file_path);
- }
- Vx_bitmap_file_path = Fnreverse (Fcons (build_string (BITMAPDIR),
- Vx_bitmap_file_path));
- }
-
-
- /* Cursors. Once emacs allocates an X cursor, it never frees it.
- Presumably cursors are very lightweight, and this it ok. If
- this turns out not to be the case, we should only cache the
- last N cursors used (2<n<10?) and XFreeCursor() on the least
- recently used ones.
- */
-
- Lisp_Object Vcursor_alist;
-
- /* XmuCvtStringToCursor is a little bogus, and when it can't convert to
- a real cursor, it will sometimes return a "success" value, after
- triggering a BadPixmap error. It then gives you a cursor that will
- itself generate BadCursor errors. So we install this error handler
- to catch/notice the X error and take that as meaning "couldn't convert."
- */
-
- static int XmuCvtStringToCursor_got_error;
- static int XmuCvtStringToCursor_error_handler (dpy, error)
- Display *dpy;
- XErrorEvent *error;
- {
- XmuCvtStringToCursor_got_error = 1;
- return 0;
- }
-
- DEFUN ("x-valid-color-name-p", Fx_valid_color_name_p, Sx_valid_color_name_p,
- 1, 2, 0,
- "Returns true if COLOR names a color that X knows about.\n\
- Valid color names are listed in the file /usr/lib/X11/rgb.txt, or\n\
- whatever the equivalent is on your system.")
- (color, screen)
- Lisp_Object color, screen;
- {
- int ok;
- XColor c;
- Widget widget;
- if (NILP (screen))
- screen = Fselected_screen ();
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen)))
- return Qnil;
- CHECK_STRING (color, 0);
- widget = XSCREEN (screen)->display.x->widget;
- BLOCK_INPUT;
- ok = XParseColor (XtDisplay (widget),
- DefaultColormapOfScreen (XtScreen (widget)),
- (char *) XSTRING (color)->data, &c);
- UNBLOCK_INPUT;
- return ok ? Qt : Qnil;
- }
-
- DEFUN ("x-valid-keysym-name-p", Fx_valid_keysym_name_p, Sx_valid_keysym_name_p,
- 1, 1, 0,
- "Returns true if KEYSYM names a keysym that the X library knows about.\n\
- Valid keysyms are listed in the files /usr/include/X11/keysymdef.h and in\n\
- /usr/lib/X11/XKeysymDB, or whatever the equivalents are on your system.")
- (keysym)
- Lisp_Object keysym;
- {
- CHECK_STRING (keysym, 0);
- if (XStringToKeysym ((char *) XSTRING (keysym)->data))
- return Qt;
- return Qnil;
- }
-
-
- static Cursor
- x_get_cursor (s, name, fg, bg, noerror)
- struct screen *s;
- Lisp_Object name, fg, bg;
- int noerror;
- {
- Cursor cursor;
- Lisp_Object cons, ofg, obg;
- if (noerror)
- {
- if ((!STRINGP (name)) ||
- (!NILP (fg) && !STRINGP (fg)) ||
- (!NILP (bg) && !STRINGP (bg)))
- return 0;
- }
- else
- {
- CHECK_STRING (name, 0);
- if (!NILP (fg)) CHECK_STRING (fg, 0);
- if (!NILP (bg)) CHECK_STRING (bg, 0);
- }
- cons = assoc_no_quit (name, Vcursor_alist);
- if (NILP (cons))
- {
- int (*old_handler) ();
- XrmValue arg, from, to;
- Cardinal nargs = 1;
- Screen *screen = XtScreen (s->display.x->widget);
- arg.addr = (XtPointer) &screen;
- arg.size = sizeof (Screen *);
- from.addr = (XtPointer) XSTRING (name)->data;
- from.size = (unsigned int) XSTRING (name)->size;
- to.addr = 0;
- to.size = 0;
- BLOCK_INPUT;
- XSync (XtDisplay (s->display.x->widget), 0);
- XmuCvtStringToCursor_got_error = 0;
- old_handler = XSetErrorHandler (XmuCvtStringToCursor_error_handler);
- XmuCvtStringToCursor (&arg, &nargs, &from, &to);
- XSync (XtDisplay (s->display.x->widget), 0);
- XSetErrorHandler (old_handler);
- UNBLOCK_INPUT;
- if (XmuCvtStringToCursor_got_error) cursor = 0;
- else if (to.addr) cursor = *((Cursor *) to.addr);
- else cursor = 0;
- if (! cursor && noerror)
- return 0;
- else if (! cursor)
- while (1)
- Fsignal (Qerror, Fcons (build_string ("unknown cursor"),
- Fcons (name, Qnil)));
- ofg = obg = Qnil;
- cons = Fcons (name, Fcons (word_to_lisp ((int) cursor),
- Fcons (ofg, Fcons (obg, Qnil))));
- Vcursor_alist = Fcons (cons, Vcursor_alist);
- }
- else
- {
- cursor = lisp_to_word (XCONS (XCONS (cons)->cdr)->car);
- ofg = XCONS (XCONS (XCONS (cons)->cdr)->cdr)->car;
- obg = XCONS (XCONS (XCONS (XCONS (cons)->cdr)->cdr)->cdr)->car;
- }
- if (!NILP (fg) && !NILP (bg) &&
- (NILP (Fequal (fg, ofg)) || NILP (Fequal (bg, obg))))
- {
- XColor fgc, bgc;
- int result;
- Widget widget = s->display.x->widget;
- Display *dpy = XtDisplay (widget);
- Colormap cmap = DefaultColormapOfScreen (XtScreen (widget));
-
- BLOCK_INPUT;
- result = XParseColor (dpy, cmap, (char *) XSTRING (fg)->data, &fgc);
- UNBLOCK_INPUT;
- if (! result && noerror)
- return 0;
- else if (! result)
- while (1)
- Fsignal (Qerror, Fcons (build_string ("unrecognised color"),
- Fcons (fg, Qnil)));
- BLOCK_INPUT;
- result = XParseColor (dpy, cmap, (char *) XSTRING (bg)->data, &bgc);
- UNBLOCK_INPUT;
- if (! result && noerror)
- return 0;
- else if (! result)
- while (1)
- Fsignal (Qerror, Fcons (build_string ("unrecognised color"),
- Fcons (bg, Qnil)));
- XCONS (XCONS (XCONS (cons)->cdr)->cdr)->car = fg;
- XCONS (XCONS (XCONS (XCONS (cons)->cdr)->cdr)->cdr)->car = bg;
- BLOCK_INPUT;
- XRecolorCursor (dpy, cursor, &fgc, &bgc);
- UNBLOCK_INPUT;
- }
- return cursor;
- }
-
-
- DEFUN ("x-set-screen-pointer", Fx_set_screen_pointer, Sx_set_screen_pointer,
- 2, 4, 0,
- "Set the mouse cursor of SCREEN to the cursor named CURSOR-NAME,\n\
- with colors FOREGROUND and BACKGROUND. The string may be any of the\n\
- standard cursor names from appendix B of the Xlib manual (also known as\n\
- the file <X11/cursorfont.h>) minus the XC_ prefix, or it may be a font\n\
- name and glyph index of the form \"FONT fontname index [[font] index]\",\n\
- or it may be a bitmap file acceptable to XmuLocateBitmapFile().\n\
- If it is a bitmap file, and if a bitmap file whose name is the name of\n\
- the cursor with \"msk\" exists, then it is used as the mask. For example,\n\
- a pair of files may be named \"cursor.xbm\" and \"cursor.xbmmsk\".")
- (screen, cursor_name, fg, bg)
- Lisp_Object screen, cursor_name, fg, bg;
- {
- Cursor cursor;
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen)))
- return Qnil;
- cursor = x_get_cursor (XSCREEN (screen), cursor_name, fg, bg, 0);
- BLOCK_INPUT;
- XDefineCursor (XtDisplay (XSCREEN (screen)->display.x->edit_widget),
- XtWindow (XSCREEN (screen)->display.x->edit_widget),
- cursor);
- XFlush (XtDisplay (XSCREEN (screen)->display.x->edit_widget));
- UNBLOCK_INPUT;
- store_screen_param (XSCREEN (screen), intern ("pointer"), cursor_name);
- return Qnil;
- }
-
-
- /* GC calls x_show_gc_cursor() to change the mouse pointer to indicate GC.
- If this returns 0, then it couldn't change the cursor for whatever reason,
- and a minibuffer message will be output instead. x_show_normal_cursor()
- will be called at the end.
- */
- static int change_cursor_for_gc ();
-
- int
- x_show_gc_cursor (s)
- struct screen* s;
- {
- return change_cursor_for_gc (s, 1);
- }
-
- int
- x_show_normal_cursor (s)
- struct screen* s;
- {
- return change_cursor_for_gc (s, 0);
- }
-
-
- extern Lisp_Object get_screen_param (struct screen *, Lisp_Object);
-
- static int
- change_cursor_for_gc (s, gc_p)
- struct screen *s;
- int gc_p;
- {
- Cursor cursor;
- static int changed;
-
- if (!s || !SCREEN_IS_X(s) || NILP (Vx_gc_pointer_shape))
- return 0;
-
- if (! gc_p && !changed)
- return 0;
-
- if (gc_p)
- cursor = x_get_cursor (s, Vx_gc_pointer_shape, Qnil, Qnil, 1);
- else
- cursor = x_get_cursor (s, get_screen_param (s, intern ("pointer")),
- Qnil, Qnil, 1);
- if (! cursor)
- {
- if (gc_p)
- message ("Garbage collecting... (x-gc-pointer-shape is bogus!)");
- changed = 0;
- return 1;
- }
-
- BLOCK_INPUT;
- XDefineCursor (XtDisplay (s->display.x->edit_widget),
- XtWindow (s->display.x->edit_widget),
- cursor);
- XFlushQueue ();
- UNBLOCK_INPUT;
- changed = 1;
- return 1;
- }
-
-
-
- #ifdef USE_SOUND
- extern int not_on_console; /* defined in fns.c */
- #endif
-
- extern Lisp_Object x_term_init (Lisp_Object);
-
- DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
- 1, 1, 0, "Open a connection to an X server.\n\
- Argument ARGV is a list of strings describing the command line options.\n\
- Returns a copy of ARGV from which the arguments used by the Xt code\n\
- to open the connect have been removed.")
- (argv_list)
- Lisp_Object argv_list;
- {
- Lisp_Object argv_rest;
-
- if (x_current_display != 0)
- error ("X server connection is already initialized");
-
- /* This is what sets x_current_display. This also initializes many symbols,
- such as those used for input. */
- argv_rest = x_term_init (argv_list);
-
- text_part_sym = intern ("text-part");
- modeline_part_sym = intern ("modeline-part");
-
- XFASTINT (Vwindow_system_version) = 11;
- Xatoms_of_xfns ();
- Xatoms_of_xselect ();
-
- #ifdef USE_SOUND
- /* When running on a SparcStation or SGI, we cannot use digitized sounds as
- beeps unless emacs is running on the same machine that $DISPLAY points
- to, and $DISPLAY points to screen 0 of that machine.
- */
- {
- char *dpy = x_current_display->display_name;
- char *tail = (char *) strchr (dpy, ':');
- if (! tail ||
- strncmp (tail, ":0", 2))
- not_on_console = 1;
- else {
- char dpyname[255], localname[255];
- strncpy (dpyname, dpy, tail-dpy);
- dpyname [tail-dpy] = 0;
- if (!*dpyname ||
- !strcmp(dpyname, "unix") ||
- !strcmp(dpyname, "localhost"))
- not_on_console = 0;
- else if (gethostname (localname, sizeof (localname)))
- not_on_console = 1; /* can't find hostname? */
- else {
- /* gethostbyname() reuses the structure it returns,
- so we have to copy the string out of it. */
- struct hostent *h = gethostbyname (dpyname);
- not_on_console = !h || !!(strcmp (localname, h->h_name));
- }
- }
- }
- #endif /* USE_SOUND */
-
- return argv_rest;
- }
-
- DEFUN ("x-window-id", Fx_window_id, Sx_window_id, 1, 1, 0,
- "Get the ID of the X11 window. This gives us a chance to manipulate\n\
- the Emacs window from within a different program. Since the id is an\n\
- unsigned long, we return it as a string.")
- (screen)
- Lisp_Object screen;
- {
- char str[20];
-
- CHECK_SCREEN (screen, 0);
- if (! SCREEN_IS_X (XSCREEN (screen)))
- return Qnil;
- sprintf (str, "%lu", XtWindow (XSCREEN (screen)->display.x->edit_widget));
- return (make_string (str, strlen (str)));
- }
-
-
- DEFUN ("x-close-current-connection", Fx_close_current_connection,
- Sx_close_current_connection,
- 0, 0, 0, "Close the connection to the current X server.")
- ()
- {
- /* This is ONLY used when killing emacs; For switching displays
- we'll have to take care of setting CloseDownMode elsewhere. */
- #ifdef FREE_CHECKING
- extern void (*__free_hook)();
- int checking_free;
- #endif
-
- if (x_current_display)
- {
- BLOCK_INPUT;
- #ifdef FREE_CHECKING
- checking_free = (__free_hook != 0);
-
- /* Disable strict free checking, to avoid bug in X library */
- if (checking_free)
- disable_strict_free_check ();
- #endif
- XCloseDisplay (x_current_display);
- x_current_display = 0;
- Vwindow_system = Qnil;
- #ifdef FREE_CHECKING
- if (checking_free)
- enable_strict_free_check ();
- #endif
- UNBLOCK_INPUT;
- }
- else
- fatal ("No current X display connection to close");
- return Qnil;
- }
-
- static int
- emacs_safe_XSyncFunction(dpy)
- register Display *dpy;
- {
- BLOCK_INPUT;
- XSync (dpy, 0);
- UNBLOCK_INPUT;
- return 0;
- }
-
- DEFUN ("x-debug-mode", Fx_debug_mode, Sx_debug_mode, 1, 1, 0,
- "With a true arg, put the connection to the X server in synchronous\n\
- mode; this is slower. False turns it off.\n\
- Do not simply call XSynchronize() from gdb; that won't work.")
- (arg)
- Lisp_Object arg;
- {
- if (!NILP (arg))
- {
- BLOCK_INPUT;
- XSetAfterFunction (x_current_display, emacs_safe_XSyncFunction);
- UNBLOCK_INPUT;
- message ("X connection is synchronous");
- }
- else
- {
- BLOCK_INPUT;
- XSetAfterFunction (x_current_display, 0);
- UNBLOCK_INPUT;
- message ("X connection is asynchronous");
- }
- return arg;
- }
-
-
- void
- syms_of_xfns ()
- {
- init_x_parm_symbols ();
-
- /* This is zero if not using X windows. */
- x_current_display = 0;
-
- WM_COMMAND_screen = Qnil;
- staticpro (&WM_COMMAND_screen);
-
- DEFVAR_LISP ("x-gc-pointer-shape", &Vx_gc_pointer_shape,
- "The shape of the mouse-pointer during garbage collection.\n\
- If this is nil, then the cursor will not be changed, and echo-area messages\n\
- will be used instead.");
- Vx_gc_pointer_shape = Qnil;
-
- DEFVAR_LISP ("bar-cursor", &Vbar_cursor,
- "Use vertical bar cursor if non-nil.");
- Vbar_cursor = Qnil;
-
- DEFVAR_LISP ("x-screen-defaults", &Vx_screen_defaults,
- "Alist of default screen-creation parameters for X-window screens.\n\
- These override what is specified in `~/.Xdefaults' but are overridden\n\
- by the arguments to the particular call to `x-create-screen'.");
- Vx_screen_defaults = Qnil;
-
- DEFVAR_LISP ("default-screen-name", &Vdefault_screen_name,
- "The default name to assign to newly-created screens.\n\
- This can be overridden by arguments to `x-create-screen'.\n\
- This must be a string.");
- Vdefault_screen_name = Fpurecopy (build_string ("emacs"));
-
- DEFVAR_LISP ("x-emacs-application-class", &Vx_emacs_application_class,
- "The X application class of the Emacs process.\n\
- This controls, among other things, the name of the `app-defaults' file\n\
- that emacs will use. For changes to this variable to take effect, they\n\
- must be made before the connection to the X server is initialized, that is,\n\
- this variable may only be changed before emacs is dumped, or by setting it\n\
- in the file lisp/term/x-win.el.");
- Vx_emacs_application_class = Fpurecopy (build_string ("Emacs"));
-
- DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
- "A list of the directories in which X bitmap files may be found.\n\
- If nil, this is initialized from the \"*bitmapFilePath\" resource.");
- Vx_bitmap_file_path = Qnil;
-
- DEFVAR_BOOL ("x-allow-sendevents", &x_allow_sendevents,
- "*Non-nil means to allow synthetic events. Nil means they are ignored.\n\
- Beware: allowing emacs to process SendEvents opens a big security hole.");
- x_allow_sendevents = 0;
-
- staticpro (&Vcursor_alist);
- Vcursor_alist = Qnil;
-
- defsubr (&Sx_display_visual_class);
- defsubr (&Sx_color_display_p);
- defsubr (&Sx_pixel_width);
- defsubr (&Sx_pixel_height);
- defsubr (&Sx_display_pixel_width);
- defsubr (&Sx_display_pixel_height);
- defsubr (&Sx_display_planes);
- defsubr (&Sx_display_color_cells);
- defsubr (&Sx_server_vendor);
- defsubr (&Sx_server_version);
- defsubr (&Sx_window_id);
- defsubr (&Sx_grab_pointer);
- defsubr (&Sx_ungrab_pointer);
- defsubr (&Sx_create_screen);
- defsubr (&Sx_open_connection);
- defsubr (&Sx_close_current_connection);
- #ifdef ENERGIZE
- defsubr (&Senergize_toggle_psheet);
- #endif
- defsubr (&Sx_show_lineinfo_column);
- defsubr (&Sx_hide_lineinfo_column);
- defsubr (&Sx_debug_mode);
- defsubr (&Sx_get_resource);
- defsubr (&Sx_set_screen_icon_pixmap);
- defsubr (&Sx_set_screen_pointer);
- defsubr (&Sx_valid_color_name_p);
- defsubr (&Sx_valid_keysym_name_p);
-
- defsubr (&Sx_EnterNotify_internal);
- defsubr (&Sx_LeaveNotify_internal);
- defsubr (&Sx_FocusIn_internal);
- defsubr (&Sx_FocusOut_internal);
- defsubr (&Sx_MapNotify_internal);
- defsubr (&Sx_UnmapNotify_internal);
- defsubr (&Sx_VisibilityNotify_internal);
- defsubr (&Sx_non_VisibilityNotify_internal);
-
- Qx_EnterNotify_internal = intern ("x-EnterNotify-internal");
- Qx_LeaveNotify_internal = intern ("x-LeaveNotify-internal");
- Qx_FocusIn_internal = intern ("x-FocusIn-internal");
- Qx_FocusOut_internal = intern ("x-FocusOut-internal");
- Qx_MapNotify_internal = intern ("x-MapNotify-internal");
- Qx_UnmapNotify_internal = intern ("x-UnmapNotify-internal");
- Qx_VisibilityNotify_internal = intern ("x-VisibilityNotify-internal");
- Qx_non_VisibilityNotify_internal = intern("x-non-VisibilityNotify-internal");
- }
-
- void
- Xatoms_of_xfns ()
- {
- #define ATOM(x) XInternAtom(x_current_display, (x), False)
-
- BLOCK_INPUT;
- Xatom_WM_PROTOCOLS = ATOM("WM_PROTOCOLS");
- Xatom_WM_DELETE_WINDOW = ATOM("WM_DELETE_WINDOW");
- Xatom_WM_SAVE_YOURSELF = ATOM("WM_SAVE_YOURSELF");
- Xatom_WM_TAKE_FOCUS = ATOM("WM_TAKE_FOCUS");
- UNBLOCK_INPUT;
- }
-
- #endif /* HAVE_X_WINDOWS */
-