curses 1.4.5 → 1.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (249) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/push_gem.yml +48 -0
  3. data/History.md +3 -0
  4. data/curses.gemspec +1 -1
  5. metadata +8 -247
  6. data/vendor/PDCurses/.gitignore +0 -47
  7. data/vendor/PDCurses/.travis.yml +0 -49
  8. data/vendor/PDCurses/CMakeLists.txt +0 -68
  9. data/vendor/PDCurses/HISTORY.md +0 -2036
  10. data/vendor/PDCurses/IMPLEMNT.md +0 -327
  11. data/vendor/PDCurses/Makefile +0 -27
  12. data/vendor/PDCurses/README.md +0 -77
  13. data/vendor/PDCurses/acs_defs.h +0 -265
  14. data/vendor/PDCurses/appveyor.yml +0 -218
  15. data/vendor/PDCurses/cmake/README.md +0 -71
  16. data/vendor/PDCurses/cmake/build_dependencies.cmake +0 -178
  17. data/vendor/PDCurses/cmake/build_options.cmake +0 -25
  18. data/vendor/PDCurses/cmake/dll_version.cmake +0 -26
  19. data/vendor/PDCurses/cmake/gen_config_header.cmake +0 -43
  20. data/vendor/PDCurses/cmake/get_version.cmake +0 -17
  21. data/vendor/PDCurses/cmake/make_uninstall.cmake +0 -19
  22. data/vendor/PDCurses/cmake/project_common.cmake +0 -121
  23. data/vendor/PDCurses/cmake/resource.in.cmake +0 -52
  24. data/vendor/PDCurses/cmake/sdl2_ttf/CMakeLists.txt +0 -83
  25. data/vendor/PDCurses/cmake/target_arch.cmake +0 -36
  26. data/vendor/PDCurses/cmake/version.in.cmake +0 -73
  27. data/vendor/PDCurses/cmake/watcom_open_dos16_toolchain.cmake +0 -96
  28. data/vendor/PDCurses/cmake/watcom_open_dos32_toolchain.cmake +0 -106
  29. data/vendor/PDCurses/cmake/watcom_open_os2v2_toolchain.cmake +0 -105
  30. data/vendor/PDCurses/curses.h +0 -1846
  31. data/vendor/PDCurses/curspriv.h +0 -134
  32. data/vendor/PDCurses/demos/README.md +0 -25
  33. data/vendor/PDCurses/demos/firework.c +0 -144
  34. data/vendor/PDCurses/demos/newtest.c +0 -581
  35. data/vendor/PDCurses/demos/ozdemo.c +0 -447
  36. data/vendor/PDCurses/demos/ptest.c +0 -283
  37. data/vendor/PDCurses/demos/rain.c +0 -157
  38. data/vendor/PDCurses/demos/testcurs.c +0 -1607
  39. data/vendor/PDCurses/demos/tui.c +0 -1048
  40. data/vendor/PDCurses/demos/tui.h +0 -65
  41. data/vendor/PDCurses/demos/tuidemo.c +0 -233
  42. data/vendor/PDCurses/demos/version.c +0 -61
  43. data/vendor/PDCurses/demos/worm.c +0 -432
  44. data/vendor/PDCurses/demos/xmas.c +0 -955
  45. data/vendor/PDCurses/dos/CMakeLists.txt +0 -47
  46. data/vendor/PDCurses/dos/Makefile +0 -105
  47. data/vendor/PDCurses/dos/Makefile.bcc +0 -83
  48. data/vendor/PDCurses/dos/Makefile.dmc +0 -257
  49. data/vendor/PDCurses/dos/Makefile.msc +0 -113
  50. data/vendor/PDCurses/dos/Makefile.wcc +0 -107
  51. data/vendor/PDCurses/dos/README.md +0 -51
  52. data/vendor/PDCurses/dos/bccdos.lrf +0 -9
  53. data/vendor/PDCurses/dos/mscdos.lrf +0 -50
  54. data/vendor/PDCurses/dos/pdcclip.c +0 -132
  55. data/vendor/PDCurses/dos/pdcdisp.c +0 -135
  56. data/vendor/PDCurses/dos/pdcdos.h +0 -194
  57. data/vendor/PDCurses/dos/pdcgetsc.c +0 -98
  58. data/vendor/PDCurses/dos/pdckbd.c +0 -513
  59. data/vendor/PDCurses/dos/pdcscrn.c +0 -785
  60. data/vendor/PDCurses/dos/pdcsetsc.c +0 -101
  61. data/vendor/PDCurses/dos/pdcutil.c +0 -212
  62. data/vendor/PDCurses/libobjs.mif +0 -26
  63. data/vendor/PDCurses/makedist.mif +0 -20
  64. data/vendor/PDCurses/man/Makefile +0 -37
  65. data/vendor/PDCurses/man/README.md +0 -21
  66. data/vendor/PDCurses/man/intro.md +0 -361
  67. data/vendor/PDCurses/man/manext.c +0 -119
  68. data/vendor/PDCurses/man/sdl.md +0 -152
  69. data/vendor/PDCurses/man/sdl2.md +0 -58
  70. data/vendor/PDCurses/man/x11.md +0 -407
  71. data/vendor/PDCurses/ncurses/CMakeLists.txt +0 -66
  72. data/vendor/PDCurses/ncurses/README.md +0 -26
  73. data/vendor/PDCurses/ncurses/makefile +0 -29
  74. data/vendor/PDCurses/os2/CMakeLists.txt +0 -41
  75. data/vendor/PDCurses/os2/Makefile +0 -132
  76. data/vendor/PDCurses/os2/Makefile.bcc +0 -90
  77. data/vendor/PDCurses/os2/Makefile.wcc +0 -43
  78. data/vendor/PDCurses/os2/README.md +0 -43
  79. data/vendor/PDCurses/os2/iccos2.lrf +0 -50
  80. data/vendor/PDCurses/os2/iccos2.mak +0 -256
  81. data/vendor/PDCurses/os2/pdcclip.c +0 -188
  82. data/vendor/PDCurses/os2/pdcdisp.c +0 -93
  83. data/vendor/PDCurses/os2/pdcgetsc.c +0 -89
  84. data/vendor/PDCurses/os2/pdckbd.c +0 -521
  85. data/vendor/PDCurses/os2/pdcos2.h +0 -55
  86. data/vendor/PDCurses/os2/pdcscrn.c +0 -449
  87. data/vendor/PDCurses/os2/pdcsetsc.c +0 -112
  88. data/vendor/PDCurses/os2/pdcutil.c +0 -52
  89. data/vendor/PDCurses/panel.h +0 -56
  90. data/vendor/PDCurses/pdcurses/README.md +0 -25
  91. data/vendor/PDCurses/pdcurses/addch.c +0 -693
  92. data/vendor/PDCurses/pdcurses/addchstr.c +0 -245
  93. data/vendor/PDCurses/pdcurses/addstr.c +0 -240
  94. data/vendor/PDCurses/pdcurses/attr.c +0 -359
  95. data/vendor/PDCurses/pdcurses/beep.c +0 -68
  96. data/vendor/PDCurses/pdcurses/bkgd.c +0 -223
  97. data/vendor/PDCurses/pdcurses/border.c +0 -411
  98. data/vendor/PDCurses/pdcurses/clear.c +0 -159
  99. data/vendor/PDCurses/pdcurses/color.c +0 -298
  100. data/vendor/PDCurses/pdcurses/debug.c +0 -109
  101. data/vendor/PDCurses/pdcurses/delch.c +0 -96
  102. data/vendor/PDCurses/pdcurses/deleteln.c +0 -211
  103. data/vendor/PDCurses/pdcurses/deprec.c +0 -27
  104. data/vendor/PDCurses/pdcurses/getch.c +0 -417
  105. data/vendor/PDCurses/pdcurses/getstr.c +0 -474
  106. data/vendor/PDCurses/pdcurses/getyx.c +0 -139
  107. data/vendor/PDCurses/pdcurses/inch.c +0 -127
  108. data/vendor/PDCurses/pdcurses/inchstr.c +0 -214
  109. data/vendor/PDCurses/pdcurses/initscr.c +0 -367
  110. data/vendor/PDCurses/pdcurses/inopts.c +0 -324
  111. data/vendor/PDCurses/pdcurses/insch.c +0 -271
  112. data/vendor/PDCurses/pdcurses/insstr.c +0 -264
  113. data/vendor/PDCurses/pdcurses/instr.c +0 -246
  114. data/vendor/PDCurses/pdcurses/kernel.c +0 -259
  115. data/vendor/PDCurses/pdcurses/keyname.c +0 -157
  116. data/vendor/PDCurses/pdcurses/mouse.c +0 -438
  117. data/vendor/PDCurses/pdcurses/move.c +0 -57
  118. data/vendor/PDCurses/pdcurses/outopts.c +0 -159
  119. data/vendor/PDCurses/pdcurses/overlay.c +0 -214
  120. data/vendor/PDCurses/pdcurses/pad.c +0 -260
  121. data/vendor/PDCurses/pdcurses/panel.c +0 -633
  122. data/vendor/PDCurses/pdcurses/printw.c +0 -126
  123. data/vendor/PDCurses/pdcurses/refresh.c +0 -279
  124. data/vendor/PDCurses/pdcurses/scanw.c +0 -578
  125. data/vendor/PDCurses/pdcurses/scr_dump.c +0 -213
  126. data/vendor/PDCurses/pdcurses/scroll.c +0 -101
  127. data/vendor/PDCurses/pdcurses/slk.c +0 -591
  128. data/vendor/PDCurses/pdcurses/termattr.c +0 -182
  129. data/vendor/PDCurses/pdcurses/terminfo.c +0 -217
  130. data/vendor/PDCurses/pdcurses/touch.c +0 -163
  131. data/vendor/PDCurses/pdcurses/util.c +0 -312
  132. data/vendor/PDCurses/pdcurses/window.c +0 -569
  133. data/vendor/PDCurses/sdl1/Makefile +0 -129
  134. data/vendor/PDCurses/sdl1/Makefile.mng +0 -110
  135. data/vendor/PDCurses/sdl1/README.md +0 -31
  136. data/vendor/PDCurses/sdl1/deffont.h +0 -385
  137. data/vendor/PDCurses/sdl1/deficon.h +0 -23
  138. data/vendor/PDCurses/sdl1/pdcclip.c +0 -131
  139. data/vendor/PDCurses/sdl1/pdcdisp.c +0 -373
  140. data/vendor/PDCurses/sdl1/pdcgetsc.c +0 -30
  141. data/vendor/PDCurses/sdl1/pdckbd.c +0 -405
  142. data/vendor/PDCurses/sdl1/pdcscrn.c +0 -414
  143. data/vendor/PDCurses/sdl1/pdcsdl.h +0 -31
  144. data/vendor/PDCurses/sdl1/pdcsetsc.c +0 -64
  145. data/vendor/PDCurses/sdl1/pdcutil.c +0 -40
  146. data/vendor/PDCurses/sdl1/sdltest.c +0 -79
  147. data/vendor/PDCurses/sdl2/CMakeLists.txt +0 -76
  148. data/vendor/PDCurses/sdl2/Makefile +0 -135
  149. data/vendor/PDCurses/sdl2/Makefile.vc +0 -164
  150. data/vendor/PDCurses/sdl2/README.md +0 -34
  151. data/vendor/PDCurses/sdl2/deffont.h +0 -385
  152. data/vendor/PDCurses/sdl2/deficon.h +0 -23
  153. data/vendor/PDCurses/sdl2/pdcclip.c +0 -93
  154. data/vendor/PDCurses/sdl2/pdcdisp.c +0 -534
  155. data/vendor/PDCurses/sdl2/pdcgetsc.c +0 -30
  156. data/vendor/PDCurses/sdl2/pdckbd.c +0 -480
  157. data/vendor/PDCurses/sdl2/pdcscrn.c +0 -443
  158. data/vendor/PDCurses/sdl2/pdcsdl.h +0 -33
  159. data/vendor/PDCurses/sdl2/pdcsetsc.c +0 -67
  160. data/vendor/PDCurses/sdl2/pdcutil.c +0 -39
  161. data/vendor/PDCurses/sdl2/sdltest.c +0 -81
  162. data/vendor/PDCurses/term.h +0 -48
  163. data/vendor/PDCurses/version.mif +0 -7
  164. data/vendor/PDCurses/vt/CMakeLists.txt +0 -28
  165. data/vendor/PDCurses/vt/Makefile +0 -135
  166. data/vendor/PDCurses/vt/Makefile.bcc +0 -111
  167. data/vendor/PDCurses/vt/Makefile.dmc +0 -258
  168. data/vendor/PDCurses/vt/Makefile.vc +0 -144
  169. data/vendor/PDCurses/vt/Makefile.wcc +0 -107
  170. data/vendor/PDCurses/vt/README.md +0 -64
  171. data/vendor/PDCurses/vt/pdcclip.c +0 -20
  172. data/vendor/PDCurses/vt/pdcdisp.c +0 -284
  173. data/vendor/PDCurses/vt/pdcgetsc.c +0 -27
  174. data/vendor/PDCurses/vt/pdckbd.c +0 -394
  175. data/vendor/PDCurses/vt/pdcscrn.c +0 -434
  176. data/vendor/PDCurses/vt/pdcsetsc.c +0 -45
  177. data/vendor/PDCurses/vt/pdcutil.c +0 -43
  178. data/vendor/PDCurses/vt/pdcvt.h +0 -16
  179. data/vendor/PDCurses/watcom.mif +0 -68
  180. data/vendor/PDCurses/wincon/CMakeLists.txt +0 -27
  181. data/vendor/PDCurses/wincon/Makefile.bcc +0 -88
  182. data/vendor/PDCurses/wincon/Makefile.dmc +0 -256
  183. data/vendor/PDCurses/wincon/Makefile.lcc +0 -273
  184. data/vendor/PDCurses/wincon/Makefile.mng +0 -176
  185. data/vendor/PDCurses/wincon/Makefile.vc +0 -144
  186. data/vendor/PDCurses/wincon/Makefile.wcc +0 -51
  187. data/vendor/PDCurses/wincon/README.md +0 -85
  188. data/vendor/PDCurses/wincon/pdcclip.c +0 -174
  189. data/vendor/PDCurses/wincon/pdcdisp.c +0 -143
  190. data/vendor/PDCurses/wincon/pdcgetsc.c +0 -55
  191. data/vendor/PDCurses/wincon/pdckbd.c +0 -786
  192. data/vendor/PDCurses/wincon/pdcscrn.c +0 -717
  193. data/vendor/PDCurses/wincon/pdcsetsc.c +0 -91
  194. data/vendor/PDCurses/wincon/pdcurses.ico +0 -0
  195. data/vendor/PDCurses/wincon/pdcurses.rc +0 -28
  196. data/vendor/PDCurses/wincon/pdcutil.c +0 -41
  197. data/vendor/PDCurses/wincon/pdcwin.h +0 -31
  198. data/vendor/PDCurses/wingui/CMakeLists.txt +0 -27
  199. data/vendor/PDCurses/wingui/Makefile.bcc +0 -85
  200. data/vendor/PDCurses/wingui/Makefile.dmc +0 -259
  201. data/vendor/PDCurses/wingui/Makefile.lcc +0 -273
  202. data/vendor/PDCurses/wingui/Makefile.mng +0 -171
  203. data/vendor/PDCurses/wingui/Makefile.vc +0 -144
  204. data/vendor/PDCurses/wingui/Makefile.wcc +0 -51
  205. data/vendor/PDCurses/wingui/README.md +0 -93
  206. data/vendor/PDCurses/wingui/pdcclip.c +0 -174
  207. data/vendor/PDCurses/wingui/pdcdisp.c +0 -718
  208. data/vendor/PDCurses/wingui/pdcgetsc.c +0 -30
  209. data/vendor/PDCurses/wingui/pdckbd.c +0 -143
  210. data/vendor/PDCurses/wingui/pdcscrn.c +0 -2797
  211. data/vendor/PDCurses/wingui/pdcsetsc.c +0 -89
  212. data/vendor/PDCurses/wingui/pdcurses.ico +0 -0
  213. data/vendor/PDCurses/wingui/pdcurses.rc +0 -28
  214. data/vendor/PDCurses/wingui/pdcutil.c +0 -61
  215. data/vendor/PDCurses/wingui/pdcwin.h +0 -122
  216. data/vendor/PDCurses/x11/Makefile.in +0 -754
  217. data/vendor/PDCurses/x11/PDCurses.spec +0 -82
  218. data/vendor/PDCurses/x11/README.md +0 -62
  219. data/vendor/PDCurses/x11/ScrollBox.c +0 -319
  220. data/vendor/PDCurses/x11/ScrollBox.h +0 -51
  221. data/vendor/PDCurses/x11/ScrollBoxP.h +0 -70
  222. data/vendor/PDCurses/x11/aclocal.m4 +0 -994
  223. data/vendor/PDCurses/x11/big_icon.xbm +0 -46
  224. data/vendor/PDCurses/x11/compose.h +0 -201
  225. data/vendor/PDCurses/x11/config.guess +0 -1500
  226. data/vendor/PDCurses/x11/config.h.in +0 -100
  227. data/vendor/PDCurses/x11/config.sub +0 -1616
  228. data/vendor/PDCurses/x11/configure +0 -6700
  229. data/vendor/PDCurses/x11/configure.ac +0 -295
  230. data/vendor/PDCurses/x11/debian/changelog +0 -6
  231. data/vendor/PDCurses/x11/debian/compat +0 -1
  232. data/vendor/PDCurses/x11/debian/control +0 -11
  233. data/vendor/PDCurses/x11/debian/copyright +0 -27
  234. data/vendor/PDCurses/x11/debian/rules +0 -98
  235. data/vendor/PDCurses/x11/install-sh +0 -253
  236. data/vendor/PDCurses/x11/little_icon.xbm +0 -14
  237. data/vendor/PDCurses/x11/ncurses_cfg.h +0 -45
  238. data/vendor/PDCurses/x11/pdcclip.c +0 -173
  239. data/vendor/PDCurses/x11/pdcdisp.c +0 -85
  240. data/vendor/PDCurses/x11/pdcgetsc.c +0 -28
  241. data/vendor/PDCurses/x11/pdckbd.c +0 -104
  242. data/vendor/PDCurses/x11/pdcscrn.c +0 -258
  243. data/vendor/PDCurses/x11/pdcsetsc.c +0 -95
  244. data/vendor/PDCurses/x11/pdcutil.c +0 -52
  245. data/vendor/PDCurses/x11/pdcx11.c +0 -316
  246. data/vendor/PDCurses/x11/pdcx11.h +0 -191
  247. data/vendor/PDCurses/x11/sb.c +0 -155
  248. data/vendor/PDCurses/x11/x11.c +0 -3686
  249. data/vendor/PDCurses/x11/xcurses-config.in +0 -81
