Commit 52cf03a1 authored by Geoff Voelker's avatar Geoff Voelker

(Vwindow_system): Declared.

(win32_fill_rect, dumpglyphs, do_line_dance, x_draw_box):
Use Get/ReleaseFrameDC.

(pixel_to_glyph_coords): Support tty mode.
(w32_read_socket): Explicitly use FALSE.
Handle WM_PALLETTECHANGED event.
(parse_button): Handle mouse button emulation.

(my_show_window, my_set_window_pos): New functions.
(x_set_offset, x_set_window_size, x_raise_frame, x_lower_frame):
Use my_set_window_pos.
(x_make_frame_visible, x_iconify_frame): Use my_show_window.

(x_draw_box): Don't trim right and bottom.
(x_make_frame_visible): Don't invoke SetForgroundWindow.

(win32_term_init): Use GetDC directly.  Initialize palette
and win32_num_mouse_buttons.
(win32_update_begin): Regenerate palette if necessary.
(x_delete_display): Free palette.

(win32_initialize) [ATTACH_THREADS]: Only AttachThreadInput if
conditional is defined.
parent 69cddef0
......@@ -15,8 +15,7 @@ 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, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Added by Kevin Gallo */
......@@ -50,6 +49,8 @@ Boston, MA 02111-1307, USA. */
extern void free_frame_menubar ();
extern Lisp_Object Vwindow_system;
#define x_any_window_to_frame x_window_to_frame
#define x_top_window_to_frame x_window_to_frame
......@@ -98,6 +99,10 @@ HANDLE hMainThread = NULL;
static FRAME_PTR last_mouse_frame;
static RECT last_mouse_glyph;
Lisp_Object Vwin32_num_mouse_buttons;
Lisp_Object Vwin32_swap_mouse_buttons;
/* The scroll bar in which the last motion event occurred.
If the last motion event occurred in a scroll bar, we set this
......@@ -195,7 +200,6 @@ win32_fill_rect (f, _hdc, pix, lprect)
{
HDC hdc;
HBRUSH hb;
HANDLE oldobj;
RECT rect;
if (_hdc)
......@@ -203,18 +207,15 @@ win32_fill_rect (f, _hdc, pix, lprect)
else
{
if (!f) return;
hdc = my_get_dc (FRAME_WIN32_WINDOW (f));
hdc = get_frame_dc (f);
}
hb = CreateSolidBrush (pix);
oldobj = SelectObject (hdc, hb);
FillRect (hdc, lprect, hb);
SelectObject (hdc, oldobj);
DeleteObject (hb);
if (!_hdc)
ReleaseDC (FRAME_WIN32_WINDOW (f), hdc);
release_frame_dc (f, hdc);
}
void
......@@ -222,7 +223,7 @@ win32_clear_window (f)
FRAME_PTR f;
{
RECT rect;
GetClientRect (FRAME_WIN32_WINDOW (f), &rect);
win32_clear_rect (f, NULL, &rect);
}
......@@ -249,6 +250,14 @@ win32_update_begin (f)
BLOCK_INPUT;
/* Regenerate display palette before drawing if list of requested
colors has changed. */
if (FRAME_WIN32_DISPLAY_INFO (f)->regen_palette)
{
win32_regenerate_palette (f);
FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = FALSE;
}
if (f == FRAME_WIN32_DISPLAY_INFO (f)->mouse_face_mouse_frame)
{
/* Don't do highlighting for mouse motion during the update. */
......@@ -418,7 +427,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
int orig_left = left;
HDC hdc;
hdc = my_get_dc (window);
hdc = get_frame_dc (f);
while (n > 0)
{
......@@ -571,7 +580,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
}
}
ReleaseDC (window, hdc);
release_frame_dc (f, hdc);
}
......@@ -828,7 +837,7 @@ do_line_dance ()
x_display_cursor (updating_frame, 0);
hdc = my_get_dc (FRAME_WIN32_WINDOW (f));
hdc = get_frame_dc (f);
for (i = 0; i < ht; ++i)
if (line_dance[i] != -1 && (distance = line_dance[i]-i) > 0)
......@@ -862,7 +871,7 @@ do_line_dance ()
i = j+1;
}
ReleaseDC (FRAME_WIN32_WINDOW (f), hdc);
release_frame_dc (f, hdc);
for (i = 0; i < ht; ++i)
if (line_dance[i] == -1)
......@@ -1098,6 +1107,14 @@ pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
RECT *bounds;
int noclip;
{
/* Support tty mode: if Vwindow_system is nil, behave correctly. */
if (NILP (Vwindow_system))
{
*x = pix_x;
*y = pix_y;
return;
}
/* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
even for negative values. */
if (pix_x < 0)
......@@ -1139,6 +1156,14 @@ glyph_to_pixel_coords (f, x, y, pix_x, pix_y)
register int x, y;
register int *pix_x, *pix_y;
{
/* Support tty mode: if Vwindow_system is nil, behave correctly. */
if (NILP (Vwindow_system))
{
*pix_x = x;
*pix_y = y;
return;
}
*pix_x = CHAR_TO_PIXEL_COL (f, x);
*pix_y = CHAR_TO_PIXEL_ROW (f, y);
}
......@@ -1163,19 +1188,31 @@ parse_button (message, pbutton, pup)
up = 1;
break;
case WM_MBUTTONDOWN:
button = 1;
if (NILP (Vwin32_swap_mouse_buttons))
button = 1;
else
button = 2;
up = 0;
break;
case WM_MBUTTONUP:
button = 1;
if (NILP (Vwin32_swap_mouse_buttons))
button = 1;
else
button = 2;
up = 1;
break;
case WM_RBUTTONDOWN:
button = 2;
if (NILP (Vwin32_swap_mouse_buttons))
button = 2;
else
button = 1;
up = 0;
break;
case WM_RBUTTONUP:
button = 2;
if (NILP (Vwin32_swap_mouse_buttons))
button = 2;
else
button = 1;
up = 1;
break;
default:
......@@ -1770,6 +1807,36 @@ my_create_scrollbar (f, bar)
return ((HWND) msg.wParam);
}
//#define ATTACH_THREADS
void
my_show_window (HWND hwnd, int how)
{
#ifndef ATTACH_THREADS
SendMessage (hwnd, WM_EMACS_SHOWWINDOW, (WPARAM) how, 0);
#else
ShowWindow (hwnd , how);
#endif
}
void
my_set_window_pos (HWND hwnd, HWND hwndAfter,
int x, int y, int cx, int cy, int flags)
{
#ifndef ATTACH_THREADS
Win32WindowPos pos;
pos.hwndAfter = hwndAfter;
pos.x = x;
pos.y = y;
pos.cx = cx;
pos.cy = cy;
pos.flags = flags;
SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
#else
SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
#endif
}
void
my_destroy_window (f, hwnd)
struct frame * f;
......@@ -1877,6 +1944,7 @@ x_scroll_bar_move (bar, top, left, width, height)
MoveWindow (w, left, top, width, height, TRUE);
SetScrollRange (w, SB_CTL, 0, height, FALSE);
InvalidateRect (w, NULL, FALSE);
XSETINT (bar->left, left);
XSETINT (bar->top, top);
......@@ -2069,7 +2137,7 @@ win32_judge_scroll_bars (f)
This may be called from a signal handler, so we have to ignore GC
mark bits. */
static void
static int
x_scroll_bar_handle_click (bar, msg, emacs_event)
struct scroll_bar *bar;
Win32Msg *msg;
......@@ -2078,12 +2146,10 @@ x_scroll_bar_handle_click (bar, msg, emacs_event)
if (! GC_WINDOWP (bar->window))
abort ();
emacs_event->kind = scroll_bar_click;
emacs_event->kind = win32_scroll_bar_click;
emacs_event->code = 0;
emacs_event->modifiers = (msg->dwModifiers
| ((LOWORD (msg->msg.wParam) == SB_ENDSCROLL)
? up_modifier
: down_modifier));
/* not really meaningful to distinguish up/down */
emacs_event->modifiers = msg->dwModifiers;
emacs_event->frame_or_window = bar->window;
emacs_event->timestamp = msg->msg.time;
......@@ -2096,18 +2162,17 @@ x_scroll_bar_handle_click (bar, msg, emacs_event)
switch (LOWORD (msg->msg.wParam))
{
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
emacs_event->part = scroll_bar_handle;
if (VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height)) <= 0xffff)
y = HIWORD (msg->msg.wParam);
break;
case SB_LINEDOWN:
emacs_event->part = scroll_bar_handle;
emacs_event->part = scroll_bar_down_arrow;
if (y < top_range) y++;
break;
case SB_LINEUP:
emacs_event->part = scroll_bar_handle;
emacs_event->part = scroll_bar_up_arrow;
if (y) y--;
break;
case SB_PAGEUP:
......@@ -2124,17 +2189,20 @@ x_scroll_bar_handle_click (bar, msg, emacs_event)
emacs_event->part = scroll_bar_handle;
y = top_range;
break;
case SB_ENDSCROLL:
case SB_THUMBPOSITION:
emacs_event->part = scroll_bar_handle;
x_scroll_bar_set_handle (bar, y , y, 0);
break;
case SB_ENDSCROLL:
default:
emacs_event->part = scroll_bar_handle;
break;
return FALSE;
}
x_scroll_bar_set_handle (bar, y , y, 0);
XSETINT (emacs_event->x, y);
XSETINT (emacs_event->y, top_range);
return TRUE;
}
}
......@@ -2196,13 +2264,34 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
x_scroll_bar_clear (f)
FRAME_PTR f;
{
#if 0
Lisp_Object bar;
for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
bar = XSCROLL_BAR (bar)->next)
UpdateWindow (SCROLL_BAR_WIN32_WINDOW (XSCROLL_BAR (bar)));
#endif
{
HWND window = SCROLL_BAR_WIN32_WINDOW (XSCROLL_BAR (bar));
HDC hdc = GetDC (window);
RECT rect;
GetClientRect (window, &rect);
select_palette (f, hdc);
win32_clear_rect (f, hdc, &rect);
deselect_palette (f, hdc);
}
}
show_scroll_bars (f, how)
FRAME_PTR f;
int how;
{
Lisp_Object bar;
for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
bar = XSCROLL_BAR (bar)->next)
{
HWND window = SCROLL_BAR_WIN32_WINDOW (XSCROLL_BAR (bar));
my_show_window (window, how);
}
}
......@@ -2303,7 +2392,7 @@ w32_read_socket (sd, bufp, numchars, waitp, expected)
if (numchars <= 0)
abort (); /* Don't think this happens. */
while (get_next_msg (&msg, 0))
while (get_next_msg (&msg, FALSE))
{
switch (msg.msg.message)
{
......@@ -2339,6 +2428,12 @@ w32_read_socket (sd, bufp, numchars, waitp, expected)
}
break;
case WM_PALETTECHANGED:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
/* Realize palette - will force update if needed. */
release_frame_dc (f, get_frame_dc (f));
break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
......@@ -2350,7 +2445,7 @@ w32_read_socket (sd, bufp, numchars, waitp, expected)
temp_buffer[temp_index++] = msg.msg.wParam;
bufp->kind = non_ascii_keystroke;
bufp->code = msg.msg.wParam;
bufp->modifiers = win32_kbd_mods_to_emacs (msg.dwModifiers);
bufp->modifiers = win32_kbd_mods_to_emacs (msg.dwModifiers);
XSETFRAME (bufp->frame_or_window, f);
bufp->timestamp = msg.msg.time;
bufp++;
......@@ -2462,10 +2557,12 @@ w32_read_socket (sd, bufp, numchars, waitp, expected)
if (bar && numchars >= 1)
{
x_scroll_bar_handle_click (bar, &msg, bufp);
bufp++;
count++;
numchars--;
if (x_scroll_bar_handle_click (bar, &msg, bufp))
{
bufp++;
count++;
numchars--;
}
}
}
......@@ -2684,25 +2781,19 @@ x_draw_box (f)
HBRUSH hb;
HDC hdc;
hdc = my_get_dc (FRAME_WIN32_WINDOW (f));
hdc = get_frame_dc (f);
hb = CreateSolidBrush (f->output_data.win32->cursor_pixel);
rect.left = CHAR_TO_PIXEL_COL (f, curs_x);
rect.top = CHAR_TO_PIXEL_ROW (f, curs_y);
rect.right = rect.left + FONT_WIDTH (f->output_data.win32->font) - 1;
rect.bottom = rect.top + f->output_data.win32->line_height - 1;
/* rect.left++; */
/* rect.top++; */
rect.right--;
rect.bottom--;
rect.right = rect.left + FONT_WIDTH (f->output_data.win32->font);
rect.bottom = rect.top + f->output_data.win32->line_height;
FrameRect (hdc, &rect, hb);
DeleteObject (hb);
ReleaseDC (FRAME_WIN32_WINDOW (f), hdc);
release_frame_dc (f, hdc);
}
/* Clear the cursor of frame F to background color,
......@@ -3130,11 +3221,11 @@ x_set_offset (f, xoff, yoff, change_gravity)
modified_top += f->output_data.win32->border_width;
}
SetWindowPos (FRAME_WIN32_WINDOW (f),
NULL,
modified_left, modified_top,
0,0,
SWP_NOZORDER | SWP_NOSIZE);
my_set_window_pos (FRAME_WIN32_WINDOW (f),
NULL,
modified_left, modified_top,
0,0,
SWP_NOZORDER | SWP_NOSIZE);
UNBLOCK_INPUT;
}
......@@ -3177,12 +3268,12 @@ x_set_window_size (f, change_gravity, cols, rows)
/* All windows have an extra pixel */
SetWindowPos (FRAME_WIN32_WINDOW (f),
NULL,
0, 0,
rect.right - rect.left + 1,
rect.bottom - rect.top + 1,
SWP_NOZORDER | SWP_NOMOVE);
my_set_window_pos (FRAME_WIN32_WINDOW (f),
NULL,
0, 0,
rect.right - rect.left + 1,
rect.bottom - rect.top + 1,
SWP_NOZORDER | SWP_NOMOVE);
}
/* Now, strictly speaking, we can't be sure that this is accurate,
......@@ -3272,13 +3363,13 @@ x_unfocus_frame (f)
x_raise_frame (f)
struct frame *f;
{
if (f->async_visible)
// if (f->async_visible)
{
BLOCK_INPUT;
SetWindowPos (FRAME_WIN32_WINDOW (f),
HWND_TOP,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE);
my_set_window_pos (FRAME_WIN32_WINDOW (f),
HWND_TOP,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE);
UNBLOCK_INPUT;
}
}
......@@ -3288,13 +3379,13 @@ x_raise_frame (f)
x_lower_frame (f)
struct frame *f;
{
if (f->async_visible)
// if (f->async_visible)
{
BLOCK_INPUT;
SetWindowPos (FRAME_WIN32_WINDOW (f),
HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE);
my_set_window_pos (FRAME_WIN32_WINDOW (f),
HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE);
UNBLOCK_INPUT;
}
}
......@@ -3331,14 +3422,15 @@ x_make_frame_visible (f)
if we get to x_make_frame_visible a second time
before the window gets really visible. */
if (! FRAME_ICONIFIED_P (f)
&& ! f->output_data.win32->asked_for_visible)
{
x_set_offset (f, f->output_data.win32->left_pos,
f->output_data.win32->top_pos, 0);
}
&& ! f->output_data.win32->asked_for_visible)
{
x_set_offset (f, f->output_data.win32->left_pos, f->output_data.win32->top_pos, 0);
// SetForegroundWindow (FRAME_WIN32_WINDOW (f));
}
f->output_data.win32->asked_for_visible = 1;
ShowWindow (FRAME_WIN32_WINDOW (f), SW_SHOW);
my_show_window (FRAME_WIN32_WINDOW (f), SW_SHOWNORMAL);
}
/* Synchronize to ensure Emacs knows the frame is visible
......@@ -3401,7 +3493,7 @@ x_make_frame_invisible (f)
BLOCK_INPUT;
ShowWindow (FRAME_WIN32_WINDOW (f), SW_HIDE);
my_show_window (FRAME_WIN32_WINDOW (f), SW_HIDE);
/* We can't distinguish this from iconification
just by the event that we get from the server.
......@@ -3418,7 +3510,8 @@ x_make_frame_invisible (f)
/* Change window state from mapped to iconified. */
void x_iconify_frame (f)
void
x_iconify_frame (f)
struct frame *f;
{
int result;
......@@ -3432,7 +3525,9 @@ void x_iconify_frame (f)
BLOCK_INPUT;
ShowWindow (FRAME_WIN32_WINDOW (f), SW_SHOWMINIMIZED);
my_show_window (FRAME_WIN32_WINDOW (f), SW_SHOWMINIMIZED);
/* The frame doesn't seem to be lowered automatically. */
x_lower_frame (f);
f->async_iconified = 1;
......@@ -3597,7 +3692,7 @@ win32_term_init (display_name, xrm_option, resource_name)
all versions. */
dpyinfo->xrdb = xrdb;
#endif
hdc = my_get_dc (GetDesktopWindow ());
hdc = GetDC (GetDesktopWindow ());
dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
......@@ -3606,6 +3701,7 @@ win32_term_init (display_name, xrm_option, resource_name)
dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
dpyinfo->height_in = GetDeviceCaps (hdc, LOGPIXELSX);
dpyinfo->width_in = GetDeviceCaps (hdc, LOGPIXELSY);
dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
dpyinfo->grabbed = 0;
dpyinfo->reference_count = 0;
dpyinfo->n_fonts = 0;
......@@ -3627,6 +3723,18 @@ win32_term_init (display_name, xrm_option, resource_name)
ReleaseDC (GetDesktopWindow (), hdc);
/* Determine if there is a middle mouse button, to allow parse_button
to decide whether right mouse events should be mouse-2 or
mouse-3. */
XSETINT (Vwin32_num_mouse_buttons, GetSystemMetrics (SM_CMOUSEBUTTONS));
/* initialise palette with white and black */
{
COLORREF color;
defined_color (0, "white", &color, 1);
defined_color (0, "black", &color, 1);
}
#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
#ifdef F_SETOWN_SOCK_NEG
......@@ -3676,6 +3784,21 @@ x_delete_display (dpyinfo)
}
}
/* free palette table */
{
struct win32_palette_entry * plist;
plist = dpyinfo->color_list;
while (plist)
{
struct win32_palette_entry * pentry = plist;
plist = plist->next;
xfree(pentry);
}
dpyinfo->color_list = NULL;
if (dpyinfo->palette)
DeleteObject(dpyinfo->palette);
}
xfree (dpyinfo->font_table);
xfree (dpyinfo->win32_id_name);
}
......@@ -3744,8 +3867,17 @@ win32_initialize ()
GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
}
/* It is desirable that mainThread should have the same notion of
focus window and active window as winThread. Unfortunately, the
following call to AttachThreadInput, which should do precisely what
we need, causes major problems when Emacs is linked as a console
program. Unfortunately, we have good reasons for doing that, so
instead we need to send messages to winThread to make some API
calls for us (ones that affect, or depend on, the active/focus
window state. */
#ifdef ATTACH_THREADS
AttachThreadInput (dwMainThreadId, dwWinThreadId, TRUE);
#endif
}
void
......@@ -3759,4 +3891,15 @@ syms_of_win32term ()
staticpro (&Qvendor_specific_keysyms);
Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
DEFVAR_INT ("win32-num-mouse-buttons",
&Vwin32_num_mouse_buttons,
"Number of physical mouse buttons.");
Vwin32_num_mouse_buttons = Qnil;
DEFVAR_LISP ("win32-swap-mouse-buttons",
&Vwin32_swap_mouse_buttons,
"Swap the mapping of middle and right mouse buttons.\n\
When nil, middle button is mouse-2 and right button is mouse-3.");
Vwin32_swap_mouse_buttons = Qnil;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment