summaryrefslogtreecommitdiff
path: root/src/w32term.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32term.c')
-rw-r--r--src/w32term.c372
1 files changed, 242 insertions, 130 deletions
diff --git a/src/w32term.c b/src/w32term.c
index f3d13b826e1..f46a54fafb9 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -58,8 +58,6 @@ Boston, MA 02110-1301, USA. */
#include "composite.h"
#include "coding.h"
-#define abs(x) ((x) < 0 ? -(x) : (x))
-
/* Fringe bitmaps. */
@@ -218,10 +216,9 @@ extern int errno;
extern EMACS_INT extra_keyboard_modifiers;
static void x_update_window_end P_ ((struct window *, int, int));
-void w32_delete_display P_ ((struct w32_display_info *));
static void w32_handle_tool_bar_click P_ ((struct frame *,
struct input_event *));
-void w32_define_cursor P_ ((Window, Cursor));
+static void w32_define_cursor P_ ((Window, Cursor));
void x_lower_frame P_ ((struct frame *));
void x_scroll_bar_clear P_ ((struct frame *));
@@ -230,14 +227,14 @@ void x_raise_frame P_ ((struct frame *));
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));
-void w32_initialize P_ ((void));
+static void w32_initialize P_ ((void));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
static void w32_frame_up_to_date P_ ((struct frame *));
-static void w32_set_terminal_modes P_ ((void));
-static void w32_reset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+static void w32_set_terminal_modes P_ ((struct terminal *));
+static void w32_reset_terminal_modes P_ ((struct terminal *));
+static void x_clear_frame P_ ((struct frame *));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct w32_display_info *,
@@ -683,6 +680,60 @@ w32_draw_fringe_bitmap (w, row, p)
hdc = get_frame_dc (f);
+ if (!p->overlay_p)
+ {
+ int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
+
+ /* If the fringe is adjacent to the left (right) scroll bar of a
+ leftmost (rightmost, respectively) window, then extend its
+ background to the gap between the fringe and the bar. */
+ if ((WINDOW_LEFTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ || (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
+ {
+ int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
+
+ if (sb_width > 0)
+ {
+ int left = WINDOW_SCROLL_BAR_AREA_X (w);
+ int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
+ * FRAME_COLUMN_WIDTH (f));
+
+ if (bx < 0)
+ {
+ /* Bitmap fills the fringe. */
+ if (left + width == p->x)
+ bx = left + sb_width;
+ else if (p->x + p->wd == left)
+ bx = left;
+ if (bx >= 0)
+ {
+ int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+
+ nx = width - sb_width;
+ by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
+ row->y));
+ ny = row->visible_height;
+ }
+ }
+ else
+ {
+ if (left + width == bx)
+ {
+ bx = left + sb_width;
+ nx += width - sb_width;
+ }
+ else if (bx + nx == left)
+ nx += width - sb_width;
+ }
+ }
+ }
+
+ if (bx >= 0 && nx > 0)
+ w32_fill_area (f, hdc, face->background, bx, by, nx, ny);
+ }
+
/* Must clip because of partially visible lines. */
rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
if (p->y < rowY)
@@ -700,12 +751,6 @@ w32_draw_fringe_bitmap (w, row, p)
else
w32_clip_to_row (w, row, -1, hdc);
- if (p->bx >= 0 && !p->overlay_p)
- {
- w32_fill_area (f, hdc, face->background,
- p->bx, p->by, p->nx, p->ny);
- }
-
if (p->which && p->which < max_fringe_bmp)
{
HBITMAP pixmap = fringe_bmp[p->which];
@@ -801,7 +846,7 @@ w32_destroy_fringe_bitmap (which)
rarely happens). */
static void
-w32_set_terminal_modes (void)
+w32_set_terminal_modes (struct terminal *term)
{
}
@@ -809,7 +854,7 @@ w32_set_terminal_modes (void)
the W32 windows go away, and suspending requires no action. */
static void
-w32_reset_terminal_modes (void)
+w32_reset_terminal_modes (struct terminal *term)
{
}
@@ -2549,7 +2594,7 @@ x_draw_glyph_string (s)
if (s->face->overline_color_defaulted_p)
{
w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
- s->y + dy, s->background_width, h);
+ s->y + dy, s->background_width, h);
}
else
{
@@ -2608,16 +2653,10 @@ w32_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
for X frames. */
static void
-x_delete_glyphs (n)
+x_delete_glyphs (f, n)
+ struct frame *f;
register int n;
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
if (! FRAME_W32_P (f))
return;
@@ -2629,15 +2668,8 @@ x_delete_glyphs (n)
frame. Otherwise clear the selected frame. */
static void
-x_clear_frame ()
+x_clear_frame (struct frame *f)
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
if (! FRAME_W32_P (f))
return;
@@ -2664,18 +2696,14 @@ x_clear_frame ()
/* Make audible bell. */
static void
-w32_ring_bell (void)
+w32_ring_bell (struct frame *f)
{
- struct frame *f;
-
- f = SELECTED_FRAME ();
-
BLOCK_INPUT;
if (FRAME_W32_P (f) && visible_bell)
{
int i;
- HWND hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ());
+ HWND hwnd = FRAME_W32_WINDOW (f);
for (i = 0; i < 5; i++)
{
@@ -2685,7 +2713,7 @@ w32_ring_bell (void)
FlashWindow (hwnd, FALSE);
}
else
- w32_sys_ring_bell ();
+ w32_sys_ring_bell (f);
UNBLOCK_INPUT;
}
@@ -2712,16 +2740,10 @@ w32_set_terminal_window (n)
lines or deleting -N lines at vertical position VPOS. */
static void
-x_ins_del_lines (vpos, n)
+x_ins_del_lines (f, vpos, n)
+ struct frame *f;
int vpos, n;
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
if (! FRAME_W32_P (f))
return;
@@ -3126,7 +3148,8 @@ construct_mouse_wheel (result, msg, f)
POINT p;
int delta;
- result->kind = WHEEL_EVENT;
+ result->kind = msg->msg.message == WM_MOUSEHWHEEL ? HORIZ_WHEEL_EVENT
+ : WHEEL_EVENT;
result->code = 0;
result->timestamp = msg->msg.time;
@@ -3278,7 +3301,7 @@ redo_mouse_highlight ()
HIWORD (last_mouse_motion_event.lParam));
}
-void
+static void
w32_define_cursor (window, cursor)
Window window;
Cursor cursor;
@@ -3638,6 +3661,7 @@ x_scroll_bar_create (w, top, left, width, height)
XSETINT (bar->start, 0);
XSETINT (bar->end, 0);
bar->dragging = Qnil;
+ bar->fringe_extended_p = Qnil;
/* Requires geometry to be set before call to create the real window */
@@ -3701,6 +3725,7 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
struct scroll_bar *bar;
int top, height, left, sb_left, width, sb_width;
int window_y, window_height;
+ int fringe_extended_p;
/* Get window dimensions. */
window_box (w, -1, 0, &window_y, 0, &window_height);
@@ -3720,9 +3745,20 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
/* Compute the left edge of the scroll bar. */
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
- sb_left = left + width - sb_width - (width - sb_width) / 2;
+ sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
+ else
+ sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
+
+ if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ fringe_extended_p = (WINDOW_LEFTMOST_P (w)
+ && WINDOW_LEFT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_LEFT_MARGIN_COLS (w) == 0));
else
- sb_left = left + (width - sb_width) / 2;
+ fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_RIGHT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
/* Does the scroll bar exist yet? */
if (NILP (w->vertical_scroll_bar))
@@ -3732,7 +3768,10 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
if (width > 0 && height > 0)
{
hdc = get_frame_dc (f);
- w32_clear_area (f, hdc, left, top, width, height);
+ if (fringe_extended_p)
+ w32_clear_area (f, hdc, sb_left, top, sb_width, height);
+ else
+ w32_clear_area (f, hdc, left, top, width, height);
release_frame_dc (f, hdc);
}
UNBLOCK_INPUT;
@@ -3751,7 +3790,8 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
if ( XINT (bar->left) == sb_left
&& XINT (bar->top) == top
&& XINT (bar->width) == sb_width
- && XINT (bar->height) == height )
+ && XINT (bar->height) == height
+ && !NILP (bar->fringe_extended_p) == fringe_extended_p )
{
/* Redraw after clear_frame. */
if (!my_show_window (f, hwnd, SW_NORMAL))
@@ -3768,11 +3808,10 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
hdc = get_frame_dc (f);
/* Since Windows scroll bars are smaller than the space reserved
for them on the frame, we have to clear "under" them. */
- w32_clear_area (f, hdc,
- left,
- top,
- width,
- height);
+ if (fringe_extended_p)
+ w32_clear_area (f, hdc, sb_left, top, sb_width, height);
+ else
+ w32_clear_area (f, hdc, left, top, width, height);
release_frame_dc (f, hdc);
}
/* Make sure scroll bar is "visible" before moving, to ensure the
@@ -3802,6 +3841,8 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
UNBLOCK_INPUT;
}
}
+ bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
+
w32_set_scroll_bar_thumb (bar, portion, position, whole);
XSETVECTOR (w->vertical_scroll_bar, bar);
@@ -4450,6 +4491,7 @@ w32_read_socket (sd, expected, hold_quit)
}
case WM_MOUSEWHEEL:
+ case WM_MOUSEHWHEEL:
{
if (dpyinfo->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame))
@@ -5876,8 +5918,8 @@ x_free_frame_resources (f)
free_frame_menubar (f);
- unload_color (f, f->output_data.x->foreground_pixel);
- unload_color (f, f->output_data.x->background_pixel);
+ unload_color (f, FRAME_FOREGROUND_PIXEL (f));
+ unload_color (f, FRAME_BACKGROUND_PIXEL (f));
unload_color (f, f->output_data.w32->cursor_pixel);
unload_color (f, f->output_data.w32->cursor_foreground_pixel);
unload_color (f, f->output_data.w32->border_pixel);
@@ -5916,14 +5958,13 @@ x_free_frame_resources (f)
/* Destroy the window of frame F. */
-
+void
x_destroy_window (f)
struct frame *f;
{
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
x_free_frame_resources (f);
-
dpyinfo->reference_count--;
}
@@ -6183,6 +6224,132 @@ w32_make_rdb (xrm_option)
return buffer;
}
+void
+x_flush (struct frame * f)
+{ /* Nothing to do */ }
+
+
+extern frame_parm_handler w32_frame_parm_handlers[];
+
+static struct redisplay_interface w32_redisplay_interface =
+{
+ w32_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,
+ 0, /* flush_display_optional */
+ x_clear_window_mouse_face,
+ w32_get_glyph_overhangs,
+ x_fix_overlapping_area,
+ w32_draw_fringe_bitmap,
+ w32_define_fringe_bitmap,
+ w32_destroy_fringe_bitmap,
+ w32_per_char_metric,
+ w32_encode_char,
+ NULL, /* w32_compute_glyph_string_overhangs */
+ x_draw_glyph_string,
+ w32_define_frame_cursor,
+ w32_clear_frame_area,
+ w32_draw_window_cursor,
+ w32_draw_vertical_window_border,
+ w32_shift_glyphs_for_insert
+};
+
+static void x_delete_terminal (struct terminal *term);
+
+static struct terminal *
+w32_create_terminal (struct w32_display_info *dpyinfo)
+{
+ struct terminal *terminal;
+
+ terminal = create_terminal ();
+
+ terminal->type = output_w32;
+ terminal->display_info.w32 = dpyinfo;
+ dpyinfo->terminal = terminal;
+
+ /* MSVC does not type K&R functions with no arguments correctly, and
+ so we must explicitly cast them. */
+ terminal->clear_frame_hook = x_clear_frame;
+ terminal->ins_del_lines_hook = x_ins_del_lines;
+ terminal->delete_glyphs_hook = x_delete_glyphs;
+ terminal->ring_bell_hook = w32_ring_bell;
+ terminal->reset_terminal_modes_hook = w32_reset_terminal_modes;
+ terminal->set_terminal_modes_hook = w32_set_terminal_modes;
+ terminal->update_begin_hook = x_update_begin;
+ terminal->update_end_hook = x_update_end;
+ terminal->set_terminal_window_hook = w32_set_terminal_window;
+ terminal->read_socket_hook = w32_read_socket;
+ terminal->frame_up_to_date_hook = w32_frame_up_to_date;
+ terminal->mouse_position_hook = w32_mouse_position;
+ terminal->frame_rehighlight_hook = w32_frame_rehighlight;
+ terminal->frame_raise_lower_hook = w32_frame_raise_lower;
+ // terminal->fullscreen_hook = XTfullscreen_hook;
+ terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
+ terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
+ terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
+ terminal->judge_scroll_bars_hook = w32_judge_scroll_bars;
+
+ terminal->delete_frame_hook = x_destroy_window;
+ terminal->delete_terminal_hook = x_delete_terminal;
+
+ terminal->rif = &w32_redisplay_interface;
+ terminal->scroll_region_ok = 1; /* We'll scroll partial frames. */
+ terminal->char_ins_del_ok = 1;
+ terminal->line_ins_del_ok = 1; /* We'll just blt 'em. */
+ terminal->fast_clear_end_of_line = 1; /* X does this well. */
+ terminal->memory_below_frame = 0; /* We don't remember what scrolls
+ off the bottom. */
+
+#ifdef MULTI_KBOARD
+ /* We don't yet support separate terminals on W32, so don't try to share
+ keyboards between virtual terminals that are on the same physical
+ terminal like X does. */
+ terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+ init_kboard (terminal->kboard);
+ terminal->kboard->next_kboard = all_kboards;
+ all_kboards = terminal->kboard;
+ /* Don't let the initial kboard remain current longer than necessary.
+ That would cause problems if a file loaded on startup tries to
+ prompt in the mini-buffer. */
+ if (current_kboard == initial_kboard)
+ current_kboard = terminal->kboard;
+ terminal->kboard->reference_count++;
+#endif
+
+ return terminal;
+}
+
+static void
+x_delete_terminal (struct terminal *terminal)
+{
+ struct w32_display_info *dpyinfo = terminal->display_info.w32;
+ int i;
+
+ /* Protect against recursive calls. Fdelete_frame in
+ delete_terminal calls us back when it deletes our last frame. */
+ if (!terminal->name)
+ return;
+
+ BLOCK_INPUT;
+ /* Free the fonts in the font table. */
+ for (i = 0; i < dpyinfo->n_fonts; i++)
+ if (dpyinfo->font_table[i].name)
+ {
+ DeleteObject (((XFontStruct*)(dpyinfo->font_table[i].font))->hfont);
+ }
+
+ x_delete_display (dpyinfo);
+ UNBLOCK_INPUT;
+}
+
struct w32_display_info *
w32_term_init (display_name, xrm_option, resource_name)
Lisp_Object display_name;
@@ -6190,6 +6357,7 @@ w32_term_init (display_name, xrm_option, resource_name)
char *resource_name;
{
struct w32_display_info *dpyinfo;
+ struct terminal *terminal;
HDC hdc;
BLOCK_INPUT;
@@ -6203,6 +6371,12 @@ w32_term_init (display_name, xrm_option, resource_name)
w32_initialize_display_info (display_name);
dpyinfo = &one_w32_display_info;
+ terminal = w32_create_terminal (dpyinfo);
+
+ /* Set the name of the terminal. */
+ terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+ strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+ terminal->name[SBYTES (display_name)] = 0;
dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL;
@@ -6232,6 +6406,9 @@ w32_term_init (display_name, xrm_option, resource_name)
w32_defined_color (0, "black", &color, 1);
}
+ /* Add the default keyboard. */
+ add_keyboard_wait_descriptor (0);
+
/* Create Fringe Bitmaps and store them for later use.
On W32, bitmaps are all unsigned short, as Windows requires
@@ -6239,7 +6416,7 @@ w32_term_init (display_name, xrm_option, resource_name)
horizontally reflected compared to how they appear on X, so we
need to bitswap and convert to unsigned shorts before creating
the bitmaps. */
- w32_init_fringe ();
+ w32_init_fringe (terminal->rif);
#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
@@ -6263,7 +6440,6 @@ w32_term_init (display_name, xrm_option, resource_name)
}
/* Get rid of display DPYINFO, assuming all frames are already gone. */
-
void
x_delete_display (dpyinfo)
struct w32_display_info *dpyinfo;
@@ -6314,73 +6490,9 @@ x_delete_display (dpyinfo)
DWORD WINAPI w32_msg_worker (void * arg);
-void
-x_flush (struct frame * f)
-{ /* Nothing to do */ }
-
-extern frame_parm_handler w32_frame_parm_handlers[];
-
-static struct redisplay_interface w32_redisplay_interface =
-{
- w32_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,
- 0, /* flush_display_optional */
- x_clear_window_mouse_face,
- w32_get_glyph_overhangs,
- x_fix_overlapping_area,
- w32_draw_fringe_bitmap,
- w32_define_fringe_bitmap,
- w32_destroy_fringe_bitmap,
- w32_per_char_metric,
- w32_encode_char,
- NULL, /* w32_compute_glyph_string_overhangs */
- x_draw_glyph_string,
- w32_define_frame_cursor,
- w32_clear_frame_area,
- w32_draw_window_cursor,
- w32_draw_vertical_window_border,
- w32_shift_glyphs_for_insert
-};
-
-void
+static void
w32_initialize ()
{
- rif = &w32_redisplay_interface;
-
- /* MSVC does not type K&R functions with no arguments correctly, and
- so we must explicitly cast them. */
- clear_frame_hook = (void (*)(void)) x_clear_frame;
- ring_bell_hook = (void (*)(void)) w32_ring_bell;
- update_begin_hook = x_update_begin;
- update_end_hook = x_update_end;
-
- read_socket_hook = w32_read_socket;
-
- frame_up_to_date_hook = w32_frame_up_to_date;
-
- mouse_position_hook = w32_mouse_position;
- frame_rehighlight_hook = w32_frame_rehighlight;
- frame_raise_lower_hook = w32_frame_raise_lower;
- set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
- condemn_scroll_bars_hook = w32_condemn_scroll_bars;
- redeem_scroll_bar_hook = w32_redeem_scroll_bar;
- judge_scroll_bars_hook = w32_judge_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;
w32_system_caret_hwnd = NULL;