NHDT->ANH, nethack->anethack, nhdat->anhdat
[aNetHack.git] / sys / wince / mhcmd.c
blobef93369a1f5e040b5e2526d280b4bfa25949316f
1 /* aNetHack 0.0.1 mhcmd.c $ANH-Date: 1432512800 2015/05/25 00:13:20 $ $ANH-Branch: master $:$ANH-Revision: 1.14 $ */
2 /* aNetHack may be freely redistributed. See license for details. */
4 #include "winMS.h"
5 #include <assert.h>
6 #include "mhcmd.h"
7 #include "mhinput.h"
8 #include "mhcolor.h"
10 static TCHAR szNHCmdWindowClass[] = TEXT("MSNethackCmdWndClass");
12 #ifndef C
13 #define C(c) (0x1f & (c))
14 #endif
16 /* cell status 0 */
17 #define NH_CST_CHECKED 1
19 /* fonts */
20 #define NH_CMDPAD_FONT_NORMAL 0
21 #define NH_CMDPAD_FONT_MAX 0
23 /* type of the cell */
24 #define NH_CELL_REG 0
25 #define NH_CELL_CTRL 1
26 #define NH_CELL_CAP 2
27 #define NH_CELL_SHIFT 3
28 #define NH_CELL_LAYOUT_NEW 4
29 #define NH_CELL_LAYOUT_MENU 5
31 #define NH_CMDSET_MAXSIZE 64
33 /* Keypad cell information
35 NHCmdPadCell.cell_type NHCmdPadCell.data
36 ----------- ----------
37 NH_CELL_REG (int)>=0 - index in the
38 current keypad layout set (loads a new layout)
39 -1 - restore default (saved) layout
40 NH_CELL_CTRL not used
41 NH_CELL_CAP not used
42 NH_CELL_SHIFT not used
43 NH_CELL_LAYOUT_NEW pointer to the new keypad layout
44 layout (NHCmdLayout*)
45 NH_CELL_LAYOUT_MENU pointer to the layout set (NHCmdSet* - if
46 NULL then nhcmdset_default is used)
48 typedef struct t_NHCmdPadCell {
49 UINT cmd_code; /* Windows command code (menu processing - not implemented
50 - set to -1) */
51 char f_char[16]; /* anethack char */
52 char text[16]; /* display text */
53 int image; /* >0 - image ID in IDB_KEYPAD bitmap
54 <=0 - absolute index of the font table */
55 int type; /* cell type */
56 int mult; /* cell width multiplier */
57 void *data; /* internal data for the cell type */
58 } NHCmdPadCell, *PNHCmdPadCell;
60 /* command layout */
61 typedef struct t_NHCmdLayout {
62 char name[64];
63 int rows;
64 int columns;
65 NHCmdPadCell cells[];
66 } NHCmdLayout, *PNHCmdLayout;
68 /* set of command layouts */
69 typedef struct t_NHCmdSet {
70 int count;
71 struct t_NHCmdSetElem {
72 PNHCmdLayout layout;
73 BOOL free_on_destroy;
74 } elements[NH_CMDSET_MAXSIZE];
75 } NHCmdSet, *PNHCmdSet;
77 /* display cell layout */
78 typedef struct t_NHCmdPadLayoutCell {
79 POINT orig; /* origin of the cell rect */
80 BYTE type; /* cell type */
81 int state; /* cell state */
82 } NHCmdPadLayoutCell, *PNHCmdPadLayoutCell;
84 /* command window data */
85 typedef struct mswin_anethack_cmd_window {
86 SIZE cell_size; /* cell size */
87 HFONT font[NH_CMDPAD_FONT_MAX + 1]; /* fonts for cell text */
88 HBITMAP images; /* key images map */
89 int active_cell; /* current active cell */
91 boolean is_caps; /* is CAPS selected */
92 boolean is_ctrl; /* is CRTL selected */
93 boolean is_shift; /* is SHIFT selected */
95 PNHCmdLayout layout_current; /* current layout */
96 PNHCmdLayout layout_save; /* saved layout */
97 PNHCmdPadLayoutCell cells; /* display cells */
99 #if defined(WIN_CE_SMARTPHONE)
100 PNHCmdLayout layout_selected; /* since we use
101 layout
102 command for menu also
103 we need to store the layout
104 that was
105 selected by a user
107 #endif
108 } NHCmdWindow, *PNHCmdWindow;
110 LRESULT CALLBACK NHCommandWndProc(HWND, UINT, WPARAM, LPARAM);
111 static void register_command_window_class();
112 static void LayoutCmdWindow(HWND hWnd);
113 static void SetCmdWindowLayout(HWND hWnd, PNHCmdLayout layout);
114 static int CellFromPoint(PNHCmdWindow data, POINT pt);
115 static void CalculateCellSize(HWND hWnd, LPSIZE pSize, LPSIZE windowSize);
116 static void HighlightCell(HWND hWnd, int cell, BOOL isSelected);
117 static void ActivateCell(HWND hWnd, int cell);
118 static void PushNethackCommand(const char *cmd_char_str, int is_ctrl);
120 /*------------------- keyboard keys layout functions -----------------------*/
121 PNHCmdLayout nhcmdlayout_create(const char *name, int rows, int columns);
122 void nhcmdlayout_init(PNHCmdLayout p, PNHCmdPadCell cells);
123 #define nhcmdlayout_rows(p) ((p)->rows)
124 #define nhcmdlayout_columns(p) ((p)->columns)
125 #define nhcmdlayout_row(p, x) (&((p)->cells[(p)->columns * (x)]))
126 #define nhcmdlayout_cell(p, x, y) (&((p)->cells[(p)->columns * (x) + (y)]))
127 #define nhcmdlayout_cell_direct(p, i) (&((p)->cells[(i)]))
128 void nhcmdlayout_destroy(PNHCmdLayout p);
130 /*----------------- keyboard keys layout set functions ---------------------*/
131 PNHCmdSet nhcmdset_create();
132 int nhcmdset_count(PNHCmdSet p);
133 PNHCmdLayout nhcmdset_get(PNHCmdSet p, int index);
134 const char *nhcmdset_get_name(PNHCmdSet p, int index);
135 void nhcmdset_add(PNHCmdSet p, PNHCmdLayout layout);
136 void nhcmdset_destroy(PNHCmdSet p);
138 /*-------------------- message handlers -----------------------------------*/
139 static void onPaint(HWND hWnd); // on WM_PAINT
140 static void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); // on WM_CREATE
141 static void onMouseDown(HWND hWnd, WPARAM wParam,
142 LPARAM lParam); // on WM_LBUTTONDOWN
143 static void onMouseMove(HWND hWnd, WPARAM wParam,
144 LPARAM lParam); // on WM_MOUSEMOVE
145 static void onMouseUp(HWND hWnd, WPARAM wParam,
146 LPARAM lParam); // on WM_LBUTTONUP
148 /*----------------------- static data -------------------------------------*/
149 static PNHCmdSet nhcmdset_current = 0;
150 static PNHCmdSet nhcmdset_default = 0;
152 /*---------------------- Pre-definde keyboard layouts --------------------*/
153 #ifdef WIN_CE_SMARTPHONE
155 /* dimensions of the command pad */
156 #define NH_CMDPAD_ROWS 4
157 #define NH_CMDPAD_COLS 3
158 #define NH_CMDPAD_CELLNUM (NH_CMDPAD_COLS * NH_CMDPAD_ROWS)
160 /* layout indexes */
161 #define NH_LAYOUT_GENERAL 0
162 #define NH_LAYOUT_MOVEMENT 1
163 #define NH_LAYOUT_ATTACK 2
164 #define NH_LAYOUT_ITEM_HANDLING 3
165 #define NH_LAYOUT_CONTROLS 4
166 #define NH_LAYOUT_ADV_MOVEMENT 5
167 #define NH_LAYOUT_ITEM_LOOKUP 6
168 #define NH_LAYOUT_WIZARD 7
170 /* template menu layout */
171 NHCmdPadCell cells_layout_menu[NH_CMDPAD_CELLNUM] = {
172 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
173 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
174 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
175 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
176 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
177 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
178 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
179 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
180 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
181 { -1, "", "<<", -NH_CMDPAD_FONT_NORMAL, NH_CELL_LAYOUT_NEW, 1, NULL },
182 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
183 { -1, "", ">>", -NH_CMDPAD_FONT_NORMAL, NH_CELL_LAYOUT_NEW, 1, NULL }
186 /* movement layout */
187 NHCmdPadCell cells_layout_movement[NH_CMDPAD_CELLNUM] = {
188 { -1, "7", "7", 1, NH_CELL_REG, 1, (void *) - 1 },
189 { -1, "8", "8", 2, NH_CELL_REG, 1, (void *) - 1 },
190 { -1, "9", "9", 3, NH_CELL_REG, 1, (void *) - 1 },
191 { -1, "4", "4", 4, NH_CELL_REG, 1, (void *) - 1 },
192 { -1, ".", ".", 5, NH_CELL_REG, 1, (void *) - 1 },
193 { -1, "6", "6", 6, NH_CELL_REG, 1, (void *) - 1 },
194 { -1, "1", "1", 7, NH_CELL_REG, 1, (void *) - 1 },
195 { -1, "2", "2", 8, NH_CELL_REG, 1, (void *) - 1 },
196 { -1, "3", "3", 9, NH_CELL_REG, 1, (void *) - 1 },
197 { -1, "<", "<", 10, NH_CELL_REG, 1, (void *) - 1 },
198 { -1, ">", ">", 12, NH_CELL_REG, 1, (void *) - 1 },
199 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
202 /* attack layout */
203 NHCmdPadCell cells_layout_attack[NH_CMDPAD_CELLNUM] = {
204 { -1, "t", "t", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
205 { -1, "w", "w", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
206 { -1, "x", "x", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
207 { -1, "f", "f", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
208 { -1, "z", "z", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
209 { -1, "Z", "Z", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
210 { -1, "r", "r", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
211 { -1, "a", "a", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
212 { -1, "q", "q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
213 { -1, "\x04", "^D", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
214 (void *) - 1 },
215 { -1, "F", "F", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
216 (void *) NH_LAYOUT_MOVEMENT },
217 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
220 /* item handling layout */
221 NHCmdPadCell cells_layout_item_handling[NH_CMDPAD_CELLNUM] = {
222 { -1, "W", "W", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
223 { -1, "P", "P", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
224 { -1, "d", "d", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
225 { -1, "T", "T", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
226 { -1, "R", "R", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
227 { -1, "D", "D", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
228 { -1, "=", "=", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
229 { -1, "i", "i", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
230 { -1, "Q", "Q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
231 { -1, "A", "A", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
232 { -1, "I", "I", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
233 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
236 /* General */
237 NHCmdPadCell cells_layout_general[NH_CMDPAD_CELLNUM] = {
238 { -1, "q", "q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
239 { -1, "e", "e", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
240 { -1, "l", "l", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
241 { -1, "s", "s", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
242 { -1, "E", "E", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
243 { -1, "\x01", "^A", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
244 (void *) - 1 },
245 { -1, "c", "c", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
246 { -1, "o", "o", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
247 { -1, "p", "p", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
248 { -1, ":", ":", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
249 { -1, ",", ",", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
250 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
253 /* game controls layout */
254 NHCmdPadCell cells_layout_game[NH_CMDPAD_CELLNUM] = {
255 { -1, "S", "S", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
256 { -1, "h", "h", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
257 { -1, "C", "C", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
258 { -1, "@", "@", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
259 { -1, "\\", "\\", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
260 { -1, "O", "O", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
261 { -1, "&", "&", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
262 { -1, "\x18", "^X", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
263 (void *) - 1 },
264 { -1, "\x10", "^P", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
265 (void *) - 1 },
266 { -1, "X", "X", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
267 { -1, "#", "#", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
268 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
271 /* advanced movement layout */
272 NHCmdPadCell cells_layout_adv_movement[NH_CMDPAD_CELLNUM] = {
273 { -1, "g", "g", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
274 (void *) NH_LAYOUT_MOVEMENT },
275 { -1, "G", "G", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
276 (void *) NH_LAYOUT_MOVEMENT },
277 { -1, "m", "m", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
278 (void *) NH_LAYOUT_MOVEMENT },
279 { -1, "M", "M", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
280 (void *) NH_LAYOUT_MOVEMENT },
281 { -1, "_", "_", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
282 { -1, "\x14", "^T", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
283 (void *) - 1 },
284 { -1, "j", "j", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
285 { -1, "<", "<", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
286 { -1, ">", ">", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
287 { -1, "^", "^", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
288 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
289 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
292 /* item lookup layout */
293 NHCmdPadCell cells_layout_lookup[NH_CMDPAD_CELLNUM] = {
294 { -1, ";", ";", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
295 { -1, "^", "^", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
296 { -1, "]", "]", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
297 { -1, ")", ")", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
298 { -1, "=", "=", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
299 { -1, "*", "*", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
300 { -1, "(", "(", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
301 { -1, "\"", "\"", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
302 { -1, "$", "$", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
303 { -1, "+", "+", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
304 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
305 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
308 /* wizard mode layout */
309 NHCmdPadCell cells_layout_wizard[NH_CMDPAD_CELLNUM] = {
310 { -1, "\x05", "^e", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
311 (void *) - 1 },
312 { -1, "\x06", "^f", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
313 (void *) - 1 },
314 { -1, "\x07", "^g", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
315 (void *) - 1 },
316 { -1, "\x09", "^i", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
317 (void *) - 1 },
318 { -1, "\x0f", "^o", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
319 (void *) - 1 },
320 { -1, "\x16", "^v", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
321 (void *) - 1 },
322 { -1, "\x17", "^w", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
323 (void *) - 1 },
324 { -1, "\x14", "^T", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1,
325 (void *) - 1 },
326 { -1, "#", "#", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
327 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
328 { -1, "", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
329 { -1, "X", "X", 13, NH_CELL_LAYOUT_MENU, 1, 0 }
332 #else /* !WIN_CE_SMARTPHONE */
334 /* dimensions of the command pad */
335 #define NH_CMDPAD_ROWS 4
336 #define NH_CMDPAD_COLS 14
337 #define NH_CMDPAD_CELLNUM (NH_CMDPAD_COLS * NH_CMDPAD_ROWS)
339 /* lowercase layout */
340 NHCmdPadCell cells_layout_mod1[NH_CMDPAD_ROWS * NH_CMDPAD_COLS] = {
341 { -1, "7", "7", 1, NH_CELL_REG, 1, (void *) - 1 },
342 { -1, "8", "8", 2, NH_CELL_REG, 1, (void *) - 1 },
343 { -1, "9", "9", 3, NH_CELL_REG, 1, (void *) - 1 },
344 { -1, "\x1b", "Esc", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 2, NULL },
345 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
346 NULL }, /* complement for ESC */
347 { -1, "?", "?", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
348 { -1, "*", "*", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
349 { -1, ",", ",", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
350 { -1, "/", "/", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
351 { -1, ":", ":", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
352 { -1, ";", ";", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
353 { -1, "-", "-", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
354 { -1, "#", "#", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
355 { -1, "^", "^", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
357 { -1, "4", "4", 4, NH_CELL_REG, 1, (void *) - 1 },
358 { -1, "5", "5", 5, NH_CELL_REG, 1, (void *) - 1 },
359 { -1, "6", "6", 6, NH_CELL_REG, 1, (void *) - 1 },
360 { -1, " ", "CAP", -NH_CMDPAD_FONT_NORMAL, NH_CELL_CAP, 2, NULL },
361 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
362 NULL }, /* complement for CAPS */
363 { -1, "a", "a", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
364 { -1, "b", "b", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
365 { -1, "c", "c", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
366 { -1, "d", "d", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
367 { -1, "e", "e", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
368 { -1, "f", "f", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
369 { -1, "g", "g", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
370 { -1, "h", "h", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
371 { -1, "i", "i", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
373 { -1, "1", "1", 7, NH_CELL_REG, 1, (void *) - 1 },
374 { -1, "2", "2", 8, NH_CELL_REG, 1, (void *) - 1 },
375 { -1, "3", "3", 9, NH_CELL_REG, 1, (void *) - 1 },
376 { -1, " ", "Shft", -NH_CMDPAD_FONT_NORMAL, NH_CELL_SHIFT, 2, NULL },
377 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
378 NULL }, /* complement for shift */
379 { -1, "j", "j", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
380 { -1, "k", "k", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
381 { -1, "l", "l", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
382 { -1, "m", "m", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
383 { -1, "n", "n", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
384 { -1, "o", "o", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
385 { -1, "p", "p", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
386 { -1, "q", "q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
387 { -1, "r", "r", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
389 { -1, "<", "<", 10, NH_CELL_REG, 1, (void *) - 1 },
390 { -1, ".", ".", 11, NH_CELL_REG, 1, (void *) - 1 },
391 { -1, ">", ">", 12, NH_CELL_REG, 1, (void *) - 1 },
392 { -1, " ", "Ctrl", -NH_CMDPAD_FONT_NORMAL, NH_CELL_CTRL, 2, NULL },
393 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
394 NULL }, /* complement for CTRL */
395 { -1, "s", "s", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
396 { -1, "t", "t", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
397 { -1, "u", "u", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
398 { -1, "v", "v", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
399 { -1, "w", "w", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
400 { -1, "x", "x", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
401 { -1, "y", "y", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
402 { -1, "z", "z", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
403 { -1, "\\", "\\", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 }
406 /* uppercase layout */
407 NHCmdPadCell cells_layout_mod2[-NH_CMDPAD_ROWS * -NH_CMDPAD_COLS] = {
408 { -1, "7", "7", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
409 { -1, "8", "8", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
410 { -1, "9", "9", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
411 { -1, "\x1b", "Esc", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 2, NULL },
412 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
413 NULL }, /* complement for ESC */
414 { -1, "?", "?", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
415 { -1, "*", "*", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
416 { -1, "[", "[", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
417 { -1, "(", "(", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
418 { -1, ")", ")", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
419 { -1, "+", "+", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
420 { -1, "=", "=", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
421 { -1, "\"", "\"", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
422 { -1, "$", "$", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
424 { -1, "4", "4", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
425 { -1, "5", "5", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
426 { -1, "6", "6", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
427 { -1, " ", "CAP", -NH_CMDPAD_FONT_NORMAL, NH_CELL_CAP, 2, NULL },
428 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
429 NULL }, /* complement for CAPS */
430 { -1, "A", "A", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
431 { -1, "B", "B", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
432 { -1, "C", "C", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
433 { -1, "D", "D", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
434 { -1, "E", "E", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
435 { -1, "F", "F", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
436 { -1, "G", "G", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
437 { -1, "H", "H", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
438 { -1, "I", "I", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
440 { -1, "1", "1", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
441 { -1, "2", "2", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
442 { -1, "3", "3", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
443 { -1, " ", "Shft", -NH_CMDPAD_FONT_NORMAL, NH_CELL_SHIFT, 2, NULL },
444 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
445 NULL }, /* complement for shift */
446 { -1, "J", "J", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
447 { -1, "K", "K", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
448 { -1, "L", "L", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
449 { -1, "M", "M", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
450 { -1, "N", "N", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
451 { -1, "O", "O", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
452 { -1, "P", "P", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
453 { -1, "Q", "Q", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
454 { -1, "R", "R", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
456 { -1, "<", "<", 10, NH_CELL_REG, 1, (void *) - 1 },
457 { -1, "0", "0", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
458 { -1, ">", ">", 12, NH_CELL_REG, 1, (void *) - 1 },
459 { -1, " ", "Ctrl", -NH_CMDPAD_FONT_NORMAL, NH_CELL_CTRL, 2, NULL },
460 { -1, " ", "", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 0,
461 NULL }, /* complement for CTRL */
462 { -1, "S", "S", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
463 { -1, "T", "T", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
464 { -1, "U", "U", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
465 { -1, "V", "V", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
466 { -1, "W", "W", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
467 { -1, "X", "X", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
468 { -1, "Y", "Y", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
469 { -1, "Z", "Z", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 },
470 { -1, "@", "@", -NH_CMDPAD_FONT_NORMAL, NH_CELL_REG, 1, (void *) - 1 }
473 #endif /* !WIN_CE_SMARTPHONE */
475 /*-------------------------------------------------------------------------*/
476 HWND
477 mswin_init_command_window()
479 static int run_once = 0;
480 HWND ret;
482 /* register window class */
483 if (!run_once) {
484 register_command_window_class();
485 run_once = 1;
488 /* create window */
489 ret = CreateWindow(
490 szNHCmdWindowClass, /* registered class name */
491 NULL, /* window name */
492 WS_CHILD | WS_CLIPSIBLINGS, /* window style */
493 0, /* horizontal position of window - set it later */
494 0, /* vertical position of window - set it later */
495 0, /* window width - set it later */
496 0, /* window height - set it later*/
497 GetNHApp()->hMainWnd, /* handle to parent or owner window */
498 NULL, /* menu handle or child identifier */
499 GetNHApp()->hApp, /* handle to application instance */
500 NULL); /* window-creation data */
501 if (!ret) {
502 panic("Cannot create command window");
504 return ret;
506 /*-------------------------------------------------------------------------*/
507 /* calculate mimimum window size */
508 void
509 mswin_command_window_size(HWND hwnd, LPSIZE sz)
511 SIZE cell_size;
512 PNHCmdWindow data;
513 data = (PNHCmdWindow) GetWindowLong(hwnd, GWL_USERDATA);
514 if (!data) {
515 sz->cx = sz->cy = 0;
516 } else {
517 CalculateCellSize(hwnd, &cell_size, sz);
518 sz->cx = max(cell_size.cx * nhcmdlayout_columns(data->layout_current)
519 + 2 * GetSystemMetrics(SM_CXBORDER),
520 sz->cx);
521 sz->cy = max(cell_size.cy * nhcmdlayout_rows(data->layout_current)
522 + 2 * GetSystemMetrics(SM_CYBORDER),
523 sz->cy);
526 /*-------------------------------------------------------------------------*/
527 void
528 register_command_window_class()
530 WNDCLASS wcex;
531 PNHCmdLayout plt;
532 ZeroMemory(&wcex, sizeof(wcex));
534 /* window class */
535 wcex.style = CS_NOCLOSE;
536 wcex.lpfnWndProc = (WNDPROC) NHCommandWndProc;
537 wcex.cbClsExtra = 0;
538 wcex.cbWndExtra = 0;
539 wcex.hInstance = GetNHApp()->hApp;
540 wcex.hIcon = NULL;
541 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
542 wcex.hbrBackground = mswin_get_brush(NHW_KEYPAD, MSWIN_COLOR_BG);
543 wcex.lpszMenuName = NULL;
544 wcex.lpszClassName = szNHCmdWindowClass;
546 if (!RegisterClass(&wcex)) {
547 panic("cannot register Map window class");
550 /* create default command set */
551 nhcmdset_current = nhcmdset_default = nhcmdset_create();
553 #ifdef WIN_CE_SMARTPHONE
554 plt = nhcmdlayout_create("General", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
555 nhcmdlayout_init(plt, cells_layout_general);
556 nhcmdset_add(nhcmdset_current, plt);
558 plt = nhcmdlayout_create("Movement", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
559 nhcmdlayout_init(plt, cells_layout_movement);
560 nhcmdset_add(nhcmdset_current, plt);
562 plt = nhcmdlayout_create("Attack", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
563 nhcmdlayout_init(plt, cells_layout_attack);
564 nhcmdset_add(nhcmdset_current, plt);
566 plt = nhcmdlayout_create("Item Handling", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
567 nhcmdlayout_init(plt, cells_layout_item_handling);
568 nhcmdset_add(nhcmdset_current, plt);
570 plt = nhcmdlayout_create("Game Controls", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
571 nhcmdlayout_init(plt, cells_layout_game);
572 nhcmdset_add(nhcmdset_current, plt);
574 plt = nhcmdlayout_create("Advanced Movement", NH_CMDPAD_ROWS,
575 NH_CMDPAD_COLS);
576 nhcmdlayout_init(plt, cells_layout_adv_movement);
577 nhcmdset_add(nhcmdset_current, plt);
579 plt = nhcmdlayout_create("Item Lookup", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
580 nhcmdlayout_init(plt, cells_layout_lookup);
581 nhcmdset_add(nhcmdset_current, plt);
583 if (wizard) {
584 plt =
585 nhcmdlayout_create("Wizard Mode", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
586 nhcmdlayout_init(plt, cells_layout_wizard);
587 nhcmdset_add(nhcmdset_current, plt);
590 #else /* ! WIN_CE_SMARTPHONE */
591 plt = nhcmdlayout_create("lowercase", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
592 nhcmdlayout_init(plt, cells_layout_mod1);
593 nhcmdset_add(nhcmdset_current, plt);
595 plt = nhcmdlayout_create("uppercase", NH_CMDPAD_ROWS, NH_CMDPAD_COLS);
596 nhcmdlayout_init(plt, cells_layout_mod2);
597 nhcmdset_add(nhcmdset_current, plt);
598 #endif /* WIN_CE_SMARTPHONE */
600 /*-------------------------------------------------------------------------*/
601 LRESULT CALLBACK
602 NHCommandWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
604 PNHCmdWindow data;
605 int i;
607 switch (message) {
608 case WM_CREATE:
609 onCreate(hWnd, wParam, lParam);
610 break;
612 case WM_PAINT:
613 onPaint(hWnd);
614 break;
616 case WM_SIZE:
617 LayoutCmdWindow(hWnd);
618 break;
620 case WM_LBUTTONDOWN:
621 onMouseDown(hWnd, wParam, lParam);
622 return 0;
624 case WM_MOUSEMOVE:
625 /* proceed only if if have mouse focus (set in onMouseDown() -
626 left mouse button is pressed) */
627 if (GetCapture() == hWnd) {
628 onMouseMove(hWnd, wParam, lParam);
629 return 0;
630 } else {
631 return 1;
633 break;
635 case WM_LBUTTONUP:
636 /* proceed only if if have mouse focus (set in onMouseDown()) */
637 if (GetCapture() == hWnd) {
638 onMouseUp(hWnd, wParam, lParam);
639 return 0;
640 } else {
641 return 1;
643 break;
645 case WM_DESTROY:
646 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
647 for (i = 0; i <= NH_CMDPAD_FONT_MAX; i++)
648 if (data->font[i])
649 DeleteObject(data->font[i]);
650 free(data);
651 SetWindowLong(hWnd, GWL_USERDATA, (LONG) 0);
652 break;
654 default:
655 return DefWindowProc(hWnd, message, wParam, lParam);
657 return FALSE;
659 /*-------------------------------------------------------------------------*/
660 void
661 onPaint(HWND hWnd)
663 PNHCmdWindow data;
664 PAINTSTRUCT ps;
665 HDC hDC;
666 int x, y;
667 TCHAR wbuf[BUFSZ];
668 HGDIOBJ saveFont;
669 BITMAP bm;
670 int cell_index;
672 /* get window data */
673 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
675 hDC = BeginPaint(hWnd, &ps);
677 if (!IsRectEmpty(&ps.rcPaint)) {
678 HGDIOBJ oldBr;
679 HBRUSH hbrPattern;
680 COLORREF OldBg, OldFg;
681 HPEN hPen;
682 HGDIOBJ hOldPen;
684 saveFont = SelectObject(hDC, data->font[NH_CMDPAD_FONT_NORMAL]);
685 OldBg = SetBkColor(hDC, mswin_get_color(NHW_KEYPAD, MSWIN_COLOR_BG));
686 OldFg =
687 SetTextColor(hDC, mswin_get_color(NHW_KEYPAD, MSWIN_COLOR_FG));
689 GetObject(data->images, sizeof(BITMAP), (LPVOID) &bm);
691 hbrPattern = CreatePatternBrush(data->images);
692 hPen = CreatePen(PS_SOLID, 1,
693 mswin_get_color(NHW_KEYPAD, MSWIN_COLOR_FG));
695 for (x = 0, cell_index = 0;
696 x < nhcmdlayout_rows(data->layout_current); x++)
697 for (y = 0; y < nhcmdlayout_columns(data->layout_current);
698 y++, cell_index++) {
699 RECT cell_rt;
700 POINT pt[5];
701 PNHCmdPadCell p_cell_data;
703 p_cell_data =
704 nhcmdlayout_cell_direct(data->layout_current, cell_index);
706 /* calculate the cell rectangle */
707 cell_rt.left = data->cells[cell_index].orig.x;
708 cell_rt.top = data->cells[cell_index].orig.y;
709 cell_rt.right = data->cells[cell_index].orig.x
710 + data->cell_size.cx * p_cell_data->mult;
711 cell_rt.bottom =
712 data->cells[cell_index].orig.y + data->cell_size.cy;
714 /* draw border */
715 hOldPen = SelectObject(hDC, hPen);
716 pt[0].x = cell_rt.left;
717 pt[0].y = cell_rt.top;
718 pt[1].x = cell_rt.right;
719 pt[1].y = cell_rt.top;
720 pt[2].x = cell_rt.right;
721 pt[2].y = cell_rt.bottom;
722 pt[3].x = cell_rt.left;
723 pt[3].y = cell_rt.bottom;
724 pt[4].x = cell_rt.left;
725 pt[4].y = cell_rt.top;
726 Polyline(hDC, pt, 5);
727 SelectObject(hDC, hOldPen);
729 /* calculate clipping rectangle for the text */
730 cell_rt.left++;
731 cell_rt.top++;
732 cell_rt.right--;
733 cell_rt.bottom--;
735 /* draw the cell text */
736 if (p_cell_data->image <= 0) {
737 SelectObject(hDC, data->font[-p_cell_data->image]);
738 DrawText(hDC, NH_A2W(p_cell_data->text, wbuf, BUFSZ),
739 strlen(p_cell_data->text), &cell_rt,
740 DT_CENTER | DT_VCENTER | DT_SINGLELINE
741 | DT_NOPREFIX);
742 } else {
743 /* draw bitmap */
744 int bmOffset;
745 RECT bitmap_rt;
747 bmOffset = (p_cell_data->image - 1) * bm.bmHeight;
749 bitmap_rt.left =
750 ((cell_rt.left + cell_rt.right)
751 - min(bm.bmHeight, (cell_rt.right - cell_rt.left)))
752 / 2;
753 bitmap_rt.top =
754 ((cell_rt.bottom + cell_rt.top)
755 - min(bm.bmHeight, (cell_rt.bottom - cell_rt.top)))
756 / 2;
757 bitmap_rt.right =
758 bitmap_rt.left
759 + min(bm.bmHeight, (cell_rt.right - cell_rt.left));
760 bitmap_rt.bottom =
761 bitmap_rt.top
762 + min(bm.bmHeight, (cell_rt.bottom - cell_rt.top));
764 SetBrushOrgEx(hDC, bitmap_rt.left - bmOffset,
765 bitmap_rt.top, NULL);
766 oldBr = SelectObject(hDC, hbrPattern);
767 PatBlt(hDC, bitmap_rt.left, bitmap_rt.top,
768 bitmap_rt.right - bitmap_rt.left,
769 bitmap_rt.bottom - bitmap_rt.top, PATCOPY);
770 SelectObject(hDC, oldBr);
773 /* invert the cell if it is selected */
774 if (data->cells[cell_index].state == NH_CST_CHECKED) {
775 IntersectRect(&cell_rt, &cell_rt, &ps.rcPaint);
776 PatBlt(hDC, cell_rt.left, cell_rt.top,
777 cell_rt.right - cell_rt.left,
778 cell_rt.bottom - cell_rt.top, DSTINVERT);
782 SetTextColor(hDC, OldFg);
783 SetBkColor(hDC, OldBg);
784 SelectObject(hDC, saveFont);
785 DeleteObject(hbrPattern);
786 DeleteObject(hPen);
788 EndPaint(hWnd, &ps);
790 /*-------------------------------------------------------------------------*/
791 void
792 onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
794 PNHCmdWindow data;
796 /* set window data */
797 data = (PNHCmdWindow) malloc(sizeof(NHCmdWindow));
798 if (!data)
799 panic("out of memory");
801 ZeroMemory(data, sizeof(NHCmdWindow));
802 SetWindowLong(hWnd, GWL_USERDATA, (LONG) data);
804 data->active_cell = -1;
806 /* load images bitmap */
807 data->images = LoadBitmap(GetNHApp()->hApp, MAKEINTRESOURCE(IDB_KEYPAD));
808 if (!data->images)
809 panic("cannot load keypad bitmap");
811 /* create default layouts */
812 data->layout_current = 0;
813 data->layout_save = 0;
814 data->cells = 0;
816 #if defined(WIN_CE_SMARTPHONE)
817 data->layout_selected = nhcmdset_get(nhcmdset_current, 0);
818 #endif
820 /* set default layout */
821 SetCmdWindowLayout(hWnd, nhcmdset_get(nhcmdset_current, 0));
823 /*-------------------------------------------------------------------------*/
824 void
825 LayoutCmdWindow(HWND hWnd)
827 RECT clrt;
828 SIZE windowSize;
829 PNHCmdWindow data;
830 int i, j;
831 int x, y;
832 LOGFONT lgfnt;
833 int index;
835 GetClientRect(hWnd, &clrt);
836 if (IsRectEmpty(&clrt))
837 return;
839 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
840 if (!data->layout_current)
841 return;
843 /* calculate cell size */
844 windowSize.cx = clrt.right - clrt.left;
845 windowSize.cy = clrt.bottom - clrt.top;
846 CalculateCellSize(hWnd, &data->cell_size, &windowSize);
848 /* initialize display cells aray */
849 x = 0;
850 y = 0;
851 for (i = 0, index = 0; i < nhcmdlayout_rows(data->layout_current); i++) {
852 for (j = 0; j < nhcmdlayout_columns(data->layout_current);
853 j++, index++) {
854 data->cells[index].orig.x = x;
855 data->cells[index].orig.y = y;
856 data->cells[index].type =
857 nhcmdlayout_cell_direct(data->layout_current, index)->type;
859 switch (data->cells[index].type) {
860 case NH_CELL_CTRL:
861 data->cells[index].state = data->is_ctrl ? NH_CST_CHECKED : 0;
862 break;
863 case NH_CELL_CAP:
864 data->cells[index].state = data->is_caps ? NH_CST_CHECKED : 0;
865 break;
866 case NH_CELL_SHIFT:
867 data->cells[index].state =
868 data->is_shift ? NH_CST_CHECKED : 0;
869 break;
870 default:
871 data->cells[index].state = 0;
874 x += data->cell_size.cx
875 * nhcmdlayout_cell_direct(data->layout_current, index)->mult;
877 x = 0;
878 y += data->cell_size.cy;
881 /* create font for display cell text */
882 for (i = 0; i <= NH_CMDPAD_FONT_MAX; i++)
883 if (data->font[i])
884 DeleteObject(data->font[i]);
886 ZeroMemory(&lgfnt, sizeof(lgfnt));
887 lgfnt.lfHeight = data->cell_size.cy; // height of font
888 lgfnt.lfWidth = 0; // average character width
889 lgfnt.lfEscapement = 0; // angle of escapement
890 lgfnt.lfOrientation = 0; // base-line orientation angle
891 lgfnt.lfWeight = FW_NORMAL; // font weight
892 lgfnt.lfItalic = FALSE; // italic attribute option
893 lgfnt.lfUnderline = FALSE; // underline attribute option
894 lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
895 lgfnt.lfCharSet = ANSI_CHARSET; // character set identifier
896 lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
897 lgfnt.lfClipPrecision = CLIP_CHARACTER_PRECIS; // clipping precision
898 lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
899 if (iflags.wc_font_message && *iflags.wc_font_message) {
900 lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
901 NH_A2W(iflags.wc_font_message, lgfnt.lfFaceName, LF_FACESIZE);
902 } else {
903 lgfnt.lfPitchAndFamily = VARIABLE_PITCH; // pitch and family
905 data->font[NH_CMDPAD_FONT_NORMAL] = CreateFontIndirect(&lgfnt);
907 InvalidateRect(hWnd, NULL, TRUE);
909 /*-------------------------------------------------------------------------*/
910 void
911 SetCmdWindowLayout(HWND hWnd, PNHCmdLayout layout)
913 PNHCmdWindow data;
914 int size;
916 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
917 if (data->layout_current == layout)
918 return;
920 data->layout_current = layout;
921 size = sizeof(NHCmdPadLayoutCell) * nhcmdlayout_rows(layout)
922 * nhcmdlayout_columns(layout);
923 data->cells = (PNHCmdPadLayoutCell) realloc(data->cells, size);
924 ZeroMemory(data->cells, size);
925 LayoutCmdWindow(hWnd);
927 /*-------------------------------------------------------------------------*/
928 void
929 onMouseDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
931 PNHCmdWindow data;
932 POINT mpt;
934 /* get mouse coordinates */
935 mpt.x = LOWORD(lParam);
936 mpt.y = HIWORD(lParam);
938 /* map mouse coordinates to the display cell */
939 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
940 data->active_cell = CellFromPoint(data, mpt);
941 if (data->active_cell == -1)
942 return;
944 /* set mouse focus to the current window */
945 SetCapture(hWnd);
947 /* invert the selection */
948 HighlightCell(hWnd, data->active_cell,
949 (data->cells[data->active_cell].state != NH_CST_CHECKED));
951 /*-------------------------------------------------------------------------*/
952 void
953 onMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
955 PNHCmdWindow data;
956 POINT mpt;
957 int newActiveCell;
959 /* get mouse coordinates */
960 mpt.x = LOWORD(lParam);
961 mpt.y = HIWORD(lParam);
963 /* map mouse coordinates to the display cell */
964 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
965 newActiveCell = CellFromPoint(data, mpt);
966 if (data->active_cell == -1)
967 return;
969 /* if mouse is within orginal display cell - select the cell otherwise
970 clear the selection */
971 switch (nhcmdlayout_cell_direct(data->layout_current, data->active_cell)
972 ->type) {
973 case NH_CELL_REG:
974 HighlightCell(hWnd, data->active_cell,
975 (newActiveCell == data->active_cell));
976 break;
978 case NH_CELL_CTRL:
979 HighlightCell(hWnd, data->active_cell,
980 ((newActiveCell == data->active_cell) ? !data->is_ctrl
981 : data->is_ctrl));
982 break;
984 case NH_CELL_CAP:
985 HighlightCell(hWnd, data->active_cell,
986 ((newActiveCell == data->active_cell) ? !data->is_caps
987 : data->is_caps));
988 break;
991 /*-------------------------------------------------------------------------*/
992 void
993 onMouseUp(HWND hWnd, WPARAM wParam, LPARAM lParam)
995 PNHCmdWindow data;
997 /* release mouse capture */
998 ReleaseCapture();
1000 /* get active display cell */
1001 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
1002 if (data->active_cell == -1)
1003 return;
1005 ActivateCell(hWnd, data->active_cell);
1007 data->active_cell = -1;
1009 /*-------------------------------------------------------------------------*/
1010 void
1011 ActivateCell(HWND hWnd, int cell)
1013 PNHCmdWindow data;
1014 PNHCmdPadCell p_cell_data;
1015 int i;
1017 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
1018 if (!data)
1019 return;
1020 p_cell_data = nhcmdlayout_cell_direct(data->layout_current, cell);
1022 /* act depending on the cell type:
1023 CAPS - change layout
1024 CTRL - modify CTRL status
1025 REG - place keyboard event on the anethack input queue
1027 switch (p_cell_data->type) {
1028 case NH_CELL_REG:
1029 if (data->is_ctrl) {
1030 PushNethackCommand(p_cell_data->f_char, 1);
1032 data->is_ctrl = 0;
1033 for (i = 0; i < nhcmdlayout_rows(data->layout_current)
1034 * nhcmdlayout_columns(data->layout_current);
1035 i++) {
1036 if (nhcmdlayout_cell_direct(data->layout_current, i)->type
1037 == NH_CELL_CTRL) {
1038 HighlightCell(hWnd, i, data->is_ctrl);
1041 } else {
1042 PushNethackCommand(p_cell_data->f_char, 0);
1044 HighlightCell(hWnd, cell, FALSE);
1046 // select a new layout if present
1047 i = (int) p_cell_data->data;
1048 if (i == -1) {
1049 if (data->layout_save)
1050 SetCmdWindowLayout(hWnd, data->layout_save);
1051 data->layout_save = NULL;
1052 } else {
1053 if (!data->layout_save)
1054 data->layout_save = data->layout_current;
1055 SetCmdWindowLayout(hWnd, nhcmdset_get(nhcmdset_current, i));
1058 if (!data->is_shift)
1059 break;
1060 // else fall through and reset the shift
1062 case NH_CELL_SHIFT:
1063 data->is_shift = !data->is_shift;
1064 SetCmdWindowLayout(hWnd, (data->is_shift ^ data->is_caps)
1065 ? nhcmdset_get(nhcmdset_current, 1)
1066 : nhcmdset_get(nhcmdset_current, 0));
1067 data->cells[cell].state = data->is_shift ? NH_CST_CHECKED : 0;
1068 InvalidateRect(hWnd, NULL, TRUE);
1069 break;
1071 case NH_CELL_CTRL:
1072 data->is_ctrl = !data->is_ctrl;
1073 HighlightCell(hWnd, cell, data->is_ctrl);
1074 break;
1076 case NH_CELL_CAP:
1077 data->is_caps = !data->is_caps;
1078 SetCmdWindowLayout(hWnd, (data->is_shift ^ data->is_caps)
1079 ? nhcmdset_get(nhcmdset_current, 1)
1080 : nhcmdset_get(nhcmdset_current, 0));
1081 data->cells[cell].state = data->is_caps ? NH_CST_CHECKED : 0;
1082 InvalidateRect(hWnd, NULL, TRUE);
1083 break;
1085 case NH_CELL_LAYOUT_NEW: {
1086 PNHCmdLayout pLayout;
1088 HighlightCell(hWnd, cell, FALSE);
1090 pLayout = (PNHCmdLayout) p_cell_data->data;
1091 if (pLayout) {
1092 SetCmdWindowLayout(hWnd, pLayout);
1094 } break;
1096 case NH_CELL_LAYOUT_MENU: {
1097 winid wid;
1098 int i;
1099 anything any;
1100 menu_item *selected = 0;
1101 PNHCmdSet pSet;
1103 HighlightCell(hWnd, cell, FALSE);
1105 pSet = (PNHCmdSet) p_cell_data->data;
1106 if (!pSet)
1107 pSet = nhcmdset_default;
1109 wid = mswin_create_nhwindow(NHW_MENU);
1110 mswin_start_menu(wid);
1111 for (i = 0; i < nhcmdset_count(pSet); i++) {
1112 any.a_void = nhcmdset_get(pSet, i);
1113 mswin_add_menu(wid, NO_GLYPH, &any, 'a' + i, 0, ATR_NONE,
1114 nhcmdset_get_name(pSet, i), FALSE);
1116 mswin_end_menu(wid, "Select keypad layout");
1117 i = select_menu(wid, PICK_ONE, &selected);
1118 mswin_destroy_nhwindow(wid);
1120 if (i == 1) {
1121 #if defined(WIN_CE_SMARTPHONE)
1122 data->layout_selected = (PNHCmdLayout) selected[0].item.a_void;
1123 #endif
1124 SetCmdWindowLayout(hWnd, (PNHCmdLayout) selected[0].item.a_void);
1126 } break;
1129 /*-------------------------------------------------------------------------*/
1131 CellFromPoint(PNHCmdWindow data, POINT pt)
1133 int i;
1134 for (i = 0; i < nhcmdlayout_rows(data->layout_current)
1135 * nhcmdlayout_columns(data->layout_current);
1136 i++) {
1137 RECT cell_rt;
1138 cell_rt.left = data->cells[i].orig.x;
1139 cell_rt.top = data->cells[i].orig.y;
1140 cell_rt.right =
1141 data->cells[i].orig.x
1142 + data->cell_size.cx
1143 * nhcmdlayout_cell_direct(data->layout_current, i)->mult;
1144 cell_rt.bottom = data->cells[i].orig.y + data->cell_size.cy;
1145 if (PtInRect(&cell_rt, pt))
1146 return i;
1148 return -1;
1150 /*-------------------------------------------------------------------------*/
1151 void
1152 CalculateCellSize(HWND hWnd, LPSIZE pSize, LPSIZE pWindowSize)
1154 HDC hdc;
1155 PNHCmdWindow data;
1156 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
1157 if (!data)
1158 return;
1160 hdc = GetDC(hWnd);
1162 /* if windows size is specified - attempt ro stretch cells across
1163 the the window size. If not - make default cell size based on
1164 10 points font. Make sure that cell cesize does not exceeds 20 points
1166 if (pWindowSize->cx > 0)
1167 pSize->cx =
1168 pWindowSize->cx / nhcmdlayout_columns(data->layout_current);
1169 else
1170 pSize->cx = 10 * GetDeviceCaps(hdc, LOGPIXELSX) / 72;
1171 pSize->cx = min(pSize->cx, 20 * GetDeviceCaps(hdc, LOGPIXELSX) / 72);
1173 if (pWindowSize->cy > 0)
1174 pSize->cy = pWindowSize->cy / nhcmdlayout_rows(data->layout_current);
1175 else
1176 pSize->cy = 10 * GetDeviceCaps(hdc, LOGPIXELSY) / 72;
1177 pSize->cy = min(pSize->cy, 20 * GetDeviceCaps(hdc, LOGPIXELSY) / 72);
1179 ReleaseDC(hWnd, hdc);
1181 /*-------------------------------------------------------------------------*/
1182 void
1183 HighlightCell(HWND hWnd, int cell, BOOL isSelected)
1185 HDC hDC;
1186 PNHCmdWindow data;
1187 int prevState;
1189 data = (PNHCmdWindow) GetWindowLong(hWnd, GWL_USERDATA);
1190 prevState = data->cells[cell].state;
1191 data->cells[cell].state = (isSelected) ? NH_CST_CHECKED : 0;
1193 if (prevState != data->cells[cell].state) {
1194 hDC = GetDC(hWnd);
1195 PatBlt(hDC, data->cells[cell].orig.x + 1,
1196 data->cells[cell].orig.y + 1,
1197 data->cell_size.cx
1198 * nhcmdlayout_cell_direct(data->layout_current, cell)
1199 ->mult
1200 - 2,
1201 data->cell_size.cy - 2, DSTINVERT);
1202 ReleaseDC(hWnd, hDC);
1205 /*-------------------------------------------------------------------------*/
1206 void
1207 PushNethackCommand(const char *cmd_char_str, int is_ctrl)
1209 while (*cmd_char_str) {
1210 if (is_ctrl) {
1211 NHEVENT_KBD(C(*cmd_char_str));
1212 } else {
1213 NHEVENT_KBD(*cmd_char_str);
1215 cmd_char_str++;
1219 /*-------------------------------------------------------------------------*/
1220 /*------------------- keyboard keys layout functions ----------------------*/
1221 /*-------------------------------------------------------------------------*/
1222 PNHCmdLayout
1223 nhcmdlayout_create(const char *name, int rows, int columns)
1225 PNHCmdLayout p;
1226 int i;
1228 i = sizeof(NHCmdLayout) + rows * columns * sizeof(NHCmdPadCell);
1229 p = (PNHCmdLayout) malloc(i);
1230 ZeroMemory(p, i);
1231 p->rows = rows;
1232 p->columns = columns;
1233 strncpy(p->name, name, sizeof(p->name) - 1);
1234 for (i = 0; i < rows * columns; i++) {
1235 p->cells[i].cmd_code = -1;
1236 p->cells[i].image = -NH_CMDPAD_FONT_NORMAL;
1237 p->cells[i].type = 1;
1238 p->cells[i].mult = 1;
1240 return p;
1242 /*-------------------------------------------------------------------------*/
1243 void
1244 nhcmdlayout_init(PNHCmdLayout p, PNHCmdPadCell cells)
1246 memcpy(p->cells, cells, p->rows * p->columns * sizeof(NHCmdPadCell));
1249 void
1250 nhcmdlayout_destroy(PNHCmdLayout p)
1252 free(p);
1255 /*-------------------------------------------------------------------------*/
1256 /*----------------- keyboard keys layout set functions --------------------*/
1257 /*-------------------------------------------------------------------------*/
1258 PNHCmdSet
1259 nhcmdset_create()
1261 PNHCmdSet p;
1262 p = (PNHCmdSet) malloc(sizeof(NHCmdSet));
1263 ZeroMemory(p, sizeof(NHCmdSet));
1264 return p;
1266 /*-------------------------------------------------------------------------*/
1268 nhcmdset_count(PNHCmdSet p)
1270 assert(p);
1271 return p->count;
1273 /*-------------------------------------------------------------------------*/
1274 PNHCmdLayout
1275 nhcmdset_get(PNHCmdSet p, int index)
1277 assert(p);
1278 assert(index >= 0 && index < p->count);
1279 return p->elements[index].layout;
1281 /*-------------------------------------------------------------------------*/
1282 const char *
1283 nhcmdset_get_name(PNHCmdSet p, int index)
1285 assert(p);
1286 assert(index >= 0 && index < p->count);
1287 return p->elements[index].layout->name;
1289 /*-------------------------------------------------------------------------*/
1290 void
1291 nhcmdset_add(PNHCmdSet p, PNHCmdLayout layout)
1293 assert(p);
1294 assert(p->count < NH_CMDSET_MAXSIZE);
1295 p->elements[p->count].layout = layout;
1296 p->elements[p->count].free_on_destroy = 0;
1297 p->count++;
1299 /*-------------------------------------------------------------------------*/
1300 void
1301 nhcmdset_destroy(PNHCmdSet p)
1303 int i = 0;
1304 assert(p);
1305 for (i = 0; i < p->count; i++) {
1306 if (p->elements[i].free_on_destroy) {
1307 nhcmdlayout_destroy(p->elements[i].layout);
1310 free(p);
1312 /*-------------------------------------------------------------------------*/
1314 #if defined(WIN_CE_SMARTPHONE)
1315 /* special keypad input handling for SmartPhone
1316 the phone keypad maps to VK_* as shown below.
1317 some keys might not be present, e.g. VK_TFLIP
1318 sofkey1 softkey2 VK_TSOFT1, VK_TSOFT2
1319 ^ VK_TUP
1320 < + > VK_TLEFT, VK_TACTION, VK_TRIGHT
1321 v VK_TDOWN
1322 home back VK_THOME, VK_TBACK
1323 talk end VK_TTALK, VK_TEND
1324 1 2 3 VK_T0..VK_T9
1325 4 5 6 ...
1326 7 8 9 ...
1327 * 0 # VK_TSTAR, VK_TPOUND
1328 other buttons include
1329 VK_TRECORD
1330 VK_TPOWER, VK_TVOLUMEUP, VK_TVOLUMEDOWN
1331 VK_TFLIP
1333 BOOL
1334 NHSPhoneTranslateKbdMessage(WPARAM wParam, LPARAM lParam, BOOL keyDown)
1336 PNHCmdWindow data;
1337 int index = -1;
1339 /* get window data */
1340 data = (PNHCmdWindow) GetWindowLong(GetNHApp()->hCmdWnd, GWL_USERDATA);
1341 if (!data)
1342 return FALSE;
1344 switch (wParam) {
1345 case VK_T0:
1346 index = 10;
1347 break;
1349 case VK_T1:
1350 index = 0;
1351 break;
1353 case VK_T2:
1354 index = 1;
1355 break;
1357 case VK_T3:
1358 index = 2;
1359 break;
1361 case VK_T4:
1362 index = 3;
1363 break;
1365 case VK_T5:
1366 index = 4;
1367 break;
1369 case VK_T6:
1370 index = 5;
1371 break;
1373 case VK_T7:
1374 index = 6;
1375 break;
1377 case VK_T8:
1378 index = 7;
1379 break;
1381 case VK_T9:
1382 index = 8;
1383 break;
1385 case VK_TSTAR:
1386 index = 9;
1387 break;
1389 case VK_TPOUND:
1390 index = 11;
1391 break;
1394 if (index >= 0) {
1395 HighlightCell(GetNHApp()->hCmdWnd, index, keyDown);
1396 if (keyDown)
1397 ActivateCell(GetNHApp()->hCmdWnd, index);
1398 return TRUE;
1399 } else {
1400 return FALSE;
1403 /*-------------------------------------------------------------------------*/
1404 void
1405 NHSPhoneSetKeypadFromString(const char *str)
1407 PNHCmdWindow data;
1408 PNHCmdSet p = 0;
1409 PNHCmdLayout layout_prev = 0;
1410 PNHCmdLayout layout_cur = 0;
1411 char buf[2][BUFSZ];
1412 int i, lcount;
1413 char *s;
1415 assert(NH_CMDPAD_ROWS == 4);
1417 data = (PNHCmdWindow) GetWindowLong(GetNHApp()->hCmdWnd, GWL_USERDATA);
1418 if (!data)
1419 return;
1421 p = nhcmdset_create();
1423 ZeroMemory(buf, sizeof(buf));
1424 if (sscanf(str, "%s or %s", buf[1], buf[0]) != 2) {
1425 ZeroMemory(buf, sizeof(buf));
1426 strncpy(buf[0], str, sizeof(buf[0]) - 1);
1429 lcount = 10; /* create new layout on the first iteration */
1430 for (i = 0; i < 2; i++) {
1431 s = buf[i];
1432 while (*s) {
1433 char c_start, c_end, c_char;
1435 /* parse character ranges */
1436 if (isalnum((c_start = s[0])) && s[1] == '-'
1437 && isalnum((c_end = s[2]))) {
1438 s += 2;
1439 } else {
1440 c_start = c_end = *s;
1443 for (c_char = c_start; c_char <= c_end; c_char++) {
1444 if (lcount >= 10) {
1445 /* create layout */
1446 lcount = 0;
1447 layout_prev = layout_cur;
1448 layout_cur = nhcmdlayout_create("noname", NH_CMDPAD_ROWS,
1449 NH_CMDPAD_COLS);
1450 nhcmdlayout_init(layout_cur, cells_layout_menu);
1452 nhcmdlayout_cell(layout_cur, 3, 0)->data = layout_prev;
1453 nhcmdlayout_cell(layout_cur, 3, 2)->data = 0;
1455 nhcmdset_add(p, layout_cur);
1456 p->elements[p->count - 1].free_on_destroy = 1;
1458 if (layout_prev) {
1459 nhcmdlayout_cell(layout_prev, 3, 2)->data =
1460 layout_cur;
1464 if (lcount == 9)
1465 lcount = 10; // skip '#'
1466 nhcmdlayout_cell_direct(layout_cur, lcount)->f_char[0] =
1467 c_char;
1468 if (c_char == '\033') {
1469 strcpy(nhcmdlayout_cell_direct(layout_cur, lcount)->text,
1470 "esc");
1471 nhcmdlayout_cell_direct(layout_cur, lcount)->image =
1472 14; /* 14 is a ESC symbol in IDB_KEYPAD */
1473 } else {
1474 nhcmdlayout_cell_direct(layout_cur, lcount)->text[0] =
1475 c_char;
1476 nhcmdlayout_cell_direct(layout_cur, lcount)->text[1] =
1477 '\x0';
1480 /* increment character count in the current layout */
1481 lcount++;
1484 /* prepareg next charcter from the source string */
1485 s++;
1489 /* install the new set */
1490 if (nhcmdset_current != nhcmdset_default)
1491 nhcmdset_destroy(nhcmdset_current);
1492 nhcmdset_current = p;
1493 SetCmdWindowLayout(GetNHApp()->hCmdWnd,
1494 nhcmdset_get(nhcmdset_current, 0));
1496 /*-------------------------------------------------------------------------*/
1497 void
1498 NHSPhoneSetKeypadDirection()
1500 PNHCmdWindow data;
1502 data = (PNHCmdWindow) GetWindowLong(GetNHApp()->hCmdWnd, GWL_USERDATA);
1503 if (!data)
1504 return;
1506 if (nhcmdset_current != nhcmdset_default)
1507 nhcmdset_destroy(nhcmdset_current);
1508 nhcmdset_current = nhcmdset_default;
1509 SetCmdWindowLayout(GetNHApp()->hCmdWnd,
1510 nhcmdset_get(nhcmdset_current, NH_LAYOUT_MOVEMENT));
1512 /*-------------------------------------------------------------------------*/
1513 void
1514 NHSPhoneSetKeypadDefault()
1516 PNHCmdWindow data;
1518 data = (PNHCmdWindow) GetWindowLong(GetNHApp()->hCmdWnd, GWL_USERDATA);
1519 if (!data)
1520 return;
1522 if (nhcmdset_current != nhcmdset_default)
1523 nhcmdset_destroy(nhcmdset_current);
1524 nhcmdset_current = nhcmdset_default;
1525 SetCmdWindowLayout(GetNHApp()->hCmdWnd,
1526 data->layout_selected
1527 ? data->layout_selected
1528 : nhcmdset_get(nhcmdset_current, 0));
1531 #endif /* defined (WIN_CE_SMARTHPONE) */