#include <sys/ioctl.h>
#endif /* ! defined (BSD_SYSTEM) */
-#include "systty.h"
#include "systime.h"
#ifndef INCLUDED_FCNTL
#include <X11/Xaw3d/Simple.h>
#include <X11/Xaw3d/Scrollbar.h>
#define ARROW_SCROLLBAR
+#define XAW_ARROW_SCROLLBARS
#include <X11/Xaw3d/ScrollbarP.h>
#else /* !HAVE_XAW3D */
#include <X11/Xaw/Simple.h>
extern Lisp_Object Vx_no_window_manager;
-extern Lisp_Object Qface, Qmouse_face, Qeql;
+extern Lisp_Object Qeql;
extern int errno;
void x_set_window_size P_ ((struct frame *, int, int, int));
void x_wm_set_window_state P_ ((struct frame *, int));
void x_wm_set_icon_pixmap P_ ((struct frame *, int));
+struct display *x_create_frame_display P_ ((struct x_display_info *));
+void x_delete_frame_display P_ ((struct display *));
void x_initialize P_ ((void));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
static int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_begin P_ ((struct frame *));
static void x_update_window_begin P_ ((struct window *));
static void x_after_update_window_line P_ ((struct glyph_row *));
-static struct scroll_bar *x_window_to_scroll_bar P_ ((Window));
+static struct scroll_bar *x_window_to_scroll_bar P_ ((Display *, Window));
static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
enum scroll_bar_part *,
Lisp_Object *, Lisp_Object *,
{
Lisp_Object rest, frame;
FOR_EACH_FRAME (rest, frame)
- x_flush (XFRAME (frame));
+ if (FRAME_X_P (XFRAME (frame)))
+ x_flush (XFRAME (frame));
}
else if (FRAME_X_P (f))
XFlush (FRAME_X_DISPLAY (f));
/* Nothing to do. */
}
-
/* Start update of window W. Set the global variable updated_window
to the window being updated and set output_cursor to the cursor
position of W. */
for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
if (GC_FRAMEP (XCAR (tail))
&& (f = XFRAME (XCAR (tail)),
- (f->output_data.nothing != 1
+ (FRAME_X_P (f)
+ && f->output_data.nothing != 1
&& FRAME_X_DISPLAY_INFO (f) == dpyinfo))
&& f->output_data.x->widget == widget)
return f;
{
case EnterNotify:
case LeaveNotify:
- if (event->xcrossing.detail != NotifyInferior
- && event->xcrossing.focus
- && ! (frame->output_data.x->focus_state & FOCUS_EXPLICIT))
- nr_events = x_focus_changed ((event->type == EnterNotify
- ? FocusIn : FocusOut),
- FOCUS_IMPLICIT,
- dpyinfo,
- frame,
- bufp,
- numchars);
+ {
+ struct frame *focus_frame = dpyinfo->x_focus_event_frame;
+ int focus_state
+ = focus_frame ? focus_frame->output_data.x->focus_state : 0;
+
+ if (event->xcrossing.detail != NotifyInferior
+ && event->xcrossing.focus
+ && ! (focus_state & FOCUS_EXPLICIT))
+ nr_events = x_focus_changed ((event->type == EnterNotify
+ ? FocusIn : FocusOut),
+ FOCUS_IMPLICIT,
+ dpyinfo,
+ frame,
+ bufp,
+ numchars);
+ }
break;
case FocusIn:
/* Clear the mouse-moved flag for every frame on this display. */
FOR_EACH_FRAME (tail, frame)
- if (FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
+ if (FRAME_X_P (XFRAME (frame))
+ && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
XFRAME (frame)->mouse_moved = 0;
last_mouse_scroll_bar = Qnil;
/* If not, is it one of our scroll bars? */
if (! f1)
{
- struct scroll_bar *bar = x_window_to_scroll_bar (win);
+ struct scroll_bar *bar;
+
+ bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win);
if (bar)
{
/* Scroll bar support. */
-/* Given an X window ID, find the struct scroll_bar which manages it.
+/* Given an X window ID and a DISPLAY, find the struct scroll_bar which
+ manages it.
This can be called in GC, so we have to make sure to strip off mark
bits. */
static struct scroll_bar *
-x_window_to_scroll_bar (window_id)
+x_window_to_scroll_bar (display, window_id)
+ Display *display;
Window window_id;
{
Lisp_Object tail;
#ifdef USE_GTK
- window_id = (Window) xg_get_scroll_id_for_window (window_id);
+ window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
#endif /* USE_GTK */
for (tail = Vframe_list;
if (! GC_FRAMEP (frame))
abort ();
+ if (! FRAME_X_P (XFRAME (frame)))
+ continue;
+
/* Scan this frame's scroll bar list for a scroll bar with the
right window ID. */
condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
condemned = Qnil,
! GC_NILP (bar));
bar = XSCROLL_BAR (bar)->next)
- if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)) == window_id)
+ if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)) == window_id &&
+ FRAME_X_DISPLAY (XFRAME (frame)) == display)
return XSCROLL_BAR (bar);
}
XGCTYPE (tail) == Lisp_Cons;
tail = XCDR (tail))
{
- Lisp_Object frame = XCAR (tail);
- Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
+ if (FRAME_X_P (XFRAME (XCAR (tail))))
+ {
+ Lisp_Object frame = XCAR (tail);
+ Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
- if (menu_bar && xlwmenu_window_p (menu_bar, window))
- return menu_bar;
+ if (menu_bar && xlwmenu_window_p (menu_bar, window))
+ return menu_bar;
+ }
}
return NULL;
#endif
#ifdef USE_GTK
-static struct x_display_info *current_dpyinfo;
static struct input_event **current_bufp;
static int *current_numcharsp;
static int current_count;
GdkEvent *ev;
gpointer data;
{
- XEvent *xev = (XEvent*)gxev;
+ XEvent *xev = (XEvent *) gxev;
if (current_numcharsp)
{
+ struct x_display_info *dpyinfo;
+
+ dpyinfo = x_display_info_for_display (xev->xany.display);
+
#ifdef HAVE_X_I18N
/* Filter events for the current X input method.
GTK calls XFilterEvent but not for key press and release,
so we do it here. */
if (xev->type == KeyPress || xev->type == KeyRelease)
- if (x_filter_event (current_dpyinfo, xev))
+ if (dpyinfo && x_filter_event (dpyinfo, xev))
return GDK_FILTER_REMOVE;
#endif
- current_count += handle_one_xevent (current_dpyinfo,
- xev,
- current_bufp,
- current_numcharsp,
- ¤t_finish);
+
+ if (! dpyinfo)
+ current_finish = X_EVENT_NORMAL;
+ else
+ current_count += handle_one_xevent (dpyinfo,
+ xev,
+ current_bufp,
+ current_numcharsp,
+ ¤t_finish);
}
else
- current_finish = x_dispatch_event (xev, GDK_DISPLAY ());
+ current_finish = x_dispatch_event (xev, xev->xany.display);
if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
return GDK_FILTER_REMOVE;
/* Dispatch event to the widget. */
goto OTHER;
#else /* not USE_TOOLKIT_SCROLL_BARS */
- bar = x_window_to_scroll_bar (event.xexpose.window);
+ bar = x_window_to_scroll_bar (event.xexpose.display,
+ event.xexpose.window);
if (bar)
x_scroll_bar_expose (bar, &event);
/* Window will be selected only when it is not selected now and
last mouse movement event was not in it. Minibuffer window
will be selected iff it is active. */
- if (WINDOWP(window)
+ if (WINDOWP (window)
&& !EQ (window, last_window)
&& !EQ (window, selected_window)
&& numchars > 0)
{
#ifndef USE_TOOLKIT_SCROLL_BARS
struct scroll_bar *bar
- = x_window_to_scroll_bar (event.xmotion.window);
+ = x_window_to_scroll_bar (event.xmotion.display,
+ event.xmotion.window);
if (bar)
x_scroll_bar_note_movement (bar, &event);
else
{
struct scroll_bar *bar
- = x_window_to_scroll_bar (event.xbutton.window);
+ = x_window_to_scroll_bar (event.xbutton.display,
+ event.xbutton.window);
#ifdef USE_TOOLKIT_SCROLL_BARS
/* Make the "Ctrl-Mouse-2 splits window" work for toolkit
EVENT_INIT (*bufpp);
bufpp = bufp;
- for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
- if (dpyinfo->display == display)
- break;
+ dpyinfo = x_display_info_for_display (display);
if (dpyinfo)
{
EXPECTED is nonzero if the caller knows input is available. */
static int
-XTread_socket (sd, bufp, numchars, expected)
- register int sd;
+XTread_socket (bufp, numchars, expected)
/* register */ struct input_event *bufp;
/* register */ int numchars;
int expected;
UNBLOCK_INPUT;
#endif
-#ifdef USE_GTK
- /* For GTK we must use the GTK event loop. But XEvents gets passed
- to our filter function above, and then to the big event switch.
- We use a bunch of globals to communicate with our filter function,
- that is kind of ugly, but it works. */
- current_dpyinfo = dpyinfo;
-
- while (gtk_events_pending ())
- {
- current_count = count;
- current_numcharsp = &numchars;
- current_bufp = &bufp;
-
- gtk_main_iteration ();
-
- count = current_count;
- current_bufp = 0;
- current_numcharsp = 0;
-
- if (current_finish == X_EVENT_GOTO_OUT)
- goto out;
- }
-
-#else /* not USE_GTK */
+#ifndef USE_GTK
while (XPending (dpyinfo->display))
{
int finish;
if (finish == X_EVENT_GOTO_OUT)
goto out;
}
-#endif /* USE_GTK */
+#endif /* not USE_GTK */
}
+#ifdef USE_GTK
+
+ /* For GTK we must use the GTK event loop. But XEvents gets passed
+ to our filter function above, and then to the big event switch.
+ We use a bunch of globals to communicate with our filter function,
+ that is kind of ugly, but it works.
+
+ There is no way to do one display at the time, GTK just does events
+ from all displays. */
+
+ while (gtk_events_pending ())
+ {
+ current_count = count;
+ current_numcharsp = &numchars;
+ current_bufp = &bufp;
+
+ gtk_main_iteration ();
+
+ count = current_count;
+ current_bufp = 0;
+ current_numcharsp = 0;
+
+ if (current_finish == X_EVENT_GOTO_OUT)
+ break;
+ }
+#endif /* USE_GTK */
+
out:;
/* On some systems, an X bug causes Emacs to get no more events
struct glyph *cursor_glyph;
GC gc;
- /* Compute frame-relative coordinates from window-relative
- coordinates. */
- x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- y = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
- + row->ascent - w->phys_cursor_ascent);
- h = row->height - 1;
-
/* Get the glyph the cursor is on. If we can't tell because
the current matrix is invalid or such, give up. */
cursor_glyph = get_phys_cursor_glyph (w);
wd = min (FRAME_COLUMN_WIDTH (f), wd);
w->phys_cursor_width = wd;
+ /* Compute frame-relative coordinates from window-relative
+ coordinates. */
+ x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+ y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
+
+ /* Compute the proper height and ascent of the rectangle, based
+ on the actual glyph. Using the full height of the row looks
+ bad when there are tall images on that row. */
+ h = max (FRAME_LINE_HEIGHT (f), cursor_glyph->ascent + cursor_glyph->descent);
+ if (h < row->height)
+ y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
+ h--;
+
/* The foreground of cursor_gc is typically the same as the normal
background color, which can cause the cursor box to be invisible. */
xgcv.foreground = f->output_data.x->cursor_pixel;
if (STRINGP (file))
{
#ifdef USE_GTK
- /* Use gtk_window_set_icon_from_file() if available,
+ /* Use gtk_window_set_icon_from_file () if available,
It's not restricted to bitmaps */
- if (xg_set_icon(f, file))
+ if (xg_set_icon (f, file))
return 0;
#endif /* USE_GTK */
bitmap_id = x_create_bitmap_from_file (f, file);
- x_create_bitmap_mask(f, bitmap_id);
+ x_create_bitmap_mask (f, bitmap_id);
}
else
{
FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id
= x_create_bitmap_from_data (f, gnu_bits,
gnu_width, gnu_height);
- x_create_bitmap_mask(f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
+ x_create_bitmap_mask (f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
}
/* The first time we create the GNU bitmap and mask,
}
#endif
+#ifdef USE_GTK
+ if (dpyinfo)
+ xg_display_close (dpyinfo->display);
+#endif
+
/* Indicate that this display is dead. */
if (dpyinfo)
dpyinfo->display = 0;
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
- if (FRAME_X_DISPLAY_INFO (f) == dpyinfo)
+ if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
{
FRAME_XIC (f) = NULL;
if (FRAME_XIC_FONTSET (f))
{
struct frame *f = XFRAME (frame);
- if (FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo)
+ if (FRAME_X_P (f)
+ && FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo)
if (FRAME_XIC (f) == NULL)
{
create_frame_xic (f);
if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
{
- modified_left += FRAME_X_OUTPUT (f)->x_pixels_outer_diff;
- modified_top += FRAME_X_OUTPUT (f)->y_pixels_outer_diff;
+ /* Some WMs (twm, wmaker at least) has an offset that is smaller
+ than the WM decorations. So we use the calculated offset instead
+ of the WM decoration sizes here (x/y_pixels_outer_diff). */
+ modified_left += FRAME_X_OUTPUT (f)->move_offset_left;
+ modified_top += FRAME_X_OUTPUT (f)->move_offset_top;
}
XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
{
int expect_top = FRAME_X_OUTPUT (f)->expected_top;
int expect_left = FRAME_X_OUTPUT (f)->expected_left;
-
+
if (expect_top != f->top_pos || expect_left != f->left_pos)
{
- if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
- FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
+ FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
+ FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos;
+ FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos;
+
x_set_offset (f, expect_left, expect_top, 1);
}
else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
Display *dpy = dpyinfo->display;
int try_XLoadQueryFont = 0;
int count;
- int allow_scalable_fonts_p = 0;
+ int allow_auto_scaled_font = 0;
if (size < 0)
{
- allow_scalable_fonts_p = 1;
+ allow_auto_scaled_font = 1;
size = 0;
}
((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */
tem = XCDR (dpyinfo->name_list_element);
key = Fcons (Fcons (pattern, make_number (maxnames)),
- allow_scalable_fonts_p ? Qt : Qnil);
+ allow_auto_scaled_font ? Qt : Qnil);
list = Fassoc (key, tem);
if (!NILP (list))
{
{
int width = 0;
char *p = names[i];
- int average_width = -1, dashes = 0;
+ int average_width = -1, resx = 0, dashes = 0;
/* Count the number of dashes in NAMES[I]. If there are
- 14 dashes, and the field value following 12th dash
- (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
- is usually too ugly to be used for editing. Let's
- ignore it. */
+ 14 dashes, the field value following 9th dash
+ (RESOLUTION_X) is nonzero, and the field value
+ following 12th dash (AVERAGE_WIDTH) is 0, this is a
+ auto-scaled font which is usually too ugly to be used
+ for editing. Let's ignore it. */
while (*p)
if (*p++ == '-')
{
dashes++;
if (dashes == 7) /* PIXEL_SIZE field */
width = atoi (p);
+ else if (dashes == 9)
+ resx = atoi (p);
else if (dashes == 12) /* AVERAGE_WIDTH field */
average_width = atoi (p);
}
- if (allow_scalable_fonts_p
- || dashes < 14 || average_width != 0)
+ if (allow_auto_scaled_font
+ || dashes < 14 || average_width != 0 || resx == 0)
{
tem = build_string (names[i]);
if (NILP (Fassoc (tem, list)))
{
int connection;
Display *dpy;
+ struct display *display;
struct x_display_info *dpyinfo;
XrmDatabase xrdb;
char **argv2 = argv;
GdkAtom atom;
- /* GTK 2.0 can only handle one display, GTK 2.2 can handle more
- than one, but this remains to be implemented. */
- if (x_initialized > 1)
- return 0;
-
- for (argc = 0; argc < NUM_ARGV; ++argc)
- argv[argc] = 0;
+ if (x_initialized++ > 1)
+ {
+ /* Opening another display. If xg_display_open returns less
+ than zero, we are probably on GTK 2.0, which can only handle
+ one display. GTK 2.2 or later can handle more than one. */
+ if (xg_display_open (SDATA (display_name), &dpy) < 0)
+ error ("Sorry, this version of GTK can only handle one display");
+ }
+ else
+ {
+ for (argc = 0; argc < NUM_ARGV; ++argc)
+ argv[argc] = 0;
- argc = 0;
- argv[argc++] = initial_argv[0];
+ argc = 0;
+ argv[argc++] = initial_argv[0];
- if (! NILP (display_name))
- {
- argv[argc++] = "--display";
- argv[argc++] = SDATA (display_name);
- }
+ if (! NILP (display_name))
+ {
+ argv[argc++] = "--display";
+ argv[argc++] = SDATA (display_name);
+ }
- argv[argc++] = "--name";
- argv[argc++] = resource_name;
+ argv[argc++] = "--name";
+ argv[argc++] = resource_name;
#ifdef HAVE_X11R5
- XSetLocaleModifiers ("");
+ XSetLocaleModifiers ("");
#endif
- gtk_init (&argc, &argv2);
+ gtk_init (&argc, &argv2);
- /* gtk_init does set_locale. We must fix locale after calling it. */
- fixup_locale ();
- xg_initialize ();
+ /* gtk_init does set_locale. We must fix locale after calling it. */
+ fixup_locale ();
+ xg_initialize ();
- dpy = GDK_DISPLAY ();
+ dpy = GDK_DISPLAY ();
- /* NULL window -> events for all windows go to our function */
- gdk_window_add_filter (NULL, event_handler_gdk, NULL);
+ /* NULL window -> events for all windows go to our function */
+ gdk_window_add_filter (NULL, event_handler_gdk, NULL);
- /* Load our own gtkrc if it exists. */
- {
- struct gcpro gcpro1, gcpro2;
- char *file = "~/.emacs.d/gtkrc";
- Lisp_Object s, abs_file;
+ /* Load our own gtkrc if it exists. */
+ {
+ struct gcpro gcpro1, gcpro2;
+ char *file = "~/.emacs.d/gtkrc";
+ Lisp_Object s, abs_file;
- GCPRO2 (s, abs_file);
- s = make_string (file, strlen (file));
- abs_file = Fexpand_file_name(s, Qnil);
+ GCPRO2 (s, abs_file);
+ s = make_string (file, strlen (file));
+ abs_file = Fexpand_file_name (s, Qnil);
- if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
- gtk_rc_parse (SDATA (abs_file));
+ if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
+ gtk_rc_parse (SDATA (abs_file));
- UNGCPRO;
- }
+ UNGCPRO;
+ }
- XSetErrorHandler (x_error_handler);
- XSetIOErrorHandler (x_io_error_quitter);
+ XSetErrorHandler (x_error_handler);
+ XSetIOErrorHandler (x_io_error_quitter);
+ }
}
#else /* not USE_GTK */
#ifdef USE_X_TOOLKIT
dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info));
bzero (dpyinfo, sizeof *dpyinfo);
+ display = x_create_frame_display (dpyinfo);
+
#ifdef MULTI_KBOARD
{
struct x_display_info *share;
x_find_modifier_meanings (dpyinfo);
/* Get the scroll bar cursor. */
+#ifdef USE_GTK
+ /* We must create a GTK cursor, it is required for GTK widgets. */
+ dpyinfo->xg_cursor = xg_create_default_cursor (dpyinfo->display);
+#endif /* USE_GTK */
+
dpyinfo->vertical_scroll_bar_cursor
= XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow);
x_delete_display (dpyinfo)
struct x_display_info *dpyinfo;
{
+ int i;
+
+ {
+ /* Delete the generic struct display for this X display. */
+ struct display *d;
+ for (d = display_list; d; d = d->next_display)
+ if (d->type == output_x_window && d->display_info.x != dpyinfo)
+ {
+ delete_display (d);
+ break;
+ }
+ }
+
delete_keyboard_wait_descriptor (dpyinfo->connection);
/* Discard this display from x_display_name_list and x_display_list.
xim_close_dpy (dpyinfo);
#endif
+ /* Free the font names in the font table. */
+ for (i = 0; i < dpyinfo->n_fonts; i++)
+ if (dpyinfo->font_table[i].name)
+ {
+ if (dpyinfo->font_table[i].name != dpyinfo->font_table[i].full_name)
+ xfree (dpyinfo->font_table[i].full_name);
+ xfree (dpyinfo->font_table[i].name);
+ }
+
+ if (dpyinfo->font_table->font_encoder)
+ xfree (dpyinfo->font_table->font_encoder);
+
xfree (dpyinfo->font_table);
xfree (dpyinfo->x_id_name);
xfree (dpyinfo->color_cells);
extern frame_parm_handler x_frame_parm_handlers[];
static struct redisplay_interface x_redisplay_interface =
-{
- x_frame_parm_handlers,
- x_produce_glyphs,
- x_write_glyphs,
- x_insert_glyphs,
- x_clear_end_of_line,
- x_scroll_run,
- x_after_update_window_line,
- x_update_window_begin,
- x_update_window_end,
- x_cursor_to,
- x_flush,
+ {
+ x_frame_parm_handlers,
+ x_produce_glyphs,
+ x_write_glyphs,
+ x_insert_glyphs,
+ x_clear_end_of_line,
+ x_scroll_run,
+ x_after_update_window_line,
+ x_update_window_begin,
+ x_update_window_end,
+ x_cursor_to,
+ x_flush,
#ifndef XFlush
- x_flush,
+ x_flush,
#else
- 0, /* flush_display_optional */
+ 0, /* flush_display_optional */
#endif
- x_clear_window_mouse_face,
- x_get_glyph_overhangs,
- x_fix_overlapping_area,
- x_draw_fringe_bitmap,
- x_per_char_metric,
- x_encode_char,
- x_compute_glyph_string_overhangs,
- x_draw_glyph_string,
- x_define_frame_cursor,
- x_clear_frame_area,
- x_draw_window_cursor,
- x_draw_vertical_window_border,
- x_shift_glyphs_for_insert
-};
+ x_clear_window_mouse_face,
+ x_get_glyph_overhangs,
+ x_fix_overlapping_area,
+ x_draw_fringe_bitmap,
+ x_per_char_metric,
+ x_encode_char,
+ x_compute_glyph_string_overhangs,
+ x_draw_glyph_string,
+ x_define_frame_cursor,
+ x_clear_frame_area,
+ x_draw_window_cursor,
+ x_draw_vertical_window_border,
+ x_shift_glyphs_for_insert
+ };
+
+
+/* This function is called when the last frame on a display is deleted. */
+void
+x_delete_frame_display (struct display *display)
+{
+ /* We don't do anything, the connection to the X server must remain
+ open. */
+}
+
+
+struct display *
+x_create_frame_display (struct x_display_info *dpyinfo)
+{
+ struct display *display;
+
+ display = create_display ();
+
+ display->type = output_x_window;
+ display->display_info.x = dpyinfo;
+ dpyinfo->frame_display = display;
+
+ display->clear_frame_hook = x_clear_frame;
+ display->ins_del_lines_hook = x_ins_del_lines;
+ display->delete_glyphs_hook = x_delete_glyphs;
+ display->ring_bell_hook = XTring_bell;
+ display->reset_terminal_modes_hook = XTreset_terminal_modes;
+ display->set_terminal_modes_hook = XTset_terminal_modes;
+ display->update_begin_hook = x_update_begin;
+ display->update_end_hook = x_update_end;
+ display->set_terminal_window_hook = XTset_terminal_window;
+ display->read_socket_hook = XTread_socket;
+ display->frame_up_to_date_hook = XTframe_up_to_date;
+ display->mouse_position_hook = XTmouse_position;
+ display->frame_rehighlight_hook = XTframe_rehighlight;
+ display->frame_raise_lower_hook = XTframe_raise_lower;
+ display->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
+ display->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
+ display->redeem_scroll_bar_hook = XTredeem_scroll_bar;
+ display->judge_scroll_bars_hook = XTjudge_scroll_bars;
+
+ display->delete_frame_hook = x_destroy_window;
+ display->delete_display_hook = x_delete_frame_display;
+
+ display->rif = &x_redisplay_interface;
+ display->scroll_region_ok = 1; /* We'll scroll partial frames. */
+ display->char_ins_del_ok = 1;
+ display->line_ins_del_ok = 1; /* We'll just blt 'em. */
+ display->fast_clear_end_of_line = 1; /* X does this well. */
+ display->memory_below_frame = 0; /* We don't remember what scrolls
+ off the bottom. */
+
+ return display;
+}
void
x_initialize ()
{
- rif = &x_redisplay_interface;
-
- clear_frame_hook = x_clear_frame;
- ins_del_lines_hook = x_ins_del_lines;
- delete_glyphs_hook = x_delete_glyphs;
- ring_bell_hook = XTring_bell;
- reset_terminal_modes_hook = XTreset_terminal_modes;
- set_terminal_modes_hook = XTset_terminal_modes;
- update_begin_hook = x_update_begin;
- update_end_hook = x_update_end;
- set_terminal_window_hook = XTset_terminal_window;
- read_socket_hook = XTread_socket;
- frame_up_to_date_hook = XTframe_up_to_date;
- mouse_position_hook = XTmouse_position;
- frame_rehighlight_hook = XTframe_rehighlight;
- frame_raise_lower_hook = XTframe_raise_lower;
- set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
- condemn_scroll_bars_hook = XTcondemn_scroll_bars;
- redeem_scroll_bar_hook = XTredeem_scroll_bar;
- judge_scroll_bars_hook = XTjudge_scroll_bars;
-
- scroll_region_ok = 1; /* we'll scroll partial frames */
- char_ins_del_ok = 1;
- line_ins_del_ok = 1; /* we'll just blt 'em */
- fast_clear_end_of_line = 1; /* X does this well */
- memory_below_frame = 0; /* we don't remember what scrolls
- off the bottom */
baud_rate = 19200;
x_noop_count = 0;