/* Graphical user interface functions for the Microsoft W32 API.
- Copyright (C) 1989, 1992, 93, 94, 95, 96, 97, 98, 99, 2000, 01, 04
- Free Software Foundation, Inc.
+ Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
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, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
/* Added by Kevin Gallo */
extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));
extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));
extern void w32_free_menu_strings P_ ((HWND));
+extern XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, int));
extern int quit_char;
over text or in the modeline. */
Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
-Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape, Vx_hand_shape;
+Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape;
/* The shape when over mouse-sensitive text. */
TrackMouseEvent_Proc track_mouse_event_fn = NULL;
ClipboardSequence_Proc clipboard_sequence_fn = NULL;
+extern AppendMenuW_Proc unicode_append_menu;
/* W95 mousewheel handler */
unsigned int msh_mousewheel = 0;
CHECK_LIVE_FRAME (frame);
f = XFRAME (frame);
if (! FRAME_W32_P (f))
- error ("non-w32 frame used");
+ error ("Non-W32 frame used");
return f;
}
CHECK_LIVE_FRAME (frame);
f = XFRAME (frame);
if (! FRAME_W32_P (f))
- error ("non-w32 frame used");
+ error ("Non-W32 frame used");
return FRAME_W32_DISPLAY_INFO (f);
}
}
}
\f
-BOOL my_show_window P_ ((struct frame *, HWND, int));
-void my_set_window_pos P_ ((HWND, HWND, int, int, int, int, UINT));
static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
+static void my_create_window P_ ((struct frame *));
+static void my_create_tip_window P_ ((struct frame *));
/* TODO: Native Input Method support; see x_create_im. */
void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE);
if (title)
{
- GetTextExtentPoint32 (hdc, title, strlen (title), &size);
+ if (unicode_append_menu)
+ GetTextExtentPoint32W (hdc, (WCHAR *) title,
+ wcslen ((WCHAR *) title),
+ &size);
+ else
+ GetTextExtentPoint32 (hdc, title, strlen (title), &size);
+
pMis->itemWidth = size.cx;
if (pMis->itemHeight < size.cy)
pMis->itemHeight = size.cy;
menu_font = CreateFontIndirect (&menu_logfont);
old_font = SelectObject (hdc, menu_font);
- /* Always draw title as if not selected. */
- ExtTextOut (hdc,
- pDis->rcItem.left
- + GetSystemMetrics (SM_CXMENUCHECK),
- pDis->rcItem.top,
- ETO_OPAQUE, &pDis->rcItem,
- title, strlen (title), NULL);
+ /* Always draw title as if not selected. */
+ if (unicode_append_menu)
+ ExtTextOutW (hdc,
+ pDis->rcItem.left
+ + GetSystemMetrics (SM_CXMENUCHECK),
+ pDis->rcItem.top,
+ ETO_OPAQUE, &pDis->rcItem,
+ (WCHAR *) title,
+ wcslen ((WCHAR *) title), NULL);
+ else
+ ExtTextOut (hdc,
+ pDis->rcItem.left
+ + GetSystemMetrics (SM_CXMENUCHECK),
+ pDis->rcItem.top,
+ ETO_OPAQUE, &pDis->rcItem,
+ title, strlen (title), NULL);
SelectObject (hdc, old_font);
DeleteObject (menu_font);
return 0;
}
-void
+static void
my_create_window (f)
struct frame * f;
{
indirectly via the Window thread, as we do not need to process Window
messages for the tooltip. Creating tooltips indirectly also creates
deadlocks when tooltips are created for menu items. */
-void
+static void
my_create_tip_window (f)
struct frame *f;
{
/* Fill out details in lf according to the font that was
actually loaded. */
lf.lfHeight = font->tm.tmInternalLeading - font->tm.tmHeight;
- lf.lfWidth = font->tm.tmAveCharWidth;
+ lf.lfWidth = font->tm.tmMaxCharWidth;
lf.lfWeight = font->tm.tmWeight;
lf.lfItalic = font->tm.tmItalic;
lf.lfCharSet = font->tm.tmCharSet;
fontp->name = (char *) xmalloc (strlen (fontname) + 1);
bcopy (fontname, fontp->name, strlen (fontname) + 1);
+ if (lf.lfPitchAndFamily == FIXED_PITCH)
+ {
+ /* Fixed width font. */
+ fontp->average_width = fontp->space_width = FONT_WIDTH (font);
+ }
+ else
+ {
+ wchar_t space = 32;
+ XCharStruct* pcm;
+ pcm = w32_per_char_metric (font, &space, ANSI_FONT);
+ if (pcm)
+ fontp->space_width = pcm->width;
+ else
+ fontp->space_width = FONT_WIDTH (font);
+
+ fontp->average_width = font->tm.tmAveCharWidth;
+ }
+
charset = xlfd_charset_of_font (fontname);
/* Cache the W32 codepage for a font. This makes w32_encode_char
{
Lisp_Object bdf_fonts;
struct font_info *retval = NULL;
+ struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
bdf_fonts = w32_list_bdf_fonts (build_string (fontname), 1);
{
char *bdf_name, *bdf_file;
Lisp_Object bdf_pair;
+ int i;
bdf_name = SDATA (XCAR (bdf_fonts));
bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist);
bdf_file = SDATA (XCDR (bdf_pair));
+ // If the font is already loaded, do not load it again.
+ for (i = 0; i < dpyinfo->n_fonts; i++)
+ {
+ if ((dpyinfo->font_table[i].name
+ && !strcmp (dpyinfo->font_table[i].name, bdf_name))
+ || (dpyinfo->font_table[i].full_name
+ && !strcmp (dpyinfo->font_table[i].full_name, bdf_name)))
+ return dpyinfo->font_table + i;
+ }
+
retval = w32_load_bdf_font (f, bdf_name, size, bdf_file);
bdf_fonts = XCDR (bdf_fonts);
setup_coding_system
(Fcheck_coding_system (Vlocale_coding_system), &coding);
coding.src_multibyte = 1;
- coding.dst_multibyte = 1;
+ coding.dst_multibyte = 0;
/* Need to set COMPOSITION_DISABLED, otherwise Emacs crashes in
encode_coding_iso2022 trying to dereference a null pointer. */
coding.composing = COMPOSITION_DISABLED;
char * fontname;
char * pattern;
{
- char *regex = alloca (strlen (pattern) * 2 + 3);
- char *font_name_copy = alloca (strlen (fontname) + 1);
char *ptr;
+ char *font_name_copy;
+ char *regex = alloca (strlen (pattern) * 2 + 3);
- /* Copy fontname so we can modify it during comparison. */
+ font_name_copy = alloca (strlen (fontname) + 1);
strcpy (font_name_copy, fontname);
ptr = regex;
return FALSE;
}
- return (fast_c_string_match_ignore_case (build_string (regex),
- font_name_copy) >= 0);
+ return (fast_string_match_ignore_case (build_string (regex),
+ build_string(font_name_copy)) >= 0);
}
/* Callback functions, and a structure holding info they need, for
}
DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
- doc: /* Returns the vendor ID string of the W32 system (Microsoft).
+ doc: /* Returns the "vendor ID" string of the W32 system (Microsoft).
The optional argument DISPLAY specifies which display to ask about.
DISPLAY should be either a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
doc: /* Returns the version numbers of the server of DISPLAY.
The value is a list of three integers: the major and minor
-version numbers, and the vendor-specific release
+version numbers of the X Protocol in use, and the distributor-specific release
number. See also the function `x-server-vendor'.
The optional argument DISPLAY specifies which display to ask about.
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
- try_window (FRAME_ROOT_WINDOW (f), pos);
+ try_window (FRAME_ROOT_WINDOW (f), pos, 0);
/* Compute width and height of the tooltip. */
width = height = 0;
return 0;
}
-DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
+/* Since we compile with _WIN32_WINNT set to 0x0400 (for NT4 compatibility)
+ we end up with the old file dialogs. Define a big enough struct for the
+ new dialog to trick GetOpenFileName into giving us the new dialogs on
+ Windows 2000 and XP. */
+typedef struct
+{
+ OPENFILENAME real_details;
+ void * pReserved;
+ DWORD dwReserved;
+ DWORD FlagsEx;
+} NEWOPENFILENAME;
+
+
+DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
doc: /* Read file name, prompting with PROMPT in directory DIR.
Use a file selection dialog.
Select DEFAULT-FILENAME in the dialog's file selection box, if
-specified. Ensure that file exists if MUSTMATCH is non-nil. */)
- (prompt, dir, default_filename, mustmatch)
- Lisp_Object prompt, dir, default_filename, mustmatch;
+specified. Ensure that file exists if MUSTMATCH is non-nil.
+If ONLY-DIR-P is non-nil, the user can only select directories. */)
+ (prompt, dir, default_filename, mustmatch, only_dir_p)
+ Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
{
struct frame *f = SELECTED_FRAME ();
Lisp_Object file = Qnil;
int count = SPECPDL_INDEX ();
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
char filename[MAX_PATH + 1];
char init_dir[MAX_PATH + 1];
int default_filter_index = 1; /* 1: All Files, 2: Directories only */
- GCPRO5 (prompt, dir, default_filename, mustmatch, file);
+ GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
CHECK_STRING (prompt);
CHECK_STRING (dir);
filename[0] = '\0';
{
- OPENFILENAME file_details;
+ NEWOPENFILENAME new_file_details;
+ BOOL file_opened = FALSE;
+ OPENFILENAME * file_details = &new_file_details.real_details;
/* Prevent redisplay. */
specbind (Qinhibit_redisplay, Qt);
BLOCK_INPUT;
- bzero (&file_details, sizeof (file_details));
- file_details.lStructSize = sizeof (file_details);
- file_details.hwndOwner = FRAME_W32_WINDOW (f);
+ bzero (&new_file_details, sizeof (new_file_details));
+ /* Apparently NT4 crashes if you give it an unexpected size.
+ I'm not sure about Windows 9x, so play it safe. */
+ if (w32_major_version > 4 && w32_major_version < 95)
+ file_details->lStructSize = sizeof (new_file_details);
+ else
+ file_details->lStructSize = sizeof (file_details);
+
+ file_details->hwndOwner = FRAME_W32_WINDOW (f);
/* Undocumented Bug in Common File Dialog:
If a filter is not specified, shell links are not resolved. */
- file_details.lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0";
- file_details.lpstrFile = filename;
- file_details.nMaxFile = sizeof (filename);
- file_details.lpstrInitialDir = init_dir;
- file_details.lpstrTitle = SDATA (prompt);
-
- /* If prompt starts with Dired, default to directories only. */
- /* A bit hacky, but there doesn't seem to be a better way to
- DTRT for dired. */
- if (strncmp (file_details.lpstrTitle, "Dired", 5) == 0)
+ file_details->lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0";
+ file_details->lpstrFile = filename;
+ file_details->nMaxFile = sizeof (filename);
+ file_details->lpstrInitialDir = init_dir;
+ file_details->lpstrTitle = SDATA (prompt);
+
+ if (! NILP (only_dir_p))
default_filter_index = 2;
- file_details.nFilterIndex = default_filter_index;
+ file_details->nFilterIndex = default_filter_index;
- file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
+ file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
| OFN_EXPLORER | OFN_ENABLEHOOK);
if (!NILP (mustmatch))
- file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
+ {
+ /* Require that the path to the parent directory exists. */
+ file_details->Flags |= OFN_PATHMUSTEXIST;
+ /* If we are looking for a file, require that it exists. */
+ if (NILP (only_dir_p))
+ file_details->Flags |= OFN_FILEMUSTEXIST;
+ }
+
+ file_details->lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
- file_details.lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
+ file_opened = GetOpenFileName (file_details);
- if (GetOpenFileName (&file_details))
+ UNBLOCK_INPUT;
+
+ if (file_opened)
{
dostounix_filename (filename);
- if (file_details.nFilterIndex == 2)
+
+ if (file_details->nFilterIndex == 2)
{
/* "Directories" selected - strip dummy file name. */
char * last = strrchr (filename, '/');
dir, mustmatch, dir, Qfile_name_history,
default_filename, Qnil);
- UNBLOCK_INPUT;
file = unbind_to (count, file);
}
DEFVAR_BOOL ("w32-strict-painting",
&w32_strict_painting,
doc: /* Non-nil means use strict rules for repainting frames.
-Set this to nil to get the old behaviour for repainting; this should
+Set this to nil to get the old behavior for repainting; this should
only be necessary if the default setting causes problems. */);
w32_strict_painting = 1;
staticpro (&Qw32_charset_ansi);
Qw32_charset_ansi = intern ("w32-charset-ansi");
staticpro (&Qw32_charset_symbol);
+ Qw32_charset_default = intern ("w32-charset-default");
+ staticpro (&Qw32_charset_default);
Qw32_charset_symbol = intern ("w32-charset-symbol");
staticpro (&Qw32_charset_shiftjis);
Qw32_charset_shiftjis = intern ("w32-charset-shiftjis");
#undef abort
+void w32_abort (void) NO_RETURN;
+
void
w32_abort()
{
int button;
button = MessageBox (NULL,
"A fatal error has occurred!\n\n"
- "Select Abort to exit, Retry to debug, Ignore to continue",
+ "Would you like to attach a debugger?\n\n"
+ "Select YES to debug, NO to abort Emacs",
"Emacs Abort Dialog",
MB_ICONEXCLAMATION | MB_TASKMODAL
- | MB_SETFOREGROUND | MB_ABORTRETRYIGNORE);
+ | MB_SETFOREGROUND | MB_YESNO);
switch (button)
{
- case IDRETRY:
+ case IDYES:
DebugBreak ();
- break;
- case IDIGNORE:
- break;
- case IDABORT:
+ exit (2); /* tell the compiler we will never return */
+ case IDNO:
default:
abort ();
break;