aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Voelker1996-05-03 18:39:41 +0000
committerGeoff Voelker1996-05-03 18:39:41 +0000
commit5ac45f986bc9ec2c7bc9e76bc0ac5df87a46bd62 (patch)
treebff9e16023554139fd1a55d4a399c7bd26854365
parentc2ccbd4304f754eae74decb1a2fe40327772e0ad (diff)
downloademacs-5ac45f986bc9ec2c7bc9e76bc0ac5df87a46bd62.tar.gz
emacs-5ac45f986bc9ec2c7bc9e76bc0ac5df87a46bd62.zip
(quit_char, Vwin32_enable_italics, Vwin32_enable_palette):
New variables. (syms_of_win32fns): Set up new lisp variables.
-rw-r--r--src/w32fns.c1051
1 files changed, 785 insertions, 266 deletions
diff --git a/src/w32fns.c b/src/w32fns.c
index 38f09bbf852..64258a6d51f 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA. */
41extern void abort (); 41extern void abort ();
42extern void free_frame_menubar (); 42extern void free_frame_menubar ();
43extern struct scroll_bar *x_window_to_scroll_bar (); 43extern struct scroll_bar *x_window_to_scroll_bar ();
44extern int quit_char;
44 45
45/* The colormap for converting color names to RGB values */ 46/* The colormap for converting color names to RGB values */
46Lisp_Object Vwin32_color_map; 47Lisp_Object Vwin32_color_map;
@@ -52,6 +53,17 @@ Lisp_Object Vwin32_pass_alt_to_system;
52 are passed on to Windows. */ 53 are passed on to Windows. */
53Lisp_Object Vwin32_pass_optional_keys_to_system; 54Lisp_Object Vwin32_pass_optional_keys_to_system;
54 55
56/* Switch to control whether we inhibit requests for italicised fonts (which
57 are synthesized, look ugly, and are trashed by cursor movement under NT). */
58Lisp_Object Vwin32_enable_italics;
59
60/* Enable palette management. */
61Lisp_Object Vwin32_enable_palette;
62
63/* Control how close left/right button down events must be to
64 be converted to a middle button down event. */
65Lisp_Object Vwin32_mouse_button_tolerance;
66
55/* The name we're using in resource queries. */ 67/* The name we're using in resource queries. */
56Lisp_Object Vx_resource_name; 68Lisp_Object Vx_resource_name;
57 69
@@ -139,6 +151,15 @@ Lisp_Object Quser_position;
139Lisp_Object Quser_size; 151Lisp_Object Quser_size;
140Lisp_Object Qdisplay; 152Lisp_Object Qdisplay;
141 153
154/* State variables for emulating a three button mouse. */
155#define LMOUSE 1
156#define MMOUSE 2
157#define RMOUSE 4
158
159static int button_state = 0;
160static Win32Msg saved_mouse_msg;
161static unsigned timer_id; /* non-zero when timer is active */
162
142/* The below are defined in frame.c. */ 163/* The below are defined in frame.c. */
143extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth; 164extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
144extern Lisp_Object Qunsplittable, Qmenu_bar_lines; 165extern Lisp_Object Qunsplittable, Qmenu_bar_lines;
@@ -147,6 +168,10 @@ extern Lisp_Object Vwindow_system_version;
147 168
148extern Lisp_Object last_mouse_scroll_bar; 169extern Lisp_Object last_mouse_scroll_bar;
149extern int last_mouse_scroll_bar_pos; 170extern int last_mouse_scroll_bar_pos;
171
172/* From win32term.c. */
173extern Lisp_Object Vwin32_num_mouse_buttons;
174
150Time last_mouse_movement_time; 175Time last_mouse_movement_time;
151 176
152 177
@@ -823,25 +848,90 @@ x_report_frame_params (f, alistptr)
823} 848}
824 849
825 850
826#if 0 851DEFUN ("win32-define-rgb-color", Fwin32_define_rgb_color, Swin32_define_rgb_color, 4, 4, 0,
827DEFUN ("win32-rgb", Fwin32_rgb, Swin32_rgb, 3, 3, 0, 852 "Convert RGB numbers to a windows color reference and associate with NAME (a string).\n\
828 "Convert RGB numbers to a windows color reference.") 853This adds or updates a named color to win32-color-map, making it available for use.\n\
829 (red, green, blue) 854The original entry's RGB ref is returned, or nil if the entry is new.")
830 Lisp_Object red, green, blue; 855 (red, green, blue, name)
856 Lisp_Object red, green, blue, name;
831{ 857{
832 Lisp_Object rgb; 858 Lisp_Object rgb;
859 Lisp_Object oldrgb = Qnil;
860 Lisp_Object entry;
861
862 CHECK_NUMBER (red, 0);
863 CHECK_NUMBER (green, 0);
864 CHECK_NUMBER (blue, 0);
865 CHECK_STRING (name, 0);
833 866
834 CHECK_NUMBER (red, 0); 867 XSET (rgb, Lisp_Int, RGB(XUINT (red), XUINT (green), XUINT (blue)));
835 CHECK_NUMBER (green, 0);
836 CHECK_NUMBER (blue, 0);
837 868
838 XSET (rgb, Lisp_Int, RGB(XUINT(red), XUINT(green), XUINT(blue))); 869 BLOCK_INPUT;
839 870
840 return (rgb); 871 /* replace existing entry in win32-color-map or add new entry. */
872 entry = Fassoc (name, Vwin32_color_map);
873 if (NILP (entry))
874 {
875 entry = Fcons (name, rgb);
876 Vwin32_color_map = Fcons (entry, Vwin32_color_map);
877 }
878 else
879 {
880 oldrgb = Fcdr (entry);
881 Fsetcdr (entry, rgb);
882 }
883
884 UNBLOCK_INPUT;
885
886 return (oldrgb);
841} 887}
842 888
889DEFUN ("win32-load-color-file", Fwin32_load_color_file, Swin32_load_color_file, 1, 1, 0,
890 "Create an alist of color entries from an external file (ie. rgb.txt).\n\
891Assign this value to win32-color-map to replace the existing color map.\n\
892\
893The file should define one named RGB color per line like so:\
894 R G B name\n\
895where R,G,B are numbers between 0 and 255 and name is an arbitrary string.")
896 (filename)
897 Lisp_Object filename;
898{
899 FILE *fp;
900 Lisp_Object cmap = Qnil;
901 Lisp_Object abspath;
902
903 CHECK_STRING (filename, 0);
904 abspath = Fexpand_file_name (filename, Qnil);
905
906 fp = fopen (XSTRING (filename)->data, "rt");
907 if (fp)
908 {
909 char buf[512];
910 int red, green, blue;
911 int num;
912
913 BLOCK_INPUT;
914
915 while (fgets (buf, sizeof (buf), fp) != NULL) {
916 if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
917 {
918 char *name = buf + num;
919 num = strlen (name) - 1;
920 if (name[num] == '\n')
921 name[num] = 0;
922 cmap = Fcons (Fcons (build_string (name),
923 make_number (RGB (red, green, blue))),
924 cmap);
925 }
926 }
927 fclose (fp);
928
929 UNBLOCK_INPUT;
930 }
931
932 return cmap;
933}
843 934
844#else
845/* The default colors for the win32 color map */ 935/* The default colors for the win32 color map */
846typedef struct colormap_t 936typedef struct colormap_t
847{ 937{
@@ -1115,7 +1205,6 @@ DEFUN ("win32-default-color-map", Fwin32_default_color_map, Swin32_default_color
1115 1205
1116 return (cmap); 1206 return (cmap);
1117} 1207}
1118#endif
1119 1208
1120Lisp_Object 1209Lisp_Object
1121win32_to_x_color (rgb) 1210win32_to_x_color (rgb)
@@ -1168,6 +1257,122 @@ x_to_win32_color (colorname)
1168 return ret; 1257 return ret;
1169} 1258}
1170 1259
1260
1261void
1262win32_regenerate_palette (FRAME_PTR f)
1263{
1264 struct win32_palette_entry * list;
1265 LOGPALETTE * log_palette;
1266 HPALETTE new_palette;
1267 int i;
1268
1269 /* don't bother trying to create palette if not supported */
1270 if (! FRAME_WIN32_DISPLAY_INFO (f)->has_palette)
1271 return;
1272
1273 log_palette = (LOGPALETTE *)
1274 alloca (sizeof (LOGPALETTE) +
1275 FRAME_WIN32_DISPLAY_INFO (f)->num_colors * sizeof (PALETTEENTRY));
1276 log_palette->palVersion = 0x300;
1277 log_palette->palNumEntries = FRAME_WIN32_DISPLAY_INFO (f)->num_colors;
1278
1279 list = FRAME_WIN32_DISPLAY_INFO (f)->color_list;
1280 for (i = 0;
1281 i < FRAME_WIN32_DISPLAY_INFO (f)->num_colors;
1282 i++, list = list->next)
1283 log_palette->palPalEntry[i] = list->entry;
1284
1285 new_palette = CreatePalette (log_palette);
1286
1287 enter_crit ();
1288
1289 if (FRAME_WIN32_DISPLAY_INFO (f)->palette)
1290 DeleteObject (FRAME_WIN32_DISPLAY_INFO (f)->palette);
1291 FRAME_WIN32_DISPLAY_INFO (f)->palette = new_palette;
1292
1293 /* Realize display palette and garbage all frames. */
1294 release_frame_dc (f, get_frame_dc (f));
1295
1296 leave_crit ();
1297}
1298
1299#define WIN32_COLOR(pe) RGB (pe.peRed, pe.peGreen, pe.peBlue)
1300#define SET_WIN32_COLOR(pe, color) \
1301 do \
1302 { \
1303 pe.peRed = GetRValue (color); \
1304 pe.peGreen = GetGValue (color); \
1305 pe.peBlue = GetBValue (color); \
1306 pe.peFlags = 0; \
1307 } while (0)
1308
1309#if 0
1310/* Keep these around in case we ever want to track color usage. */
1311void
1312win32_map_color (FRAME_PTR f, COLORREF color)
1313{
1314 struct win32_palette_entry * list = FRAME_WIN32_DISPLAY_INFO (f)->color_list;
1315
1316 if (NILP (Vwin32_enable_palette))
1317 return;
1318
1319 /* check if color is already mapped */
1320 while (list)
1321 {
1322 if (WIN32_COLOR (list->entry) == color)
1323 {
1324 ++list->refcount;
1325 return;
1326 }
1327 list = list->next;
1328 }
1329
1330 /* not already mapped, so add to list and recreate Windows palette */
1331 list = (struct win32_palette_entry *)
1332 xmalloc (sizeof (struct win32_palette_entry));
1333 SET_WIN32_COLOR (list->entry, color);
1334 list->refcount = 1;
1335 list->next = FRAME_WIN32_DISPLAY_INFO (f)->color_list;
1336 FRAME_WIN32_DISPLAY_INFO (f)->color_list = list;
1337 FRAME_WIN32_DISPLAY_INFO (f)->num_colors++;
1338
1339 /* set flag that palette must be regenerated */
1340 FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = TRUE;
1341}
1342
1343void
1344win32_unmap_color (FRAME_PTR f, COLORREF color)
1345{
1346 struct win32_palette_entry * list = FRAME_WIN32_DISPLAY_INFO (f)->color_list;
1347 struct win32_palette_entry **prev = &FRAME_WIN32_DISPLAY_INFO (f)->color_list;
1348
1349 if (NILP (Vwin32_enable_palette))
1350 return;
1351
1352 /* check if color is already mapped */
1353 while (list)
1354 {
1355 if (WIN32_COLOR (list->entry) == color)
1356 {
1357 if (--list->refcount == 0)
1358 {
1359 *prev = list->next;
1360 xfree (list);
1361 FRAME_WIN32_DISPLAY_INFO (f)->num_colors--;
1362 break;
1363 }
1364 else
1365 return;
1366 }
1367 prev = &list->next;
1368 list = list->next;
1369 }
1370
1371 /* set flag that palette must be regenerated */
1372 FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = TRUE;
1373}
1374#endif
1375
1171/* Decide if color named COLOR is valid for the display associated with 1376/* Decide if color named COLOR is valid for the display associated with
1172 the selected frame; if so, return the rgb values in COLOR_DEF. 1377 the selected frame; if so, return the rgb values in COLOR_DEF.
1173 If ALLOC is nonzero, allocate a new colormap cell. */ 1378 If ALLOC is nonzero, allocate a new colormap cell. */
@@ -1185,11 +1390,42 @@ defined_color (f, color, color_def, alloc)
1185 1390
1186 if (!NILP (tem)) 1391 if (!NILP (tem))
1187 { 1392 {
1188 /* map color to nearest in (default) palette, to avoid 1393 if (!NILP (Vwin32_enable_palette))
1189 dithering on limited color displays. */ 1394 {
1395 struct win32_palette_entry * entry =
1396 FRAME_WIN32_DISPLAY_INFO (f)->color_list;
1397 struct win32_palette_entry ** prev =
1398 &FRAME_WIN32_DISPLAY_INFO (f)->color_list;
1399
1400 /* check if color is already mapped */
1401 while (entry)
1402 {
1403 if (WIN32_COLOR (entry->entry) == XUINT (tem))
1404 break;
1405 prev = &entry->next;
1406 entry = entry->next;
1407 }
1408
1409 if (entry == NULL && alloc)
1410 {
1411 /* not already mapped, so add to list */
1412 entry = (struct win32_palette_entry *)
1413 xmalloc (sizeof (struct win32_palette_entry));
1414 SET_WIN32_COLOR (entry->entry, XUINT (tem));
1415 entry->next = NULL;
1416 *prev = entry;
1417 FRAME_WIN32_DISPLAY_INFO (f)->num_colors++;
1418
1419 /* set flag that palette must be regenerated */
1420 FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = TRUE;
1421 }
1422 }
1423 /* Ensure COLORREF value is snapped to nearest color in (default)
1424 palette by simulating the PALETTERGB macro. This works whether
1425 or not the display device has a palette. */
1190 *color_def = XUINT (tem) | 0x2000000; 1426 *color_def = XUINT (tem) | 0x2000000;
1191 return 1; 1427 return 1;
1192 } 1428 }
1193 else 1429 else
1194 { 1430 {
1195 return 0; 1431 return 0;
@@ -1243,6 +1479,7 @@ x_set_foreground_color (f, arg, oldval)
1243{ 1479{
1244 f->output_data.win32->foreground_pixel 1480 f->output_data.win32->foreground_pixel
1245 = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); 1481 = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1482
1246 if (FRAME_WIN32_WINDOW (f) != 0) 1483 if (FRAME_WIN32_WINDOW (f) != 0)
1247 { 1484 {
1248 recompute_basic_faces (f); 1485 recompute_basic_faces (f);
@@ -2332,7 +2569,7 @@ win32_init_class (hinst)
2332{ 2569{
2333 WNDCLASS wc; 2570 WNDCLASS wc;
2334 2571
2335 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 2572 wc.style = CS_HREDRAW | CS_VREDRAW;
2336 wc.lpfnWndProc = (WNDPROC) win32_wnd_proc; 2573 wc.lpfnWndProc = (WNDPROC) win32_wnd_proc;
2337 wc.cbClsExtra = 0; 2574 wc.cbClsExtra = 0;
2338 wc.cbWndExtra = WND_EXTRA_BYTES; 2575 wc.cbWndExtra = WND_EXTRA_BYTES;
@@ -2391,69 +2628,10 @@ win32_createwindow (f)
2391 SetWindowLong (hwnd, WND_X_UNITS_INDEX, FONT_WIDTH (f->output_data.win32->font)); 2628 SetWindowLong (hwnd, WND_X_UNITS_INDEX, FONT_WIDTH (f->output_data.win32->font));
2392 SetWindowLong (hwnd, WND_Y_UNITS_INDEX, f->output_data.win32->line_height); 2629 SetWindowLong (hwnd, WND_Y_UNITS_INDEX, f->output_data.win32->line_height);
2393 SetWindowLong (hwnd, WND_BACKGROUND_INDEX, f->output_data.win32->background_pixel); 2630 SetWindowLong (hwnd, WND_BACKGROUND_INDEX, f->output_data.win32->background_pixel);
2394 }
2395}
2396
2397DWORD
2398win_msg_worker (dw)
2399 DWORD dw;
2400{
2401 MSG msg;
2402
2403 /* Ensure our message queue is created */
2404
2405 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2406
2407 PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0);
2408
2409 while (GetMessage (&msg, NULL, 0, 0))
2410 {
2411 if (msg.hwnd == NULL)
2412 {
2413 switch (msg.message)
2414 {
2415 case WM_EMACS_CREATEWINDOW:
2416 win32_createwindow ((struct frame *) msg.wParam);
2417 PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0);
2418 break;
2419 case WM_EMACS_CREATESCROLLBAR:
2420 {
2421 HWND hwnd = win32_createscrollbar ((struct frame *) msg.wParam,
2422 (struct scroll_bar *) msg.lParam);
2423 PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, (WPARAM)hwnd, 0);
2424 }
2425 break;
2426 case WM_EMACS_KILL:
2427 return (0);
2428 }
2429 }
2430 else
2431 {
2432 DispatchMessage (&msg);
2433 }
2434 }
2435
2436 return (0);
2437}
2438 2631
2439HDC 2632 /* Do this to discard the default setting specified by our parent. */
2440map_mode (hdc) 2633 ShowWindow (hwnd, SW_HIDE);
2441 HDC hdc;
2442{
2443 if (hdc)
2444 {
2445#if 0
2446 /* Make mapping mode be in 1/20 of point */
2447
2448 SetMapMode (hdc, MM_ANISOTROPIC);
2449 SetWindowExtEx (hdc, 1440, 1440, NULL);
2450 SetViewportExtEx (hdc,
2451 GetDeviceCaps (hdc, LOGPIXELSX),
2452 GetDeviceCaps (hdc, LOGPIXELSY),
2453 NULL);
2454#endif
2455 } 2634 }
2456 return (hdc);
2457} 2635}
2458 2636
2459/* Convert between the modifier bits Win32 uses and the modifier bits 2637/* Convert between the modifier bits Win32 uses and the modifier bits
@@ -2643,6 +2821,60 @@ map_keypad_keys (unsigned int wparam, unsigned int lparam)
2643 return wparam; 2821 return wparam;
2644} 2822}
2645 2823
2824/* Main message dispatch loop. */
2825
2826DWORD
2827win_msg_worker (dw)
2828 DWORD dw;
2829{
2830 MSG msg;
2831
2832 /* Ensure our message queue is created */
2833
2834 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2835
2836 PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0);
2837
2838 while (GetMessage (&msg, NULL, 0, 0))
2839 {
2840 if (msg.hwnd == NULL)
2841 {
2842 switch (msg.message)
2843 {
2844 case WM_TIMER:
2845 if (saved_mouse_msg.msg.hwnd)
2846 {
2847 Win32Msg wmsg = saved_mouse_msg;
2848 my_post_msg (&wmsg, wmsg.msg.hwnd, wmsg.msg.message,
2849 wmsg.msg.wParam, wmsg.msg.lParam);
2850 saved_mouse_msg.msg.hwnd = 0;
2851 }
2852 timer_id = 0;
2853 break;
2854 case WM_EMACS_CREATEWINDOW:
2855 win32_createwindow ((struct frame *) msg.wParam);
2856 PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0);
2857 break;
2858 case WM_EMACS_CREATESCROLLBAR:
2859 {
2860 HWND hwnd = win32_createscrollbar ((struct frame *) msg.wParam,
2861 (struct scroll_bar *) msg.lParam);
2862 PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, (WPARAM)hwnd, 0);
2863 }
2864 break;
2865 case WM_EMACS_KILL:
2866 return (0);
2867 }
2868 }
2869 else
2870 {
2871 DispatchMessage (&msg);
2872 }
2873 }
2874
2875 return (0);
2876}
2877
2646/* Main window procedure */ 2878/* Main window procedure */
2647 2879
2648extern char *lispy_function_keys[]; 2880extern char *lispy_function_keys[];
@@ -2662,50 +2894,33 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
2662 switch (msg) 2894 switch (msg)
2663 { 2895 {
2664 case WM_ERASEBKGND: 2896 case WM_ERASEBKGND:
2665 { 2897 enter_crit ();
2666 HBRUSH hb; 2898 GetUpdateRect (hwnd, &wmsg.rect, FALSE);
2667 HANDLE oldobj; 2899 leave_crit ();
2668 RECT rect; 2900 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2669 2901 return 1;
2670 GetClientRect (hwnd, &rect); 2902 case WM_PALETTECHANGED:
2671 2903 /* ignore our own changes */
2672 hb = CreateSolidBrush (GetWindowLong (hwnd, WND_BACKGROUND_INDEX)); 2904 if ((HWND)wParam != hwnd)
2673 2905 {
2674 oldobj = SelectObject ((HDC)wParam, hb); 2906 /* simply notify main thread it may need to update frames */
2675 2907 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2676 FillRect((HDC)wParam, &rect, hb); 2908 }
2677 2909 return 0;
2678 SelectObject((HDC)wParam, oldobj);
2679
2680 DeleteObject (hb);
2681
2682 return (0);
2683 }
2684 case WM_PAINT: 2910 case WM_PAINT:
2685 { 2911 {
2686 PAINTSTRUCT paintStruct; 2912 PAINTSTRUCT paintStruct;
2687 2913
2914 enter_crit ();
2688 BeginPaint (hwnd, &paintStruct); 2915 BeginPaint (hwnd, &paintStruct);
2689 wmsg.rect = paintStruct.rcPaint; 2916 wmsg.rect = paintStruct.rcPaint;
2690 EndPaint (hwnd, &paintStruct); 2917 EndPaint (hwnd, &paintStruct);
2691 2918 leave_crit ();
2919
2692 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 2920 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2693 2921
2694 return (0); 2922 return (0);
2695 } 2923 }
2696
2697 case WM_CREATE:
2698 {
2699 HDC hdc = my_get_dc (hwnd);
2700
2701 /* Make mapping mode be in 1/20 of point */
2702
2703 map_mode (hdc);
2704
2705 ReleaseDC (hwnd, hdc);
2706 }
2707
2708 return (0);
2709 2924
2710 case WM_KEYUP: 2925 case WM_KEYUP:
2711 case WM_SYSKEYUP: 2926 case WM_SYSKEYUP:
@@ -2749,15 +2964,140 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
2749 case WM_CHAR: 2964 case WM_CHAR:
2750 wmsg.dwModifiers = construct_modifiers (wParam, lParam); 2965 wmsg.dwModifiers = construct_modifiers (wParam, lParam);
2751 2966
2967 enter_crit ();
2752 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 2968 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2969
2970 /* Detect quit_char and set quit-flag directly. Note that we dow
2971 this *after* posting the message to ensure the main thread will
2972 be woken up if blocked in sys_select(). */
2973 {
2974 int c = wParam;
2975 if (isalpha (c) && (wmsg.dwModifiers == LEFT_CTRL_PRESSED
2976 || wmsg.dwModifiers == RIGHT_CTRL_PRESSED))
2977 c = make_ctrl_char (c) & 0377;
2978 if (c == quit_char)
2979 Vquit_flag = Qt;
2980 }
2981 leave_crit ();
2753 break; 2982 break;
2754 2983
2984 /* Simulate middle mouse button events when left and right buttons
2985 are used together, but only if user has two button mouse. */
2755 case WM_LBUTTONDOWN: 2986 case WM_LBUTTONDOWN:
2987 case WM_RBUTTONDOWN:
2988 if (XINT (Vwin32_num_mouse_buttons) == 3)
2989 goto handle_plain_button;
2990
2991 {
2992 int this = (msg == WM_LBUTTONDOWN) ? LMOUSE : RMOUSE;
2993 int other = (msg == WM_LBUTTONDOWN) ? RMOUSE : LMOUSE;
2994
2995 if (button_state & this) abort ();
2996
2997 if (button_state == 0)
2998 SetCapture (hwnd);
2999
3000 button_state |= this;
3001
3002 if (button_state & other)
3003 {
3004 if (timer_id)
3005 {
3006 KillTimer (NULL, timer_id);
3007 timer_id = 0;
3008
3009 /* Generate middle mouse event instead. */
3010 msg = WM_MBUTTONDOWN;
3011 button_state |= MMOUSE;
3012 }
3013 else if (button_state & MMOUSE)
3014 {
3015 /* Ignore button event if we've already generated a
3016 middle mouse down event. This happens if the
3017 user releases and press one of the two buttons
3018 after we've faked a middle mouse event. */
3019 return 0;
3020 }
3021 else
3022 {
3023 /* Flush out saved message. */
3024 wmsg = saved_mouse_msg;
3025 my_post_msg (&wmsg, wmsg.msg.hwnd, wmsg.msg.message,
3026 wmsg.msg.wParam, wmsg.msg.lParam);
3027 }
3028 wmsg.dwModifiers = win32_get_modifiers ();
3029 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3030
3031 /* Clear message buffer. */
3032 saved_mouse_msg.msg.hwnd = 0;
3033 }
3034 else
3035 {
3036 /* Hold onto message for now. */
3037 timer_id =
3038 SetTimer (NULL, 0, XINT (Vwin32_mouse_button_tolerance), NULL);
3039 saved_mouse_msg.msg.hwnd = hwnd;
3040 saved_mouse_msg.msg.message = msg;
3041 saved_mouse_msg.msg.wParam = wParam;
3042 saved_mouse_msg.msg.lParam = lParam;
3043 saved_mouse_msg.msg.time = GetMessageTime ();
3044 saved_mouse_msg.dwModifiers = win32_get_modifiers ();
3045 }
3046 }
3047 return 0;
3048
2756 case WM_LBUTTONUP: 3049 case WM_LBUTTONUP:
3050 case WM_RBUTTONUP:
3051 if (XINT (Vwin32_num_mouse_buttons) == 3)
3052 goto handle_plain_button;
3053
3054 {
3055 int this = (msg == WM_LBUTTONUP) ? LMOUSE : RMOUSE;
3056 int other = (msg == WM_LBUTTONUP) ? RMOUSE : LMOUSE;
3057
3058 if ((button_state & this) == 0) abort ();
3059
3060 button_state &= ~this;
3061
3062 if (button_state & MMOUSE)
3063 {
3064 /* Only generate event when second button is released. */
3065 if ((button_state & other) == 0)
3066 {
3067 msg = WM_MBUTTONUP;
3068 button_state &= ~MMOUSE;
3069
3070 if (button_state) abort ();
3071 }
3072 else
3073 return 0;
3074 }
3075 else
3076 {
3077 /* Flush out saved message if necessary. */
3078 if (saved_mouse_msg.msg.hwnd)
3079 {
3080 wmsg = saved_mouse_msg;
3081 my_post_msg (&wmsg, wmsg.msg.hwnd, wmsg.msg.message,
3082 wmsg.msg.wParam, wmsg.msg.lParam);
3083 }
3084 }
3085 wmsg.dwModifiers = win32_get_modifiers ();
3086 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3087
3088 /* Always clear message buffer and cancel timer. */
3089 saved_mouse_msg.msg.hwnd = 0;
3090 KillTimer (NULL, timer_id);
3091 timer_id = 0;
3092
3093 if (button_state == 0)
3094 ReleaseCapture ();
3095 }
3096 return 0;
3097
2757 case WM_MBUTTONDOWN: 3098 case WM_MBUTTONDOWN:
2758 case WM_MBUTTONUP: 3099 case WM_MBUTTONUP:
2759 case WM_RBUTTONDOWN: 3100 handle_plain_button:
2760 case WM_RBUTTONUP:
2761 { 3101 {
2762 BOOL up; 3102 BOOL up;
2763 3103
@@ -2769,9 +3109,28 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
2769 } 3109 }
2770 3110
2771 wmsg.dwModifiers = win32_get_modifiers (); 3111 wmsg.dwModifiers = win32_get_modifiers ();
2772
2773 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 3112 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2774 goto dflt; 3113 return 0;
3114
3115#if 0
3116 case WM_MOUSEMOVE:
3117 /* Flush out saved message if necessary. */
3118 if (saved_mouse_msg.msg.hwnd)
3119 {
3120 wmsg = saved_mouse_msg;
3121 my_post_msg (&wmsg, wmsg.msg.hwnd, wmsg.msg.message,
3122 wmsg.msg.wParam, wmsg.msg.lParam);
3123 }
3124 wmsg.dwModifiers = win32_get_modifiers ();
3125 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3126
3127 /* Always clear message buffer and cancel timer. */
3128 saved_mouse_msg.msg.hwnd = 0;
3129 KillTimer (NULL, timer_id);
3130 timer_id = 0;
3131
3132 return 0;
3133#endif
2775 3134
2776 case WM_SETFOCUS: 3135 case WM_SETFOCUS:
2777 reset_modifiers (); 3136 reset_modifiers ();
@@ -2782,10 +3141,12 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
2782 case WM_VSCROLL: 3141 case WM_VSCROLL:
2783 case WM_SYSCOMMAND: 3142 case WM_SYSCOMMAND:
2784 case WM_COMMAND: 3143 case WM_COMMAND:
3144 wmsg.dwModifiers = win32_get_modifiers ();
2785 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 3145 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2786 goto dflt; 3146 goto dflt;
2787 3147
2788 case WM_CLOSE: 3148 case WM_CLOSE:
3149 wmsg.dwModifiers = win32_get_modifiers ();
2789 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 3150 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2790 return 0; 3151 return 0;
2791 3152
@@ -2805,6 +3166,7 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
2805 DWORD dwYUnits; 3166 DWORD dwYUnits;
2806 RECT wr; 3167 RECT wr;
2807 3168
3169 wp.length = sizeof(wp);
2808 GetWindowRect (hwnd, &wr); 3170 GetWindowRect (hwnd, &wr);
2809 3171
2810 enter_crit (); 3172 enter_crit ();
@@ -2854,6 +3216,14 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
2854 if (ret == 0) return (0); 3216 if (ret == 0) return (0);
2855 3217
2856 goto dflt; 3218 goto dflt;
3219 case WM_EMACS_SHOWWINDOW:
3220 return ShowWindow (hwnd, wParam);
3221 case WM_EMACS_SETWINDOWPOS:
3222 {
3223 Win32WindowPos * pos = (Win32WindowPos *) wParam;
3224 return SetWindowPos (hwnd, pos->hwndAfter,
3225 pos->x, pos->y, pos->cx, pos->cy, pos->flags);
3226 }
2857 case WM_EMACS_DESTROYWINDOW: 3227 case WM_EMACS_DESTROYWINDOW:
2858 DestroyWindow ((HWND) wParam); 3228 DestroyWindow ((HWND) wParam);
2859 break; 3229 break;
@@ -3027,6 +3397,8 @@ This function is an internal primitive--use `make-frame' instead.")
3027 3397
3028 /* Note that Windows does support scroll bars. */ 3398 /* Note that Windows does support scroll bars. */
3029 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1; 3399 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3400 /* By default, make scrollbars the system standard width. */
3401 f->scroll_bar_pixel_width = GetSystemMetrics (SM_CXVSCROLL);
3030 3402
3031 XSETFRAME (frame, f); 3403 XSETFRAME (frame, f);
3032 GCPRO1 (frame); 3404 GCPRO1 (frame);
@@ -3250,90 +3622,64 @@ x_get_focus_frame (frame)
3250} 3622}
3251 3623
3252DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0, 3624DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0,
3253 "Set the focus on FRAME.") 3625 "This function is obsolete, and does nothing.")
3254 (frame) 3626 (frame)
3255 Lisp_Object frame; 3627 Lisp_Object frame;
3256{ 3628{
3257 CHECK_LIVE_FRAME (frame, 0);
3258
3259 if (FRAME_WIN32_P (XFRAME (frame)))
3260 {
3261 BLOCK_INPUT;
3262 x_focus_on_frame (XFRAME (frame));
3263 UNBLOCK_INPUT;
3264 return frame;
3265 }
3266
3267 return Qnil; 3629 return Qnil;
3268} 3630}
3269 3631
3270DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0, 3632DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0,
3271 "If a frame has been focused, release it.") 3633 "This function is obsolete, and does nothing.")
3272 () 3634 ()
3273{ 3635{
3274 if (FRAME_WIN32_P (selected_frame))
3275 {
3276 struct win32_display_info *dpyinfo = FRAME_WIN32_DISPLAY_INFO (selected_frame);
3277
3278 if (dpyinfo->win32_focus_frame)
3279 {
3280 BLOCK_INPUT;
3281 x_unfocus_frame (dpyinfo->win32_focus_frame);
3282 UNBLOCK_INPUT;
3283 }
3284 }
3285
3286 return Qnil; 3636 return Qnil;
3287} 3637}
3288 3638
3289XFontStruct 3639XFontStruct *
3290*win32_load_font (dpyinfo,name) 3640win32_load_font (dpyinfo,name)
3291struct win32_display_info *dpyinfo; 3641struct win32_display_info *dpyinfo;
3292char * name; 3642char * name;
3293{ 3643{
3294 XFontStruct * font = NULL; 3644 XFontStruct * font = NULL;
3295 BOOL ok; 3645 BOOL ok;
3296 3646
3297 { 3647 {
3298 LOGFONT lf; 3648 LOGFONT lf;
3299 3649
3300 if (!name || !x_to_win32_font(name, &lf)) 3650 if (!name || !x_to_win32_font (name, &lf))
3301 return (NULL); 3651 return (NULL);
3302 3652
3303 font = (XFontStruct *) xmalloc (sizeof (XFontStruct)); 3653 font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
3304 3654
3305 if (!font) return (NULL); 3655 if (!font) return (NULL);
3306 3656
3307 BLOCK_INPUT; 3657 BLOCK_INPUT;
3308 3658
3309 font->hfont = CreateFontIndirect(&lf); 3659 font->hfont = CreateFontIndirect (&lf);
3310 } 3660 }
3311
3312 if (font->hfont == NULL)
3313 {
3314 ok = FALSE;
3315 }
3316 else
3317 {
3318 HDC hdc;
3319 HANDLE oldobj;
3320 3661
3321 hdc = my_get_dc (dpyinfo->root_window); 3662 if (font->hfont == NULL)
3322 3663 {
3323 oldobj = SelectObject (hdc, font->hfont); 3664 ok = FALSE;
3324 3665 }
3325 ok = GetTextMetrics (hdc, &font->tm); 3666 else
3326 3667 {
3327 SelectObject (hdc, oldobj); 3668 HDC hdc;
3328 3669 HANDLE oldobj;
3329 ReleaseDC (dpyinfo->root_window, hdc); 3670
3330 } 3671 hdc = GetDC (dpyinfo->root_window);
3331 3672 oldobj = SelectObject (hdc, font->hfont);
3673 ok = GetTextMetrics (hdc, &font->tm);
3674 SelectObject (hdc, oldobj);
3675 ReleaseDC (dpyinfo->root_window, hdc);
3676 }
3677
3332 UNBLOCK_INPUT; 3678 UNBLOCK_INPUT;
3333 3679
3334 if (ok) return (font); 3680 if (ok) return (font);
3335 3681
3336 win32_unload_font(dpyinfo, font); 3682 win32_unload_font (dpyinfo, font);
3337 return (NULL); 3683 return (NULL);
3338} 3684}
3339 3685
@@ -3428,31 +3774,70 @@ x_to_win32_weight (lpw)
3428 char * lpw; 3774 char * lpw;
3429{ 3775{
3430 if (!lpw) return (FW_DONTCARE); 3776 if (!lpw) return (FW_DONTCARE);
3431 3777
3432 if (stricmp (lpw, "bold") == 0) 3778 if (stricmp (lpw,"heavy") == 0) return FW_HEAVY;
3433 return (FW_BOLD); 3779 else if (stricmp (lpw,"extrabold") == 0) return FW_EXTRABOLD;
3434 else if (stricmp (lpw, "demibold") == 0) 3780 else if (stricmp (lpw,"bold") == 0) return FW_BOLD;
3435 return (FW_SEMIBOLD); 3781 else if (stricmp (lpw,"demibold") == 0) return FW_SEMIBOLD;
3436 else if (stricmp (lpw, "medium") == 0) 3782 else if (stricmp (lpw,"medium") == 0) return FW_MEDIUM;
3437 return (FW_MEDIUM); 3783 else if (stricmp (lpw,"normal") == 0) return FW_NORMAL;
3438 else if (stricmp (lpw, "normal") == 0) 3784 else if (stricmp (lpw,"light") == 0) return FW_LIGHT;
3439 return (FW_NORMAL); 3785 else if (stricmp (lpw,"extralight") == 0) return FW_EXTRALIGHT;
3786 else if (stricmp (lpw,"thin") == 0) return FW_THIN;
3440 else 3787 else
3441 return (FW_DONTCARE); 3788 return FW_DONTCARE;
3442} 3789}
3443 3790
3791
3444char * 3792char *
3445win32_to_x_weight (fnweight) 3793win32_to_x_weight (fnweight)
3446 int fnweight; 3794 int fnweight;
3447{ 3795{
3448 if (fnweight >= FW_BOLD) 3796 if (fnweight >= FW_HEAVY) return "heavy";
3449 return ("bold"); 3797 if (fnweight >= FW_EXTRABOLD) return "extrabold";
3450 else if (fnweight >= FW_SEMIBOLD) 3798 if (fnweight >= FW_BOLD) return "bold";
3451 return ("demibold"); 3799 if (fnweight >= FW_SEMIBOLD) return "semibold";
3452 else if (fnweight >= FW_MEDIUM) 3800 if (fnweight >= FW_MEDIUM) return "medium";
3453 return ("medium"); 3801 if (fnweight >= FW_NORMAL) return "normal";
3454 else 3802 if (fnweight >= FW_LIGHT) return "light";
3455 return ("normal"); 3803 if (fnweight >= FW_EXTRALIGHT) return "extralight";
3804 if (fnweight >= FW_THIN) return "thin";
3805 else
3806 return "*";
3807}
3808
3809LONG
3810x_to_win32_charset (lpcs)
3811 char * lpcs;
3812{
3813 if (!lpcs) return (0);
3814
3815 if (stricmp (lpcs,"ansi") == 0) return ANSI_CHARSET;
3816 else if (stricmp (lpcs,"iso8859-1") == 0) return ANSI_CHARSET;
3817 else if (stricmp (lpcs,"iso8859") == 0) return ANSI_CHARSET;
3818 else if (stricmp (lpcs,"oem") == 0) return OEM_CHARSET;
3819#ifdef UNICODE_CHARSET
3820 else if (stricmp (lpcs,"unicode") == 0) return UNICODE_CHARSET;
3821 else if (stricmp (lpcs,"iso10646") == 0) return UNICODE_CHARSET;
3822#endif
3823 else
3824 return 0;
3825}
3826
3827char *
3828win32_to_x_charset (fncharset)
3829 int fncharset;
3830{
3831 switch (fncharset)
3832 {
3833 case ANSI_CHARSET: return "ansi";
3834 case OEM_CHARSET: return "oem";
3835 case SYMBOL_CHARSET: return "symbol";
3836#ifdef UNICODE_CHARSET
3837 case UNICODE_CHARSET: return "unicode";
3838#endif
3839 }
3840 return "*";
3456} 3841}
3457 3842
3458BOOL 3843BOOL
@@ -3463,29 +3848,25 @@ win32_to_x_font (lplogfont, lpxstr, len)
3463{ 3848{
3464 if (!lpxstr) return (FALSE); 3849 if (!lpxstr) return (FALSE);
3465 3850
3466 if (lplogfont) 3851 if (lplogfont)
3467 { 3852 {
3468 int height = (lplogfont->lfHeight * 1440)
3469 / one_win32_display_info.height_in;
3470 int width = (lplogfont->lfWidth * 1440)
3471 / one_win32_display_info.width_in;
3472
3473 height = abs (height);
3474 _snprintf (lpxstr, len - 1, 3853 _snprintf (lpxstr, len - 1,
3475 "-*-%s-%s-%c-%s-%s-*-%d-*-*-%c-%d-*-*-", 3854 "-*-%s-%s-%c-*-*-%d-%d-*-*-%c-%d-*-%s-",
3476 lplogfont->lfFaceName, 3855 lplogfont->lfFaceName,
3477 win32_to_x_weight (lplogfont->lfWeight), 3856 win32_to_x_weight (lplogfont->lfWeight),
3478 lplogfont->lfItalic ? 'i' : 'r', 3857 lplogfont->lfItalic?'i':'r',
3479 "*", "*", 3858 abs (lplogfont->lfHeight),
3480 height, 3859 (abs (lplogfont->lfHeight) * 720) / one_win32_display_info.height_in,
3481 ((lplogfont->lfPitchAndFamily & 0x3) == VARIABLE_PITCH) ? 'p' : 'c', 3860 ((lplogfont->lfPitchAndFamily & 0x3) == VARIABLE_PITCH) ? 'p' : 'c',
3482 width); 3861 lplogfont->lfWidth * 10,
3483 } 3862 win32_to_x_charset (lplogfont->lfCharSet)
3484 else 3863 );
3864 }
3865 else
3485 { 3866 {
3486 strncpy (lpxstr, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-", len - 1); 3867 strncpy (lpxstr,"-*-*-*-*-*-*-*-*-*-*-*-*-*-*-", len - 1);
3487 } 3868 }
3488 3869
3489 lpxstr[len - 1] = 0; /* just to be sure */ 3870 lpxstr[len - 1] = 0; /* just to be sure */
3490 return (TRUE); 3871 return (TRUE);
3491} 3872}
@@ -3498,59 +3879,132 @@ x_to_win32_font (lpxstr, lplogfont)
3498 if (!lplogfont) return (FALSE); 3879 if (!lplogfont) return (FALSE);
3499 3880
3500 memset (lplogfont, 0, sizeof (*lplogfont)); 3881 memset (lplogfont, 0, sizeof (*lplogfont));
3501 3882
3502 lplogfont->lfCharSet = OEM_CHARSET; 3883#if 0
3503 lplogfont->lfOutPrecision = OUT_DEFAULT_PRECIS; 3884 lplogfont->lfOutPrecision = OUT_DEFAULT_PRECIS;
3504 lplogfont->lfClipPrecision = CLIP_DEFAULT_PRECIS; 3885 lplogfont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
3505 lplogfont->lfQuality = DEFAULT_QUALITY; 3886 lplogfont->lfQuality = DEFAULT_QUALITY;
3887#else
3888 /* go for maximum quality */
3889 lplogfont->lfOutPrecision = OUT_STROKE_PRECIS;
3890 lplogfont->lfClipPrecision = CLIP_STROKE_PRECIS;
3891 lplogfont->lfQuality = PROOF_QUALITY;
3892#endif
3893
3894 if (!lpxstr)
3895 return FALSE;
3896
3897 /* Provide a simple escape mechanism for specifying Windows font names
3898 * directly -- if font spec does not beginning with '-', assume this
3899 * format:
3900 * "<font name>[:height in pixels[:width in pixels[:weight]]]"
3901 */
3506 3902
3507 if (lpxstr && *lpxstr == '-') lpxstr++; 3903 if (*lpxstr == '-')
3508 3904 {
3509 { 3905 int fields;
3510 int fields; 3906 char name[50], weight[20], slant, pitch, pixels[10], height[10], width[10], remainder[20];
3511 char name[50], weight[20], slant, pitch, height[10], width[10]; 3907 char * encoding;
3512 3908
3513 fields = (lpxstr 3909 fields = sscanf (lpxstr,
3514 ? sscanf (lpxstr, 3910 "-%*[^-]-%49[^-]-%19[^-]-%c-%*[^-]-%*[^-]-%9[^-]-%9[^-]-%*[^-]-%*[^-]-%c-%9[^-]-%19s",
3515 "%*[^-]-%[^-]-%[^-]-%c-%*[^-]-%*[^-]-%*[^-]-%[^-]-%*[^-]-%*[^-]-%c-%[^-]", 3911 name, weight, &slant, pixels, height, &pitch, width, remainder);
3516 name, weight, &slant, height, &pitch, width) 3912
3517 : 0); 3913 if (fields == EOF) return (FALSE);
3518 3914
3519 if (fields == EOF) return (FALSE); 3915 if (fields > 0 && name[0] != '*')
3520 3916 {
3521 if (fields > 0 && name[0] != '*') 3917 strncpy (lplogfont->lfFaceName,name, LF_FACESIZE);
3522 { 3918 lplogfont->lfFaceName[LF_FACESIZE-1] = 0;
3523 strncpy (lplogfont->lfFaceName, name, LF_FACESIZE); 3919 }
3524 } 3920 else
3525 else 3921 {
3922 lplogfont->lfFaceName[0] = 0;
3923 }
3924
3925 fields--;
3926
3927 lplogfont->lfWeight = x_to_win32_weight ((fields > 0 ? weight : ""));
3928
3929 fields--;
3930
3931 if (!NILP (Vwin32_enable_italics))
3932 lplogfont->lfItalic = (fields > 0 && slant == 'i');
3933
3934 fields--;
3935
3936 if (fields > 0 && pixels[0] != '*')
3937 lplogfont->lfHeight = atoi (pixels);
3938
3939 fields--;
3940
3941 if (fields > 0 && lplogfont->lfHeight == 0 && height[0] != '*')
3942 lplogfont->lfHeight = (atoi (height)
3943 * one_win32_display_info.height_in) / 720;
3944
3945 fields--;
3946
3947 lplogfont->lfPitchAndFamily =
3948 (fields > 0 && pitch == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
3949
3950 fields--;
3951
3952 if (fields > 0 && width[0] != '*')
3953 lplogfont->lfWidth = atoi (width) / 10;
3954
3955 fields--;
3956
3957 /* Not all font specs include the registry field, so we allow for an
3958 optional registry field before the encoding when parsing
3959 remainder. Also we strip the trailing '-' if present. */
3526 { 3960 {
3527 lplogfont->lfFaceName[0] = 0; 3961 int len = strlen (remainder);
3962 if (len > 0 && remainder[len-1] == '-')
3963 remainder[len-1] = 0;
3528 } 3964 }
3529 3965 encoding = remainder;
3530 fields--; 3966 if (strncmp (encoding, "*-", 2) == 0)
3531 3967 encoding += 2;
3532 lplogfont->lfWeight = x_to_win32_weight((fields > 0 ? weight : "")); 3968 lplogfont->lfCharSet = x_to_win32_charset (fields > 0 ? encoding : "");
3533 3969 }
3534 fields--; 3970 else
3535 3971 {
3536 lplogfont->lfItalic = (fields > 0 && slant == 'i'); 3972 int fields;
3537 3973 char name[100], height[10], width[10], weight[20];
3538 fields--;
3539
3540 if (fields > 0 && height[0] != '*')
3541 lplogfont->lfHeight = (atoi (height) * one_win32_display_info.height_in) / 1440;
3542
3543 fields--;
3544
3545 lplogfont->lfPitchAndFamily = (fields > 0 && pitch == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
3546
3547 fields--;
3548
3549 if (fields > 0 && width[0] != '*')
3550 lplogfont->lfWidth = (atoi (width) * one_win32_display_info.width_in) / 1440;
3551 3974
3552 lplogfont->lfCharSet = ANSI_CHARSET; 3975 fields = sscanf (lpxstr,
3553 } 3976 "%99[^:]:%9[^:]:%9[^:]:%19s",
3977 name, height, width, weight);
3978
3979 if (fields == EOF) return (FALSE);
3980
3981 if (fields > 0)
3982 {
3983 strncpy (lplogfont->lfFaceName,name, LF_FACESIZE);
3984 lplogfont->lfFaceName[LF_FACESIZE-1] = 0;
3985 }
3986 else
3987 {
3988 lplogfont->lfFaceName[0] = 0;
3989 }
3990
3991 fields--;
3992
3993 if (fields > 0)
3994 lplogfont->lfHeight = atoi (height);
3995
3996 fields--;
3997
3998 if (fields > 0)
3999 lplogfont->lfWidth = atoi (width);
4000
4001 fields--;
4002
4003 lplogfont->lfWeight = x_to_win32_weight ((fields > 0 ? weight : ""));
4004 }
4005
4006 /* This makes TrueType fonts work better. */
4007 lplogfont->lfHeight = - abs (lplogfont->lfHeight);
3554 4008
3555 return (TRUE); 4009 return (TRUE);
3556} 4010}
@@ -3744,7 +4198,7 @@ even if they match PATTERN and FACE.")
3744 ef.numFonts = 0; 4198 ef.numFonts = 0;
3745 4199
3746 { 4200 {
3747 ef.hdc = my_get_dc (FRAME_WIN32_WINDOW (f)); 4201 ef.hdc = GetDC (FRAME_WIN32_WINDOW (f));
3748 4202
3749 EnumFontFamilies (ef.hdc, NULL, (FONTENUMPROC) enum_font_cb1, (LPARAM)&ef); 4203 EnumFontFamilies (ef.hdc, NULL, (FONTENUMPROC) enum_font_cb1, (LPARAM)&ef);
3750 4204
@@ -3930,9 +4384,11 @@ If omitted or nil, that stands for the selected frame's display.")
3930 HDC hdc; 4384 HDC hdc;
3931 int cap; 4385 int cap;
3932 4386
3933 hdc = my_get_dc (dpyinfo->root_window); 4387 hdc = GetDC (dpyinfo->root_window);
3934 4388 if (dpyinfo->has_palette)
3935 cap = GetDeviceCaps (hdc,NUMCOLORS); 4389 cap = GetDeviceCaps (hdc,SIZEPALETTE);
4390 else
4391 cap = GetDeviceCaps (hdc,NUMCOLORS);
3936 4392
3937 ReleaseDC (dpyinfo->root_window, hdc); 4393 ReleaseDC (dpyinfo->root_window, hdc);
3938 4394
@@ -4011,7 +4467,7 @@ If omitted or nil, that stands for the selected frame's display.")
4011 HDC hdc; 4467 HDC hdc;
4012 int cap; 4468 int cap;
4013 4469
4014 hdc = my_get_dc (dpyinfo->root_window); 4470 hdc = GetDC (dpyinfo->root_window);
4015 4471
4016 cap = GetDeviceCaps (hdc, VERTSIZE); 4472 cap = GetDeviceCaps (hdc, VERTSIZE);
4017 4473
@@ -4033,7 +4489,7 @@ If omitted or nil, that stands for the selected frame's display.")
4033 HDC hdc; 4489 HDC hdc;
4034 int cap; 4490 int cap;
4035 4491
4036 hdc = my_get_dc (dpyinfo->root_window); 4492 hdc = GetDC (dpyinfo->root_window);
4037 4493
4038 cap = GetDeviceCaps (hdc, HORZSIZE); 4494 cap = GetDeviceCaps (hdc, HORZSIZE);
4039 4495
@@ -4190,7 +4646,27 @@ terminate Emacs if we can't open the connection.")
4190 if (! NILP (xrm_string)) 4646 if (! NILP (xrm_string))
4191 CHECK_STRING (xrm_string, 1); 4647 CHECK_STRING (xrm_string, 1);
4192 4648
4193 Vwin32_color_map = Fwin32_default_color_map (); 4649 /* Allow color mapping to be defined externally; first look in user's
4650 HOME directory, then in Emacs etc dir for a file called rgb.txt. */
4651 {
4652 Lisp_Object color_file;
4653 struct gcpro gcpro1;
4654
4655 color_file = build_string("~/rgb.txt");
4656
4657 GCPRO1 (color_file);
4658
4659 if (NILP (Ffile_readable_p (color_file)))
4660 color_file =
4661 Fexpand_file_name (build_string ("rgb.txt"),
4662 Fsymbol_value (intern ("data-directory")));
4663
4664 Vwin32_color_map = Fwin32_load_color_file (color_file);
4665
4666 UNGCPRO;
4667 }
4668 if (NILP (Vwin32_color_map))
4669 Vwin32_color_map = Fwin32_default_color_map ();
4194 4670
4195 if (! NILP (xrm_string)) 4671 if (! NILP (xrm_string))
4196 xrm_option = (unsigned char *) XSTRING (xrm_string)->data; 4672 xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
@@ -4198,6 +4674,15 @@ terminate Emacs if we can't open the connection.")
4198 xrm_option = (unsigned char *) 0; 4674 xrm_option = (unsigned char *) 0;
4199 4675
4200 /* Use this general default value to start with. */ 4676 /* Use this general default value to start with. */
4677 /* First remove .exe suffix from invocation-name - it looks ugly. */
4678 {
4679 char basename[ MAX_PATH ], *str;
4680
4681 strcpy (basename, XSTRING (Vinvocation_name)->data);
4682 str = strrchr (basename, '.');
4683 if (str) *str = 0;
4684 Vinvocation_name = build_string (basename);
4685 }
4201 Vx_resource_name = Vinvocation_name; 4686 Vx_resource_name = Vinvocation_name;
4202 4687
4203 validate_x_resource_name (); 4688 validate_x_resource_name ();
@@ -4402,6 +4887,23 @@ open the System menu. When nil, Emacs silently swallows alt key events.");
4402and application keys) are passed on to Windows."); 4887and application keys) are passed on to Windows.");
4403 Vwin32_pass_optional_keys_to_system = Qnil; 4888 Vwin32_pass_optional_keys_to_system = Qnil;
4404 4889
4890 DEFVAR_LISP ("win32-enable-italics", &Vwin32_enable_italics,
4891 "Non-nil enables selection of artificially italicized fonts.");
4892 Vwin32_enable_italics = Qnil;
4893
4894 DEFVAR_LISP ("win32-enable-palette", &Vwin32_enable_palette,
4895 "Non-nil enables Windows palette management to map colors exactly.");
4896 Vwin32_enable_palette = Qt;
4897
4898 DEFVAR_INT ("win32-mouse-button-tolerance",
4899 &Vwin32_mouse_button_tolerance,
4900 "Analogue of double click interval for faking middle mouse events.\n\
4901The value is the minimum time in milliseconds that must elapse between\n\
4902left/right button down events before they are considered distinct events.\n\
4903If both mouse buttons are depressed within this interval, a middle mouse\n\
4904button down event is generated instead.");
4905 XSETINT (Vwin32_mouse_button_tolerance, GetDoubleClickTime () / 2);
4906
4405 init_x_parm_symbols (); 4907 init_x_parm_symbols ();
4406 4908
4407 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, 4909 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
@@ -4477,6 +4979,9 @@ unless you set it to something else.");
4477 /* Win32 specific functions */ 4979 /* Win32 specific functions */
4478 4980
4479 defsubr (&Swin32_select_font); 4981 defsubr (&Swin32_select_font);
4982 defsubr (&Swin32_define_rgb_color);
4983 defsubr (&Swin32_default_color_map);
4984 defsubr (&Swin32_load_color_file);
4480} 4985}
4481 4986
4482#undef abort 4987#undef abort
@@ -4484,9 +4989,23 @@ unless you set it to something else.");
4484void 4989void
4485win32_abort() 4990win32_abort()
4486{ 4991{
4487 MessageBox (NULL, 4992 int button;
4488 "A fatal error has occurred - aborting!", 4993 button = MessageBox (NULL,
4489 "Emacs Abort Dialog", 4994 "A fatal error has occurred!\n\n"
4490 MB_OK|MB_ICONEXCLAMATION); 4995 "Select Abort to exit, Retry to debug, Ignore to continue",
4491 abort(); 4996 "Emacs Abort Dialog",
4997 MB_ICONEXCLAMATION | MB_TASKMODAL
4998 | MB_SETFOREGROUND | MB_ABORTRETRYIGNORE);
4999 switch (button)
5000 {
5001 case IDRETRY:
5002 DebugBreak ();
5003 break;
5004 case IDIGNORE:
5005 break;
5006 case IDABORT:
5007 default:
5008 abort ();
5009 break;
5010 }
4492} 5011}