@@ -1,2797 +0,0 @@
1
- /* Public Domain Curses */
2
-
3
- #include "pdcwin.h"
4
- #include <tchar.h>
5
- #include <stdint.h>
6
- #include <assert.h>
7
-
8
- /* COLOR_PAIR to attribute encoding table. */
9
-
10
- static short *color_pair_indices = (short *)NULL;
11
- COLORREF *pdc_rgbs = (COLORREF *)NULL;
12
- static int menu_shown = 1;
13
- static int min_lines = 25, max_lines = 25;
14
- static int min_cols = 80, max_cols = 80;
15
-
16
- #if defined( CHTYPE_LONG) && CHTYPE_LONG >= 2 && defined( PDC_WIDE)
17
- #define USING_COMBINING_CHARACTER_SCHEME
18
- int PDC_expand_combined_characters( const cchar_t c, cchar_t *added); /* addch.c */
19
- #endif
20
-
21
- /* Some older versions of Microsoft C/C++ don't understand about
22
- inlined functions. Until we puzzle out which ones do and which
23
- don't, we'll just leave "inlined" functions as plain old static
24
- functions. */
25
-
26
- #ifdef _MSC_VER
27
- #define INLINE static
28
- #else
29
- #define INLINE static inline
30
- #endif
31
-
32
- static int keep_size_within_bounds( int *lines, int *cols);
33
- INLINE int set_default_sizes_from_registry( const int n_cols, const int n_rows,
34
- const int xloc, const int yloc, const int menu_shown);
35
- void PDC_transform_line_given_hdc( const HDC hdc, const int lineno,
36
- int x, int len, const chtype *srcp);
37
-
38
- #define N_COLORS 256
39
-
40
- #ifdef A_OVERLINE
41
- #define A_ALL_LINES (A_UNDERLINE | A_LEFTLINE | A_RIGHTLINE | A_OVERLINE | A_STRIKEOUT)
42
- #else
43
- #define A_ALL_LINES (A_UNDERLINE | A_LEFTLINE | A_RIGHTLINE)
44
- #endif
45
-
46
- /* If PDC_MAX_MOUSE_BUTTONS is undefined, it means the user hasn't */
47
- /* gotten a current 'curses.h' in which five-button mice are supported. */
48
- /* To handle this gracefully, we'll just fall back to three buttons. */
49
-
50
- #ifndef PDC_MAX_MOUSE_BUTTONS
51
- #define PDC_MAX_MOUSE_BUTTONS 3
52
- #endif
53
-
54
- #define VERTICAL_WHEEL_EVENT PDC_MAX_MOUSE_BUTTONS
55
- #define HORIZONTAL_WHEEL_EVENT (PDC_MAX_MOUSE_BUTTONS + 1)
56
-
57
- unsigned long pdc_key_modifiers = 0L;
58
- int PDC_show_ctrl_alts = 0;
59
-
60
- /* RR: Removed statis on next line */
61
- bool PDC_bDone = FALSE;
62
- static HWND originally_focussed_window;
63
-
64
- int debug_printf( const char *format, ...)
65
- {
66
- static bool debugging = TRUE;
67
-
68
- if( debugging)
69
- {
70
- const char *output_filename = getenv( "PDC_DEBUG");
71
-
72
- if( !output_filename)
73
- debugging = FALSE; /* don't bother trying again */
74
- else
75
- {
76
- FILE *ofile = fopen( output_filename, "a");
77
-
78
- if( ofile)
79
- {
80
- va_list argptr;
81
- va_start( argptr, format);
82
- vfprintf( ofile, format, argptr);
83
- va_end( argptr);
84
- fclose( ofile);
85
- }
86
- else
87
- {
88
- printf( "Opening '%s' failed\n", output_filename);
89
- exit( 0);
90
- debugging = FALSE; /* don't bother trying again */
91
- }
92
- }
93
- }
94
- return( 0);
95
- }
96
-
97
- HWND PDC_hWnd;
98
- static int PDC_argc = 0;
99
- static char **PDC_argv = NULL;
100
-
101
- static void final_cleanup( void)
102
- {
103
- debug_printf( "final_cleanup: SP = %p\n", SP);
104
- if (SP)
105
- {
106
- RECT rect;
107
-
108
- GetWindowRect( PDC_hWnd, &rect);
109
- set_default_sizes_from_registry( SP->cols, SP->lines,
110
- rect.left, rect.top, menu_shown);
111
- }
112
- PDC_LOG(( "final_cleanup: freeing fonts\n"));
113
- PDC_transform_line( 0, 0, 0, NULL); /* free any fonts */
114
- if( originally_focussed_window)
115
- SetForegroundWindow( originally_focussed_window);
116
- if( PDC_argc)
117
- {
118
- int i;
119
-
120
- for( i = 0; i < PDC_argc; i++)
121
- free( PDC_argv[i]);
122
- free( PDC_argv);
123
- PDC_argc = 0;
124
- PDC_argv = NULL;
125
- }
126
- #ifdef USING_COMBINING_CHARACTER_SCHEME
127
- PDC_expand_combined_characters( 0, NULL); /* free internal buffer */
128
- #endif
129
- debug_printf( "reset foreground window\n");
130
- }
131
-
132
- void PDC_scr_close(void)
133
- {
134
- PDC_LOG(("PDC_scr_close() - called\n"));
135
- final_cleanup( );
136
- PDC_bDone = TRUE;
137
- }
138
-
139
- /* NOTE that PDC_scr_free( ) is called only from delscreen( ), */
140
- /* which is rarely called. It appears that most programs simply */
141
- /* rely on the memory getting freed when the program terminates. */
142
- /* It seems conceivable to me that we could get into some trouble */
143
- /* here, if SP is freed and NULLed, but then accessed again, */
144
- /* possibly within the WinGUI window thread. */
145
-
146
- void PDC_scr_free(void)
147
- {
148
- if (SP)
149
- free(SP);
150
- SP = (SCREEN *)NULL;
151
-
152
- if (color_pair_indices)
153
- free(color_pair_indices);
154
- color_pair_indices = (short *)NULL;
155
-
156
- if (pdc_rgbs)
157
- free(pdc_rgbs);
158
- pdc_rgbs = (COLORREF *)NULL;
159
- }
160
-
161
- int PDC_choose_a_new_font( void); /* pdcdisp.c */
162
- void PDC_add_clipboard_to_key_queue( void); /* pdckbd.c */
163
-
164
- #define KEY_QUEUE_SIZE 30
165
-
166
- /* By default, the PDC_shutdown_key[] array contains 0 */
167
- /* (i.e., there's no key that's supposed to be returned for */
168
- /* exit handling), and 22 = Ctrl-V (i.e., hit Ctrl-V to */
169
- /* paste text from the clipboard into the key queue); then */
170
- /* Ctl-= (enlarge font) and Ctl-Minus (decrease font); then */
171
- /* Ctl-, (select font from dialog). */
172
-
173
- static int PDC_shutdown_key[PDC_MAX_FUNCTION_KEYS] = { 0, 22, CTL_EQUAL, CTL_MINUS,
174
- CTL_COMMA };
175
- int PDC_n_rows, PDC_n_cols;
176
- int PDC_cxChar, PDC_cyChar, PDC_key_queue_low = 0, PDC_key_queue_high = 0;
177
- int PDC_key_queue[KEY_QUEUE_SIZE];
178
-
179
- /* If the following is true, you can enter Unicode values by hitting */
180
- /* Alt and holding it down while typing the value of the character on */
181
- /* the numeric keypad (for decimal entry); _or_ you can hit Alt-Padplus */
182
- /* and then enter a hex value, while holding down the Alt key. In */
183
- /* either case, when you release the Alt key, the Unicode character */
184
- /* is added to the queue. For hex entry, 0-9 can come either from */
185
- /* the numeric keypad or the "usual" keyboard. */
186
- bool PDC_allow_numpad_unicode = TRUE;
187
- static int numpad_unicode_value = 0;
188
-
189
- static void adjust_font_size( const int font_size_change);
190
-
191
- static void add_key_to_queue( const int new_key)
192
- {
193
- const int new_idx = ((PDC_key_queue_high + 1) % KEY_QUEUE_SIZE);
194
- /* This is usually 10, but is set to 16 if the user */
195
- /* hits ALT_PADPLUS and is about to enter a hex value: */
196
- static int unicode_radix = 10;
197
-
198
- if( PDC_allow_numpad_unicode)
199
- {
200
- int digit = -1;
201
-
202
- if( new_key >= ALT_PAD0 && new_key <= ALT_PAD9)
203
- digit = new_key - ALT_PAD0;
204
- /* In hex Unicode entry, you can enter digits on both */
205
- /* the numeric and "standard" keyboards : */
206
- if( unicode_radix == 16 && new_key >= ALT_0 && new_key <= ALT_9)
207
- digit = new_key - ALT_0;
208
- if( unicode_radix == 16 && new_key >= ALT_A && new_key <= ALT_F)
209
- digit = new_key - ALT_A + 10;
210
- if( digit >= 0)
211
- {
212
- numpad_unicode_value = numpad_unicode_value * unicode_radix + digit;
213
- return;
214
- }
215
- if( new_key == ALT_PADPLUS)
216
- { /* signal to begin hex Unicode entry */
217
- unicode_radix = 16;
218
- return;
219
- }
220
- }
221
- unicode_radix = 10;
222
- if( new_key && new_key == PDC_shutdown_key[FUNCTION_KEY_PASTE])
223
- PDC_add_clipboard_to_key_queue( );
224
- else if( new_key && new_key == PDC_shutdown_key[FUNCTION_KEY_ABORT])
225
- exit( -1);
226
- else if( new_key && new_key == PDC_shutdown_key[FUNCTION_KEY_ENLARGE_FONT])
227
- adjust_font_size( 1);
228
- else if( new_key && new_key == PDC_shutdown_key[FUNCTION_KEY_SHRINK_FONT])
229
- adjust_font_size( -1);
230
- else if( new_key && new_key == PDC_shutdown_key[FUNCTION_KEY_CHOOSE_FONT])
231
- {
232
- if( PDC_choose_a_new_font( ))
233
- adjust_font_size( 0);
234
- }
235
- else if( new_idx != PDC_key_queue_low)
236
- {
237
- PDC_key_queue[PDC_key_queue_high] = new_key;
238
- PDC_key_queue_high = new_idx;
239
- }
240
- }
241
-
242
- /************************************************************************
243
- * Table for key code translation of function keys in keypad mode *
244
- * These values are for strict IBM keyboard compatibles only *
245
- ************************************************************************/
246
-
247
- typedef struct
248
- {
249
- unsigned short normal;
250
- unsigned short shift;
251
- unsigned short control;
252
- unsigned short alt;
253
- unsigned short extended;
254
- } KPTAB;
255
-
256
-
257
- static const KPTAB kptab[] =
258
- {
259
- {0, 0, 0, 0, 0 }, /* 0 */
260
- {0, 0, 0, 0, 0 }, /* 1 VK_LBUTTON */
261
- {0, 0, 0, 0, 0 }, /* 2 VK_RBUTTON */
262
- {CTL_PAUSE, 'a', 'b', 'c', 0 }, /* 3 VK_CANCEL */
263
- {0, 0, 0, 0, 0 }, /* 4 VK_MBUTTON */
264
- {0, 0, 0, 0, 0 }, /* 5 */
265
- {0, 0, 0, 0, 0 }, /* 6 */
266
- {0, 0, 0, 0, 0 }, /* 7 */
267
- {0x08, 0x08, 0x7F, ALT_BKSP, 0 }, /* 8 VK_BACK */
268
- {0x09, KEY_BTAB, CTL_TAB, ALT_TAB, 999 }, /* 9 VK_TAB */
269
- {0, 0, 0, 0, 0 }, /* 10 */
270
- {0, 0, 0, 0, 0 }, /* 11 */
271
- {KEY_B2, 0x35, CTL_PAD5, ALT_PAD5, 0 }, /* 12 VK_CLEAR */
272
- {0x0D, 0x0D, CTL_ENTER, ALT_ENTER, 1 }, /* 13 VK_RETURN */
273
- {0, 0, 0, 0, 0 }, /* 14 */
274
- {0, 0, 0, 0, 0 }, /* 15 */
275
- {0, 0, 0, 0, 0 }, /* 16 VK_SHIFT HANDLED SEPARATELY */
276
- {0, 0, 0, 0, 0 }, /* 17 VK_CONTROL HANDLED SEPARATELY */
277
- {0, 0, 0, 0, 0 }, /* 18 VK_MENU HANDLED SEPARATELY */
278
- {KEY_PAUSE, KEY_SPAUSE,CTL_PAUSE, 0, 0 }, /* 19 VK_PAUSE */
279
- {0, 0, 0, 0, 0 }, /* 20 VK_CAPITAL HANDLED SEPARATELY */
280
- {0, 0, 0, 0, 0 }, /* 21 VK_HANGUL */
281
- {0, 0, 0, 0, 0 }, /* 22 */
282
- {0, 0, 0, 0, 0 }, /* 23 VK_JUNJA */
283
- {0, 0, 0, 0, 0 }, /* 24 VK_FINAL */
284
- {0, 0, 0, 0, 0 }, /* 25 VK_HANJA */
285
- {0, 0, 0, 0, 0 }, /* 26 */
286
- {0x1B, 0x1B, 0x1B, ALT_ESC, 0 }, /* 27 VK_ESCAPE */
287
- {0, 0, 0, 0, 0 }, /* 28 VK_CONVERT */
288
- {0, 0, 0, 0, 0 }, /* 29 VK_NONCONVERT */
289
- {0, 0, 0, 0, 0 }, /* 30 VK_ACCEPT */
290
- {0, 0, 0, 0, 0 }, /* 31 VK_MODECHANGE */
291
- {0x20, 0x20, 0x20, 0x20, 0 }, /* 32 VK_SPACE */
292
- {KEY_A3, 0x39, CTL_PAD9, ALT_PAD9, 3 }, /* 33 VK_PRIOR */
293
- {KEY_C3, 0x33, CTL_PAD3, ALT_PAD3, 4 }, /* 34 VK_NEXT */
294
- {KEY_C1, 0x31, CTL_PAD1, ALT_PAD1, 5 }, /* 35 VK_END */
295
- {KEY_A1, 0x37, CTL_PAD7, ALT_PAD7, 6 }, /* 36 VK_HOME */
296
- {KEY_B1, 0x34, CTL_PAD4, ALT_PAD4, 7 }, /* 37 VK_LEFT */
297
- {KEY_A2, 0x38, CTL_PAD8, ALT_PAD8, 8 }, /* 38 VK_UP */
298
- {KEY_B3, 0x36, CTL_PAD6, ALT_PAD6, 9 }, /* 39 VK_RIGHT */
299
- {KEY_C2, 0x32, CTL_PAD2, ALT_PAD2, 10 }, /* 40 VK_DOWN */
300
- {0, 0, 0, 0, 0 }, /* 41 VK_SELECT */
301
- {0, 0, 0, 0, 0 }, /* 42 VK_PRINT */
302
- {0, 0, 0, 0, 0 }, /* 43 VK_EXECUTE */
303
- {KEY_PRINTSCREEN, 0, 0, ALT_PRINTSCREEN, 0 }, /* 44 VK_SNAPSHOT*/
304
- {PAD0, 0x30, CTL_PAD0, ALT_PAD0, 11 }, /* 45 VK_INSERT */
305
- {PADSTOP, 0x2E, CTL_PADSTOP, ALT_PADSTOP,12 }, /* 46 VK_DELETE */
306
- {0, 0, 0, 0, 0 }, /* 47 VK_HELP */
307
- {0x30, 0x29, CTL_0, ALT_0, 0 }, /* 48 */
308
- {0x31, 0x21, CTL_1, ALT_1, 0 }, /* 49 */
309
- {0x32, 0x40, CTL_2, ALT_2, 0 }, /* 50 */
310
- {0x33, 0x23, CTL_3, ALT_3, 0 }, /* 51 */
311
- {0x34, 0x24, CTL_4, ALT_4, 0 }, /* 52 */
312
- {0x35, 0x25, CTL_5, ALT_5, 0 }, /* 53 */
313
- {0x36, 0x5E, CTL_6, ALT_6, 0 }, /* 54 */
314
- {0x37, 0x26, CTL_7, ALT_7, 0 }, /* 55 */
315
- {0x38, 0x2A, CTL_8, ALT_8, 0 }, /* 56 */
316
- {0x39, 0x28, CTL_9, ALT_9, 0 }, /* 57 */
317
- {0, 0, 0, 0, 0 }, /* 58 */
318
- {0, 0, 0, 0, 0 }, /* 59 */
319
- {0, 0, 0, 0, 0 }, /* 60 */
320
- {0, 0, 0, 0, 0 }, /* 61 */
321
- {0, 0, 0, 0, 0 }, /* 62 */
322
- {0, 0, 0, 0, 0 }, /* 63 */
323
- {0, 0, 0, 0, 0 }, /* 64 */
324
- {0x61, 0x41, 0x01, ALT_A, 0 }, /* 65 */
325
- {0x62, 0x42, 0x02, ALT_B, 0 }, /* 66 */
326
- {0x63, 0x43, 0x03, ALT_C, 0 }, /* 67 */
327
- {0x64, 0x44, 0x04, ALT_D, 0 }, /* 68 */
328
- {0x65, 0x45, 0x05, ALT_E, 0 }, /* 69 */
329
- {0x66, 0x46, 0x06, ALT_F, 0 }, /* 70 */
330
- {0x67, 0x47, 0x07, ALT_G, 0 }, /* 71 */
331
- {0x68, 0x48, 0x08, ALT_H, 0 }, /* 72 */
332
- {0x69, 0x49, 0x09, ALT_I, 0 }, /* 73 */
333
- {0x6A, 0x4A, 0x0A, ALT_J, 0 }, /* 74 */
334
- {0x6B, 0x4B, 0x0B, ALT_K, 0 }, /* 75 */
335
- {0x6C, 0x4C, 0x0C, ALT_L, 0 }, /* 76 */
336
- {0x6D, 0x4D, 0x0D, ALT_M, 0 }, /* 77 */
337
- {0x6E, 0x4E, 0x0E, ALT_N, 0 }, /* 78 */
338
- {0x6F, 0x4F, 0x0F, ALT_O, 0 }, /* 79 */
339
- {0x70, 0x50, 0x10, ALT_P, 0 }, /* 80 */
340
- {0x71, 0x51, 0x11, ALT_Q, 0 }, /* 81 */
341
- {0x72, 0x52, 0x12, ALT_R, 0 }, /* 82 */
342
- {0x73, 0x53, 0x13, ALT_S, 0 }, /* 83 */
343
- {0x74, 0x54, 0x14, ALT_T, 0 }, /* 84 */
344
- {0x75, 0x55, 0x15, ALT_U, 0 }, /* 85 */
345
- {0x76, 0x56, 0x16, ALT_V, 0 }, /* 86 */
346
- {0x77, 0x57, 0x17, ALT_W, 0 }, /* 87 */
347
- {0x78, 0x58, 0x18, ALT_X, 0 }, /* 88 */
348
- {0x79, 0x59, 0x19, ALT_Y, 0 }, /* 89 */
349
- {0x7A, 0x5A, 0x1A, ALT_Z, 0 }, /* 90 */
350
- {0, 0, 0, 0, 0 }, /* 91 VK_LWIN */
351
- {0, 0, 0, 0, 0 }, /* 92 VK_RWIN */
352
- {KEY_APPS, KEY_SAPPS, CTL_APPS, ALT_APPS, 13 }, /* 93 VK_APPS */
353
- {0, 0, 0, 0, 0 }, /* 94 */
354
- {0, 0, 0, 0, 0 }, /* 95 */
355
- {0x30, 0, CTL_PAD0, ALT_PAD0, 0 }, /* 96 VK_NUMPAD0 */
356
- {0x31, 0, CTL_PAD1, ALT_PAD1, 0 }, /* 97 VK_NUMPAD1 */
357
- {0x32, 0, CTL_PAD2, ALT_PAD2, 0 }, /* 98 VK_NUMPAD2 */
358
- {0x33, 0, CTL_PAD3, ALT_PAD3, 0 }, /* 99 VK_NUMPAD3 */
359
- {0x34, 0, CTL_PAD4, ALT_PAD4, 0 }, /* 100 VK_NUMPAD4 */
360
- {0x35, 0, CTL_PAD5, ALT_PAD5, 0 }, /* 101 VK_NUMPAD5 */
361
- {0x36, 0, CTL_PAD6, ALT_PAD6, 0 }, /* 102 VK_NUMPAD6 */
362
- {0x37, 0, CTL_PAD7, ALT_PAD7, 0 }, /* 103 VK_NUMPAD7 */
363
- {0x38, 0, CTL_PAD8, ALT_PAD8, 0 }, /* 104 VK_NUMPAD8 */
364
- {0x39, 0, CTL_PAD9, ALT_PAD9, 0 }, /* 105 VK_NUMPAD9 */
365
- {PADSTAR, SHF_PADSTAR,CTL_PADSTAR, ALT_PADSTAR,999 }, /* 106 VK_MULTIPLY*/
366
- {PADPLUS, SHF_PADPLUS,CTL_PADPLUS, ALT_PADPLUS,999 }, /* 107 VK_ADD */
367
- {0, 0, 0, 0, 0 }, /* 108 VK_SEPARATOR */
368
- {PADMINUS, SHF_PADMINUS,CTL_PADMINUS,ALT_PADMINUS,999}, /* 109 VK_SUBTRACT*/
369
- {0x2E, 0, CTL_PADSTOP, ALT_PADSTOP,0 }, /* 110 VK_DECIMAL */
370
- {PADSLASH, SHF_PADSLASH,CTL_PADSLASH,ALT_PADSLASH,2 }, /* 111 VK_DIVIDE */
371
- {KEY_F(1), KEY_F(13), KEY_F(25), KEY_F(37), 0 }, /* 112 VK_F1 */
372
- {KEY_F(2), KEY_F(14), KEY_F(26), KEY_F(38), 0 }, /* 113 VK_F2 */
373
- {KEY_F(3), KEY_F(15), KEY_F(27), KEY_F(39), 0 }, /* 114 VK_F3 */
374
- {KEY_F(4), KEY_F(16), KEY_F(28), KEY_F(40), 0 }, /* 115 VK_F4 */
375
- {KEY_F(5), KEY_F(17), KEY_F(29), KEY_F(41), 0 }, /* 116 VK_F5 */
376
- {KEY_F(6), KEY_F(18), KEY_F(30), KEY_F(42), 0 }, /* 117 VK_F6 */
377
- {KEY_F(7), KEY_F(19), KEY_F(31), KEY_F(43), 0 }, /* 118 VK_F7 */
378
- {KEY_F(8), KEY_F(20), KEY_F(32), KEY_F(44), 0 }, /* 119 VK_F8 */
379
- {KEY_F(9), KEY_F(21), KEY_F(33), KEY_F(45), 0 }, /* 120 VK_F9 */
380
- {KEY_F(10), KEY_F(22), KEY_F(34), KEY_F(46), 0 }, /* 121 VK_F10 */
381
- {KEY_F(11), KEY_F(23), KEY_F(35), KEY_F(47), 0 }, /* 122 VK_F11 */
382
- {KEY_F(12), KEY_F(24), KEY_F(36), KEY_F(48), 0 }, /* 123 VK_F12 */
383
-
384
- /* 124 through 218 */
385
-
386
- {0, 0, 0, 0, 0}, /* 124 VK_F13 */
387
- {0, 0, 0, 0, 0}, /* 125 VK_F14 */
388
- {0, 0, 0, 0, 0}, /* 126 VK_F15 */
389
- {0, 0, 0, 0, 0}, /* 127 VK_F16 */
390
- {0, 0, 0, 0, 0}, /* 128 VK_F17 */
391
- {0, 0, 0, 0, 0}, /* 129 VK_F18 */
392
- {0, 0, 0, 0, 0}, /* 130 VK_F19 */
393
- {0, 0, 0, 0, 0}, /* 131 VK_F20 */
394
- {0, 0, 0, 0, 0}, /* 132 VK_F21 */
395
- {0, 0, 0, 0, 0}, /* 133 VK_F22 */
396
- {0, 0, 0, 0, 0}, /* 134 VK_F23 */
397
- {0, 0, 0, 0, 0}, /* 135 VK_F24 */
398
- {0, 0, 0, 0, 0}, /* 136 unassigned */
399
- {0, 0, 0, 0, 0}, /* 137 unassigned */
400
- {0, 0, 0, 0, 0}, /* 138 unassigned */
401
- {0, 0, 0, 0, 0}, /* 139 unassigned */
402
- {0, 0, 0, 0, 0}, /* 140 unassigned */
403
- {0, 0, 0, 0, 0}, /* 141 unassigned */
404
- {0, 0, 0, 0, 0}, /* 142 unassigned */
405
- {0, 0, 0, 0, 0}, /* 143 unassigned */
406
- {0, 0, 0, 0, 0}, /* 144 VK_NUMLOCK */
407
- {KEY_SCROLLLOCK, 0, 0, ALT_SCROLLLOCK, 0}, /* 145 VKSCROLL */
408
- {0, 0, 0, 0, 0}, /* 146 OEM specific */
409
- {0, 0, 0, 0, 0}, /* 147 OEM specific */
410
- {0, 0, 0, 0, 0}, /* 148 OEM specific */
411
- {0, 0, 0, 0, 0}, /* 149 OEM specific */
412
- {0, 0, 0, 0, 0}, /* 150 OEM specific */
413
- {0, 0, 0, 0, 0}, /* 151 Unassigned */
414
- {0, 0, 0, 0, 0}, /* 152 Unassigned */
415
- {0, 0, 0, 0, 0}, /* 153 Unassigned */
416
- {0, 0, 0, 0, 0}, /* 154 Unassigned */
417
- {0, 0, 0, 0, 0}, /* 155 Unassigned */
418
- {0, 0, 0, 0, 0}, /* 156 Unassigned */
419
- {0, 0, 0, 0, 0}, /* 157 Unassigned */
420
- {0, 0, 0, 0, 0}, /* 158 Unassigned */
421
- {0, 0, 0, 0, 0}, /* 159 Unassigned */
422
- {0, 0, 0, 0, 0}, /* 160 VK_LSHIFT */
423
- {0, 0, 0, 0, 0}, /* 161 VK_RSHIFT */
424
- {0, 0, 0, 0, 0}, /* 162 VK_LCONTROL */
425
- {0, 0, 0, 0, 0}, /* 163 VK_RCONTROL */
426
- {0, 0, 0, 0, 0}, /* 164 VK_LMENU */
427
- {0, 0, 0, 0, 0}, /* 165 VK_RMENU */
428
- {0, 0, 0, 0, 14}, /* 166 VK_BROWSER_BACK */
429
- {0, 0, 0, 0, 15}, /* 167 VK_BROWSER_FORWARD */
430
- {0, 0, 0, 0, 16}, /* 168 VK_BROWSER_REFRESH */
431
- {0, 0, 0, 0, 17}, /* 169 VK_BROWSER_STOP */
432
- {0, 0, 0, 0, 18}, /* 170 VK_BROWSER_SEARCH */
433
- {0, 0, 0, 0, 19}, /* 171 VK_BROWSER_FAVORITES */
434
- {0, 0, 0, 0, 20}, /* 172 VK_BROWSER_HOME */
435
- {0, 0, 0, 0, 21}, /* 173 VK_VOLUME_MUTE */
436
- {0, 0, 0, 0, 22}, /* 174 VK_VOLUME_DOWN */
437
- {0, 0, 0, 0, 23}, /* 175 VK_VOLUME_UP */
438
- {0, 0, 0, 0, 24}, /* 176 VK_MEDIA_NEXT_TRACK */
439
- {0, 0, 0, 0, 25}, /* 177 VK_MEDIA_PREV_TRACK */
440
- {0, 0, 0, 0, 26}, /* 178 VK_MEDIA_STOP */
441
- {0, 0, 0, 0, 27}, /* 179 VK_MEDIA_PLAY_PAUSE */
442
- {0, 0, 0, 0, 28}, /* 180 VK_LAUNCH_MAIL */
443
- {0, 0, 0, 0, 29}, /* 181 VK_LAUNCH_MEDIA_SELECT */
444
- {0, 0, 0, 0, 30}, /* 182 VK_LAUNCH_APP1 */
445
- {0, 0, 0, 0, 31}, /* 183 VK_LAUNCH_APP2 */
446
- {0, 0, 0, 0, 0}, /* 184 Reserved */
447
- {0, 0, 0, 0, 0}, /* 185 Reserved */
448
- {';', ':', CTL_SEMICOLON, ALT_SEMICOLON, 0}, /* 186 VK_OEM_1 */
449
- {'=', '+', CTL_EQUAL, ALT_EQUAL, 0}, /* 187 VK_OEM_PLUS */
450
- {',', '<', CTL_COMMA, ALT_COMMA, 0}, /* 188 VK_OEM_COMMA */
451
- {'-', '_', CTL_MINUS, ALT_MINUS, 0}, /* 189 VK_OEM_MINUS */
452
- {'.', '>', CTL_STOP, ALT_STOP, 0}, /* 190 VK_OEM_PERIOD */
453
- {'/', '?', CTL_FSLASH, ALT_FSLASH, 0}, /* 191 VK_OEM_2 */
454
- {'`', '~', CTL_BQUOTE, ALT_BQUOTE, 0}, /* 192 VK_OEM_3 */
455
- {0, 0, 0, 0, 0}, /* 193 */
456
- {0, 0, 0, 0, 0}, /* 194 */
457
- {0, 0, 0, 0, 0}, /* 195 */
458
- {0, 0, 0, 0, 0}, /* 196 */
459
- {0, 0, 0, 0, 0}, /* 197 */
460
- {0, 0, 0, 0, 0}, /* 198 */
461
- {0, 0, 0, 0, 0}, /* 199 */
462
- {0, 0, 0, 0, 0}, /* 200 */
463
- {0, 0, 0, 0, 0}, /* 201 */
464
- {0, 0, 0, 0, 0}, /* 202 */
465
- {0, 0, 0, 0, 0}, /* 203 */
466
- {0, 0, 0, 0, 0}, /* 204 */
467
- {0, 0, 0, 0, 0}, /* 205 */
468
- {0, 0, 0, 0, 0}, /* 206 */
469
- {0, 0, 0, 0, 0}, /* 207 */
470
- {0, 0, 0, 0, 0}, /* 208 */
471
- {0, 0, 0, 0, 0}, /* 209 */
472
- {0, 0, 0, 0, 0}, /* 210 */
473
- {0, 0, 0, 0, 0}, /* 211 */
474
- {0, 0, 0, 0, 0}, /* 212 */
475
- {0, 0, 0, 0, 0}, /* 213 */
476
- {0, 0, 0, 0, 0}, /* 214 */
477
- {0, 0, 0, 0, 0}, /* 215 */
478
- {0, 0, 0, 0, 0}, /* 216 */
479
- {0, 0, 0, 0, 0}, /* 217 */
480
- {0, 0, 0, 0, 0}, /* 218 */
481
- {0x5B, 0x7B, 0x1B, ALT_LBRACKET,0 }, /* 219 VK_OEM_4 */
482
- {0x5C, 0x7C, 0x1C, ALT_BSLASH, 0 }, /* 220 VK_OEM_5 */
483
- {0x5D, 0x7D, 0x1D, ALT_RBRACKET,0 }, /* 221 VK_OEM_6 */
484
- {'\'', '"', 0x27, ALT_FQUOTE, 0 }, /* 222 VK_OEM_7 */
485
- {0, 0, 0, 0, 0 }, /* 223 VK_OEM_8 */
486
- {0, 0, 0, 0, 0 }, /* 224 */
487
- {0, 0, 0, 0, 0 } /* 225 */
488
- };
489
- /* End of kptab[] */
490
-
491
- static const KPTAB ext_kptab[] =
492
- {
493
- {0, 0, 0, 0, }, /* 0 MUST BE EMPTY */
494
- {PADENTER, SHF_PADENTER, CTL_PADENTER, ALT_PADENTER}, /* 1 13 */
495
- {PADSLASH, SHF_PADSLASH, CTL_PADSLASH, ALT_PADSLASH}, /* 2 111 */
496
- {KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP }, /* 3 33 */
497
- {KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN }, /* 4 34 */
498
- {KEY_END, KEY_SEND, CTL_END, ALT_END }, /* 5 35 */
499
- {KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME }, /* 6 36 */
500
- {KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT }, /* 7 37 */
501
- {KEY_UP, KEY_SUP, CTL_UP, ALT_UP }, /* 8 38 */
502
- {KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT }, /* 9 39 */
503
- {KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN }, /* 10 40 */
504
- {KEY_IC, KEY_SIC, CTL_INS, ALT_INS }, /* 11 45 */
505
- {KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL }, /* 12 46 */
506
- {KEY_APPS, KEY_SAPPS , CTL_APPS, ALT_APPS }, /* 13 93 VK_APPS */
507
- {KEY_BROWSER_BACK, KEY_SBROWSER_BACK, KEY_CBROWSER_BACK, KEY_ABROWSER_BACK, }, /* 14 166 VK_BROWSER_BACK */
508
- {KEY_BROWSER_FWD, KEY_SBROWSER_FWD, KEY_CBROWSER_FWD, KEY_ABROWSER_FWD, }, /* 15 167 VK_BROWSER_FORWARD */
509
- {KEY_BROWSER_REF, KEY_SBROWSER_REF, KEY_CBROWSER_REF, KEY_ABROWSER_REF, }, /* 16 168 VK_BROWSER_REFRESH */
510
- {KEY_BROWSER_STOP, KEY_SBROWSER_STOP, KEY_CBROWSER_STOP, KEY_ABROWSER_STOP, }, /* 17 169 VK_BROWSER_STOP */
511
- {KEY_SEARCH, KEY_SSEARCH, KEY_CSEARCH, KEY_ASEARCH, }, /* 18 170 VK_BROWSER_SEARCH */
512
- {KEY_FAVORITES, KEY_SFAVORITES, KEY_CFAVORITES, KEY_AFAVORITES, }, /* 19 171 VK_BROWSER_FAVORITES */
513
- {KEY_BROWSER_HOME, KEY_SBROWSER_HOME, KEY_CBROWSER_HOME, KEY_ABROWSER_HOME, }, /* 20 172 VK_BROWSER_HOME */
514
- {KEY_VOLUME_MUTE, KEY_SVOLUME_MUTE, KEY_CVOLUME_MUTE, KEY_AVOLUME_MUTE, }, /* 21 173 VK_VOLUME_MUTE */
515
- {KEY_VOLUME_DOWN, KEY_SVOLUME_DOWN, KEY_CVOLUME_DOWN, KEY_AVOLUME_DOWN, }, /* 22 174 VK_VOLUME_DOWN */
516
- {KEY_VOLUME_UP, KEY_SVOLUME_UP, KEY_CVOLUME_UP, KEY_AVOLUME_UP, }, /* 23 175 VK_VOLUME_UP */
517
- {KEY_NEXT_TRACK, KEY_SNEXT_TRACK, KEY_CNEXT_TRACK, KEY_ANEXT_TRACK, }, /* 24 176 VK_MEDIA_NEXT_TRACK */
518
- {KEY_PREV_TRACK, KEY_SPREV_TRACK, KEY_CPREV_TRACK, KEY_APREV_TRACK, }, /* 25 177 VK_MEDIA_PREV_TRACK */
519
- {KEY_MEDIA_STOP, KEY_SMEDIA_STOP, KEY_CMEDIA_STOP, KEY_AMEDIA_STOP, }, /* 26 178 VK_MEDIA_STOP */
520
- {KEY_PLAY_PAUSE, KEY_SPLAY_PAUSE, KEY_CPLAY_PAUSE, KEY_APLAY_PAUSE, }, /* 27 179 VK_MEDIA_PLAY_PAUSE */
521
- {KEY_LAUNCH_MAIL, KEY_SLAUNCH_MAIL, KEY_CLAUNCH_MAIL, KEY_ALAUNCH_MAIL, }, /* 28 180 VK_LAUNCH_MAIL */
522
- {KEY_MEDIA_SELECT, KEY_SMEDIA_SELECT, KEY_CMEDIA_SELECT, KEY_AMEDIA_SELECT, }, /* 29 181 VK_LAUNCH_MEDIA_SELECT */
523
- {KEY_LAUNCH_APP1, KEY_SLAUNCH_APP1, KEY_CLAUNCH_APP1, KEY_ALAUNCH_APP1, }, /* 30 182 VK_LAUNCH_APP1 */
524
- {KEY_LAUNCH_APP2, KEY_SLAUNCH_APP2, KEY_CLAUNCH_APP2, KEY_ALAUNCH_APP2, }, /* 31 183 VK_LAUNCH_APP2 */
525
- };
526
-
527
-
528
- HFONT PDC_get_font_handle( const int is_bold); /* pdcdisp.c */
529
-
530
- /* Mouse handling is done as follows:
531
-
532
- What we want is a setup wherein, if the user presses and releases a
533
- mouse button within SP->mouse_wait milliseconds, there will be a
534
- KEY_MOUSE issued through getch( ) and the "button state" for that button
535
- will be set to BUTTON_CLICKED.
536
-
537
- If the user presses and releases the button, and it takes _longer_
538
- than SP->mouse_wait milliseconds, then there should be a KEY_MOUSE
539
- issued with the "button state" set to BUTTON_PRESSED. Then, later,
540
- another KEY_MOUSE with a BUTTON_RELEASED.
541
-
542
- To accomplish this: when a message such as WM_LBUTTONDOWN,
543
- WM_RBUTTONDOWN, or WM_MBUTTONDOWN is issued (and more recently WM_XBUTTONDOWN
544
- for five-button mice), we set up a timer with a period of SP->mouse_wait
545
- milliseconds. There are then two possibilities. The user will release the
546
- button quickly (so it's a "click") or they won't (and it's a "press/release").
547
-
548
- In the first case, we'll get the WM_xBUTTONUP message before the
549
- WM_TIMER one. We'll kill the timer and set up the BUTTON_CLICKED state. (*)
550
-
551
- In the second case, we'll get the WM_TIMER message first, so we'll
552
- set the BUTTON_PRESSED state and kill the timer. Eventually, the user
553
- will get around to letting go of the mouse button, and we'll get that
554
- WM_xBUTTONUP message. At that time, we'll set the BUTTON_RELEASED state
555
- and add the second KEY_MOUSE to the key queue.
556
-
557
- Also, note that if there is already a KEY_MOUSE to the queue, there's
558
- no point in adding another one. At least at present, the actual mouse
559
- events aren't queued anyway. So if there was, say, a click and then a
560
- release without getch( ) being called in between, you'd then have two
561
- KEY_MOUSEs on the queue, but would have lost all information about what
562
- the first one actually was. Hence the code near the end of this function
563
- to ensure there isn't already a KEY_MOUSE in the queue.
564
-
565
- Also, a note about wheel handling. Pre-Vista, you could just say
566
- "the wheel went up" or "the wheel went down". Vista introduced the possibility
567
- that the mouse motion could be a smoothly varying quantity. So on each
568
- mouse move, we add in the amount moved, then check to see if that's
569
- enough to trigger a wheel up/down event (or possibly several). The idea
570
- is that whereas before, each movement would be 120 units (the default),
571
- you might now get a series of 40-unit moves and should emit a wheel up/down
572
- event on every third move.
573
-
574
- (*) Things are actually slightly more complicated than this. In general,
575
- it'll just be a plain old BUTTON_CLICKED state. But if there was another
576
- BUTTON_CLICKED within the last 2 * SP->mouse_wait milliseconds, then this
577
- must be a _double_ click, so we set the BUTTON_DOUBLE_CLICKED state. And
578
- if, within that time frame, there was a double or triple click, then we
579
- set the BUTTON_TRIPLE_CLICKED state. There isn't a "quad" or higher state,
580
- so if you quadruple-click the mouse, with each click separated by less
581
- than 2 * SP->mouse_wait milliseconds, then the messages sent will be
582
- BUTTON_CLICKED, BUTTON_DOUBLE_CLICKED, BUTTON_TRIPLE_CLICKED, and
583
- then another BUTTON_TRIPLE_CLICKED. */
584
-
585
- static int set_mouse( const int button_index, const int button_state,
586
- const LPARAM lParam)
587
- {
588
- int i, n_key_mouse_to_add = 1;
589
- POINT pt;
590
-
591
- pt.x = LOWORD( lParam);
592
- pt.y = HIWORD( lParam);
593
- if( button_index == -1) /* mouse moved, no button */
594
- n_key_mouse_to_add = 1;
595
- else
596
- {
597
- memset(&pdc_mouse_status, 0, sizeof(MOUSE_STATUS));
598
- if( button_index < PDC_MAX_MOUSE_BUTTONS)
599
- {
600
- if( button_index < 3)
601
- {
602
- pdc_mouse_status.button[button_index] = (short)button_state;
603
- pdc_mouse_status.changes = (1 << button_index);
604
- }
605
- else
606
- {
607
- pdc_mouse_status.xbutton[button_index - 3] = (short)button_state;
608
- pdc_mouse_status.changes = (0x40 << button_index);
609
- }
610
- }
611
- else /* actually a wheel mouse movement */
612
- { /* button_state = number of units moved */
613
- static int mouse_wheel_vertical_loc = 0;
614
- static int mouse_wheel_horizontal_loc = 0;
615
- const int mouse_wheel_sensitivity = 120;
616
-
617
- n_key_mouse_to_add = 0;
618
- if( button_index == VERTICAL_WHEEL_EVENT)
619
- {
620
- mouse_wheel_vertical_loc += button_state;
621
- while( mouse_wheel_vertical_loc > mouse_wheel_sensitivity / 2)
622
- {
623
- n_key_mouse_to_add++;
624
- mouse_wheel_vertical_loc -= mouse_wheel_sensitivity;
625
- pdc_mouse_status.changes |= PDC_MOUSE_WHEEL_UP;
626
- }
627
- while( mouse_wheel_vertical_loc < -mouse_wheel_sensitivity / 2)
628
- {
629
- n_key_mouse_to_add++;
630
- mouse_wheel_vertical_loc += mouse_wheel_sensitivity;
631
- pdc_mouse_status.changes |= PDC_MOUSE_WHEEL_DOWN;
632
- }
633
- }
634
- else /* must be a horizontal event: */
635
- {
636
- mouse_wheel_horizontal_loc += button_state;
637
- while( mouse_wheel_horizontal_loc > mouse_wheel_sensitivity / 2)
638
- {
639
- n_key_mouse_to_add++;
640
- mouse_wheel_horizontal_loc -= mouse_wheel_sensitivity;
641
- pdc_mouse_status.changes |= PDC_MOUSE_WHEEL_RIGHT;
642
- }
643
- while( mouse_wheel_horizontal_loc < -mouse_wheel_sensitivity / 2)
644
- {
645
- n_key_mouse_to_add++;
646
- mouse_wheel_horizontal_loc += mouse_wheel_sensitivity;
647
- pdc_mouse_status.changes |= PDC_MOUSE_WHEEL_LEFT;
648
- }
649
- }
650
- /* I think it may be that for wheel events, we */
651
- /* return x = y = -1, rather than getting the */
652
- /* actual mouse position. I don't like this, but */
653
- /* I like messing up existing apps even less. */
654
- pt.x = -PDC_cxChar;
655
- pt.y = -PDC_cyChar;
656
- /* ScreenToClient( PDC_hWnd, &pt); Wheel posns are in screen, */
657
- } /* not client, coords; gotta xform them */
658
- }
659
- pdc_mouse_status.x = pt.x / PDC_cxChar;
660
- pdc_mouse_status.y = pt.y / PDC_cyChar;
661
- /* if( SP->save_key_modifiers) */
662
- {
663
- int i, button_flags = 0;
664
-
665
- if( GetKeyState( VK_MENU) & 0x8000)
666
- button_flags |= PDC_BUTTON_ALT;
667
-
668
- if( GetKeyState( VK_SHIFT) & 0x8000)
669
- button_flags |= PDC_BUTTON_SHIFT;
670
-
671
- if( GetKeyState( VK_CONTROL) & 0x8000)
672
- button_flags |= PDC_BUTTON_CONTROL;
673
-
674
- for (i = 0; i < 3; i++)
675
- pdc_mouse_status.button[i] |= button_flags;
676
- for (i = 0; i < PDC_N_EXTENDED_MOUSE_BUTTONS; i++)
677
- pdc_mouse_status.xbutton[i] |= button_flags;
678
- }
679
- /* If there is already a KEY_MOUSE in the queue, we */
680
- /* don't really want to add another one. See above. */
681
- i = PDC_key_queue_low;
682
- while( i != PDC_key_queue_high)
683
- {
684
- if( PDC_key_queue[i] == KEY_MOUSE)
685
- {
686
- debug_printf( "Mouse key already in queue\n");
687
- return( 0);
688
- }
689
- i = (i + 1) % KEY_QUEUE_SIZE;
690
- }
691
- /* If the window is maximized, the click may occur just */
692
- /* outside the "real" screen area. If so, we again */
693
- /* don't want to add a key to the queue: */
694
- if( pdc_mouse_status.x >= PDC_n_cols || pdc_mouse_status.y >= PDC_n_rows)
695
- n_key_mouse_to_add = 0;
696
- /* OK, there isn't a KEY_MOUSE already in the queue. */
697
- /* So we'll add one (or zero or more, for wheel mice): */
698
- while( n_key_mouse_to_add--)
699
- add_key_to_queue( KEY_MOUSE);
700
- return( 0);
701
- }
702
-
703
- /* The following should be #defined in 'winuser.h', but such is */
704
- /* not always the case. The following fixes the exceptions: */
705
- #ifndef WM_MOUSEWHEEL
706
- #define WM_MOUSEWHEEL 0x020A
707
- #endif
708
- #ifndef WM_MOUSEHWHEEL
709
- #define WM_MOUSEHWHEEL 0x020E
710
- #endif
711
- #ifndef WM_XBUTTONDOWN
712
- #define WM_XBUTTONDOWN 0x020B
713
- #define WM_XBUTTONUP 0x020C
714
- #endif
715
- #ifndef MK_XBUTTON1
716
- #define MK_XBUTTON1 0x0020
717
- #define MK_XBUTTON2 0x0040
718
- #endif
719
-
720
- #ifdef USE_FALLBACK_FONT
721
- extern GLYPHSET *PDC_unicode_range_data;
722
- #endif /* #ifdef USE_FALLBACK_FONT */
723
-
724
- int PDC_blink_state = 0;
725
- #define TIMER_ID_FOR_BLINKING 0x2000
726
-
727
- /* When first loading a font, we use 'get_character_sizes' to briefly
728
- load the (non-bold, non-italic flavor of the) font, get its height and
729
- width, and call GetFontUnicodeRanges to determine which characters are
730
- actually available from that font. That set of ranges is used so that,
731
- when we come across characters not in the font, we can switch to a
732
- "fallback" font (Unifont, most likely). */
733
-
734
- static void get_character_sizes( const HWND hwnd,
735
- int *xchar_size, int *ychar_size)
736
- {
737
- HFONT hFont = PDC_get_font_handle( 0);
738
- HFONT prev_font;
739
- HDC hdc = GetDC (hwnd) ;
740
- TEXTMETRIC tm ;
741
- #ifdef USE_FALLBACK_FONT
742
- DWORD size;
743
- #endif
744
-
745
- prev_font = SelectObject (hdc, hFont);
746
- GetTextMetrics (hdc, &tm) ;
747
- #ifdef USE_FALLBACK_FONT
748
- assert( !PDC_unicode_range_data);
749
- size = GetFontUnicodeRanges( hdc, NULL);
750
- PDC_unicode_range_data = (GLYPHSET *)calloc( 1, size);
751
- PDC_unicode_range_data->cbThis = size;
752
- size = GetFontUnicodeRanges( hdc, PDC_unicode_range_data);
753
- #endif /* #ifdef USE_FALLBACK_FONT */
754
- SelectObject( hdc, prev_font);
755
- ReleaseDC (hwnd, hdc) ;
756
- DeleteObject( hFont);
757
- *xchar_size = tm.tmAveCharWidth ;
758
- *ychar_size = tm.tmHeight;
759
- }
760
-
761
- INLINE void sort_out_rect( RECT *rect)
762
- {
763
- int temp;
764
-
765
- if( rect->left > rect->right)
766
- {
767
- temp = rect->right;
768
- rect->right = rect->left;
769
- rect->left = temp;
770
- }
771
- if( rect->top > rect->bottom)
772
- {
773
- temp = rect->bottom;
774
- rect->bottom = rect->top;
775
- rect->top = temp;
776
- }
777
- }
778
-
779
- static int rectangle_from_chars_to_pixels( RECT *rect)
780
- {
781
- int rval = 1;
782
-
783
- if( rect->right == rect->left && rect->top == rect->bottom)
784
- rval = 0;
785
- sort_out_rect( rect);
786
- if( rect->top < 0)
787
- rval = 0;
788
- rect->right++;
789
- rect->bottom++;
790
- rect->left *= PDC_cxChar;
791
- rect->right *= PDC_cxChar;
792
- rect->top *= PDC_cyChar;
793
- rect->bottom *= PDC_cyChar;
794
- return( rval);
795
- }
796
-
797
- /* When updating the mouse rectangle, you _could_ just remove the old one
798
- and draw the new one. But that sometimes caused flickering if the mouse
799
- area was large. In such cases, it's better to determine what areas
800
- actually changed, and invert just those. So the following checks to
801
- see if two overlapping rectangles are being drawn (this is the norm)
802
- and figures out the area that actually needs to be flipped. It does
803
- seem to decrease flickering to near-zero. */
804
-
805
- static int PDC_selecting_rectangle = 1;
806
-
807
- int PDC_find_ends_of_selected_text( const int line,
808
- const RECT *rect, int *x)
809
- {
810
- int rval = 0, i;
811
-
812
- if( (rect->top - line) * (rect->bottom - line) <= 0
813
- && (rect->top != rect->bottom || rect->left != rect->right))
814
- {
815
- if( PDC_selecting_rectangle || rect->top == rect->bottom)
816
- {
817
- x[0] = min( rect->right, rect->left);
818
- x[1] = max( rect->right, rect->left);
819
- rval = 1;
820
- }
821
- else if( rect->top <= line && line <= rect->bottom)
822
- {
823
- x[0] = (line == rect->top ? rect->left : 0);
824
- x[1] = (line == rect->bottom ? rect->right : SP->cols - 1);
825
- rval = 1;
826
- }
827
- else if( rect->top >= line && line >= rect->bottom)
828
- {
829
- x[0] = (line == rect->bottom ? rect->right : 0);
830
- x[1] = (line == rect->top ? rect->left : SP->cols - 1);
831
- rval = 1;
832
- }
833
- }
834
- if( rval)
835
- for( i = 0; i < 2; i++)
836
- if( x[i] > SP->cols - 1)
837
- x[i] = SP->cols - 1;
838
- return( rval);
839
- }
840
-
841
- /* Called in only one place, so let's inline it */
842
-
843
- INLINE void show_mouse_rect( const HWND hwnd, RECT before, RECT after)
844
- {
845
- if( before.top > -1 || after.top > -1)
846
- if( memcmp( &after, &before, sizeof( RECT)))
847
- {
848
- const HDC hdc = GetDC( hwnd) ;
849
-
850
- if( PDC_selecting_rectangle)
851
- {
852
- const int show_before = rectangle_from_chars_to_pixels( &before);
853
- const int show_after = rectangle_from_chars_to_pixels( &after);
854
-
855
- if( show_before && show_after)
856
- {
857
- RECT temp;
858
-
859
- if( before.top < after.top)
860
- {
861
- temp = before; before = after; after = temp;
862
- }
863
- if( before.top < after.bottom && after.right > before.left
864
- && before.right > after.left)
865
- {
866
- const int tval = min( after.bottom, before.bottom);
867
-
868
- temp = after;
869
- temp.bottom = before.top;
870
- InvertRect( hdc, &temp);
871
-
872
- temp.top = temp.bottom;
873
- temp.bottom = tval;
874
- temp.right = max( after.right, before.right);
875
- temp.left = min( after.right, before.right);
876
- InvertRect( hdc, &temp);
877
-
878
- temp.right = max( after.left, before.left);
879
- temp.left = min( after.left, before.left);
880
- InvertRect( hdc, &temp);
881
-
882
- temp = (after.bottom > before.bottom ? after : before);
883
- temp.top = tval;
884
- InvertRect( hdc, &temp);
885
- }
886
- }
887
- else if( show_before)
888
- InvertRect( hdc, &before);
889
- else if( show_after)
890
- InvertRect( hdc, &after);
891
- }
892
- else /* _not_ selecting rectangle; selecting lines */
893
- {
894
- int line;
895
-
896
- for( line = 0; line < SP->lines; line++)
897
- {
898
- int x[4], n_rects = 0, i;
899
-
900
- n_rects = PDC_find_ends_of_selected_text( line, &before, x);
901
- n_rects += PDC_find_ends_of_selected_text( line, &after, x + n_rects * 2);
902
- if( n_rects == 2)
903
- if( x[0] == x[2] && x[1] == x[3])
904
- n_rects = 0; /* Rects are same & will cancel */
905
- for( i = 0; i < n_rects; i++)
906
- {
907
- RECT trect;
908
-
909
- trect.left = x[i + i];
910
- trect.right = x[i + i + 1];
911
- trect.top = line;
912
- trect.bottom = line;
913
- rectangle_from_chars_to_pixels( &trect);
914
- InvertRect( hdc, &trect);
915
- }
916
- }
917
- }
918
- ReleaseDC( hwnd, hdc) ;
919
- }
920
- }
921
-
922
- /* Cygwin lacks _splitpath, _wsplitpath. THE FOLLOWING ARE NOT FULLY
923
- TESTED IMPLEMENTATIONS OF THOSE TWO FUNCTIONS, because the only use we
924
- make of them is to get fname. (Though I did write a little test program,
925
- and they seem to work.) */
926
-
927
- #ifdef __CYGWIN__
928
- #ifdef PDC_WIDE
929
- static void my_wsplitpath( const wchar_t *path, wchar_t *drive,
930
- wchar_t *dir, wchar_t *fname, wchar_t *ext)
931
- {
932
- size_t i, loc = 0;
933
-
934
- assert( path);
935
- assert( fname);
936
- if( path[0] && path[1] == ':')
937
- {
938
- if( drive)
939
- {
940
- drive[0] = path[0];
941
- drive[1] = ':';
942
- drive[2] = '\0';
943
- }
944
- path += 2;
945
- }
946
- else if( drive)
947
- *drive = '\0';
948
- for( i = 0; path[i]; i++)
949
- if( path[i] == '/' || path[i] == '\\')
950
- loc = i + 1;
951
- if( dir)
952
- {
953
- memcpy( dir, path, loc * sizeof( wchar_t));
954
- dir[loc] = '\0';
955
- }
956
- if( loc)
957
- path += loc;
958
- loc = 0;
959
- while( path[loc] && path[loc] != '.')
960
- loc++;
961
- if( fname)
962
- {
963
- memcpy( fname, path, loc * sizeof( wchar_t));
964
- fname[loc] = '\0';
965
- }
966
- if( ext)
967
- wcscpy( ext, path + loc);
968
- }
969
- #endif /* #ifdef PDC_WIDE */
970
-
971
- static void my_splitpath( const char *path, char *drive,
972
- char *dir, char *fname, char *ext)
973
- {
974
- size_t i, loc = 0;
975
-
976
- assert( path);
977
- assert( fname);
978
- if( path[0] && path[1] == ':')
979
- {
980
- if( drive)
981
- {
982
- drive[0] = path[0];
983
- drive[1] = ':';
984
- drive[2] = '\0';
985
- }
986
- path += 2;
987
- }
988
- else if( drive)
989
- *drive = '\0';
990
- for( i = 0; path[i]; i++)
991
- if( path[i] == '/' || path[i] == '\\')
992
- loc = i + 1;
993
- if( dir)
994
- {
995
- memcpy( dir, path, loc * sizeof( char));
996
- dir[loc] = '\0';
997
- }
998
- if( loc)
999
- path += loc;
1000
- loc = 0;
1001
- while( path[loc] && path[loc] != '.')
1002
- loc++;
1003
- if( fname)
1004
- {
1005
- memcpy( fname, path, loc * sizeof( char));
1006
- fname[loc] = '\0';
1007
- }
1008
- if( ext)
1009
- strcpy( ext, path + loc);
1010
- }
1011
- #else /* non-Cygwin case : */
1012
- #define my_splitpath _splitpath
1013
- #define my_wsplitpath _wsplitpath
1014
- #define GOT_ARGV_ARGC
1015
- #endif /* #ifdef __CYGWIN__ */
1016
-
1017
- /* This function looks at the full command line, which includes a fully
1018
- specified path to the executable and arguments; and strips out just the
1019
- name of the app, with the arguments optionally appended. Hence,
1020
-
1021
- C:\PDCURSES\WINGUI\TESTCURS.EXE arg1 arg2
1022
-
1023
- would be reduced to 'Testcurs' (if include_args == 0) or
1024
- 'Testcurs arg1 arg2' (if include_args == 1). The former case is used to
1025
- create a (hopefully unique) registry key for the app, so that the app's
1026
- specific settings (screen and font size) will be stored for the next run.
1027
- The latter case is used to generate a default window title.
1028
-
1029
- Unfortunately, this code has to do some pretty strange things. In the
1030
- Unicode (PDC_WIDE) case, we really should use __wargv; but that pointer
1031
- may or may not be NULL. If it's NULL, we fall back on __argv. In at
1032
- least one case, where this code is compiled into a DLL using MinGW and
1033
- then used in an app compiled with MS Visual C, __argv isn't set either,
1034
- and we drop back to looking at GetCommandLine( ). Which leads to a real
1035
- oddity: GetCommandLine( ) may return something such as, say,
1036
-
1037
- "C:\PDCurses\WinGUI\testcurs.exe" -lRussian
1038
-
1039
- ...which, after being run through _splitpath or _wsplitpath, becomes
1040
-
1041
- testcurs.exe" -lRussian
1042
-
1043
- The .exe" is removed, and the command-line arguments shifted or removed,
1044
- depending on the value of include_args. Pretty strange stuff.
1045
-
1046
- However, if one calls Xinitscr( ) and passed command-line arguments when
1047
- starting this library, those arguments will be stored in PDC_argc and
1048
- PDC_argv, and will be used instead of GetCommandLine.
1049
- */
1050
-
1051
- #ifdef UNICODE
1052
- #define my_stprintf wsprintf
1053
- #define my_tcslen wcslen
1054
- #ifdef __CYGWIN__
1055
- /* Can't lowercase Unicode text in Cygwin */
1056
- #define my_tcslwr
1057
- #elif defined _MSC_VER
1058
- #define my_tcslwr _wcslwr
1059
- #else
1060
- #define my_tcslwr wcslwr
1061
- #endif /* __CYGWIN__ */
1062
- #define my_tcscat wcscat
1063
- #define my_tcscpy wcscpy
1064
- #define my_stscanf swscanf
1065
-
1066
- #else /* UNICODE */
1067
-
1068
- #define my_stprintf sprintf
1069
- #define my_tcslen strlen
1070
- #define my_tcslwr strlwr
1071
- #ifdef _MSC_VER
1072
- #define strlwr _strlwr
1073
- #endif
1074
- #define my_tcscat strcat
1075
- #define my_tcscpy strcpy
1076
- #define my_stscanf sscanf
1077
- #endif /* UNICODE */
1078
-
1079
-
1080
- static void get_app_name( TCHAR *buff, const size_t buff_size, const bool include_args)
1081
- {
1082
- int i;
1083
- size_t buff_space;
1084
- #ifdef GOT_ARGV_ARGC
1085
- int argc = (PDC_argc ? PDC_argc : __argc);
1086
- char **argv = (PDC_argc ? PDC_argv : __argv);
1087
- #else
1088
- int argc = PDC_argc;
1089
- char **argv = PDC_argv;
1090
- #endif
1091
-
1092
- #ifdef PDC_WIDE
1093
- wchar_t **wargv = __wargv;
1094
- #ifdef GOT_ARGV_ARGC
1095
- /* in case we can not access the array directly try to get it otherwise */
1096
- if( !wargv) {
1097
- wchar_t *cmd_linew = GetCommandLine( );
1098
- if (cmd_linew) {
1099
- wargv = CommandLineToArgvW (cmd_linew, &argc);
1100
- }
1101
- }
1102
- if( wargv)
1103
- {
1104
- my_wsplitpath( wargv[0], NULL, NULL, buff, NULL);
1105
- if ( include_args)
1106
- {
1107
- buff_space = buff_size - my_tcslen( buff) - 1;
1108
- for ( i = 1; i < argc; i++)
1109
- {
1110
- size_t arg_len = my_tcslen( wargv[i]) + 1;
1111
- if ( buff_space < arg_len) {
1112
- break;
1113
- }
1114
- buff_space -= arg_len;
1115
- wcscat( buff, L" ");
1116
- wcscat( buff, wargv[i]);
1117
- }
1118
- }
1119
- }
1120
- else
1121
- #endif /* #ifdef GOT_ARGV_ARGC */
1122
- if( argv)
1123
- {
1124
- char tbuff[MAX_PATH];
1125
- my_splitpath( argv[0], NULL, NULL, tbuff, NULL);
1126
- if ( include_args)
1127
- {
1128
- buff_space = buff_size - strlen( tbuff) - 1;
1129
- for ( i = 1; i < argc; i++)
1130
- {
1131
- size_t arg_len = strlen( argv[i]) + 1;
1132
- if ( buff_space < arg_len) {
1133
- break;
1134
- }
1135
- buff_space -= arg_len;
1136
- strcat( tbuff, " ");
1137
- strcat( tbuff, argv[i]);
1138
- }
1139
- }
1140
- mbstowcs( buff, tbuff, strlen( tbuff) + 1);
1141
- }
1142
- else /* no __argv or PDC_argv pointer available */
1143
- {
1144
- wchar_t *tptr;
1145
-
1146
- my_wsplitpath( GetCommandLine( ), NULL, NULL, buff, NULL);
1147
- my_tcslwr( buff + 1);
1148
- tptr = wcsstr( buff, L".exe\"");
1149
- if( tptr)
1150
- {
1151
- if( include_args)
1152
- memmove( tptr, tptr + 5, wcslen( tptr + 4) * sizeof( wchar_t));
1153
- else
1154
- *tptr = '\0';
1155
- }
1156
- }
1157
- #else /* non-Unicode case */
1158
- if( argv)
1159
- {
1160
- my_splitpath( argv[0], NULL, NULL, buff, NULL);
1161
- debug_printf( "Path: %s; exe: %s\n", argv[0], buff);
1162
- if ( include_args)
1163
- {
1164
- buff_space = buff_size - my_tcslen( buff) - 1;
1165
- for ( i = 1; i < argc; i++)
1166
- {
1167
- size_t arg_len = my_tcslen( argv[i]) + 1;
1168
- if ( buff_space < arg_len) {
1169
- break;
1170
- }
1171
- buff_space -= arg_len;
1172
- strcat( buff, " ");
1173
- strcat( buff, argv[i]);
1174
- }
1175
- }
1176
- }
1177
- else /* no __argv pointer available */
1178
- {
1179
- char *tptr;
1180
-
1181
- my_splitpath( GetCommandLine( ), NULL, NULL, buff, NULL);
1182
- strlwr( buff + 1);
1183
- tptr = strstr( buff, ".exe\"");
1184
- if( tptr)
1185
- {
1186
- if( include_args)
1187
- memmove( tptr, tptr + 5, strlen( tptr + 4));
1188
- else
1189
- *tptr = '\0';
1190
- }
1191
- }
1192
- #endif
1193
- my_tcslwr( buff + 1);
1194
- }
1195
-
1196
- /* This function extracts the first icon from the executable that is
1197
- executing this DLL */
1198
-
1199
- INLINE HICON get_app_icon( )
1200
- {
1201
- #ifdef PDC_WIDE
1202
- wchar_t filename[MAX_PATH];
1203
- #else
1204
- char filename[MAX_PATH];
1205
- #endif
1206
-
1207
- HICON icon = NULL;
1208
- if ( GetModuleFileName( NULL, filename, sizeof(filename) ) != 0 )
1209
- icon = ExtractIcon( 0, filename, 0 );
1210
- return icon;
1211
- }
1212
-
1213
- extern TCHAR PDC_font_name[];
1214
-
1215
- /* This flavor of Curses tries to store the window and font sizes on
1216
- an app-by-app basis. To do this, it uses the above get_app_name( )
1217
- function, then sets or gets a corresponding value from the Windoze
1218
- registry. The benefit should be that one can have one screen size/font
1219
- for, say, Testcurs, while having different settings for, say, Firework
1220
- or Rain or one's own programs. */
1221
-
1222
- INLINE int set_default_sizes_from_registry( const int n_cols, const int n_rows,
1223
- const int xloc, const int yloc, const int menu_shown)
1224
- {
1225
- DWORD is_new_key;
1226
- HKEY hNewKey;
1227
- long rval = RegCreateKeyEx( HKEY_CURRENT_USER, _T( "SOFTWARE\\PDCurses"),
1228
- 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
1229
- 0, &hNewKey, &is_new_key);
1230
-
1231
- if( rval == ERROR_SUCCESS)
1232
- {
1233
- TCHAR buff[180];
1234
- TCHAR key_name[MAX_PATH];
1235
- extern int PDC_font_size;
1236
-
1237
- if( IsZoomed( PDC_hWnd)) /* -1x-1 indicates a maximized window */
1238
- my_stprintf( buff,
1239
- _T( "-1x-1,%d,0,0,%d"), PDC_font_size, menu_shown);
1240
- else
1241
- my_stprintf( buff,
1242
- _T( "%dx%d,%d,%d,%d,%d"), n_cols, n_rows, PDC_font_size,
1243
- xloc, yloc, menu_shown);
1244
- my_stprintf( buff + my_tcslen( buff),
1245
- _T(";%d,%d,%d,%d:"),
1246
- min_lines, max_lines,
1247
- min_cols, max_cols);
1248
- my_tcscat( buff, PDC_font_name);
1249
-
1250
- get_app_name( key_name, MAX_PATH, FALSE);
1251
- rval = RegSetValueEx( hNewKey, key_name, 0, REG_SZ,
1252
- (BYTE *)buff, (DWORD)( my_tcslen( buff) * sizeof( TCHAR)));
1253
- RegCloseKey( hNewKey);
1254
- }
1255
- debug_printf( "Size: %d %d; %d\n", n_cols, n_rows, rval);
1256
- return( rval != ERROR_SUCCESS);
1257
- }
1258
-
1259
- /* If the window is maximized, there will usually be a fractional
1260
- character width at the right and bottom edges. The following code fills
1261
- that in with a black brush. It takes the "paint rectangle", the area
1262
- passed with a WM_PAINT message that specifies what chunk of the client
1263
- area needs to be redrawn.
1264
-
1265
- If the window is _not_ maximized, this shouldn't happen; the window
1266
- width/height should always be an integral multiple of the character
1267
- width/height, with no slivers at the right and bottom edges. */
1268
-
1269
- static void fix_up_edges( const HDC hdc, const RECT *rect)
1270
- {
1271
- const int x = PDC_n_cols * PDC_cxChar;
1272
- const int y = PDC_n_rows * PDC_cyChar;
1273
-
1274
- if( rect->right >= x || rect->bottom >= y)
1275
- {
1276
- const HBRUSH hOldBrush =
1277
- SelectObject( hdc, GetStockObject( BLACK_BRUSH));
1278
-
1279
- SelectObject( hdc, GetStockObject( NULL_PEN));
1280
- if( rect->right >= x)
1281
- Rectangle( hdc, x, rect->top, rect->right + 1, rect->bottom + 1);
1282
- if( rect->bottom >= y)
1283
- Rectangle( hdc, rect->left, y, rect->right + 1, rect->bottom + 1);
1284
- SelectObject( hdc, hOldBrush);
1285
- }
1286
- }
1287
-
1288
- static void adjust_font_size( const int font_size_change)
1289
- {
1290
- extern int PDC_font_size;
1291
-
1292
- PDC_font_size += font_size_change;
1293
- if( PDC_font_size < 2)
1294
- PDC_font_size = 2;
1295
- PDC_transform_line( 0, 0, 0, NULL); /* free any fonts */
1296
- get_character_sizes( PDC_hWnd, &PDC_cxChar, &PDC_cyChar);
1297
- /* When the font size changes, do we want to keep */
1298
- /* the window the same size (except to remove any */
1299
- /* fractional character)? Or do we keep the number */
1300
- /* of rows/columns the same? For the nonce, I'm */
1301
- /* keeping the window size fixed if the window is */
1302
- /* maximized, but keeping the number of rows/lines */
1303
- /* fixed if it's windowed. That's my opinion. If */
1304
- /* you disagree, I have others. */
1305
- if( IsZoomed( PDC_hWnd))
1306
- {
1307
- RECT client_rect;
1308
- HDC hdc;
1309
-
1310
- GetClientRect( PDC_hWnd, &client_rect);
1311
- PDC_n_rows = client_rect.bottom / PDC_cyChar;
1312
- PDC_n_cols = client_rect.right / PDC_cxChar;
1313
- keep_size_within_bounds( &PDC_n_rows, &PDC_n_cols);
1314
- PDC_resize_screen( PDC_n_rows, PDC_n_cols);
1315
- add_key_to_queue( KEY_RESIZE);
1316
- SP->resized = TRUE;
1317
- hdc = GetDC (PDC_hWnd) ;
1318
- GetClientRect( PDC_hWnd, &client_rect);
1319
- fix_up_edges( hdc, &client_rect);
1320
- ReleaseDC( PDC_hWnd, hdc) ;
1321
- }
1322
- else
1323
- {
1324
- PDC_resize_screen( PDC_n_rows, PDC_n_cols);
1325
- InvalidateRect( PDC_hWnd, NULL, FALSE);
1326
- }
1327
- }
1328
-
1329
- /* PDC_mouse_rect is the area currently highlit by dragging the */
1330
- /* mouse. It's global, sadly, because we need to ensure that */
1331
- /* the highlighting is respected when the text within that */
1332
- /* rectangle is redrawn by PDC_transform_line(). */
1333
- RECT PDC_mouse_rect = { -1, -1, -1, -1 };
1334
-
1335
- int PDC_setclipboard_raw( const char *contents, long length,
1336
- const bool translate_multibyte_to_wide_char);
1337
-
1338
- /* Called in only one place (when the left mouse button goes up), */
1339
- /* so we should inline it : */
1340
-
1341
- INLINE void HandleBlockCopy( void)
1342
- {
1343
- int i, j, len, x[2];
1344
- TCHAR *buff, *tptr;
1345
-
1346
- /* Make a first pass to determine how much text is blocked: */
1347
- for( i = len = 0; i < SP->lines; i++)
1348
- if( PDC_find_ends_of_selected_text( i, &PDC_mouse_rect, x))
1349
- len += x[1] - x[0] + 3;
1350
- buff = tptr = (TCHAR *)malloc( (len + 1) * sizeof( TCHAR));
1351
- /* Make second pass to copy that text to a buffer: */
1352
- for( i = len = 0; i < SP->lines; i++)
1353
- if( PDC_find_ends_of_selected_text( i, &PDC_mouse_rect, x))
1354
- {
1355
- const chtype *cptr = curscr->_y[i];
1356
-
1357
- for( j = 0; j < x[1] - x[0] + 1; j++)
1358
- tptr[j] = (TCHAR)cptr[j + x[0]];
1359
- while( j > 0 && tptr[j - 1] == ' ')
1360
- j--; /* remove trailing spaces */
1361
- tptr += j;
1362
- *tptr++ = (TCHAR)13;
1363
- *tptr++ = (TCHAR)10;
1364
- }
1365
- if( tptr != buff) /* at least one line read in */
1366
- {
1367
- tptr[-2] = '\0'; /* cut off the last CR/LF */
1368
- PDC_setclipboard_raw( (char *)buff, (long)( tptr - buff), FALSE);
1369
- }
1370
- free( buff);
1371
- }
1372
-
1373
- #define WM_ENLARGE_FONT (WM_USER + 1)
1374
- #define WM_SHRINK_FONT (WM_USER + 2)
1375
- #define WM_MARK_AND_COPY (WM_USER + 3)
1376
- #define WM_TOGGLE_MENU (WM_USER + 4)
1377
- #define WM_EXIT_GRACELESSLY (WM_USER + 5)
1378
- #define WM_CHOOSE_FONT (WM_USER + 6)
1379
-
1380
- static int add_resize_key = 1;
1381
-
1382
- /*man-start**************************************************************
1383
-
1384
- Resize limits
1385
- -------------
1386
-
1387
- ### Synopsis
1388
-
1389
- void PDC_set_resize_limits( const int new_min_lines,
1390
- const int new_max_lines,
1391
- const int new_min_cols,
1392
- const int new_max_cols);
1393
-
1394
- ### Description
1395
-
1396
- For platforms supporting resizable windows (SDLx, WinGUI, X11). Some
1397
- programs may be unprepared for a resize event; for these, calling
1398
- this function with the max and min limits equal ensures that no
1399
- user resizing can be done. Other programs may require at least a
1400
- certain number, and/or no more than a certain number, of columns
1401
- and/or lines.
1402
-
1403
- ### Portability
1404
-
1405
- PDCurses-only function.
1406
-
1407
- **man-end****************************************************************/
1408
-
1409
- void PDC_set_resize_limits( const int new_min_lines, const int new_max_lines,
1410
- const int new_min_cols, const int new_max_cols)
1411
- {
1412
- min_lines = max( new_min_lines, 2);
1413
- max_lines = max( new_max_lines, min_lines);
1414
- min_cols = max( new_min_cols, 2);
1415
- max_cols = max( new_max_cols, min_cols);
1416
- }
1417
-
1418
- /* The screen should hold the characters (PDC_cxChar * n_default_columns */
1419
- /* pixels wide, similarly high). In width, we need two frame widths, */
1420
- /* one on each side. Vertically, we need two frame heights, plus room */
1421
- /* for the application title and the menu. */
1422
-
1423
- static void adjust_window_size( int *xpixels, int *ypixels, int window_style,
1424
- const int menu_shown)
1425
- {
1426
- RECT rect;
1427
-
1428
- rect.left = rect.top = 0;
1429
- rect.right = *xpixels;
1430
- rect.bottom = *ypixels;
1431
- /* printf( "Adjusting to %d, %d\n", *xpixels, *ypixels); */
1432
- AdjustWindowRect( &rect, window_style, menu_shown);
1433
- *xpixels = rect.right - rect.left;
1434
- *ypixels = rect.bottom - rect.top;
1435
- }
1436
-
1437
- static int keep_size_within_bounds( int *lines, int *cols)
1438
- {
1439
- int rval = 0;
1440
-
1441
- if( *lines < min_lines)
1442
- {
1443
- *lines = min_lines;
1444
- rval = 1;
1445
- }
1446
- else if( *lines > max_lines)
1447
- {
1448
- *lines = max_lines;
1449
- rval = 2;
1450
- }
1451
- if( *cols < min_cols)
1452
- {
1453
- *cols = min_cols;
1454
- rval |= 4;
1455
- }
1456
- else if( *cols > max_cols)
1457
- {
1458
- *cols = max_cols;
1459
- rval |= 8;
1460
- }
1461
- return( rval);
1462
- }
1463
-
1464
- INLINE int get_default_sizes_from_registry( int *n_cols, int *n_rows,
1465
- int *xloc, int *yloc, int *menu_shown)
1466
- {
1467
- TCHAR data[100];
1468
- DWORD size_out = sizeof( data);
1469
- HKEY hKey = 0;
1470
- long rval = RegOpenKeyEx( HKEY_CURRENT_USER, _T( "SOFTWARE\\PDCurses"),
1471
- 0, KEY_READ, &hKey);
1472
-
1473
- if( !hKey)
1474
- return( 1);
1475
- if( rval == ERROR_SUCCESS)
1476
- {
1477
- TCHAR key_name[MAX_PATH];
1478
-
1479
- get_app_name( key_name, MAX_PATH, FALSE);
1480
- rval = RegQueryValueEx( hKey, key_name,
1481
- NULL, NULL, (BYTE *)data, &size_out);
1482
- if( rval == ERROR_SUCCESS)
1483
- {
1484
- extern int PDC_font_size;
1485
- int x = -1, y = -1, bytes_read = 0;
1486
-
1487
- my_stscanf( data, _T( "%dx%d,%d,%d,%d,%d;%d,%d,%d,%d:%n"),
1488
- &x, &y, &PDC_font_size,
1489
- xloc, yloc, menu_shown,
1490
- &min_lines, &max_lines,
1491
- &min_cols, &max_cols,
1492
- &bytes_read);
1493
- if( bytes_read > 0 && data[bytes_read - 1] == ':')
1494
- my_tcscpy( PDC_font_name, data + bytes_read);
1495
- if( n_cols)
1496
- *n_cols = x;
1497
- if( n_rows)
1498
- *n_rows = y;
1499
- if( *n_cols > 0 && *n_rows > 0) /* i.e., not maximized */
1500
- keep_size_within_bounds( n_rows, n_cols);
1501
- }
1502
- RegCloseKey( hKey);
1503
- }
1504
- if( rval != ERROR_SUCCESS)
1505
- debug_printf( "get_default_sizes_from_registry error: %d\n", rval);
1506
- return( rval != ERROR_SUCCESS);
1507
- }
1508
-
1509
- /* Ensure that the dragged rectangle */
1510
- /* is an even multiple of the char size */
1511
- INLINE void HandleSizing( WPARAM wParam, LPARAM lParam )
1512
- {
1513
- RECT *rect = (RECT *)lParam;
1514
- RECT window_rect, client_rect;
1515
- int hadd, vadd, width, height;
1516
- int n_rows, n_cols;
1517
- int rounded_width, rounded_height;
1518
-
1519
- GetWindowRect( PDC_hWnd, &window_rect);
1520
- GetClientRect( PDC_hWnd, &client_rect);
1521
- hadd = (window_rect.right - window_rect.left) - client_rect.right;
1522
- vadd = (window_rect.bottom - window_rect.top) - client_rect.bottom;
1523
- width = rect->right - rect->left - hadd;
1524
- height = rect->bottom - rect->top - vadd;
1525
-
1526
- n_cols = (width + PDC_cxChar / 2) / PDC_cxChar;
1527
- n_rows = (height + PDC_cyChar / 2) / PDC_cyChar;
1528
- keep_size_within_bounds( &n_rows, &n_cols);
1529
-
1530
- rounded_width = hadd + n_cols * PDC_cxChar;
1531
- rounded_height = vadd + n_rows * PDC_cyChar;
1532
-
1533
- if( wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT
1534
- || wParam == WMSZ_BOTTOMRIGHT)
1535
- rect->bottom = rect->top + rounded_height;
1536
- if( wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT
1537
- || wParam == WMSZ_TOPRIGHT)
1538
- rect->top = rect->bottom - rounded_height;
1539
- if( wParam == WMSZ_RIGHT || wParam == WMSZ_BOTTOMRIGHT
1540
- || wParam == WMSZ_TOPRIGHT)
1541
- rect->right = rect->left + rounded_width;
1542
- if( wParam == WMSZ_LEFT || wParam == WMSZ_BOTTOMLEFT
1543
- || wParam == WMSZ_TOPLEFT)
1544
- rect->left = rect->right - rounded_width;
1545
- }
1546
-
1547
- /* Under Wine, it appears that the code to force the window size to be
1548
- an integral number of columns and rows doesn't work. This is because
1549
- WM_SIZING messages aren't sent (this is apparently fixed as of Wine 1.7.18,
1550
- though I've not tried it yet; I'm still on Wine 1.6, the stable branch.)
1551
- You can therefore end up in a loop where the code keeps trying to resize a
1552
- window that isn't actually resizing. So, _when running in Wine only_,
1553
- we want that code not to be executed... which means having to figure out:
1554
- are we running under Wine? Which means that when PDCurses/WinGUI is
1555
- initialized, we set the following 'wine_version' pointer. One could
1556
- actually call wine_version(), if not NULL, to get the current Wine
1557
- version. */
1558
-
1559
- typedef const char *(CDECL *wine_version_func)(void);
1560
-
1561
- static wine_version_func wine_version;
1562
-
1563
- static void HandleSize( const WPARAM wParam, const LPARAM lParam)
1564
- {
1565
- static WPARAM prev_wParam = (WPARAM)-99;
1566
- const unsigned n_xpixels = LOWORD (lParam);
1567
- const unsigned n_ypixels = HIWORD (lParam);
1568
- unsigned new_n_rows, new_n_cols;
1569
-
1570
- debug_printf( "WM_SIZE: wParam %x %d %d %d\n", (unsigned)wParam,
1571
- n_xpixels, n_ypixels, SP->resized);
1572
- /* if( wine_version)
1573
- printf( "Wine version: %s\n", wine_version( )); */
1574
-
1575
-
1576
- if( wParam == SIZE_MINIMIZED )
1577
- {
1578
- prev_wParam = SIZE_MINIMIZED;
1579
- return;
1580
- }
1581
- new_n_rows = n_ypixels / PDC_cyChar;
1582
- new_n_cols = n_xpixels / PDC_cxChar;
1583
- debug_printf( "Size was %d x %d; will be %d x %d\n",
1584
- PDC_n_rows, PDC_n_cols, new_n_rows, new_n_cols);
1585
- SP->resized = FALSE;
1586
-
1587
- /* If the window will have a different number of rows */
1588
- /* or columns, we put KEY_RESIZE in the key queue. */
1589
- /* We don't do this if */
1590
- /* the resizing is the result of the window being */
1591
- /* initialized, or as a result of PDC_resize_screen */
1592
- /* being called. In the latter case, the user */
1593
- /* presumably already knows the screen's been resized. */
1594
- if( PDC_n_rows != (int)new_n_rows || PDC_n_cols != (int)new_n_cols)
1595
- {
1596
- PDC_n_cols = new_n_cols;
1597
- PDC_n_rows = new_n_rows;
1598
- debug_printf( "prev_wParam = %d; add_resize_key = %d\n",
1599
- (int)prev_wParam, add_resize_key);
1600
- if( prev_wParam != (WPARAM)-99 && add_resize_key)
1601
- {
1602
- /* don't add a key when the window is initialized */
1603
- add_key_to_queue( KEY_RESIZE);
1604
- SP->resized = TRUE;
1605
- }
1606
- }
1607
- else if( wine_version)
1608
- return;
1609
-
1610
- add_resize_key = 1;
1611
- if( wParam == SIZE_RESTORED &&
1612
- ( n_xpixels % PDC_cxChar || n_ypixels % PDC_cyChar))
1613
- {
1614
- int new_xpixels = PDC_cxChar * PDC_n_cols;
1615
- int new_ypixels = PDC_cyChar * PDC_n_rows;
1616
-
1617
- adjust_window_size( &new_xpixels, &new_ypixels,
1618
- GetWindowLong( PDC_hWnd, GWL_STYLE), menu_shown);
1619
- debug_printf( "Irregular size\n");
1620
- SetWindowPos( PDC_hWnd, 0, 0, 0,
1621
- new_xpixels, new_ypixels,
1622
- SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW);
1623
-
1624
- }
1625
-
1626
- /* If the window has been restored from minimized form, */
1627
- /* we should repaint. Otherwise, don't. */
1628
- prev_wParam = wParam;
1629
- }
1630
-
1631
- static void HandleMouseMove( WPARAM wParam, LPARAM lParam,
1632
- int* ptr_modified_key_to_return )
1633
- {
1634
- const int mouse_x = LOWORD( lParam) / PDC_cxChar;
1635
- const int mouse_y = HIWORD( lParam) / PDC_cyChar;
1636
- static int prev_mouse_x, prev_mouse_y;
1637
-
1638
- if( mouse_x != prev_mouse_x || mouse_y != prev_mouse_y)
1639
- {
1640
- int report_event = 0;
1641
-
1642
- prev_mouse_x = mouse_x;
1643
- prev_mouse_y = mouse_y;
1644
- if( wParam & MK_LBUTTON)
1645
- {
1646
- PDC_mouse_rect.left = mouse_x;
1647
- PDC_mouse_rect.top = mouse_y;
1648
- if( SP->_trap_mbe & BUTTON1_MOVED)
1649
- report_event |= PDC_MOUSE_MOVED | 1;
1650
- }
1651
- if( wParam & MK_MBUTTON)
1652
- if( SP->_trap_mbe & BUTTON2_MOVED)
1653
- report_event |= PDC_MOUSE_MOVED | 2;
1654
- if( wParam & MK_RBUTTON)
1655
- if( SP->_trap_mbe & BUTTON3_MOVED)
1656
- report_event |= PDC_MOUSE_MOVED | 4;
1657
-
1658
- #ifdef CANT_DO_THINGS_THIS_WAY
1659
- /* Logic would dictate the following lines. But with PDCurses */
1660
- /* as it's currently set up, we've run out of bits and there */
1661
- /* is no BUTTON4_MOVED or BUTTON5_MOVED. Perhaps we need to */
1662
- /* redefine _trap_mbe to be a 64-bit quantity? */
1663
- if( wParam & MK_XBUTTON1)
1664
- if( SP->_trap_mbe & BUTTON4_MOVED)
1665
- report_event |= PDC_MOUSE_MOVED | 8;
1666
- if( wParam & MK_XBUTTON2)
1667
- if( SP->_trap_mbe & BUTTON5_MOVED)
1668
- report_event |= PDC_MOUSE_MOVED | 16;
1669
- #endif
1670
-
1671
- if( !report_event)
1672
- if( SP->_trap_mbe & REPORT_MOUSE_POSITION)
1673
- report_event = PDC_MOUSE_POSITION;
1674
- if( report_event)
1675
- {
1676
- int i;
1677
-
1678
- pdc_mouse_status.changes = report_event;
1679
- for( i = 0; i < 3; i++)
1680
- {
1681
- pdc_mouse_status.button[i] = (((report_event >> i) & 1) ?
1682
- BUTTON_MOVED : 0);
1683
- }
1684
- *ptr_modified_key_to_return = 0;
1685
- set_mouse( -1, 0, lParam );
1686
- } /* -1 to 'set_mouse' signals mouse move; 0 is ignored */
1687
- }
1688
- }
1689
-
1690
- static void HandlePaint( HWND hwnd )
1691
- {
1692
- PAINTSTRUCT ps;
1693
- HDC hdc;
1694
- RECT rect;
1695
-
1696
- GetUpdateRect( hwnd, &rect, FALSE);
1697
- /* printf( "In HandlePaint: %ld %ld, %ld %ld\n",
1698
- rect.left, rect.top, rect.right, rect.bottom); */
1699
-
1700
- hdc = BeginPaint( hwnd, &ps);
1701
-
1702
- fix_up_edges( hdc, &rect);
1703
-
1704
- if( curscr && curscr->_y)
1705
- {
1706
- int i, x1, n_chars;
1707
-
1708
- x1 = rect.left / PDC_cxChar;
1709
- n_chars = rect.right / PDC_cxChar - x1 + 1;
1710
- if( n_chars > SP->cols - x1)
1711
- n_chars = SP->cols - x1;
1712
- if( n_chars > 0)
1713
- for( i = rect.top / PDC_cyChar; i <= rect.bottom / PDC_cyChar; i++)
1714
- if( i < SP->lines && curscr->_y[i])
1715
- PDC_transform_line_given_hdc( hdc, i, x1,
1716
- n_chars, curscr->_y[i] + x1);
1717
- }
1718
- EndPaint( hwnd, &ps );
1719
- }
1720
-
1721
- static bool key_already_handled = FALSE;
1722
-
1723
- static void HandleSyskeyDown( const WPARAM wParam, const LPARAM lParam,
1724
- int *ptr_modified_key_to_return )
1725
- {
1726
- const int shift_pressed = (GetKeyState( VK_SHIFT) & 0x8000);
1727
- const int ctrl_pressed = (GetKeyState( VK_CONTROL) & 0x8000);
1728
- const int alt_pressed = (GetKeyState( VK_MENU) & 0x8000);
1729
- const int extended = ((lParam & 0x01000000) != 0);
1730
- const int repeated = (int)( lParam >> 30) & 1;
1731
- const KPTAB *kptr = kptab + wParam;
1732
- int key = 0;
1733
- static int repeat_count;
1734
-
1735
- if( !repeated)
1736
- *ptr_modified_key_to_return = 0;
1737
-
1738
- if( repeated)
1739
- repeat_count++;
1740
- else
1741
- repeat_count = 0;
1742
- if( SP->return_key_modifiers && !repeated)
1743
- { /* See notes above this function */
1744
- if( wParam == VK_SHIFT)
1745
- {
1746
- if( GetKeyState( VK_LSHIFT) & 0x8000)
1747
- *ptr_modified_key_to_return = KEY_SHIFT_L;
1748
- else if( GetKeyState( VK_RSHIFT) & 0x8000)
1749
- *ptr_modified_key_to_return = KEY_SHIFT_R;
1750
- else if(( HIWORD( lParam) & 0xff) == 0x36)
1751
- *ptr_modified_key_to_return = KEY_SHIFT_R;
1752
- else
1753
- *ptr_modified_key_to_return = KEY_SHIFT_L;
1754
- }
1755
- if( wParam == VK_CONTROL)
1756
- *ptr_modified_key_to_return =
1757
- (extended ? KEY_CONTROL_R : KEY_CONTROL_L);
1758
- if( wParam == VK_MENU)
1759
- *ptr_modified_key_to_return =
1760
- (extended ? KEY_ALT_R : KEY_ALT_L);
1761
- }
1762
-
1763
- if( !key) /* it's not a shift, ctl, alt handled above */
1764
- {
1765
- if( extended && kptr->extended != 999)
1766
- kptr = ext_kptab + kptr->extended;
1767
-
1768
- if( alt_pressed)
1769
- key = kptr->alt;
1770
- else if( ctrl_pressed)
1771
- key = kptr->control;
1772
- else if( shift_pressed)
1773
- key = kptr->shift;
1774
- else
1775
- key = kptr->normal;
1776
- }
1777
-
1778
- /* On non-US keyboards, people hit Alt-Gr ("Alt-Ctrl" to */
1779
- /* those on US keyboards) to get characters not otherwise */
1780
- /* available: accented characters, local currency symbols, */
1781
- /* etc. So we default to suppressing Alt-Ctrl-letter combos. */
1782
- /* However, apps can set PDC_show_ctrl_alts if they know they're */
1783
- /* running on a US keyboard layout (or other layout that doesn't */
1784
- /* make special use of Ctrl-Alt... for example, I use the Dvorak */
1785
- /* layout; it's fine with PDC_show_ctrl_alts = 1.) */
1786
- if( key >= KEY_MIN && key <= KEY_MAX)
1787
- if( !ctrl_pressed || !alt_pressed || PDC_show_ctrl_alts)
1788
- {
1789
- add_key_to_queue( key);
1790
- if( wParam == VK_MULTIPLY || wParam == VK_DIVIDE
1791
- || wParam == VK_ADD || wParam == VK_SUBTRACT
1792
- || wParam == VK_RETURN)
1793
- if( !alt_pressed)
1794
- key_already_handled = TRUE;
1795
- }
1796
- pdc_key_modifiers = 0;
1797
- /* Save the key modifiers if required. Do this first to allow to
1798
- detect e.g. a pressed CTRL key after a hit of NUMLOCK. */
1799
-
1800
- if (SP->save_key_modifiers)
1801
- {
1802
- if( alt_pressed)
1803
- pdc_key_modifiers |= PDC_KEY_MODIFIER_ALT;
1804
-
1805
- if( shift_pressed)
1806
- pdc_key_modifiers |= PDC_KEY_MODIFIER_SHIFT;
1807
-
1808
- if( ctrl_pressed)
1809
- pdc_key_modifiers |= PDC_KEY_MODIFIER_CONTROL;
1810
-
1811
- if( GetKeyState( VK_NUMLOCK) & 1)
1812
- pdc_key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK;
1813
-
1814
- if( repeat_count)
1815
- pdc_key_modifiers |= PDC_KEY_MODIFIER_REPEAT;
1816
- }
1817
- }
1818
-
1819
- /* Blinking text is supposed to blink twice a second. Therefore,
1820
- HandleTimer( ) is called every .5 seconds.
1821
-
1822
- In truth, it's not so much 'blinking' as 'changing certain types of
1823
- text' that happens. If text is really blinking (i.e., PDC_set_blink(TRUE)
1824
- has been called), we need to flip that text. Or if text _was_ blinking
1825
- and we've just called PDC_set_blink(FALSE), all that text has to be
1826
- redrawn in 'standout' mode. Also, if PDC_set_line_color() has been
1827
- called, all text with left/right/under/over/strikeout lines needs to
1828
- be redrawn.
1829
-
1830
- So. After determining which attributes require redrawing (if any),
1831
- we run through all of 'curscr' and look for text with those attributes
1832
- set. If we find such text, we run it through PDC_transform_line.
1833
- (To speed matters up slightly, we skip over text at the start and end
1834
- of each line that lacks the desired attributes. We could conceivably
1835
- get more clever; as it stands, if the very first and very last
1836
- characters are blinking, we redraw the entire line, even though
1837
- everything in between may not require it. But it would probably be a
1838
- lot of code for little benefit.)
1839
-
1840
- Note that by default, we'll usually find that the line color hasn't
1841
- changed and the 'blink mode' is still FALSE. In that case, attr_to_seek
1842
- will be zero and the only thing we'll do here is to blink the cursor. */
1843
-
1844
- static void HandleTimer( const WPARAM wParam )
1845
- {
1846
- int i; /* see WndProc() notes */
1847
- extern int PDC_really_blinking; /* see 'pdcsetsc.c' */
1848
- static int previously_really_blinking = 0;
1849
- static int prev_line_color = -1;
1850
- chtype attr_to_seek = 0;
1851
-
1852
- if( prev_line_color != SP->line_color)
1853
- attr_to_seek = A_ALL_LINES;
1854
- if( PDC_really_blinking || previously_really_blinking)
1855
- attr_to_seek |= A_BLINK;
1856
- prev_line_color = SP->line_color;
1857
- previously_really_blinking = PDC_really_blinking;
1858
- PDC_blink_state ^= 1;
1859
- if( attr_to_seek)
1860
- {
1861
- for( i = 0; i < SP->lines; i++)
1862
- {
1863
- if( curscr->_y[i])
1864
- {
1865
- int j = 0, n_chars;
1866
- chtype *line = curscr->_y[i];
1867
-
1868
- /* skip over starting text that isn't blinking: */
1869
- while( j < SP->cols && !(*line & attr_to_seek))
1870
- {
1871
- j++;
1872
- line++;
1873
- }
1874
- n_chars = SP->cols - j;
1875
- /* then skip over text at the end that's not blinking: */
1876
- while( n_chars && !(line[n_chars - 1] & attr_to_seek))
1877
- {
1878
- n_chars--;
1879
- }
1880
- if( n_chars)
1881
- PDC_transform_line( i, j, n_chars, line);
1882
- }
1883
- /* else
1884
- MessageBox( 0, "NULL _y[] found\n", "PDCurses", MB_OK); */
1885
- }
1886
- }
1887
- if( SP->cursrow >=SP->lines || SP->curscol >= SP->cols
1888
- || SP->cursrow < 0 || SP->curscol < 0
1889
- || !curscr->_y || !curscr->_y[SP->cursrow])
1890
- debug_printf( "Cursor off-screen: %d %d, %d %d\n",
1891
- SP->cursrow, SP->curscol, SP->lines, SP->cols);
1892
- else if( PDC_CURSOR_IS_BLINKING)
1893
- PDC_transform_line( SP->cursrow, SP->curscol, 1,
1894
- curscr->_y[SP->cursrow] + SP->curscol);
1895
- }
1896
-
1897
- /* Options to enlarge/shrink the font are currently commented out. */
1898
-
1899
- static HMENU set_menu( void)
1900
- {
1901
- const HMENU hMenu = CreateMenu( );
1902
- #ifdef PDC_WIDE
1903
- AppendMenu( hMenu, MF_STRING, WM_CHOOSE_FONT, L"Font");
1904
- AppendMenu( hMenu, MF_STRING, WM_PASTE, L"Paste");
1905
- #else
1906
- AppendMenu( hMenu, MF_STRING, WM_CHOOSE_FONT, "Font");
1907
- AppendMenu( hMenu, MF_STRING, WM_PASTE, "Paste");
1908
- #endif
1909
- return( hMenu);
1910
- }
1911
-
1912
- INLINE void HandleMenuToggle( bool *ptr_ignore_resize)
1913
- {
1914
- const bool is_zoomed = IsZoomed( PDC_hWnd);
1915
- HMENU hMenu;
1916
-
1917
- menu_shown ^= 1;
1918
- hMenu = GetSystemMenu( PDC_hWnd, FALSE);
1919
- CheckMenuItem( hMenu, WM_TOGGLE_MENU, MF_BYCOMMAND
1920
- | (menu_shown ? MF_CHECKED : MF_UNCHECKED));
1921
-
1922
- if( !is_zoomed)
1923
- *ptr_ignore_resize = TRUE;
1924
- if( !menu_shown)
1925
- {
1926
- hMenu = GetMenu( PDC_hWnd); /* destroy existing menu */
1927
- DestroyMenu( hMenu);
1928
- hMenu = CreateMenu( ); /* then set an empty menu */
1929
- SetMenu( PDC_hWnd, hMenu);
1930
- }
1931
- else
1932
- {
1933
- SetMenu( PDC_hWnd, set_menu( ));
1934
- }
1935
- *ptr_ignore_resize = FALSE;
1936
-
1937
- if( !is_zoomed)
1938
- {
1939
- PDC_resize_screen( PDC_n_rows, PDC_n_cols );
1940
- }
1941
-
1942
- InvalidateRect( PDC_hWnd, NULL, FALSE);
1943
- }
1944
-
1945
- INLINE uint64_t milliseconds_since_1970( void)
1946
- {
1947
- FILETIME ft;
1948
- const uint64_t jd_1601 = 2305813; /* actually 2305813.5 */
1949
- const uint64_t jd_1970 = 2440587; /* actually 2440587.5 */
1950
- const uint64_t ten_million = 10000000;
1951
- const uint64_t diff = (jd_1970 - jd_1601) * ten_million * 86400;
1952
- uint64_t decimicroseconds_since_1970; /* i.e., time in units of 1e-7 seconds */
1953
-
1954
- GetSystemTimeAsFileTime( &ft);
1955
- decimicroseconds_since_1970 = ((uint64_t)ft.dwLowDateTime |
1956
- ((uint64_t)ft.dwHighDateTime << 32)) - diff;
1957
- return( decimicroseconds_since_1970 / 10000);
1958
- }
1959
-
1960
- /* Note that there are two types of WM_TIMER timer messages. One type
1961
- indicates that SP->mouse_wait milliseconds have elapsed since a mouse
1962
- button was pressed; that's handled as described in the above notes.
1963
- The other type, issued every half second, indicates that blinking
1964
- should take place. For these, HandleTimer() is called (see above).
1965
-
1966
- On WM_PAINT, we determine what parts of 'curscr' would be covered by
1967
- the update rectangle, and run those through PDC_transform_line.
1968
-
1969
- For determining left/right shift, alt, and control, I borrowed code
1970
- from SDL. Note that the Win32 version of PDCurses doesn't work correctly
1971
- here for Win9x; it just does GetKeyState( VK_LSHIFT), etc., which is
1972
- apparently not supported in Win9x. So no matter which shift (or alt or
1973
- Ctrl key) is hit, the right-hand variant is returned in that library.
1974
- The SDL handling, and hence the handling below, _does_ work on Win9x.
1975
- Note, though, that in Win9x, detection of the Shift keys is hardware
1976
- dependent; if you've an unusual keyboard, both Shift keys may be
1977
- detected as right, or both as left. */
1978
-
1979
- #if defined(_WIN32) && defined(__GNUC__)
1980
- #define ALIGN_STACK __attribute__((force_align_arg_pointer))
1981
- #else
1982
- #define ALIGN_STACK
1983
- #endif
1984
-
1985
- static LRESULT ALIGN_STACK CALLBACK WndProc (const HWND hwnd,
1986
- const UINT message,
1987
- const WPARAM wParam,
1988
- const LPARAM lParam)
1989
- {
1990
- int button_down = -1, button_up = -1;
1991
- static int mouse_buttons_pressed = 0;
1992
- static LPARAM mouse_lParam;
1993
- static uint64_t last_click_time[PDC_MAX_MOUSE_BUTTONS];
1994
- /* in millisec since 1970 */
1995
- static int modified_key_to_return = 0;
1996
- const RECT before_rect = PDC_mouse_rect;
1997
- static bool ignore_resize = FALSE;
1998
-
1999
- PDC_hWnd = hwnd;
2000
- if( !hwnd)
2001
- debug_printf( "Null hWnd: msg %u, wParam %x, lParam %lx\n",
2002
- message, wParam, lParam);
2003
-
2004
- switch (message)
2005
- {
2006
- case WM_SIZING:
2007
- HandleSizing( wParam, lParam );
2008
- return( TRUE );
2009
-
2010
- case WM_SIZE:
2011
- /* If ignore_resize = 1, don't bother resizing; */
2012
- /* the final window size has yet to be set */
2013
- if( ignore_resize == FALSE)
2014
- HandleSize( wParam, lParam);
2015
- return 0 ;
2016
-
2017
- case WM_MOUSEWHEEL:
2018
- debug_printf( "Mouse wheel: %x %lx\n", wParam, lParam);
2019
- modified_key_to_return = 0;
2020
- set_mouse( VERTICAL_WHEEL_EVENT, (short)( HIWORD(wParam)), lParam);
2021
- break;
2022
-
2023
- case WM_MOUSEHWHEEL:
2024
- debug_printf( "Mouse horiz wheel: %x %lx\n", wParam, lParam);
2025
- modified_key_to_return = 0;
2026
- set_mouse( HORIZONTAL_WHEEL_EVENT, (short)( HIWORD(wParam)), lParam);
2027
- break;
2028
-
2029
- case WM_MOUSEMOVE:
2030
- HandleMouseMove( wParam, lParam, &modified_key_to_return );
2031
- break;
2032
-
2033
- case WM_LBUTTONDOWN:
2034
- PDC_mouse_rect.left = PDC_mouse_rect.right =
2035
- LOWORD( lParam) / PDC_cxChar;
2036
- PDC_mouse_rect.top = PDC_mouse_rect.bottom =
2037
- HIWORD( lParam) / PDC_cyChar;
2038
- PDC_selecting_rectangle = (wParam & MK_SHIFT);
2039
- SetCapture( hwnd);
2040
- button_down = 0;
2041
- break;
2042
-
2043
- case WM_LBUTTONUP:
2044
- button_up = 0;
2045
- ReleaseCapture( );
2046
- if( (PDC_mouse_rect.left != PDC_mouse_rect.right ||
2047
- PDC_mouse_rect.top != PDC_mouse_rect.bottom) &&
2048
- (PDC_mouse_rect.right >= 0 && PDC_mouse_rect.left >= 0
2049
- && curscr && curscr->_y) )
2050
- {
2051
- /* RR: will crash sometimes */
2052
- /* As an example on double-click of the title bar */
2053
- HandleBlockCopy();
2054
- }
2055
- PDC_mouse_rect.top = PDC_mouse_rect.bottom = -1; /* now hide rect */
2056
- break;
2057
-
2058
- case WM_RBUTTONDOWN:
2059
- button_down = 2;
2060
- SetCapture( hwnd);
2061
- break;
2062
-
2063
- case WM_RBUTTONUP:
2064
- button_up = 2;
2065
- ReleaseCapture( );
2066
- break;
2067
-
2068
- case WM_MBUTTONDOWN:
2069
- button_down = 1;
2070
- SetCapture( hwnd);
2071
- break;
2072
-
2073
- case WM_MBUTTONUP:
2074
- button_up = 1;
2075
- ReleaseCapture( );
2076
- break;
2077
-
2078
- #if( PDC_MAX_MOUSE_BUTTONS >= 5)
2079
- /* WinGUI can support five mouse buttons. But some may wish */
2080
- /* to leave PDC_MAX_MOUSE_BUTTONS=3, for compatibility */
2081
- /* with older PDCurses libraries. Hence the above #if. */
2082
- case WM_XBUTTONDOWN:
2083
- button_down = ((wParam & MK_XBUTTON1) ? 3 : 4);
2084
- SetCapture( hwnd);
2085
- break;
2086
-
2087
- case WM_XBUTTONUP:
2088
- #ifdef WRONG_WAY
2089
- /* You'd think we'd use the following line, wouldn't you? */
2090
- /* But we can't, because an XBUTTONUP message doesn't actually */
2091
- /* tell you which button was released! So we'll assume that */
2092
- /* the released xbutton matches a pressed one; and we've kept */
2093
- /* track of which buttons are currently pressed. */
2094
- button_up = ((wParam & MK_XBUTTON1) ? 3 : 4);
2095
- #endif
2096
- button_up = (((mouse_buttons_pressed & 8) ||
2097
- pdc_mouse_status.xbutton[0] & BUTTON_PRESSED) ? 3 : 4);
2098
- ReleaseCapture( );
2099
- break;
2100
- #endif /* #if( PDC_MAX_MOUSE_BUTTONS >= 5) */
2101
-
2102
- case WM_MOVE:
2103
- return 0 ;
2104
-
2105
- case WM_ERASEBKGND: /* no need to erase background; it'll */
2106
- return( 0); /* all get painted over anyway */
2107
-
2108
- /* The WM_PAINT routine is sort of "borrowed" from doupdate( ) from */
2109
- /* refresh.c. I'm not entirely sure that this is what ought to be */
2110
- /* done, though it does appear to work correctly. */
2111
- case WM_PAINT:
2112
- if( hwnd && curscr )
2113
- {
2114
- HandlePaint( hwnd );
2115
- }
2116
- break;
2117
-
2118
- case WM_KEYUP:
2119
- case WM_SYSKEYUP:
2120
- if( wParam == VK_MENU && numpad_unicode_value)
2121
- {
2122
- modified_key_to_return = numpad_unicode_value;
2123
- numpad_unicode_value = 0;
2124
- pdc_key_modifiers = 0;
2125
- }
2126
- if( modified_key_to_return )
2127
- {
2128
- add_key_to_queue( modified_key_to_return );
2129
- modified_key_to_return = 0;
2130
- }
2131
- break;
2132
-
2133
- case WM_CHAR: /* _Don't_ add Shift-Tab; it's handled elsewhere */
2134
- if( wParam != 9 || !(GetKeyState( VK_SHIFT) & 0x8000))
2135
- if( !key_already_handled)
2136
- add_key_to_queue( (int)wParam );
2137
- key_already_handled = FALSE;
2138
- break;
2139
-
2140
- case WM_KEYDOWN:
2141
- case WM_SYSKEYDOWN:
2142
- if( wParam < 225 && wParam > 0 )
2143
- {
2144
- HandleSyskeyDown( wParam, lParam, &modified_key_to_return );
2145
- }
2146
- return 0 ;
2147
-
2148
- case WM_SYSCHAR:
2149
- return 0 ;
2150
-
2151
- case WM_TIMER:
2152
- /* see notes above this function */
2153
- if( wParam != TIMER_ID_FOR_BLINKING )
2154
- {
2155
- static const int remap_table[PDC_MAX_MOUSE_BUTTONS] =
2156
- { BUTTON1_PRESSED, BUTTON2_PRESSED, BUTTON3_PRESSED,
2157
- BUTTON4_PRESSED, BUTTON5_PRESSED };
2158
-
2159
- modified_key_to_return = 0;
2160
- if( SP && (SP->_trap_mbe & remap_table[wParam]))
2161
- set_mouse( (const int) wParam, BUTTON_PRESSED, mouse_lParam);
2162
- KillTimer( PDC_hWnd, (int)wParam);
2163
- mouse_buttons_pressed ^= (1 << wParam);
2164
- }
2165
- else if( SP && curscr && curscr->_y)
2166
- {
2167
- /* blink the blinking text */
2168
- HandleTimer( wParam );
2169
- }
2170
- break;
2171
-
2172
- case WM_CLOSE:
2173
- {
2174
- if( !PDC_shutdown_key[FUNCTION_KEY_SHUT_DOWN])
2175
- {
2176
- final_cleanup( );
2177
- PDC_bDone = TRUE;
2178
- exit( 0);
2179
- }
2180
- else
2181
- add_key_to_queue( PDC_shutdown_key[FUNCTION_KEY_SHUT_DOWN]);
2182
- }
2183
- return( 0);
2184
-
2185
- case WM_COMMAND:
2186
- case WM_SYSCOMMAND:
2187
- if( wParam == WM_EXIT_GRACELESSLY)
2188
- {
2189
- final_cleanup( );
2190
- PDC_bDone = TRUE;
2191
- exit( 0);
2192
- }
2193
- else if( wParam == WM_ENLARGE_FONT || wParam == WM_SHRINK_FONT)
2194
- {
2195
- adjust_font_size( (wParam == WM_ENLARGE_FONT) ? 1 : -1);
2196
- return( 0);
2197
- }
2198
- else if( wParam == WM_CHOOSE_FONT)
2199
- {
2200
- if( PDC_choose_a_new_font( ))
2201
- adjust_font_size( 0);
2202
- return( 0);
2203
- }
2204
- else if( wParam == WM_PASTE)
2205
- {
2206
- PDC_add_clipboard_to_key_queue( );
2207
- }
2208
- else if( wParam == WM_TOGGLE_MENU)
2209
- {
2210
- HandleMenuToggle( &ignore_resize);
2211
- }
2212
- break;
2213
-
2214
- case WM_DESTROY:
2215
- PDC_LOG(("WM_DESTROY\n"));
2216
- PostQuitMessage (0) ;
2217
- PDC_bDone = TRUE;
2218
- return 0 ;
2219
- }
2220
-
2221
- if( hwnd)
2222
- show_mouse_rect( hwnd, before_rect, PDC_mouse_rect);
2223
-
2224
- if( button_down >= 0)
2225
- {
2226
- modified_key_to_return = 0;
2227
- SetTimer( hwnd, button_down, SP->mouse_wait, NULL);
2228
- mouse_buttons_pressed |= (1 << button_down);
2229
- mouse_lParam = lParam;
2230
- }
2231
- if( button_up >= 0)
2232
- {
2233
- int message_to_send = -1;
2234
-
2235
- modified_key_to_return = 0;
2236
- if( (mouse_buttons_pressed >> button_up) & 1)
2237
- {
2238
- const uint64_t curr_click_time =
2239
- milliseconds_since_1970( );
2240
- static const int double_remap_table[PDC_MAX_MOUSE_BUTTONS] =
2241
- { BUTTON1_DOUBLE_CLICKED, BUTTON2_DOUBLE_CLICKED,
2242
- BUTTON3_DOUBLE_CLICKED, BUTTON4_DOUBLE_CLICKED,
2243
- BUTTON5_DOUBLE_CLICKED };
2244
- static const int triple_remap_table[PDC_MAX_MOUSE_BUTTONS] =
2245
- { BUTTON1_TRIPLE_CLICKED, BUTTON2_TRIPLE_CLICKED,
2246
- BUTTON3_TRIPLE_CLICKED, BUTTON4_TRIPLE_CLICKED,
2247
- BUTTON5_TRIPLE_CLICKED };
2248
- static int n_previous_clicks;
2249
-
2250
- if( curr_click_time <
2251
- last_click_time[button_up] + 2 * SP->mouse_wait)
2252
- n_previous_clicks++; /* 'n_previous_clicks' will be */
2253
- else /* zero for a "normal" click, 1 */
2254
- n_previous_clicks = 0; /* for a dblclick, 2 for a triple */
2255
-
2256
- if( n_previous_clicks >= 2 &&
2257
- (SP->_trap_mbe & triple_remap_table[button_up]))
2258
- message_to_send = BUTTON_TRIPLE_CLICKED;
2259
- else if( n_previous_clicks >= 1 &&
2260
- (SP->_trap_mbe & double_remap_table[button_up]))
2261
- message_to_send = BUTTON_DOUBLE_CLICKED;
2262
- else /* either it's not a doubleclick, or we aren't */
2263
- { /* checking for double clicks */
2264
- static const int remap_table[PDC_MAX_MOUSE_BUTTONS] =
2265
- { BUTTON1_CLICKED, BUTTON2_CLICKED, BUTTON3_CLICKED,
2266
- BUTTON4_CLICKED, BUTTON5_CLICKED };
2267
-
2268
- if( SP->_trap_mbe & remap_table[button_up])
2269
- message_to_send = BUTTON_CLICKED;
2270
- }
2271
- KillTimer( hwnd, button_up);
2272
- mouse_buttons_pressed ^= (1 << button_up);
2273
- last_click_time[button_up] = curr_click_time;
2274
- }
2275
- if( message_to_send == -1) /* might just send as a 'released' msg */
2276
- {
2277
- static const int remap_table[PDC_MAX_MOUSE_BUTTONS] =
2278
- { BUTTON1_RELEASED, BUTTON2_RELEASED, BUTTON3_RELEASED,
2279
- BUTTON4_RELEASED, BUTTON5_RELEASED };
2280
-
2281
- if( SP->_trap_mbe & remap_table[button_up])
2282
- message_to_send = BUTTON_RELEASED;
2283
- }
2284
- if( message_to_send != -1)
2285
- set_mouse( button_up, message_to_send, lParam);
2286
- }
2287
-
2288
- return DefWindowProc( hwnd, message, wParam, lParam) ;
2289
- }
2290
-
2291
- /* Default behaviour is that, when one clicks on the 'close' button, */
2292
- /* exit( 0) is called, just as in the SDL and X11 versions. But if */
2293
- /* one wishes, one can call PDC_set_shutdown_key to cause those */
2294
- /* buttons to put a specified character into the input queue. It's */
2295
- /* then the application's problem to exit gracefully, perhaps with */
2296
- /* messages such as 'are you sure' and so forth. */
2297
- /* If you've set a shutdown key, there's always a risk that the */
2298
- /* program will get stuck in a loop and never process said key. So */
2299
- /* when the key is set, a 'Kill' item is appended to the system menu */
2300
- /* so that the user still has some way to terminate the app, albeit */
2301
- /* with extreme prejudice (i.e., click on 'Kill' and exit is called */
2302
- /* and the app exits gracelessly.) */
2303
-
2304
- int PDC_set_function_key( const unsigned function, const int new_key)
2305
- {
2306
- int old_key = -1;
2307
-
2308
- if( function < PDC_MAX_FUNCTION_KEYS)
2309
- {
2310
- old_key = PDC_shutdown_key[function];
2311
- PDC_shutdown_key[function] = new_key;
2312
- }
2313
-
2314
- if( function == FUNCTION_KEY_SHUT_DOWN)
2315
- if( (new_key && !old_key) || (old_key && !new_key))
2316
- {
2317
- HMENU hMenu = GetSystemMenu( PDC_hWnd, FALSE);
2318
-
2319
- if( new_key)
2320
- AppendMenu( hMenu, MF_STRING, WM_EXIT_GRACELESSLY, _T( "Kill"));
2321
- else
2322
- RemoveMenu( hMenu, WM_EXIT_GRACELESSLY, MF_BYCOMMAND);
2323
- }
2324
- return( old_key);
2325
- }
2326
-
2327
- /* https://msdn.microsoft.com/en-us/library/windows/desktop/dd162826(v=vs.85).aspx
2328
- The code at the above link provides general methods for positioning a window
2329
- on a multiple-display setup. The only instance we're using is the
2330
- MONITOR_WORKAREA one, which ensures that even if monitor geometry changes,
2331
- the window will still be entirely on-screen.
2332
-
2333
- These functions entered the Win32 API with Windows 2000. If
2334
- MONITOR_DEFAULTTONEAREST isn't defined, we shouldn't try to do this. */
2335
-
2336
- #ifdef MONITOR_DEFAULTTONEAREST
2337
-
2338
- static void clip_or_center_rect_to_monitor( LPRECT prc)
2339
- {
2340
- HMONITOR hMonitor;
2341
- MONITORINFO mi;
2342
- RECT rc;
2343
- const int w = prc->right - prc->left;
2344
- const int h = prc->bottom - prc->top;
2345
-
2346
- hMonitor = MonitorFromRect(prc, MONITOR_DEFAULTTONEAREST);
2347
-
2348
- mi.cbSize = sizeof(mi);
2349
- GetMonitorInfo(hMonitor, &mi);
2350
-
2351
- rc = mi.rcMonitor;
2352
-
2353
- prc->left = max(rc.left, min(rc.right-w, prc->left));
2354
- prc->top = max(rc.top, min(rc.bottom-h, prc->top));
2355
- prc->right = prc->left + w;
2356
- prc->bottom = prc->top + h;
2357
- }
2358
-
2359
- static void clip_or_center_window_to_monitor( HWND hwnd)
2360
- {
2361
- RECT rc;
2362
-
2363
- GetWindowRect(hwnd, &rc);
2364
- clip_or_center_rect_to_monitor(&rc);
2365
- SetWindowPos(hwnd, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
2366
- }
2367
- #endif
2368
-
2369
- /* By default, the user cannot resize the window. This is because
2370
- many apps don't handle KEY_RESIZE, and one can get odd behavior
2371
- in such cases. There are two ways around this. If you call
2372
- PDC_set_resize_limits( ) before initwin( ), telling WinGUI exactly how
2373
- large/small the window can be, the window will be user-resizable. Or
2374
- you can set ttytype[0...3] to contain the resize limits. A call such as
2375
-
2376
- PDC_set_resize_limits( 42, 42, 135, 135);
2377
-
2378
- will result in the window being fixed at 42 lines by 135 columns.
2379
-
2380
- PDC_set_resize_limits( 20, 50, 70, 200);
2381
-
2382
- will mean the window can have 20 to 50 lines and 70 to 200 columns.
2383
- The user will be able to resize the window freely within those limits.
2384
- See 'newtest.c' (in the 'demos' folder) for an example.
2385
-
2386
- This function is used in only one place (PDC_scr_open( )), so
2387
- it's inlined. */
2388
-
2389
- INLINE int set_up_window( void)
2390
- {
2391
- /* create the dialog window */
2392
- WNDCLASS wndclass ;
2393
- HMENU hMenu;
2394
- HANDLE hInstance = GetModuleHandleA( NULL);
2395
- int n_default_columns = 80;
2396
- int n_default_rows = 25;
2397
- int xsize, ysize, window_style;
2398
- int xloc = CW_USEDEFAULT;
2399
- int yloc = CW_USEDEFAULT;
2400
- TCHAR WindowTitle[MAX_PATH];
2401
- const TCHAR *AppName = _T( "Curses_App");
2402
- HICON icon;
2403
- static bool wndclass_has_been_registered = FALSE;
2404
-
2405
- if( !hInstance)
2406
- debug_printf( "No instance: %d\n", GetLastError( ));
2407
- originally_focussed_window = GetForegroundWindow( );
2408
- debug_printf( "hInstance %x\nOriginal window %x\n", hInstance, originally_focussed_window);
2409
- /* set the window icon from the icon in the process */
2410
- icon = get_app_icon();
2411
- if( !icon )
2412
- icon = LoadIcon( NULL, IDI_APPLICATION);
2413
- if( !wndclass_has_been_registered)
2414
- {
2415
- ATOM rval;
2416
-
2417
- wndclass.style = CS_VREDRAW ;
2418
- wndclass.lpfnWndProc = WndProc ;
2419
- wndclass.cbClsExtra = 0 ;
2420
- wndclass.cbWndExtra = 0 ;
2421
- wndclass.hInstance = hInstance ;
2422
- wndclass.hIcon = icon;
2423
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
2424
- wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
2425
- wndclass.lpszMenuName = NULL ;
2426
- wndclass.lpszClassName = AppName ;
2427
-
2428
- rval = RegisterClass( &wndclass) ;
2429
- if( !rval)
2430
- {
2431
- const DWORD last_error = GetLastError( );
2432
-
2433
- debug_printf( "RegisterClass failed: GetLastError = %lx\n", last_error);
2434
- return( -1);
2435
- }
2436
- wndclass_has_been_registered = TRUE;
2437
- }
2438
-
2439
- get_app_name( WindowTitle, MAX_PATH, TRUE);
2440
- #ifdef PDC_WIDE
2441
- debug_printf( "WindowTitle = '%ls'\n", WindowTitle);
2442
- #endif
2443
-
2444
- get_default_sizes_from_registry( &n_default_columns, &n_default_rows, &xloc, &yloc,
2445
- &menu_shown);
2446
- if( PDC_n_rows > 2 && PDC_n_cols > 2)
2447
- {
2448
- n_default_columns = PDC_n_cols;
2449
- n_default_rows = PDC_n_rows;
2450
- }
2451
- if( ttytype[1])
2452
- PDC_set_resize_limits( (unsigned char)ttytype[0],
2453
- (unsigned char)ttytype[1],
2454
- (unsigned char)ttytype[2],
2455
- (unsigned char)ttytype[3]);
2456
- debug_printf( "Size %d x %d, loc %d x %d; menu %d\n",
2457
- n_default_columns, n_default_rows, xloc, yloc, menu_shown);
2458
- get_character_sizes( NULL, &PDC_cxChar, &PDC_cyChar);
2459
-
2460
- if( min_lines != max_lines || min_cols != max_cols)
2461
- window_style = ((n_default_columns == -1) ?
2462
- WS_MAXIMIZE | WS_OVERLAPPEDWINDOW : WS_OVERLAPPEDWINDOW);
2463
- else /* fixed-size window: looks "normal", but w/o a maximize box */
2464
- window_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
2465
-
2466
- if( n_default_columns == -1)
2467
- xsize = ysize = CW_USEDEFAULT;
2468
- else
2469
- {
2470
- keep_size_within_bounds( &n_default_rows, &n_default_columns);
2471
- xsize = PDC_cxChar * n_default_columns;
2472
- ysize = PDC_cyChar * n_default_rows;
2473
- adjust_window_size( &xsize, &ysize, window_style, menu_shown);
2474
- }
2475
-
2476
- PDC_hWnd = CreateWindow( AppName, WindowTitle, window_style,
2477
- xloc, yloc,
2478
- xsize, ysize,
2479
- NULL, (menu_shown ? set_menu( ) : NULL),
2480
- hInstance, NULL) ;
2481
-
2482
- if( !PDC_hWnd)
2483
- {
2484
- const DWORD last_error = GetLastError( );
2485
-
2486
- debug_printf( "CreateWindow failed; GetLastError = %ld", last_error);
2487
- return( -2);
2488
- }
2489
-
2490
- hMenu = GetSystemMenu( PDC_hWnd, FALSE);
2491
- AppendMenu( hMenu, MF_STRING | (menu_shown ? MF_CHECKED : MF_UNCHECKED), WM_TOGGLE_MENU, _T( "Menu"));
2492
- AppendMenu( hMenu, MF_STRING, WM_CHOOSE_FONT, _T( "Choose Font"));
2493
-
2494
- debug_printf( "menu set\n");
2495
-
2496
- ShowWindow (PDC_hWnd,
2497
- (n_default_columns == -1) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL);
2498
- debug_printf( "window shown\n");
2499
- ValidateRect( PDC_hWnd, NULL); /* don't try repainting */
2500
- UpdateWindow (PDC_hWnd) ;
2501
- debug_printf( "window updated\n");
2502
- SetTimer( PDC_hWnd, TIMER_ID_FOR_BLINKING, 500, NULL);
2503
- debug_printf( "timer set\n");
2504
-
2505
- #ifdef MONITOR_DEFAULTTONEAREST
2506
- /* if the window is off-screen, move it on screen. */
2507
- clip_or_center_window_to_monitor( PDC_hWnd);
2508
- #endif
2509
-
2510
- return( 0);
2511
- }
2512
-
2513
- /* open the physical screen -- allocate SP, miscellaneous intialization,
2514
- and may save the existing screen for later restoration.
2515
-
2516
- Deciding on a for-real maximum screen size has proven difficult.
2517
- But there is really no particularly good reason to set such a maximum.
2518
- If one does, you get some tricky issues: suppose the user drags the
2519
- window to create a screen larger than MAX_LINES or MAX_COLUMNS? My
2520
- hope is to evade that problem by just setting those constants to be...
2521
- well... unrealistically large. */
2522
-
2523
- #define MAX_LINES 50000
2524
- #define MAX_COLUMNS 50000
2525
-
2526
- int PDC_scr_open( int argc, char **argv)
2527
- {
2528
- int i, r, g, b;
2529
- HMODULE hntdll = GetModuleHandle( _T("ntdll.dll"));
2530
-
2531
- if( hntdll)
2532
- wine_version = (wine_version_func)GetProcAddress(hntdll, "wine_get_version");
2533
-
2534
- PDC_LOG(("PDC_scr_open() - called\n"));
2535
- SP = calloc(1, sizeof(SCREEN));
2536
- color_pair_indices = (short *)calloc(PDC_COLOR_PAIRS * 2, sizeof( short));
2537
- pdc_rgbs = (COLORREF *)calloc(N_COLORS, sizeof( COLORREF));
2538
- if (!SP || !color_pair_indices || !pdc_rgbs)
2539
- return ERR;
2540
-
2541
- debug_printf( "colors alloc\n");
2542
- COLORS = N_COLORS; /* should give this a try and see if it works! */
2543
- for( i = 0; i < 16; i++)
2544
- {
2545
- const int intensity = ((i & 8) ? 0xff : 0xc0);
2546
-
2547
- pdc_rgbs[i] = RGB( ((i & COLOR_RED) ? intensity : 0),
2548
- ((i & COLOR_GREEN) ? intensity : 0),
2549
- ((i & COLOR_BLUE) ? intensity : 0));
2550
- }
2551
- /* 256-color xterm extended palette: 216 colors in a
2552
- 6x6x6 color cube, plus 24 (not 50) shades of gray */
2553
- for( r = 0; r < 6; r++)
2554
- for( g = 0; g < 6; g++)
2555
- for( b = 0; b < 6; b++)
2556
- pdc_rgbs[i++] = RGB( r ? r * 40 + 55 : 0,
2557
- g ? g * 40 + 55 : 0,
2558
- b ? b * 40 + 55 : 0);
2559
- for( i = 0; i < 24; i++)
2560
- pdc_rgbs[i + 232] = RGB( i * 10 + 8, i * 10 + 8, i * 10 + 8);
2561
- SP->mouse_wait = PDC_CLICK_PERIOD;
2562
- SP->visibility = 0; /* no cursor, by default */
2563
- SP->curscol = SP->cursrow = 0;
2564
- SP->audible = TRUE;
2565
- SP->mono = FALSE;
2566
-
2567
- /* note: we parse the non-wide argc (see comment in header),
2568
- therefore using non-wide char handling here */
2569
- if( argc && argv) /* store a copy of the input arguments */
2570
- {
2571
- PDC_argc = argc;
2572
- PDC_argv = (char **)calloc( argc + 1, sizeof( char *));
2573
- for( i = 0; i < argc; i++)
2574
- {
2575
- PDC_argv[i] = (char *)malloc( strlen( argv[i]) + 1);
2576
- strcpy( PDC_argv[i], argv[i]);
2577
- }
2578
- }
2579
-
2580
- if( set_up_window( ))
2581
- {
2582
- fprintf( stderr, "set_up_window failed\n");
2583
- return ERR;
2584
- }
2585
- debug_printf( "Back from set_up_window\n");
2586
- while( !PDC_get_rows( )) /* wait for screen to be drawn and */
2587
- ; /* actual size to be determined */
2588
-
2589
- debug_printf( "Back from PDC_get_rows\n");
2590
- SP->lines = PDC_get_rows();
2591
- SP->cols = PDC_get_columns();
2592
-
2593
- if (SP->lines < 2 || SP->lines > MAX_LINES
2594
- || SP->cols < 2 || SP->cols > MAX_COLUMNS)
2595
- {
2596
- fprintf(stderr, "LINES value must be >= 2 and <= %d: got %d\n",
2597
- MAX_LINES, SP->lines);
2598
- fprintf(stderr, "COLS value must be >= 2 and <= %d: got %d\n",
2599
- MAX_COLUMNS, SP->cols);
2600
-
2601
- return ERR;
2602
- }
2603
-
2604
- /* PDC_reset_prog_mode(); doesn't do anything anyway */
2605
- debug_printf( "...we're done\n");
2606
- return OK;
2607
- }
2608
-
2609
- /* the core of resize_term() */
2610
-
2611
- int PDC_resize_screen( int nlines, int ncols)
2612
- {
2613
- if( !stdscr) /* window hasn't been created yet; we're */
2614
- { /* specifying its size before doing so */
2615
- PDC_n_rows = nlines;
2616
- PDC_n_cols = ncols;
2617
- return OK;
2618
- }
2619
- SP->resized = FALSE;
2620
- debug_printf( "Incoming: %d %d\n", nlines, ncols);
2621
- if( nlines >= 2 && ncols >= 2 && PDC_cxChar && PDC_cyChar && PDC_hWnd &&
2622
- !IsZoomed( PDC_hWnd) /* && WaitResult == WAIT_OBJECT_0 */)
2623
- {
2624
- RECT rect, client_rect;
2625
- int new_width;
2626
- int new_height;
2627
-
2628
- GetWindowRect( PDC_hWnd, &rect);
2629
- GetClientRect( PDC_hWnd, &client_rect);
2630
- debug_printf( "Outgoing: %d %d\n", nlines, ncols);
2631
- new_width = ncols * PDC_cxChar;
2632
- new_height = nlines * PDC_cyChar;
2633
-
2634
- if( new_width != client_rect.right || new_height != client_rect.bottom)
2635
- { /* check to make sure size actually changed */
2636
- add_resize_key = 0;
2637
- SetWindowPos( PDC_hWnd, 0, 0, 0,
2638
- new_width + (rect.right - rect.left) - client_rect.right,
2639
- new_height + (rect.bottom - rect.top) - client_rect.bottom,
2640
- SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW);
2641
- }
2642
- }
2643
- return OK;
2644
- }
2645
-
2646
- void PDC_reset_prog_mode(void)
2647
- {
2648
- PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
2649
- #ifdef NOT_CURRENTLY_IN_USE
2650
- if( PDC_bDone == FALSE && PDC_hWnd)
2651
- {
2652
- PDC_bDone = TRUE;
2653
- SetForegroundWindow( PDC_hWnd);
2654
- }
2655
- #endif
2656
- }
2657
-
2658
- void PDC_reset_shell_mode(void)
2659
- {
2660
- }
2661
-
2662
- void PDC_restore_screen_mode(int i)
2663
- {
2664
- }
2665
-
2666
- void PDC_save_screen_mode(int i)
2667
- {
2668
- }
2669
-
2670
- /* NOTE: as with PDC_init_color() (see below), this function has to
2671
- redraw all text with color attribute 'pair' to match the newly-set
2672
- foreground and background colors. The loops to go through every character
2673
- in curscr, looking for those that need to be redrawn and ignoring
2674
- those at the front and start of each line, are very similar. */
2675
-
2676
- static short get_pair( const chtype ch)
2677
- {
2678
- return( (short)( (ch & A_COLOR) >> PDC_COLOR_SHIFT));
2679
- }
2680
-
2681
- void PDC_init_pair( short pair, short fg, short bg)
2682
- {
2683
- if( color_pair_indices[pair] != fg ||
2684
- color_pair_indices[pair + PDC_COLOR_PAIRS] != bg)
2685
- {
2686
- color_pair_indices[pair] = fg;
2687
- color_pair_indices[pair + PDC_COLOR_PAIRS] = bg;
2688
- /* Possibly go through curscr and redraw everything with that color! */
2689
- if( curscr && curscr->_y)
2690
- {
2691
- int i;
2692
-
2693
- for( i = 0; i < SP->lines; i++)
2694
- if( curscr->_y[i])
2695
- {
2696
- int j = 0, n_chars;
2697
- chtype *line = curscr->_y[i];
2698
-
2699
- /* skip over starting text that isn't of the desired color: */
2700
- while( j < SP->cols && get_pair( *line) != pair)
2701
- {
2702
- j++;
2703
- line++;
2704
- }
2705
- n_chars = SP->cols - j;
2706
- /* then skip over text at the end that's not the right color: */
2707
- while( n_chars && get_pair( line[n_chars - 1]) != pair)
2708
- n_chars--;
2709
- if( n_chars)
2710
- PDC_transform_line( i, j, n_chars, line);
2711
- }
2712
- }
2713
- }
2714
- }
2715
-
2716
- int PDC_pair_content( short pair, short *fg, short *bg)
2717
- {
2718
- *fg = color_pair_indices[pair];
2719
- *bg = color_pair_indices[pair + PDC_COLOR_PAIRS];
2720
- return OK;
2721
- }
2722
-
2723
- bool PDC_can_change_color(void)
2724
- {
2725
- return TRUE;
2726
- }
2727
-
2728
- int PDC_color_content( short color, short *red, short *green, short *blue)
2729
- {
2730
- COLORREF col = pdc_rgbs[color];
2731
-
2732
- *red = DIVROUND(GetRValue(col) * 1000, 255);
2733
- *green = DIVROUND(GetGValue(col) * 1000, 255);
2734
- *blue = DIVROUND(GetBValue(col) * 1000, 255);
2735
-
2736
- return OK;
2737
- }
2738
-
2739
- /* We have an odd problem when changing colors with PDC_init_color(). On
2740
- palette-based systems, you just change the palette and the hardware takes
2741
- care of the rest. Here, though, we actually need to redraw any text that's
2742
- drawn in the specified color. So we gotta look at each character and see if
2743
- either the foreground or background matches the index that we're changing.
2744
- Then, that text gets redrawn. For speed/simplicity, the code looks for the
2745
- first and last character in each line that would be affected, then draws those
2746
- in between (frequently, this will be zero characters, i.e., no text on that
2747
- particular line happens to use the color index in question.) See similar code
2748
- above for PDC_init_pair(), to handle basically the same problem. */
2749
-
2750
- static int color_used_for_this_char( const chtype c, const int idx)
2751
- {
2752
- const int color = get_pair( c);
2753
- const int rval = (color_pair_indices[color] == idx ||
2754
- color_pair_indices[color + PDC_COLOR_PAIRS] == idx);
2755
-
2756
- return( rval);
2757
- }
2758
-
2759
- int PDC_init_color( short color, short red, short green, short blue)
2760
- {
2761
- const COLORREF new_rgb = RGB(DIVROUND(red * 255, 1000),
2762
- DIVROUND(green * 255, 1000),
2763
- DIVROUND(blue * 255, 1000));
2764
-
2765
- if( pdc_rgbs[color] != new_rgb)
2766
- {
2767
- pdc_rgbs[color] = new_rgb;
2768
- /* Possibly go through curscr and redraw everything with that color! */
2769
- if( curscr && curscr->_y)
2770
- {
2771
- int i;
2772
-
2773
- for( i = 0; i < SP->lines; i++)
2774
- if( curscr->_y[i])
2775
- {
2776
- int j = 0, n_chars;
2777
- chtype *line = curscr->_y[i];
2778
-
2779
- /* skip over starting text that isn't of the desired color: */
2780
- while( j < SP->cols
2781
- && !color_used_for_this_char( *line, color))
2782
- {
2783
- j++;
2784
- line++;
2785
- }
2786
- n_chars = SP->cols - j;
2787
- /* then skip over text at the end that's not the right color: */
2788
- while( n_chars &&
2789
- !color_used_for_this_char( line[n_chars - 1], color))
2790
- n_chars--;
2791
- if( n_chars)
2792
- PDC_transform_line( i, j, n_chars, line);
2793
- }
2794
- }
2795
- }
2796
- return OK;
2797
- }