NHDT->ANH, nethack->anethack, nhdat->anhdat
[aNetHack.git] / win / gem / wingem1.c
blobbb4a9542efac70208d8b59ea138d4af6af6289f9
1 /* aNetHack 0.0.1 wingem1.c $ANH-Date: 1433806613 2015/06/08 23:36:53 $ $ANH-Branch: master $:$ANH-Revision: 1.13 $ */
2 /* Copyright (c) Christian Bressler 1999 */
3 /* aNetHack may be freely redistributed. See license for details. */
5 #define __TCC_COMPAT__
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <time.h>
10 #include <unistd.h>
11 #include <ctype.h>
12 #include <e_gem.h>
13 #include <string.h>
15 #include "gem_rsc.h"
16 #include "load_img.h"
17 #include "gr_rect.h"
19 #define genericptr_t void *
20 typedef signed char schar;
21 #include "wintype.h"
22 #undef genericptr_t
24 #define NDECL(f) f(void)
25 #define FDECL(f, p) f p
26 #define CHAR_P char
27 #define SCHAR_P schar
28 #define UCHAR_P uchar
29 #define XCHAR_P xchar
30 #define SHORT_P short
31 #define BOOLEAN_P boolean
32 #define ALIGNTYP_P aligntyp
33 typedef signed char xchar;
34 #include "wingem.h"
35 #undef CHAR_P
36 #undef SCHAR_P
37 #undef UCHAR_P
38 #undef XCHAR_P
39 #undef SHORT_P
40 #undef BOOLEAN_P
41 #undef ALIGNTYP_P
42 #undef NDECL
43 #undef FDECL
45 static char nullstr[] = "", md[] = "aNetHack 0.0.1.0", strCancel[] = "Cancel",
46 strOk[] = "Ok", strText[] = "Text";
48 extern winid WIN_MESSAGE, WIN_MAP, WIN_STATUS, WIN_INVEN;
50 #define MAXWIN 20
51 #define ROWNO 21
52 #define COLNO 80
53 #define MSGLEN 100
55 #define MAP_GADGETS \
56 NAME | MOVER | CLOSER | FULLER | LFARROW | RTARROW | UPARROW | DNARROW \
57 | VSLIDE | HSLIDE | SIZER | SMALLER
58 #define DIALOG_MODE AUTO_DIAL | MODAL | NO_ICONIFY
61 * Keyboard translation tables.
63 #define C(c) (0x1f & (c))
64 #define M(c) (0x80 | (c))
66 #define KEYPADLO 0x61
67 #define KEYPADHI 0x71
69 #define PADKEYS (KEYPADHI - KEYPADLO + 1)
70 #define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI)
73 * Keypad keys are translated to the normal values below.
74 * When iflags.BIOS is active, shifted keypad keys are translated to the
75 * shift values below.
77 static const struct pad {
78 char normal, shift, cntrl;
79 } keypad[PADKEYS] =
81 { C('['), 'Q', C('[') }, /* UNDO */
82 { '?', '/', '?' }, /* HELP */
83 { '(', 'a', '(' }, /* ( */
84 { ')', 'w', ')' }, /* ) */
85 { '/', '/', '/' }, /* / */
86 { C('p'), '$', C('p') }, /* * */
87 { 'y', 'Y', C('y') }, /* 7 */
88 { 'k', 'K', C('k') }, /* 8 */
89 { 'u', 'U', C('u') }, /* 9 */
90 { 'h', 'H', C('h') }, /* 4 */
91 { '.', '.', '.' },
92 { 'l', 'L', C('l') }, /* 6 */
93 { 'b', 'B', C('b') }, /* 1 */
94 { 'j', 'J', C('j') }, /* 2 */
95 { 'n', 'N', C('n') }, /* 3 */
96 { 'i', 'I', C('i') }, /* Ins */
97 { '.', ':', ':' } /* Del */
99 numpad[PADKEYS] = {
100 { C('['), 'Q', C('[') }, /* UNDO */
101 { '?', '/', '?' }, /* HELP */
102 { '(', 'a', '(' }, /* ( */
103 { ')', 'w', ')' }, /* ) */
104 { '/', '/', '/' }, /* / */
105 { C('p'), '$', C('p') }, /* * */
106 { '7', M('7'), '7' }, /* 7 */
107 { '8', M('8'), '8' }, /* 8 */
108 { '9', M('9'), '9' }, /* 9 */
109 { '4', M('4'), '4' }, /* 4 */
110 { '.', '.', '.' }, /* 5 */
111 { '6', M('6'), '6' }, /* 6 */
112 { '1', M('1'), '1' }, /* 1 */
113 { '2', M('2'), '2' }, /* 2 */
114 { '3', M('3'), '3' }, /* 3 */
115 { 'i', 'I', C('i') }, /* Ins */
116 { '.', ':', ':' } /* Del */
119 #define TBUFSZ 300
120 #define BUFSZ 256
121 extern int yn_number; /* from decl.c */
122 extern char toplines[TBUFSZ]; /* from decl.c */
123 extern char mapped_menu_cmds[]; /* from options.c */
124 extern int mar_iflags_numpad(void); /* from wingem.c */
125 extern void Gem_raw_print(const char *); /* from wingem.c */
126 extern int mar_hp_query(void); /* from wingem.c */
127 extern int mar_get_msg_history(void); /* from wingem.c */
128 extern int mar_get_msg_visible(void); /* from wingem.c */
129 extern void mar_get_font(int, char **, int *); /* from wingem.c */
130 extern int vdi2dev4[]; /* from load_img.c */
132 void recalc_msg_win(GRECT *);
133 void recalc_status_win(GRECT *);
134 void calc_std_winplace(int, GRECT *);
135 int (*v_mtext)(int, int, int, char *);
136 static int no_glyph; /* the int indicating there is no glyph */
137 IMG_header tile_image, titel_image, rip_image;
138 MFDB Tile_bilder, Map_bild, Titel_bild, Rip_bild, Black_bild, Pet_Mark,
139 FontCol_Bild;
140 static int Tile_width = 16, Tile_heigth = 16, Tiles_per_line = 20;
141 char *Tilefile = NULL;
142 /* pet_mark Design by Warwick Allison warwick@troll.no */
143 static int pet_mark_data[] = { 0x0000, 0x3600, 0x7F00, 0x7F00,
144 0x3E00, 0x1C00, 0x0800 };
145 static short *normal_palette = NULL;
147 static struct gw {
148 WIN *gw_window;
149 int gw_type, gw_dirty;
150 GRECT gw_place;
151 } Gem_nhwindow[MAXWIN];
153 typedef struct {
154 int id;
155 int size;
156 int cw, ch;
157 int prop;
158 } NHGEM_FONT;
160 /*struct gemmapdata {*/
161 GRECT dirty_map_area = { COLNO - 1, ROWNO, 0, 0 };
162 int map_cursx = 0, map_cursy = 0, curs_col = WHITE;
163 int draw_cursor = TRUE, scroll_margin = -1;
164 NHGEM_FONT map_font;
165 SCROLL scroll_map;
166 char **map_glyphs = NULL;
167 dirty_rect *dr_map;
168 /*};*/
170 /*struct gemstatusdata{*/
171 char **status_line;
172 int Anz_status_lines, status_w, status_align = FALSE;
173 NHGEM_FONT status_font;
174 dirty_rect *dr_stat;
175 /*};*/
177 /*struct gemmessagedata{*/
178 int mar_message_pause = TRUE;
179 int mar_esc_pressed = FALSE;
180 int messages_pro_zug = 0;
181 char **message_line;
182 int *message_age;
183 int msg_pos = 0, msg_max = 0, msg_anz = 0, msg_width = 0, msg_vis = 3,
184 msg_align = TRUE;
185 NHGEM_FONT msg_font;
186 dirty_rect *dr_msg;
187 /*};*/
189 /*struct geminvdata {*/
190 SCROLL scroll_menu;
191 Gem_menu_item *invent_list;
192 int Anz_inv_lines = 0, Inv_breite = 16;
193 NHGEM_FONT menu_font;
194 int Inv_how;
195 /*};*/
197 /*struct gemtextdata{*/
198 char **text_lines;
199 int Anz_text_lines = 0, text_width;
200 NHGEM_FONT text_font;
201 int use_rip = FALSE;
202 extern char **rip_line;
203 /*};*/
205 static OBJECT *zz_oblist[NHICON + 1];
207 MITEM scroll_keys[] = {
208 /* menu, key, state, mode, msg */
209 { FAIL, key(CTRLLEFT, 0), K_CTRL, PAGE_LEFT, FAIL },
210 { FAIL, key(CTRLRIGHT, 0), K_CTRL, PAGE_RIGHT, FAIL },
211 { FAIL, key(SCANUP, 0), K_SHIFT, PAGE_UP, FAIL },
212 { FAIL, key(SCANDOWN, 0), K_SHIFT, PAGE_DOWN, FAIL },
213 { FAIL, key(SCANLEFT, 0), 0, LINE_LEFT, FAIL },
214 { FAIL, key(SCANRIGHT, 0), 0, LINE_RIGHT, FAIL },
215 { FAIL, key(SCANUP, 0), 0, LINE_UP, FAIL },
216 { FAIL, key(SCANDOWN, 0), 0, LINE_DOWN, FAIL },
217 { FAIL, key(SCANLEFT, 0), K_SHIFT, LINE_START, FAIL },
218 { FAIL, key(SCANRIGHT, 0), K_SHIFT, LINE_END, FAIL },
219 { FAIL, key(SCANUP, 0), K_CTRL, WIN_START, FAIL },
220 { FAIL, key(SCANDOWN, 0), K_CTRL, WIN_END, FAIL },
221 { FAIL, key(SCANHOME, 0), K_SHIFT, WIN_END, FAIL },
222 { FAIL, key(SCANHOME, 0), 0, WIN_START, FAIL }
224 #define SCROLL_KEYS 14
226 static DIAINFO *Inv_dialog;
228 #define null_free(ptr) free(ptr), (ptr) = NULL
229 #define test_free(ptr) \
230 if (ptr) \
231 null_free(ptr)
233 static char *Menu_title = NULL;
235 void mar_display_nhwindow(winid);
236 void
237 mar_check_hilight_status(void)
239 } /* to be filled :-) */
240 static char *mar_copy_of(const char *);
242 extern void panic(const char *, ...);
243 void *
244 m_alloc(size_t amt)
246 void *ptr;
248 ptr = malloc(amt);
249 if (!ptr)
250 panic("Memory allocation failure; cannot get %lu bytes", amt);
251 return (ptr);
254 void
255 mar_clear_messagewin(void)
257 int i, *ptr = message_age;
259 if (WIN_MESSAGE == WIN_ERR)
260 return;
261 for (i = msg_anz; --i >= 0; ptr++) {
262 if (*ptr)
263 Gem_nhwindow[WIN_MESSAGE].gw_dirty = TRUE;
264 *ptr = FALSE;
266 mar_message_pause = FALSE;
268 mar_display_nhwindow(WIN_MESSAGE);
271 void
272 clipbrd_save(void *data, int cnt, boolean append, boolean is_inv)
274 char path[MAX_PATH], *text, *crlf = "\r\n";
275 long handle;
276 int i;
278 if (data && cnt > 0 && scrp_path(path, "scrap.txt")
279 && (handle = append ? Fopen(path, 1) : Fcreate(path, 0)) > 0) {
280 if (append)
281 Fseek(0L, (int) handle, SEEK_END);
282 if (is_inv) {
283 Gem_menu_item *it = (Gem_menu_item *) data;
285 for (; it; it = it->Gmi_next) {
286 text = it->Gmi_str;
287 Fwrite((int) handle, strlen(text), text);
288 Fwrite((int) handle, 2L, crlf);
290 } else {
291 for (i = 0; i < cnt; i++) {
292 text = ((char **) data)[i] + 1;
293 Fwrite((int) handle, strlen(text), text);
294 Fwrite((int) handle, 2L, crlf);
297 Fclose((int) handle);
299 scrp_changed(SCF_TEXT, 0x2e545854l); /* .TXT */
303 void
304 move_win(WIN *z_win)
306 GRECT frame = desk;
308 v_set_mode(MD_XOR);
309 v_set_line(BLACK, 1, 1, 0, 0);
310 frame.g_w <<= 1, frame.g_h <<= 1;
311 if (graf_rt_dragbox(FALSE, &z_win->curr, &frame, &z_win->curr.g_x,
312 &z_win->curr.g_y, NULL))
313 window_size(z_win, &z_win->curr);
314 else
315 window_top(z_win);
318 void
319 message_handler(int x, int y)
321 switch (objc_find(zz_oblist[MSGWIN], ROOT, MAX_DEPTH, x, y)) {
322 case UPMSG:
323 if (msg_pos > msg_vis - 1) {
324 msg_pos--;
325 Gem_nhwindow[WIN_MESSAGE].gw_dirty = TRUE;
326 mar_display_nhwindow(WIN_MESSAGE);
328 Event_Timer(50, 0, TRUE);
329 break;
330 case DNMSG:
331 if (msg_pos < msg_max) {
332 msg_pos++;
333 Gem_nhwindow[WIN_MESSAGE].gw_dirty = TRUE;
334 mar_display_nhwindow(WIN_MESSAGE);
336 Event_Timer(50, 0, TRUE);
337 break;
338 case GRABMSGWIN:
339 default:
340 move_win(Gem_nhwindow[WIN_MESSAGE].gw_window);
341 break;
342 case -1:
343 break;
348 mar_ob_mapcenter(OBJECT *p_obj)
350 WIN *p_w = WIN_MAP != WIN_ERR ? Gem_nhwindow[WIN_MAP].gw_window : NULL;
352 if (p_obj && p_w) {
353 p_obj->ob_x = p_w->work.g_x + p_w->work.g_w / 2 - p_obj->ob_width / 2;
354 p_obj->ob_y =
355 p_w->work.g_y + p_w->work.g_h / 2 - p_obj->ob_height / 2;
356 return (DIA_LASTPOS);
358 return (DIA_CENTERED);
361 /****************************** set_no_glyph
362 * *************************************/
364 void
365 mar_set_no_glyph(ng)
366 int ng;
368 no_glyph = ng;
371 void
372 mar_set_tilefile(name)
373 char *name;
375 Tilefile = name;
377 void
378 mar_set_tilex(value)
379 int value;
381 Min(&value, 32);
382 Max(&value, 1);
383 Tile_width = value;
385 void
386 mar_set_tiley(value)
387 int value;
389 Min(&value, 32);
390 Max(&value, 1);
391 Tile_heigth = value;
393 /****************************** userdef_draw
394 * *************************************/
396 void rearrange_windows(void);
397 void
398 mar_set_status_align(int sa)
400 if (status_align != sa) {
401 status_align = sa;
402 rearrange_windows();
405 void
406 mar_set_msg_align(int ma)
408 if (msg_align != ma) {
409 msg_align = ma;
410 rearrange_windows();
413 void
414 mar_set_msg_visible(int mv)
416 if (mv != msg_vis) {
417 Max(&mv, 1);
418 Min(&mv, min(msg_anz, 20));
419 Min(&mv, desk.g_h / msg_font.ch / 2);
420 msg_vis = mv;
421 rearrange_windows();
424 /* size<0 cellheight; size>0 points */
425 void
426 mar_set_fontbyid(int type, int id, int size)
428 int chardim[4];
429 if (id <= 0)
430 id = ibm_font_id;
431 if ((size > -3 && size < 3) || size < -20 || size > 20)
432 size = -ibm_font;
433 /* MAR -- 17.Mar 2002 For now allow FNT_PROP only with NHW_TEXT */
434 if (type != NHW_TEXT && (FontInfo(id)->type & (FNT_PROP | FNT_ASCII)))
435 id = ibm_font_id;
436 switch (type) {
437 case NHW_MESSAGE:
438 if (msg_font.size == -size && msg_font.id == id)
439 break;
440 msg_font.size = -size;
441 msg_font.id = id;
442 msg_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII);
443 v_set_text(msg_font.id, msg_font.size, BLACK, 0, 0, chardim);
444 msg_font.ch = chardim[3] ? chardim[3] : 1;
445 msg_font.cw = chardim[2] ? chardim[2] : 1;
446 msg_width = min(max_w / msg_font.cw - 3, MSGLEN);
447 rearrange_windows();
448 break;
449 case NHW_MAP:
450 if (map_font.size != -size || map_font.id != id) {
451 MFDB mtmp;
452 map_font.size = -size;
453 map_font.id = id;
454 map_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII);
455 v_set_text(map_font.id, map_font.size, BLACK, 0, 0, chardim);
456 map_font.ch = chardim[3] ? chardim[3] : 1;
457 map_font.cw = chardim[2] ? chardim[2] : 1;
458 mfdb(&mtmp, NULL, (COLNO - 1) * map_font.cw, ROWNO * map_font.ch,
459 0, planes);
460 if (mfdb_size(&mtmp) > mfdb_size(&FontCol_Bild)
461 && mfdb_size(&mtmp) > mfdb_size(&Map_bild)) {
462 FontCol_Bild.fd_addr = Map_bild.fd_addr =
463 (int *) realloc(Map_bild.fd_addr, mfdb_size(&mtmp));
464 if (!Map_bild.fd_addr) /* FIXME -- Not really neccessary since
465 the former space is still valid */
466 panic("Not enough Space for the map.");
468 mfdb(&FontCol_Bild, FontCol_Bild.fd_addr,
469 (COLNO - 1) * map_font.cw, ROWNO * map_font.ch, 0, planes);
470 rearrange_windows();
472 break;
473 case NHW_STATUS:
474 if (status_font.size == -size && status_font.id == id)
475 break;
476 status_font.size = -size;
477 status_font.id = id;
478 status_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII);
479 v_set_text(status_font.id, status_font.size, BLACK, 0, 0, chardim);
480 status_font.ch = chardim[3] ? chardim[3] : 1;
481 status_font.cw = chardim[2] ? chardim[2] : 1;
482 rearrange_windows();
483 break;
484 case NHW_MENU:
485 if (menu_font.size == -size && menu_font.id == id)
486 break;
487 menu_font.size = -size;
488 menu_font.id = id;
489 menu_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII);
490 v_set_text(menu_font.id, menu_font.size, BLACK, 0, 0, chardim);
491 menu_font.ch = chardim[3] ? chardim[3] : 1;
492 menu_font.cw = chardim[2] ? chardim[2] : 1;
493 break;
494 case NHW_TEXT:
495 if (text_font.size == -size && text_font.id == id)
496 break;
497 text_font.size = -size;
498 text_font.id = id;
499 text_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII);
500 v_set_text(text_font.id, text_font.size, BLACK, 0, 0, chardim);
501 text_font.ch = chardim[3] ? chardim[3] : 1;
502 text_font.cw = chardim[2] ? chardim[2] : 1;
503 break;
504 default:
505 break;
508 void
509 mar_set_font(int type, const char *font_name, int size)
511 int id = 0;
512 /* MAR -- 17.Mar 2002 usual Gem behavior, use the Font-ID */
513 if (font_name && *font_name) {
514 id = atoi(font_name);
515 if (id <= 0) {
516 int i, tid;
517 char name[32];
518 for (i = fonts_loaded; --i >= 0;) {
519 tid = vqt_name(x_handle, i, name);
520 if (!stricmp(name, font_name)) {
521 id = tid;
522 break;
527 mar_set_fontbyid(type, id, size);
529 void
530 rearrange_windows(void)
532 GRECT area;
533 int todo = TRUE;
534 if (WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window) {
535 scroll_map.px_hline =
536 mar_set_tile_mode(FAIL) ? Tile_width : map_font.cw;
537 scroll_map.px_vline =
538 mar_set_tile_mode(FAIL) ? Tile_heigth : map_font.ch;
539 if (todo) {
540 calc_std_winplace(FAIL, &area);
541 todo = FALSE;
543 calc_std_winplace(NHW_MAP, &area);
544 Gem_nhwindow[WIN_MAP].gw_window->max.g_w = area.g_w;
545 Gem_nhwindow[WIN_MAP].gw_window->max.g_h = area.g_h;
546 Gem_nhwindow[WIN_MAP].gw_window->max.g_w = area.g_w;
547 window_reinit(Gem_nhwindow[WIN_MAP].gw_window, md, md, NULL, FALSE,
548 FALSE);
550 int buf[8];
551 buf[3] = K_CTRL;
552 buf[4] = C('L');
553 AvSendMsg(ap_id, AV_SENDKEY, buf);
556 if (WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window) {
557 if (todo) {
558 calc_std_winplace(FAIL, &area);
559 todo = FALSE;
561 calc_std_winplace(NHW_MESSAGE, &area);
562 Gem_nhwindow[WIN_MESSAGE].gw_window->min_h = area.g_h;
563 window_size(Gem_nhwindow[WIN_MESSAGE].gw_window, &area);
564 redraw_window(Gem_nhwindow[WIN_MESSAGE].gw_window, NULL);
566 if (WIN_STATUS != WIN_ERR && Gem_nhwindow[WIN_STATUS].gw_window) {
567 if (todo) {
568 calc_std_winplace(FAIL, &area);
569 todo = FALSE;
571 calc_std_winplace(NHW_STATUS, &area);
572 Gem_nhwindow[WIN_STATUS].gw_window->min_h = area.g_h;
573 window_size(Gem_nhwindow[WIN_STATUS].gw_window, &area);
574 redraw_window(Gem_nhwindow[WIN_STATUS].gw_window, NULL);
577 void
578 my_color_area(GRECT *area, int col)
580 int pxy[4];
582 v_set_fill(col, 1, IP_SOLID, 0);
583 rc_grect_to_array(area, pxy);
584 v_bar(x_handle, pxy);
587 void
588 my_clear_area(GRECT *area)
590 my_color_area(area, WHITE);
593 int mar_set_tile_mode(int);
595 static void
596 win_draw_map(int first, WIN *win, GRECT *area)
598 int pla[8], w = area->g_w - 1, h = area->g_h - 1;
599 int i, x, y;
600 GRECT back = *area;
602 first = first;
604 if (!mar_set_tile_mode(FAIL)) {
605 int start =
606 (area->g_x - win->work.g_x) / map_font.cw + scroll_map.hpos;
607 int stop = (area->g_x + area->g_w + map_font.cw - 1 - win->work.g_x)
608 / map_font.cw
609 + scroll_map.hpos;
610 int starty =
611 (area->g_y - win->work.g_y) / map_font.ch + scroll_map.vpos;
612 int stopy = min((area->g_y + area->g_h + map_font.ch - 1
613 - win->work.g_y) / map_font.ch
614 + scroll_map.vpos,
615 ROWNO);
616 char tmp;
617 v_set_text(map_font.id, map_font.size, WHITE, 0, 0, NULL);
618 v_set_mode(MD_TRANS);
620 x = win->work.g_x - scroll_map.px_hpos + start * map_font.cw;
621 y = win->work.g_y - scroll_map.px_vpos + starty * map_font.ch;
622 pla[2] = pla[0] = scroll_map.px_hpos + area->g_x - win->work.g_x;
623 pla[3] = pla[1] = starty * map_font.ch;
624 pla[2] += w;
625 pla[3] += map_font.ch - 1;
626 pla[6] = pla[4] = area->g_x; /* x_wert to */
627 pla[7] = pla[5] = y; /* y_wert to */
628 pla[6] += w;
629 pla[7] += map_font.ch - 1;
630 back.g_h = map_font.ch;
631 for (i = starty; i < stopy; i++, y += map_font.ch,
632 pla[1] += map_font.ch, pla[3] += map_font.ch,
633 pla[5] += map_font.ch, pla[7] += map_font.ch) {
634 back.g_y = y;
635 my_color_area(&back, BLACK);
636 tmp = map_glyphs[i][stop];
637 map_glyphs[i][stop] = 0;
638 (*v_mtext)(x_handle, x, y, &map_glyphs[i][start]);
639 map_glyphs[i][stop] = tmp;
640 vro_cpyfm(x_handle, S_OR_D, pla, &FontCol_Bild, screen);
642 } else {
643 v_set_mode(MD_REPLACE);
644 pla[2] = pla[0] = scroll_map.px_hpos + area->g_x - win->work.g_x;
645 pla[3] = pla[1] = scroll_map.px_vpos + area->g_y - win->work.g_y;
646 pla[2] += w;
647 pla[3] += h;
648 pla[6] = pla[4] = area->g_x; /* x_wert to */
649 pla[7] = pla[5] = area->g_y; /* y_wert to */
650 pla[6] += w;
651 pla[7] += h;
652 vro_cpyfm(x_handle, S_ONLY, pla, &Map_bild, screen);
655 if (draw_cursor) {
656 v_set_line(curs_col, 1, 1, 0, 0);
657 pla[0] = pla[2] =
658 win->work.g_x
659 + scroll_map.px_hline * (map_cursx - scroll_map.hpos);
660 pla[1] = pla[3] =
661 win->work.g_y
662 + scroll_map.px_vline * (map_cursy - scroll_map.vpos);
663 pla[2] += scroll_map.px_hline - 1;
664 pla[3] += scroll_map.px_vline - 1;
665 v_rect(pla[0], pla[1], pla[2], pla[3]);
669 static int
670 draw_titel(PARMBLK *pb)
672 static int pla[8];
673 GRECT work = *(GRECT *) &pb->pb_x;
675 if (rc_intersect((GRECT *) &pb->pb_xc, &work)) {
676 pla[0] = pla[1] = 0;
677 pla[2] = pb->pb_w - 1;
678 pla[3] = pb->pb_h - 1;
679 pla[6] = pla[4] = pb->pb_x; /* x_wert to */
680 pla[7] = pla[5] = pb->pb_y; /* y_wert to */
681 pla[6] += pb->pb_w - 1;
682 pla[7] += pb->pb_h - 1;
684 vro_cpyfm(x_handle, S_ONLY, pla, &Titel_bild, screen);
687 return (0);
690 static int
691 draw_lines(PARMBLK *pb)
693 GRECT area = *(GRECT *) &pb->pb_x;
695 if (rc_intersect((GRECT *) &pb->pb_xc, &area)) {
696 char **ptr;
697 int x = pb->pb_x, y = pb->pb_y, start_line = (area.g_y - y);
699 v_set_mode((text_font.cw & 7) == 0 && text_font.prop == 0 ? MD_REPLACE
700 : MD_TRANS);
702 /* void v_set_text(int font,int height,int color,int effect,int
703 * rotate,int out[4]) */
704 v_set_text(text_font.id, text_font.size, BLACK, 0, 0, NULL);
705 start_line /= text_font.ch;
706 y += start_line * text_font.ch;
707 x -= (int) scroll_menu.px_hpos;
708 ptr = &text_lines[start_line += scroll_menu.vpos];
709 start_line =
710 min((area.g_y - y + area.g_h + text_font.ch - 1) / text_font.ch,
711 Anz_text_lines - start_line);
712 area.g_h = text_font.ch;
713 Vsync();
714 /* x=(x+7) & ~7;*/
715 for (; --start_line >= 0; y += text_font.ch) {
716 area.g_y = y;
717 my_clear_area(&area);
718 if (**ptr - 1) {
719 v_set_text(FAIL, 0, BLUE, 0x01, 0, NULL);
720 (*v_mtext)(x_handle, x, y, (*ptr++) + 1);
721 v_set_text(FAIL, 0, BLACK, 0x00, 0, NULL);
722 } else
723 (*v_mtext)(x_handle, x, y, (*ptr++) + 1);
726 return (0);
729 static int
730 draw_rip(PARMBLK *pb)
732 GRECT area = *(GRECT *) &pb->pb_x;
733 if (rc_intersect((GRECT *) &pb->pb_xc, &area)) {
734 char **ptr;
735 int x = pb->pb_x, y = pb->pb_y, start_line = (area.g_y - y),
736 chardim[4], pla[8], i;
737 v_set_mode(MD_REPLACE);
738 /* void v_set_text(int font,int height,int color,int effect,int
739 * rotate,int out[4]) */
740 v_set_text(text_font.id, text_font.size, BLACK, 0, 0, chardim);
741 start_line /= text_font.ch;
742 y += start_line * text_font.ch;
743 x -= scroll_menu.px_hpos;
744 ptr = &text_lines[start_line += scroll_menu.vpos];
745 start_line =
746 min((area.g_y - y + area.g_h + text_font.ch - 1) / text_font.ch,
747 Anz_text_lines - start_line);
748 area.g_h = text_font.ch;
749 Vsync();
750 x = (x + 7) & ~7;
751 for (; --start_line >= 0; y += text_font.ch) {
752 area.g_y = y;
753 my_clear_area(&area);
754 if (**ptr - 1) {
755 v_set_text(FAIL, 0, BLUE, 0x01, 0, NULL);
756 (*v_mtext)(x_handle, x, y, (*ptr++) + 1);
757 v_set_text(FAIL, 0, BLACK, 0x00, 0, NULL);
758 } else
759 (*v_mtext)(x_handle, x, y, (*ptr++) + 1);
761 pla[0] = pla[1] = 0;
762 pla[2] = min(pb->pb_w - 1, Rip_bild.fd_w - 1);
763 pla[3] = min(pb->pb_h - 1, Rip_bild.fd_h - 1);
764 pla[6] = pla[4] =
765 pb->pb_x + (pb->pb_w - Rip_bild.fd_w) / 2; /* x_wert to */
766 pla[7] = pla[5] = pb->pb_y; /* y_wert to */
767 pla[6] += pla[2];
768 pla[7] += pla[3];
769 vro_cpyfm(x_handle, S_ONLY, pla, &Rip_bild, screen);
770 v_set_mode(MD_TRANS);
771 vst_alignment(x_handle, 1, 5, &i, &i);
772 pla[5] += 64;
773 for (i = 0; i < 7; i++, pla[5] += chardim[3]) {
774 v_set_text(text_font.id, (i == 0 || i == 6) ? text_font.size : 12,
775 WHITE, 1, 0, chardim);
776 (*v_mtext)(x_handle, pla[4] + 157, pla[5], rip_line[i]);
777 v_set_text(text_font.id, (i == 0 || i == 6) ? text_font.size : 12,
778 BLACK, 0, 0, chardim);
779 (*v_mtext)(x_handle, pla[4] + 157, pla[5], rip_line[i]);
781 vst_alignment(x_handle, 0, 5, &i, &i);
783 return (0);
786 static int
787 draw_msgline(PARMBLK *pb)
789 GRECT area = *(GRECT *) &pb->pb_x;
791 if (rc_intersect((GRECT *) &pb->pb_xc, &area)) {
792 int x = pb->pb_x, y = pb->pb_y + (msg_vis - 1) * msg_font.ch, foo, i;
793 char **ptr = &message_line[msg_pos], tmp;
794 int startx, stopx, starty, stopy;
796 x = (x + 7) & ~7; /* Byte alignment speeds output up */
798 v_set_mode(MD_REPLACE);
800 /* void v_set_text(int font,int height,int color,int effect,int
801 * rotate,int out[4]) */
802 v_set_text(msg_font.id, msg_font.size, FAIL, FAIL, 0, NULL);
803 vst_alignment(x_handle, 0, 5, &foo, &foo);
804 stopy = min(msg_pos, msg_vis);
805 /* Vsync();*/
806 startx =
807 (area.g_x - x) / msg_font.cw
808 - 1; /* MAR 06.02.2001 -- because italic covers the next char */
809 Max(&startx, 0);
810 stopx = (area.g_x + area.g_w + msg_font.cw - x - 1) / msg_font.cw;
811 x += startx * msg_font.cw;
812 for (i = 0; i < stopy; i++, y -= msg_font.ch, ptr--) {
813 if (message_age[msg_pos - i])
814 v_set_text(FAIL, 0, BLACK, 0, 0, NULL);
815 else
816 v_set_text(FAIL, 0, LBLACK, 4, 0, NULL);
817 tmp = (*ptr)[stopx];
818 (*ptr)[stopx] = 0;
819 (*v_mtext)(x_handle, x, y, &(*ptr)[startx]);
820 (*ptr)[stopx] = tmp;
823 return (0);
826 static int
827 draw_status(PARMBLK *pb)
829 GRECT area = *(GRECT *) &pb->pb_x;
831 area.g_x += 2 * status_font.cw - 2;
832 area.g_w -= 2 * status_font.cw - 2;
833 if (rc_intersect((GRECT *) &pb->pb_xc, &area)) {
834 int x = pb->pb_x, y = pb->pb_y, startx, stopx, starty, stopy, i;
835 char tmp;
837 /* void v_set_text(int font,int height,int color,int effect,int
838 * rotate,int out[4]) */
839 v_set_mode(MD_REPLACE);
840 v_set_text(status_font.id, status_font.size, BLACK, 0, 0, NULL);
841 x = (x + 2 * status_font.cw + 6) & ~7;
843 startx = (area.g_x - x) / status_font.cw;
844 starty = (area.g_y - y) / status_font.ch;
845 stopx =
846 (area.g_x + area.g_w + status_font.ch - 1 - x) / status_font.cw;
847 stopy =
848 (area.g_y + area.g_h + status_font.ch - 1 - y) / status_font.ch;
849 Max(&startx, 0); /* MAR -- Hmm, area.g_x could end up 1 below x */
850 Max(&stopx, 0);
851 x += startx * status_font.cw;
852 y += starty * status_font.ch;
853 /* Vsync();*/
854 area.g_h = status_font.ch;
855 for (i = starty; i < min(2, stopy);
856 i++, area.g_y += status_font.ch, y += status_font.ch) {
857 my_clear_area(&area);
858 tmp = status_line[i][stopx];
859 status_line[i][stopx] = 0;
860 (*v_mtext)(x_handle, x, y, &status_line[i][startx]);
861 status_line[i][stopx] = tmp;
864 return (0);
867 static int
868 draw_inventory(PARMBLK *pb)
870 GRECT area = *(GRECT *) &pb->pb_x;
872 if (rc_intersect((GRECT *) &pb->pb_xc, &area)) {
873 int gl, i, x = pb->pb_x, y = pb->pb_y, start_line = area.g_y - y;
874 Gem_menu_item *it;
876 v_set_mode(MD_REPLACE);
877 v_set_text(menu_font.id, menu_font.size, BLACK, 0, 0, NULL);
879 start_line /= menu_font.ch;
880 y += start_line * menu_font.ch;
881 x -= scroll_menu.px_hpos;
882 start_line += scroll_menu.vpos;
884 for (it = invent_list, i = start_line; --i >= 0 && it;
885 it = it->Gmi_next)
888 i = min((area.g_y - y + area.g_h + menu_font.ch - 1) / menu_font.ch,
889 Anz_inv_lines - start_line);
891 Vsync();
892 area.g_h = menu_font.ch;
894 for (; (--i >= 0) && it; it = it->Gmi_next, y += menu_font.ch) {
895 if (it->Gmi_attr)
896 v_set_text(FAIL, FALSE, BLUE, 1, FAIL, NULL); /* Bold */
897 else
898 v_set_text(FAIL, FALSE, BLACK, 0, FAIL, NULL);
900 area.g_y = y;
901 my_clear_area(&area);
902 if ((gl = it->Gmi_glyph) != no_glyph) {
903 int pla[8], h = min(menu_font.ch, Tile_heigth) - 1;
905 pla[0] = pla[2] =
906 (gl % Tiles_per_line) * Tile_width; /* x_wert from */
907 pla[1] = pla[3] =
908 (gl / Tiles_per_line) * Tile_heigth; /* y_wert from */
909 pla[4] = pla[6] = x; /* x_wert to */
910 pla[5] = pla[7] = y; /* y_wert to */
911 pla[2] += Tile_width - 1;
912 pla[3] += h;
913 pla[6] += Tile_heigth - 1;
914 pla[7] += h;
916 vro_cpyfm(x_handle, S_ONLY, pla, &Tile_bilder, screen);
918 if (it->Gmi_identifier)
919 it->Gmi_str[2] = it->Gmi_selected
920 ? (it->Gmi_count == -1L ? '+' : '#')
921 : '-';
922 (*v_mtext)(x_handle, (x + 23) & ~7, y, it->Gmi_str);
925 return (0);
928 static int
929 draw_prompt(PARMBLK *pb)
931 GRECT area = *(GRECT *) &pb->pb_x;
933 if (rc_intersect((GRECT *) &pb->pb_xc, &area)) {
934 char **ptr = (char **) pb->pb_parm;
935 int x = pb->pb_x, y = pb->pb_y, chardim[4];
937 /* void v_set_text(int font,int height,int color,int effect,int
938 * rotate,int out[4]) */
939 v_set_mode(MD_TRANS);
940 v_set_text(ibm_font_id, ibm_font, WHITE, 0, 0, chardim);
941 Vsync();
942 if (planes < 4) {
943 int pxy[4];
944 v_set_fill(BLACK, 2, 4, 0);
945 rc_grect_to_array(&area, pxy);
946 v_bar(x_handle, pxy);
947 } else
948 my_color_area(&area, LWHITE);
949 (*v_mtext)(x_handle, x, y, *(ptr++));
950 if (*ptr)
951 (*v_mtext)(x_handle, x, y + chardim[3], *ptr);
953 return (0);
956 static USERBLK ub_lines = { draw_lines, 0L }, ub_msg = { draw_msgline, 0L },
957 ub_inventory = { draw_inventory, 0L },
958 ub_titel = { draw_titel, 0L }, ub_status = { draw_status, 0L },
959 ub_prompt = { draw_prompt, 0L };
961 /**************************** rsc_funktionen *****************************/
963 void
964 my_close_dialog(DIAINFO *dialog, boolean shrink_box)
966 close_dialog(dialog, shrink_box);
967 Event_Timer(0, 0, TRUE);
970 void
971 mar_get_rsc_tree(obj_number, z_ob_obj)
972 int obj_number;
973 OBJECT **z_ob_obj;
975 rsrc_gaddr(R_TREE, obj_number, z_ob_obj);
976 fix_objects(*z_ob_obj, SCALING, 0, 0);
979 void mar_clear_map(void);
981 void
982 img_error(errnumber)
983 int errnumber;
985 char buf[BUFSZ];
987 switch (errnumber) {
988 case ERR_HEADER:
989 sprintf(buf, "%s", "[1][ Image Header | corrupt. ][ Oops ]");
990 break;
991 case ERR_ALLOC:
992 sprintf(buf, "%s",
993 "[1][ Not enough | memory for | an image. ][ Oops ]");
994 break;
995 case ERR_FILE:
996 sprintf(buf, "%s",
997 "[1][ The Image-file | is not available ][ Oops ]");
998 break;
999 case ERR_DEPACK:
1000 sprintf(buf, "%s", "[1][ The Image-file | is corrupt ][ Oops ]");
1001 break;
1002 case ERR_COLOR:
1003 sprintf(buf, "%s", "[1][ Number of colors | not supported ][ Oops ]");
1004 break;
1005 default:
1006 sprintf(buf, "[1][ img_error | strange error | number: %i ][ Hmm ]",
1007 errnumber);
1008 break;
1010 form_alert(1, buf);
1013 void
1014 mar_change_button_char(OBJECT *z_ob, int nr, char ch)
1016 *ob_get_text(z_ob, nr, 0) = ch;
1017 ob_set_hotkey(z_ob, nr, ch);
1020 void
1021 mar_set_dir_keys()
1023 static int mi_numpad = FAIL;
1024 char mcmd[] = "bjnh.lyku", npcmd[] = "123456789", *p_cmd;
1026 if (mi_numpad != mar_iflags_numpad()) {
1027 OBJECT *z_ob = zz_oblist[DIRECTION];
1028 int i;
1029 mi_numpad = mar_iflags_numpad();
1030 ob_set_hotkey(z_ob, DIRDOWN, '>');
1031 ob_set_hotkey(z_ob, DIRUP, '<');
1032 p_cmd = mi_numpad ? npcmd : mcmd;
1033 for (i = 0; i < 9; i++)
1034 mar_change_button_char(z_ob, DIR1 + 2 * i, p_cmd[i]);
1038 extern int total_tiles_used; /* tile.c */
1041 mar_gem_init()
1043 int i, bild_fehler = FALSE, fsize;
1044 char *fname;
1045 static MITEM wish_workaround = { FAIL, key(0, 'J'), K_CTRL, W_CYCLE,
1046 FAIL };
1047 OBJECT *z_ob;
1049 if ((i = open_rsc("gem_rsc.rsc", NULL, md, md, md, 0, 0, 0)) <= 0) {
1050 graf_mouse(M_OFF, NULL);
1051 if (i < 0)
1052 form_alert(1, "[3][| Fatal Error | File: GEM_RSC.RSC | not "
1053 "found. ][ grumble ]");
1054 else
1055 form_alert(1, "[3][| Fatal Error | GEM initialisation | failed. "
1056 "][ a pity ]");
1057 return (0);
1059 if (planes < 1 || planes > 8) {
1060 form_alert(
1062 "[3][ Color-depth | not supported, | try 2-256 colors. ][ Ok ]");
1063 return (0);
1065 MouseBee();
1067 /* MAR -- 17.Mar 2002 NVDI 3.0 or better uses v_ftext */
1068 v_mtext = speedo == 3 ? &v_ftext : &v_gtext;
1069 for (i = 0; i < NHICON; i++)
1070 mar_get_rsc_tree(i, &zz_oblist[i]);
1072 z_ob = zz_oblist[ABOUT];
1073 ob_hide(z_ob, OKABOUT, TRUE);
1074 ob_draw_dialog(z_ob, 0, 0, 0, 0);
1076 mar_get_font(NHW_MESSAGE, &fname, &fsize);
1077 mar_set_font(NHW_MESSAGE, fname, fsize);
1078 mar_get_font(NHW_MAP, &fname, &fsize);
1079 mar_set_font(NHW_MAP, fname, fsize);
1080 mar_get_font(NHW_STATUS, &fname, &fsize);
1081 mar_set_font(NHW_STATUS, fname, fsize);
1082 mar_get_font(NHW_MENU, &fname, &fsize);
1083 mar_set_font(NHW_MENU, fname, fsize);
1084 mar_get_font(NHW_TEXT, &fname, &fsize);
1085 mar_set_font(NHW_TEXT, fname, fsize);
1086 msg_anz = mar_get_msg_history();
1087 mar_set_msg_visible(mar_get_msg_visible());
1088 msg_width = min(max_w / msg_font.cw - 3, MSGLEN);
1090 if (max_w / status_font.cw < COLNO - 1)
1091 mar_set_fontbyid(NHW_STATUS, small_font_id, -small_font);
1092 status_w = min(max_w / status_font.cw - 3, MSGLEN);
1094 if (planes > 0 && planes < 9) {
1095 normal_palette = (short *) m_alloc(3 * colors * sizeof(short));
1096 get_colors(x_handle, normal_palette, colors);
1099 loadimg:
1100 bild_fehler = depack_img(Tilefile ? Tilefile : (planes >= 4) ? "NH16.IMG"
1101 : "NH2.IMG",
1102 &tile_image);
1103 if (bild_fehler) {
1104 z_ob = zz_oblist[ABOUT];
1105 ob_undraw_dialog(z_ob, 0, 0, 0, 0);
1106 ob_hide(z_ob, OKABOUT, FALSE);
1107 img_error(bild_fehler);
1108 return (0);
1110 if (tile_image.img_w % Tile_width || tile_image.img_h % Tile_heigth) {
1111 Tilefile = NULL;
1112 Tile_width = Tile_heigth = 16;
1113 printf("size didn't match.\n");
1114 goto loadimg;
1116 if ((tile_image.img_w / Tile_width) * (tile_image.img_h / Tile_heigth)
1117 < total_tiles_used) {
1118 Tilefile = NULL;
1119 Tile_width = Tile_heigth = 16;
1120 printf("Too few Tiles in Image.\n");
1121 goto loadimg;
1123 Tiles_per_line = tile_image.img_w / Tile_width;
1125 if (planes >= 4) {
1126 if (tile_image.planes > 1)
1127 img_set_colors(x_handle, tile_image.palette, tile_image.planes);
1128 #if 0
1129 else{
1130 int mypalette[]={};
1131 img_set_colors(x_handle, mypalette, 4);
1133 #endif
1136 mfdb(&Tile_bilder, (int *) tile_image.addr, tile_image.img_w,
1137 tile_image.img_h, 1, tile_image.planes);
1138 transform_img(&Tile_bilder);
1140 mfdb(&Map_bild, NULL, (COLNO - 1) * Tile_width, ROWNO * Tile_heigth, 0,
1141 planes);
1142 mfdb(&FontCol_Bild, NULL, (COLNO - 1) * map_font.cw, ROWNO * map_font.ch,
1143 0, planes);
1144 Map_bild.fd_addr =
1145 (int *) m_alloc(mfdb_size(&Map_bild) > mfdb_size(&FontCol_Bild)
1146 ? mfdb_size(&Map_bild)
1147 : mfdb_size(&FontCol_Bild));
1148 FontCol_Bild.fd_addr = Map_bild.fd_addr;
1150 mfdb(&Pet_Mark, pet_mark_data, 8, 7, 1, 1);
1151 vr_trnfm(x_handle, &Pet_Mark, &Pet_Mark);
1153 mfdb(&Black_bild, NULL, 16, 32, 1,
1154 1); /* MAR -- 17.Mar 2002 that should cover the biggest map-font */
1155 Black_bild.fd_addr = (int *) m_alloc(mfdb_size(&Black_bild));
1156 memset(Black_bild.fd_addr, 255, mfdb_size(&Black_bild));
1157 vr_trnfm(x_handle, &Black_bild, &Black_bild);
1159 for (i = 0; i < MAXWIN; i++) {
1160 Gem_nhwindow[i].gw_window = NULL;
1161 Gem_nhwindow[i].gw_type = 0;
1162 Gem_nhwindow[i].gw_dirty = TRUE;
1165 memset(&scroll_menu, 0, sizeof(scroll_menu));
1166 scroll_menu.scroll = AUTO_SCROLL;
1167 scroll_menu.obj = LINESLIST;
1168 scroll_menu.px_hline = menu_font.cw;
1169 scroll_menu.px_vline = menu_font.ch;
1170 scroll_menu.hscroll = scroll_menu.vscroll = 1;
1171 scroll_menu.tbar_d = 2 * gr_ch - 2;
1173 mar_set_dir_keys();
1175 memset(&scroll_map, 0, sizeof(scroll_map));
1176 scroll_map.scroll = AUTO_SCROLL;
1177 scroll_map.obj = ROOT;
1178 scroll_map.px_hline = mar_set_tile_mode(FAIL) ? Tile_width : map_font.cw;
1179 scroll_map.px_vline = mar_set_tile_mode(FAIL) ? Tile_heigth : map_font.ch;
1180 scroll_map.hsize = COLNO - 1;
1181 scroll_map.vsize = ROWNO;
1182 scroll_map.hpage = 8;
1183 scroll_map.vpage = 8;
1184 scroll_map.hscroll = 1;
1185 scroll_map.vscroll = 1;
1187 /* dial_options( round, niceline, standard, return_default, background,
1188 nonselectable,
1189 always_keys, toMouse, clipboard, hz); */
1190 dial_options(TRUE, TRUE, FALSE, RETURN_DEFAULT, AES_BACK, TRUE,
1191 KEY_ALWAYS, FALSE, TRUE, 3);
1192 /* dial_colors( dial_pattern, dial_color, dial_frame, hotkey, alert,
1193 cycle_button,
1194 check_box, radio_button, arrow, cycle_backgrnd, check_backgrnd,
1195 radio_backgrnd,
1196 arrow_backgrnd, edit_3d, draw_3d) */
1197 if (planes < 4)
1198 dial_colors(4, BLACK, WHITE, RED, RED, WHITE, BLACK, BLACK, BLACK,
1199 FAIL, FAIL, FAIL, FAIL, TRUE, TRUE);
1200 else
1201 dial_colors(7, LWHITE, BLACK, RED, RED, BLACK, BLACK, BLACK, BLACK,
1202 WHITE, WHITE, WHITE, WHITE, TRUE, TRUE);
1204 /* void MenuItems(MITEM *close,MITEM *closeall,MITEM *cycle,MITEM
1205 *invcycle,
1206 MITEM *globcycle,MITEM *full,MITEM *bottom,MITEM *iconify,MITEM
1207 *iconify_all,
1208 MITEM *menu,int menu_cnt) */
1209 /* Ctrl-W ist normaly bound to cycle */
1210 MenuItems(NULL, NULL, &wish_workaround, NULL, NULL, NULL, NULL, NULL,
1211 NULL, NULL, 0);
1213 menu_install(zz_oblist[MENU], TRUE);
1215 z_ob = zz_oblist[ABOUT];
1216 ob_undraw_dialog(z_ob, 0, 0, 0, 0);
1217 ob_hide(z_ob, OKABOUT, FALSE);
1219 return (1);
1222 /************************* mar_exit_nhwindows *******************************/
1224 void
1225 mar_exit_nhwindows()
1227 int i;
1229 for (i = MAXWIN; --i >= 0;)
1230 if (Gem_nhwindow[i].gw_type)
1231 mar_destroy_nhwindow(i);
1233 if (normal_palette) {
1234 img_set_colors(x_handle, normal_palette, tile_image.planes);
1235 null_free(normal_palette);
1237 test_free(tile_image.palette);
1238 test_free(tile_image.addr);
1239 test_free(titel_image.palette);
1240 test_free(titel_image.addr);
1243 /************************* mar_curs *******************************/
1245 void
1246 mar_curs(x, y)
1247 int x, y;
1249 Min(&dirty_map_area.g_x, x);
1250 Min(&dirty_map_area.g_y, y);
1251 Max(&dirty_map_area.g_w, x);
1252 Max(&dirty_map_area.g_h, y);
1253 Min(&dirty_map_area.g_x, map_cursx);
1254 Min(&dirty_map_area.g_y, map_cursy);
1255 Max(&dirty_map_area.g_w, map_cursx);
1256 Max(&dirty_map_area.g_h, map_cursy);
1258 map_cursx = x;
1259 map_cursy = y;
1261 if (WIN_MAP != WIN_ERR)
1262 Gem_nhwindow[WIN_MAP].gw_dirty = TRUE;
1265 void mar_cliparound(void);
1266 void
1267 mar_map_curs_weiter(void)
1269 static int once = TRUE;
1271 if (once) {
1272 redraw_window(Gem_nhwindow[WIN_STATUS].gw_window, NULL);
1273 redraw_window(Gem_nhwindow[WIN_MESSAGE].gw_window, NULL);
1274 once = FALSE;
1276 mar_curs(map_cursx + 1, map_cursy);
1277 mar_cliparound();
1280 /************************* about *******************************/
1282 void
1283 mar_about()
1285 xdialog(zz_oblist[ABOUT], md, NULL, NULL, DIA_CENTERED, FALSE,
1286 DIALOG_MODE);
1287 Event_Timer(0, 0, TRUE);
1290 /************************* ask_name *******************************/
1292 char *
1293 mar_ask_name()
1295 OBJECT *z_ob = zz_oblist[NAMEGET];
1296 int bild_fehler;
1297 char who_are_you[] = "Who are you? ";
1299 bild_fehler =
1300 depack_img(planes < 4 ? "TITLE2.IMG" : "TITLE.IMG", &titel_image);
1301 if (bild_fehler) { /* MAR -- this isn't lethal */
1302 ob_set_text(z_ob, ANETHACKPICTURE, "missing title.img.");
1303 } else {
1304 mfdb(&Titel_bild, (int *) titel_image.addr, titel_image.img_w,
1305 titel_image.img_h, 1, titel_image.planes);
1306 transform_img(&Titel_bild);
1307 z_ob[ANETHACKPICTURE].ob_type = G_USERDEF;
1308 z_ob[ANETHACKPICTURE].ob_spec.userblk = &ub_titel;
1311 ob_clear_edit(z_ob);
1312 xdialog(z_ob, who_are_you, NULL, NULL, DIA_CENTERED, FALSE, DIALOG_MODE);
1313 Event_Timer(0, 0, TRUE);
1315 test_free(titel_image.palette);
1316 test_free(titel_image.addr);
1317 test_free(Titel_bild.fd_addr);
1318 return (ob_get_text(z_ob, PLNAME, 0));
1321 /************************* more *******************************/
1323 void
1324 send_key(int key)
1326 int buf[8];
1328 buf[3] = 0; /* No Shift/Ctrl/Alt */
1329 buf[4] = key;
1330 AvSendMsg(ap_id, AV_SENDKEY, buf);
1333 void
1334 send_return()
1336 send_key(key(SCANRET, 0));
1340 K_Init(xev, availiable)
1341 XEVENT *xev;
1342 int availiable;
1344 xev = xev;
1345 return (MU_KEYBD & availiable);
1349 KM_Init(xev, availiable)
1350 XEVENT *xev;
1351 int availiable;
1353 xev = xev;
1354 return ((MU_KEYBD | MU_MESAG) & availiable);
1358 M_Init(xev, availiable)
1359 XEVENT *xev;
1360 int availiable;
1362 xev = xev;
1363 return (MU_MESAG & availiable);
1366 #define More_Init K_Init
1369 More_Handler(xev)
1370 XEVENT *xev;
1372 int ev = xev->ev_mwich;
1374 if (ev & MU_KEYBD) {
1375 char ch = (char) (xev->ev_mkreturn & 0x00FF);
1376 DIAINFO *dinf;
1377 WIN *w;
1379 switch (ch) {
1380 case '\033': /* no more more more */
1381 case ' ':
1382 if ((w = get_top_window()) && (dinf = (DIAINFO *) w->dialog)
1383 && dinf->di_tree == zz_oblist[PAGER]) {
1384 if (ch == '\033')
1385 mar_esc_pressed = TRUE;
1386 send_return();
1387 break;
1389 /* Fall thru */
1390 default:
1391 ev &= ~MU_KEYBD; /* unknown key */
1392 break;
1395 return (ev);
1398 void
1399 mar_more()
1401 if (!mar_esc_pressed) {
1402 OBJECT *z_ob = zz_oblist[PAGER];
1403 WIN *p_w;
1405 Event_Handler(More_Init, More_Handler);
1406 dial_colors(7, RED, BLACK, RED, RED, BLACK, BLACK, BLACK, BLACK,
1407 WHITE, WHITE, WHITE, WHITE, TRUE, TRUE);
1408 if (WIN_MESSAGE != WIN_ERR
1409 && (p_w = Gem_nhwindow[WIN_MESSAGE].gw_window)) {
1410 z_ob->ob_x = p_w->work.g_x;
1411 z_ob->ob_y = p_w->curr.g_y + p_w->curr.g_h + gr_ch;
1413 xdialog(z_ob, NULL, NULL, NULL, DIA_LASTPOS, FALSE, DIALOG_MODE);
1414 Event_Timer(0, 0, TRUE);
1415 Event_Handler(NULL, NULL);
1417 if (planes < 4)
1418 dial_colors(4, BLACK, WHITE, RED, RED, WHITE, BLACK, BLACK, BLACK,
1419 FAIL, FAIL, FAIL, FAIL, TRUE, TRUE);
1420 else
1421 dial_colors(7, LWHITE, BLACK, RED, RED, BLACK, BLACK, BLACK,
1422 BLACK, WHITE, WHITE, WHITE, WHITE, TRUE, TRUE);
1426 /************************* Gem_start_menu *******************************/
1427 void
1428 Gem_start_menu(win)
1429 winid win;
1431 win = win;
1432 if (invent_list) {
1433 Gem_menu_item *curr, *next;
1435 for (curr = invent_list; curr; curr = next) {
1436 next = curr->Gmi_next;
1437 free(curr->Gmi_str);
1438 free(curr);
1441 invent_list = NULL;
1442 Anz_inv_lines = 0;
1443 Inv_breite = 16;
1446 /************************* mar_add_menu *******************************/
1448 void
1449 mar_add_menu(win, item)
1450 winid win;
1451 Gem_menu_item *item;
1453 win = win;
1454 item->Gmi_next = invent_list;
1455 invent_list = item;
1456 Anz_inv_lines++;
1459 void
1460 mar_reverse_menu()
1462 Gem_menu_item *next, *head = 0, *curr = invent_list;
1464 while (curr) {
1465 next = curr->Gmi_next;
1466 curr->Gmi_next = head;
1467 head = curr;
1468 curr = next;
1470 invent_list = head;
1473 void
1474 mar_set_accelerators()
1476 char ch = 'a';
1477 Gem_menu_item *curr;
1479 for (curr = invent_list; curr; curr = curr->Gmi_next) {
1480 int extent[8];
1481 v_set_text(menu_font.id, menu_font.size, BLACK, 0, 0, NULL);
1482 vqt_extent(x_handle, curr->Gmi_str, extent);
1483 Max(&Inv_breite, extent[4] + Tile_width + menu_font.cw);
1484 if (ch && curr->Gmi_accelerator == 0 && curr->Gmi_identifier) {
1485 curr->Gmi_accelerator = ch;
1486 curr->Gmi_str[0] = ch;
1487 if (ch == 'z')
1488 ch = 'A';
1489 else if (ch == 'Z')
1490 ch = 0;
1491 else
1492 ch++;
1497 Gem_menu_item *
1498 mar_hol_inv()
1500 return (invent_list);
1503 /************************* mar_putstr_text *********************/
1505 void mar_raw_print(const char *);
1507 void
1508 mar_set_text_to_rip(winid w)
1510 use_rip = TRUE;
1512 void
1513 mar_putstr_text(winid window, int attr, const char *str)
1515 static int zeilen_frei = 0;
1516 int breite;
1517 char *ptr;
1519 window = window;
1520 if (!text_lines) {
1521 text_lines = (char **) m_alloc(12 * sizeof(char *));
1522 zeilen_frei = 12;
1524 if (!zeilen_frei) {
1525 text_lines = (char **) realloc(text_lines, (Anz_text_lines + 12)
1526 * sizeof(char *));
1527 zeilen_frei = 12;
1529 if (!text_lines) {
1530 mar_raw_print("No room for Text");
1531 return;
1534 if (str)
1535 breite = strlen(str);
1536 Min(&breite, 80);
1537 ptr = text_lines[Anz_text_lines] =
1538 (char *) m_alloc(breite * sizeof(char) + 2);
1539 *ptr = (char) (attr + 1); /* avoid 0 */
1540 strncpy(ptr + 1, str, breite);
1541 ptr[breite + 1] = 0;
1542 Anz_text_lines++;
1543 zeilen_frei--;
1547 mar_set_inv_win(Anzahl, Breite)
1548 int Anzahl, Breite;
1550 OBJECT *z_ob = zz_oblist[LINES];
1551 int retval = WIN_DIAL | MODAL | NO_ICONIFY;
1553 scroll_menu.hsize = 0;
1554 scroll_menu.vpage = (desk.g_h - 3 * gr_ch) / scroll_menu.px_vline;
1555 if (Anzahl > scroll_menu.vpage) {
1556 retval |= WD_VSLIDER;
1557 if (Breite > max_w - 3 * scroll_menu.px_hline) {
1558 retval |= WD_HSLIDER;
1559 scroll_menu.hpage =
1560 (max_w - 3 * scroll_menu.px_hline) / scroll_menu.px_hline;
1561 scroll_menu.hpos = 0;
1562 scroll_menu.hsize = Breite / scroll_menu.px_hline;
1563 scroll_menu.vpage =
1564 (desk.g_h - 4 * gr_ch - 1) / scroll_menu.px_vline;
1566 Anzahl = scroll_menu.vpage;
1567 } else {
1568 if (Breite > max_w - scroll_menu.px_hline) {
1569 retval |= WD_HSLIDER;
1570 scroll_menu.hpage =
1571 (max_w - scroll_menu.px_hline) / scroll_menu.px_hline;
1572 scroll_menu.hpos = 0;
1573 scroll_menu.hsize = Breite / scroll_menu.px_hline;
1574 scroll_menu.vpage =
1575 (desk.g_h - 4 * gr_ch - 1) / scroll_menu.px_vline;
1576 if (Anzahl > scroll_menu.vpage) {
1577 retval |= WD_VSLIDER;
1578 Anzahl = scroll_menu.vpage;
1581 scroll_menu.vpage = Anzahl;
1583 if ((scroll_menu.hmax = scroll_menu.hsize - scroll_menu.hpage) < 0)
1584 scroll_menu.hmax = 0;
1585 if ((scroll_menu.vmax = scroll_menu.vsize - scroll_menu.vpage) < 0)
1586 scroll_menu.vmax = 0;
1588 /* left/right/up 2 pixel border down 2gr_ch toolbar */
1589 z_ob[ROOT].ob_width = z_ob[LINESLIST].ob_width = Breite;
1590 z_ob[ROOT].ob_height = z_ob[QLINE].ob_y = z_ob[LINESLIST].ob_height =
1591 scroll_menu.px_vline * Anzahl;
1592 z_ob[QLINE].ob_y += gr_ch / 2;
1593 z_ob[ROOT].ob_width += 4;
1594 z_ob[ROOT].ob_height += 2 * gr_ch + 2;
1596 return (retval);
1599 /************************* mar_status_dirty *******************************/
1601 void
1602 mar_status_dirty()
1604 int ccol;
1606 ccol = mar_hp_query();
1608 if (ccol < 2)
1609 curs_col = WHITE; /* 50-100% : 0 */
1610 else if (ccol < 3)
1611 curs_col = YELLOW; /* 33-50% : 6 */
1612 else if (ccol < 5)
1613 curs_col = LYELLOW; /* 20-33% : 14*/
1614 else if (ccol < 10)
1615 curs_col = RED; /* 10-20% : 2 */
1616 else
1617 curs_col = MAGENTA; /* <10% : 7*/
1620 /************************* mar_add_message *******************************/
1622 void
1623 mar_add_message(str)
1624 const char *str;
1626 int i, mesg_hist = mar_get_msg_history();
1627 char *tmp, *rest, buf[TBUFSZ];
1629 if (WIN_MESSAGE == WIN_ERR)
1630 return;
1632 if (!mar_message_pause) {
1633 mar_message_pause = TRUE;
1634 messages_pro_zug = 0;
1635 msg_pos = msg_max;
1638 if (msg_max > mesg_hist - 2) {
1639 msg_max = mesg_hist - 2;
1640 msg_pos--;
1641 if (msg_pos < 0)
1642 msg_pos = 0;
1643 tmp = message_line[0];
1644 for (i = 0; i < mesg_hist - 1; i++) {
1645 message_line[i] = message_line[i + 1];
1646 message_age[i] = message_age[i + 1];
1648 message_line[mesg_hist - 1] = tmp;
1650 strcpy(toplines, str);
1651 messages_pro_zug++;
1652 msg_max++;
1654 if ((int) strlen(toplines) >= msg_width) {
1655 int pos = msg_width;
1656 tmp = toplines + msg_width;
1657 while (*tmp != ' ' && pos >= 0) {
1658 tmp--;
1659 pos--;
1661 if (pos <= 0)
1662 pos = msg_width; /* Mar -- Oops, what a word :-) */
1663 message_age[msg_max] = TRUE;
1664 strncpy(message_line[msg_max], toplines, pos);
1665 message_line[msg_max][pos] = 0;
1666 rest = strcpy(buf, toplines + pos);
1667 } else {
1668 message_age[msg_max] = TRUE;
1669 strncpy(message_line[msg_max], toplines, msg_width);
1670 rest = 0;
1673 Gem_nhwindow[WIN_MESSAGE].gw_dirty = TRUE;
1674 if (messages_pro_zug
1675 >= mesg_hist) { /* MAR -- Greater then should never happen */
1676 messages_pro_zug = mesg_hist;
1677 mar_display_nhwindow(WIN_MESSAGE);
1680 if (rest)
1681 mar_add_message(rest);
1684 /************************* mar_add_status_str *******************************/
1686 void
1687 mar_add_status_str(str, line)
1688 const char *str;
1689 int line;
1691 int i, last_diff = -1;
1692 GRECT area = { 0, line * status_font.ch, status_font.cw, status_font.ch };
1693 for (i = 0; (i < status_w - 2) && str[i]; i++)
1694 if (str[i] != status_line[line][i]) {
1695 if (last_diff == -1)
1696 area.g_x = i * status_font.cw;
1697 else
1698 area.g_w += status_font.cw;
1699 last_diff = i;
1700 status_line[line][i] = str[i];
1701 } else if (last_diff >= 0) {
1702 add_dirty_rect(dr_stat, &area);
1703 last_diff = -1;
1704 area.g_w = status_font.cw;
1706 for (; i < status_w - 1; i++) {
1707 if (status_line[line][i]) {
1708 if (last_diff == -1)
1709 area.g_x = i * status_font.cw;
1710 else
1711 area.g_w += status_font.cw;
1712 last_diff = i;
1714 status_line[line][i] = 0;
1716 if (last_diff >= 0)
1717 add_dirty_rect(dr_stat, &area);
1720 /************************* mar_set_menu_title *******************************/
1722 void
1723 mar_set_menu_title(str)
1724 const char *str;
1726 test_free(Menu_title); /* just in case */
1727 Menu_title = mar_copy_of(str ? str : nullstr);
1730 /************************* mar_set_menu_type *******************************/
1732 void
1733 mar_set_menu_type(how)
1734 int how;
1736 Inv_how = how;
1739 /************************* Inventory Utils *******************************/
1741 void
1742 set_all_on_page(start, page)
1743 int start, page;
1745 Gem_menu_item *curr;
1747 if (start < 0 || page < 0)
1748 return;
1750 for (curr = invent_list; start-- && curr; curr = curr->Gmi_next)
1752 for (; page-- && curr; curr = curr->Gmi_next)
1753 if (curr->Gmi_identifier && !curr->Gmi_selected)
1754 curr->Gmi_selected = TRUE;
1757 void
1758 unset_all_on_page(start, page)
1759 int start, page;
1761 Gem_menu_item *curr;
1763 if (start < 0 || page < 0)
1764 return;
1766 for (curr = invent_list; start-- && curr; curr = curr->Gmi_next)
1768 for (; page-- && curr; curr = curr->Gmi_next)
1769 if (curr->Gmi_identifier && curr->Gmi_selected) {
1770 curr->Gmi_selected = FALSE;
1771 curr->Gmi_count = -1L;
1775 void
1776 invert_all_on_page(start, page, acc)
1777 int start, page;
1778 char acc;
1780 Gem_menu_item *curr;
1782 if (start < 0 || page < 0)
1783 return;
1785 for (curr = invent_list; start-- && curr; curr = curr->Gmi_next)
1787 for (; page-- && curr; curr = curr->Gmi_next)
1788 if (curr->Gmi_identifier && (acc == 0 || curr->Gmi_groupacc == acc)) {
1789 if (curr->Gmi_selected) {
1790 curr->Gmi_selected = FALSE;
1791 curr->Gmi_count = -1L;
1792 } else
1793 curr->Gmi_selected = TRUE;
1797 /************************* Inv_Handler and Inv_Init
1798 * *******************************/
1801 scroll_top_dialog(char ch)
1803 WIN *w;
1804 DIAINFO *dinf;
1806 if ((w = get_top_window()) && (dinf = (DIAINFO *) w->dialog)
1807 && dinf->di_tree == zz_oblist[LINES]) {
1808 switch (ch) {
1809 case ' ':
1810 if (scroll_menu.vpos == scroll_menu.vmax) {
1811 send_return();
1812 break;
1814 /* Fall thru */
1815 case MENU_NEXT_PAGE:
1816 scroll_window(w, PAGE_DOWN, NULL);
1817 break;
1818 case MENU_PREVIOUS_PAGE:
1819 scroll_window(w, PAGE_UP, NULL);
1820 break;
1821 case MENU_FIRST_PAGE:
1822 scroll_window(w, WIN_START, NULL);
1823 break;
1824 case MENU_LAST_PAGE:
1825 scroll_window(w, WIN_END, NULL);
1826 break;
1827 default:
1828 return (FALSE);
1830 return (TRUE);
1832 return (FALSE);
1835 #define Text_Init KM_Init
1838 Text_Handler(xev)
1839 XEVENT *xev;
1841 int ev = xev->ev_mwich;
1843 if (ev & MU_MESAG) {
1844 int *buf = xev->ev_mmgpbuf, y_wo, i;
1845 if (*buf == FONT_CHANGED) {
1846 if (buf[3] >= 0) {
1847 mar_set_fontbyid(NHW_TEXT, buf[4], buf[5]);
1848 FontAck(buf[1], 1);
1852 if (ev & MU_KEYBD) {
1853 char ch = (char) (xev->ev_mkreturn & 0x00FF);
1855 if (!scroll_top_dialog(ch))
1856 switch (ch) {
1857 case '\033':
1858 send_return(); /* just closes the textwin */
1859 break;
1860 case C('c'):
1861 clipbrd_save(text_lines, Anz_text_lines,
1862 xev->ev_mmokstate & K_SHIFT, FALSE);
1863 break;
1864 default:
1865 ev &= ~MU_KEYBD; /* unknown key */
1866 break;
1869 return (ev);
1872 #define Inv_Init KM_Init
1874 static long count = 0;
1876 Inv_Handler(xev)
1877 XEVENT *xev;
1879 int ev = xev->ev_mwich;
1880 Gem_menu_item *it;
1881 GRECT area;
1882 OBJECT *z_ob = zz_oblist[LINES];
1884 ob_pos(z_ob, LINESLIST, &area);
1885 if (ev & MU_MESAG) {
1886 int *buf = xev->ev_mmgpbuf, y_wo, i;
1888 if (*buf == FONT_CHANGED) {
1889 if (buf[3] >= 0) {
1890 mar_set_fontbyid(NHW_MENU, buf[4], buf[5]);
1891 FontAck(buf[1], 1);
1893 } else if (*buf == OBJC_CHANGED && buf[3] == LINESLIST) {
1894 ob_undostate(z_ob, LINESLIST, SELECTED);
1895 mouse(NULL, &y_wo);
1896 y_wo = (y_wo - area.g_y) / menu_font.ch + scroll_menu.vpos;
1897 for (it = invent_list, i = 0; i < y_wo && it;
1898 it = it->Gmi_next, i++)
1900 if (it->Gmi_identifier) {
1901 it->Gmi_selected = !it->Gmi_selected;
1902 it->Gmi_count = count == 0L ? -1L : count;
1903 count = 0L;
1904 if (Inv_how != PICK_ANY) {
1905 /*my_close_dialog(Inv_dialog,TRUE);*/
1906 send_return();
1907 } else {
1908 area.g_x = (area.g_x + 23 + 2 * menu_font.cw) & ~7;
1909 area.g_w = menu_font.cw;
1910 area.g_h = menu_font.ch;
1911 area.g_y += (y_wo - scroll_menu.vpos) * menu_font.ch;
1912 ob_draw_chg(Inv_dialog, LINESLIST, &area, FAIL);
1913 } /* how != PICK_ANY */
1914 } /* identifier */
1915 } else /* LINESLIST changed */
1916 ev &= ~MU_MESAG; /* unknown message not used */
1917 } /* MU_MESAG */
1919 if (ev & MU_KEYBD) {
1920 char ch = (char) (xev->ev_mkreturn & 0x00FF);
1922 if (!scroll_top_dialog(ch)) {
1923 switch (ch) {
1924 case '0': /* special 0 is also groupaccelerator for balls */
1925 if (count <= 0)
1926 goto find_acc;
1927 case '1':
1928 case '2':
1929 case '3':
1930 case '4':
1931 case '5':
1932 case '6':
1933 case '7':
1934 case '8':
1935 case '9':
1936 if (Inv_how == PICK_NONE)
1937 goto find_acc;
1938 count = (count * 10L) + (long) (ch - '0');
1939 break;
1940 case '\033': /* cancel - from counting or loop */
1941 if (count > 0L)
1942 count = 0L;
1943 else {
1944 unset_all_on_page(0, (int) scroll_menu.vsize);
1945 my_close_dialog(Inv_dialog, TRUE);
1946 return (ev);
1948 break;
1949 case '\0': /* finished (commit) */
1950 case '\n':
1951 case '\r':
1952 break;
1953 case MENU_SELECT_PAGE:
1954 if (Inv_how == PICK_NONE)
1955 goto find_acc;
1956 if (Inv_how == PICK_ANY)
1957 set_all_on_page((int) scroll_menu.vpos,
1958 scroll_menu.vpage);
1959 break;
1960 case MENU_SELECT_ALL:
1961 if (Inv_how == PICK_NONE)
1962 goto find_acc;
1963 if (Inv_how == PICK_ANY)
1964 set_all_on_page(0, (int) scroll_menu.vsize);
1965 break;
1966 case MENU_UNSELECT_PAGE:
1967 unset_all_on_page((int) scroll_menu.vpos, scroll_menu.vpage);
1968 break;
1969 case MENU_UNSELECT_ALL:
1970 unset_all_on_page(0, (int) scroll_menu.vsize);
1971 break;
1972 case MENU_INVERT_PAGE:
1973 if (Inv_how == PICK_NONE)
1974 goto find_acc;
1975 if (Inv_how == PICK_ANY)
1976 invert_all_on_page((int) scroll_menu.vpos,
1977 scroll_menu.vpage, 0);
1978 break;
1979 case MENU_INVERT_ALL:
1980 if (Inv_how == PICK_NONE)
1981 goto find_acc;
1982 if (Inv_how == PICK_ANY)
1983 invert_all_on_page(0, (int) scroll_menu.vsize, 0);
1984 break;
1985 case MENU_SEARCH:
1986 if (Inv_how != PICK_NONE) {
1987 char buf[BUFSZ];
1988 Gem_getlin("Search for:", buf);
1989 if (!*buf || buf[0] == '\033')
1990 break;
1991 for (it = invent_list; it; it = it->Gmi_next) {
1992 if (it->Gmi_identifier && strstr(it->Gmi_str, buf)) {
1993 it->Gmi_selected = TRUE;
1994 if (Inv_how != PICK_ANY) {
1995 my_close_dialog(Inv_dialog, FALSE);
1996 break;
2001 break;
2002 case C('c'):
2003 clipbrd_save(invent_list, Anz_inv_lines,
2004 xev->ev_mmokstate & K_SHIFT, TRUE);
2005 break;
2006 default:
2007 find_acc:
2008 if (Inv_how == PICK_NONE)
2009 my_close_dialog(Inv_dialog, TRUE);
2010 else
2011 for (it = invent_list; it; it = it->Gmi_next) {
2012 if (it->Gmi_identifier
2013 && (it->Gmi_accelerator == ch
2014 || it->Gmi_groupacc == ch)) {
2015 it->Gmi_selected = !it->Gmi_selected;
2016 it->Gmi_count = count == 0L ? -1L : count;
2017 count = 0L;
2018 if (Inv_how != PICK_ANY)
2019 my_close_dialog(Inv_dialog, TRUE);
2022 break;
2023 } /* end switch(ch) */
2024 if (Inv_how == PICK_ANY) {
2025 area.g_x = (area.g_x + 23 + 2 * menu_font.cw) & ~7;
2026 area.g_w = menu_font.cw;
2027 ob_draw_chg(Inv_dialog, LINESLIST, &area, FAIL);
2029 } /* !scroll_Inv_dialog */
2030 } /* MU_KEYBD */
2032 if (Inv_how == PICK_ANY) {
2033 ob_set_text(Inv_dialog->di_tree, QLINE, strCancel);
2034 for (it = invent_list; it; it = it->Gmi_next)
2035 if (it->Gmi_identifier && it->Gmi_selected) {
2036 ob_set_text(Inv_dialog->di_tree, QLINE, strOk);
2037 break;
2039 ob_draw_chg(Inv_dialog, QLINE, NULL, FAIL);
2041 return (ev);
2044 /************************* draw_window *******************************/
2046 static void
2047 mar_draw_window(first, win, area)
2048 int first;
2049 WIN *win;
2050 GRECT *area;
2052 OBJECT *obj = (OBJECT *) win->para;
2054 if (obj) {
2055 if (first) {
2056 obj->ob_x = win->work.g_x;
2057 obj->ob_y = win->work.g_y;
2059 if (area == NULL)
2060 area = &(win->work);
2061 objc_draw(obj, ROOT, MAX_DEPTH, area->g_x, area->g_y, area->g_w,
2062 area->g_h);
2066 /************************* mar_display_nhwindow
2067 * *******************************/
2069 void
2070 redraw_winwork(WIN *w, GRECT *area)
2072 area->g_x += w->work.g_x;
2073 area->g_y += w->work.g_y;
2074 redraw_window(w, area);
2076 void
2077 mar_menu_set_slider(WIN *p_win)
2079 if (p_win) {
2080 SCROLL *sc = p_win->scroll;
2082 if (!sc)
2083 return;
2085 if (p_win->gadgets & HSLIDE) {
2086 long hsize = 1000l;
2088 if (sc->hsize > 0 && sc->hpage > 0) {
2089 hsize *= sc->hpage;
2090 hsize /= sc->hsize;
2092 window_slider(p_win, HOR_SLIDER, 0, (int) hsize);
2094 if (p_win->gadgets & VSLIDE) {
2095 long vsize = 1000l;
2097 if (sc->vsize > 0 && sc->vpage > 0) {
2098 vsize *= sc->vpage;
2099 vsize /= sc->vsize;
2101 window_slider(p_win, VERT_SLIDER, 0, (int) vsize);
2106 void
2107 recalc_msg_win(GRECT *area)
2109 OBJECT *z_ob;
2110 z_ob = zz_oblist[MSGWIN];
2111 z_ob[MSGLINES].ob_spec.userblk = &ub_msg;
2112 z_ob[MSGLINES].ob_width = z_ob[ROOT].ob_width =
2113 (msg_width + 3) * msg_font.cw;
2114 z_ob[MSGLINES].ob_width -= z_ob[UPMSG].ob_width;
2115 z_ob[ROOT].ob_height = z_ob[GRABMSGWIN].ob_height =
2116 z_ob[MSGLINES].ob_height = msg_vis * msg_font.ch;
2117 z_ob[DNMSG].ob_y = z_ob[GRABMSGWIN].ob_height - z_ob[DNMSG].ob_height;
2118 window_border(0, 0, 0, z_ob->ob_width, z_ob->ob_height, area);
2120 void
2121 recalc_status_win(GRECT *area)
2123 OBJECT *z_ob;
2124 z_ob = zz_oblist[STATUSLINE];
2125 z_ob[ROOT].ob_type = G_USERDEF;
2126 z_ob[ROOT].ob_spec.userblk = &ub_status;
2127 z_ob[ROOT].ob_width = (status_w + 2) * status_font.cw;
2128 z_ob[ROOT].ob_height = z_ob[GRABSTATUS].ob_height = 2 * status_font.ch;
2129 z_ob[GRABSTATUS].ob_width = 2 * status_font.cw - 2;
2130 window_border(0, 0, 0, z_ob->ob_width, z_ob->ob_height, area);
2132 void
2133 calc_std_winplace(int which, GRECT *place)
2135 static int todo = TRUE;
2136 static GRECT me, ma, st;
2138 if (todo || which < 0) {
2139 OBJECT *z_ob;
2140 int map_h_off, foo;
2142 /* First the messagewin */
2143 recalc_msg_win(&me);
2145 /* Now the map */
2146 wind_calc(WC_BORDER, MAP_GADGETS, 0, 0,
2147 scroll_map.px_hline * (COLNO - 1),
2148 scroll_map.px_vline * ROWNO, &foo, &foo, &foo, &map_h_off);
2149 map_h_off -= scroll_map.px_vline * ROWNO;
2150 window_border(MAP_GADGETS, 0, 0, scroll_map.px_hline * (COLNO - 1),
2151 scroll_map.px_vline * ROWNO, &ma);
2153 /* Next the statuswin */
2154 recalc_status_win(&st);
2156 /* And last but not least a final test */
2157 ma.g_h = map_h_off + scroll_map.px_vline * ROWNO;
2158 while (me.g_h + ma.g_h + st.g_h >= desk.g_h)
2159 ma.g_h -= scroll_map.px_vline;
2160 /* stack the windows */
2161 ma.g_y = me.g_y = st.g_y = desk.g_y;
2162 if (status_align) {
2163 ma.g_y += st.g_h;
2164 if (msg_align) {
2165 st.g_y += me.g_h;
2166 ma.g_y += me.g_h;
2167 } else {
2168 me.g_y += st.g_h + ma.g_h;
2170 } else {
2171 if (msg_align) {
2172 ma.g_y += me.g_h;
2173 } else {
2174 me.g_y += ma.g_h;
2176 st.g_y += me.g_h + ma.g_h;
2179 if (which)
2180 todo = FALSE;
2182 switch (which) {
2183 case NHW_MESSAGE:
2184 *place = me;
2185 break;
2186 case NHW_MAP:
2187 *place = ma;
2188 break;
2189 case NHW_STATUS:
2190 *place = st;
2191 break;
2192 default:
2193 break;
2197 void
2198 mar_display_nhwindow(wind)
2199 winid wind;
2201 DIAINFO *dlg_info;
2202 OBJECT *z_ob;
2203 int d_exit = W_ABANDON, i, breite, mar_di_mode, tmp_magx = magx;
2204 GRECT g_mapmax, area;
2205 char *tmp_button;
2206 struct gw *p_Gw;
2208 if (wind == WIN_ERR)
2209 return;
2211 p_Gw = &Gem_nhwindow[wind];
2212 switch (p_Gw->gw_type) {
2213 case NHW_TEXT:
2214 if (WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2215 mar_display_nhwindow(WIN_MESSAGE);
2216 z_ob = zz_oblist[LINES];
2217 scroll_menu.vsize = Anz_text_lines;
2218 scroll_menu.vpos = 0;
2219 if (use_rip) {
2220 if (!depack_img(planes < 4 ? "RIP2.IMG" : "RIP.IMG",
2221 &rip_image)) {
2222 mfdb(&Rip_bild, (int *) rip_image.addr, rip_image.img_w,
2223 rip_image.img_h, 1, rip_image.planes);
2224 transform_img(&Rip_bild);
2226 ub_lines.ub_code = draw_rip;
2227 } else
2228 ub_lines.ub_code = draw_lines;
2229 z_ob[LINESLIST].ob_spec.userblk = &ub_lines;
2230 breite = 16;
2231 v_set_text(text_font.id, text_font.size, BLACK, 0, 0, NULL);
2232 for (i = 0; i < Anz_text_lines; i++) {
2233 int eout[8];
2234 vqt_extent(x_handle, text_lines[i], eout);
2235 Max(&breite, eout[4]);
2237 scroll_menu.px_vline = text_font.ch;
2238 scroll_menu.px_hline = text_font.cw;
2239 mar_di_mode = mar_set_inv_win(Anz_text_lines, breite);
2240 tmp_button = ob_get_text(z_ob, QLINE, 0);
2241 ob_set_text(z_ob, QLINE, strOk);
2242 ob_undoflag(z_ob, LINESLIST, TOUCHEXIT);
2243 Event_Handler(Text_Init, Text_Handler);
2244 if ((dlg_info = open_dialog(z_ob, strText, NULL, NULL,
2245 mar_ob_mapcenter(z_ob), FALSE,
2246 mar_di_mode, FAIL, NULL, NULL)) != NULL) {
2247 WIN *ptr_win = dlg_info->di_win;
2249 ptr_win->scroll = &scroll_menu;
2250 mar_menu_set_slider(ptr_win);
2251 WindowItems(ptr_win, SCROLL_KEYS, scroll_keys);
2252 if ((d_exit = X_Form_Do(NULL)) != W_ABANDON) {
2253 my_close_dialog(dlg_info, FALSE);
2254 if (d_exit != W_CLOSED)
2255 ob_undostate(z_ob, d_exit & NO_CLICK, SELECTED);
2258 Event_Handler(NULL, NULL);
2259 ob_set_text(z_ob, QLINE, tmp_button);
2260 break;
2261 case NHW_MENU:
2262 if (WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2263 mar_display_nhwindow(WIN_MESSAGE);
2264 z_ob = zz_oblist[LINES];
2265 scroll_menu.vsize = Anz_inv_lines;
2266 scroll_menu.vpos = 0;
2267 z_ob[LINESLIST].ob_spec.userblk = &ub_inventory;
2268 if ((Menu_title)
2269 && (wind != WIN_INVEN)) /* because I sets no Menu_title */
2270 Max(&Inv_breite, gr_cw * strlen(Menu_title) + 16);
2271 scroll_menu.px_vline = menu_font.ch;
2272 scroll_menu.px_hline = menu_font.cw;
2273 mar_di_mode = mar_set_inv_win(Anz_inv_lines, Inv_breite, NHW_MENU);
2274 tmp_button = ob_get_text(z_ob, QLINE, 0);
2275 ob_set_text(z_ob, QLINE, Inv_how != PICK_NONE ? strCancel : strOk);
2276 ob_doflag(z_ob, LINESLIST, TOUCHEXIT);
2277 Event_Handler(Inv_Init, Inv_Handler);
2278 if ((Inv_dialog =
2279 open_dialog(z_ob, (wind == WIN_INVEN)
2280 ? "Inventory"
2281 : (Menu_title ? Menu_title : "Staun"),
2282 NULL, NULL, mar_ob_mapcenter(z_ob), FALSE,
2283 mar_di_mode, FAIL, NULL, NULL)) != NULL) {
2284 WIN *ptr_win = Inv_dialog->di_win;
2286 ptr_win->scroll = &scroll_menu;
2287 mar_menu_set_slider(ptr_win);
2288 WindowItems(ptr_win, SCROLL_KEYS, scroll_keys);
2289 do {
2290 int y_wo, x_wo, ru_w = 1, ru_h = 1;
2291 GRECT oarea;
2292 Gem_menu_item *it;
2293 d_exit = X_Form_Do(NULL);
2294 if ((d_exit & NO_CLICK) == LINESLIST) {
2295 ob_pos(z_ob, LINESLIST, &oarea);
2296 if (mouse(&x_wo, &y_wo) && Inv_how == PICK_ANY) {
2297 graf_rt_rubberbox(FALSE, x_wo, y_wo, FAIL, FAIL,
2298 &oarea, &ru_w, &ru_h, NULL);
2299 invert_all_on_page(
2300 (int) ((y_wo - oarea.g_y) / menu_font.ch
2301 + scroll_menu.vpos),
2302 (ru_h + menu_font.ch - 1) / menu_font.ch, 0);
2303 } else {
2304 for (it = invent_list, i = 0;
2305 i < ((y_wo - oarea.g_y) / menu_font.ch
2306 + scroll_menu.vpos)
2307 && it;
2308 it = it->Gmi_next, i++)
2310 if (it && it->Gmi_identifier) {
2311 it->Gmi_selected = !it->Gmi_selected;
2312 it->Gmi_count = count == 0L ? -1L : count;
2313 count = 0L;
2314 if (Inv_how != PICK_ANY)
2315 break;
2316 } /* identifier */
2318 oarea.g_x = (oarea.g_x + 23 + 2 * menu_font.cw) & ~7;
2319 oarea.g_y = y_wo - (y_wo - oarea.g_y) % menu_font.ch;
2320 oarea.g_w = menu_font.cw;
2321 oarea.g_h = ((ru_h + menu_font.ch - 1) / menu_font.ch)
2322 * menu_font.ch;
2323 ob_draw_chg(Inv_dialog, LINESLIST, &oarea, FAIL);
2325 if (Inv_how == PICK_ANY) {
2326 ob_set_text(Inv_dialog->di_tree, QLINE, strCancel);
2327 for (it = invent_list; it; it = it->Gmi_next)
2328 if (it->Gmi_identifier && it->Gmi_selected) {
2329 ob_set_text(Inv_dialog->di_tree, QLINE, strOk);
2330 break;
2332 ob_draw_chg(Inv_dialog, QLINE, NULL, FAIL);
2334 } while ((d_exit & NO_CLICK) == LINESLIST);
2335 if (d_exit != W_ABANDON) {
2336 my_close_dialog(Inv_dialog, FALSE);
2337 if (d_exit != W_CLOSED)
2338 ob_undostate(z_ob, d_exit & NO_CLICK, SELECTED);
2341 Event_Handler(NULL, NULL);
2342 ob_set_text(z_ob, QLINE, tmp_button);
2343 break;
2344 case NHW_MAP:
2345 if (p_Gw->gw_window == NULL) {
2346 calc_std_winplace(NHW_MAP, &p_Gw->gw_place);
2347 window_border(MAP_GADGETS, 0, 0, Tile_width * (COLNO - 1),
2348 Tile_heigth * ROWNO, &g_mapmax);
2349 p_Gw->gw_window = open_window(
2350 md, md, NULL, zz_oblist[NHICON], MAP_GADGETS, TRUE, 128, 128,
2351 &g_mapmax, &p_Gw->gw_place, &scroll_map, win_draw_map, NULL,
2352 XM_TOP | XM_BOTTOM | XM_SIZE);
2353 WindowItems(p_Gw->gw_window, SCROLL_KEYS - 1,
2354 scroll_keys); /* ClrHome centers on u */
2355 mar_clear_map();
2357 if (p_Gw->gw_dirty) {
2358 area.g_x = p_Gw->gw_window->work.g_x
2359 + scroll_map.px_hline
2360 * (dirty_map_area.g_x - scroll_map.hpos);
2361 area.g_y = p_Gw->gw_window->work.g_y
2362 + scroll_map.px_vline
2363 * (dirty_map_area.g_y - scroll_map.vpos);
2364 area.g_w = (dirty_map_area.g_w - dirty_map_area.g_x + 1)
2365 * scroll_map.px_hline;
2366 area.g_h = (dirty_map_area.g_h - dirty_map_area.g_y + 1)
2367 * scroll_map.px_vline;
2369 redraw_window(p_Gw->gw_window, &area);
2371 dirty_map_area.g_x = COLNO - 1;
2372 dirty_map_area.g_y = ROWNO;
2373 dirty_map_area.g_w = dirty_map_area.g_h = 0;
2375 break;
2376 case NHW_MESSAGE:
2377 if (p_Gw->gw_window == NULL) {
2378 calc_std_winplace(NHW_MESSAGE, &p_Gw->gw_place);
2379 z_ob = zz_oblist[MSGWIN];
2380 magx = 0; /* MAR -- Fake E_GEM to remove Backdropper */
2381 p_Gw->gw_window = open_window(
2382 NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, &p_Gw->gw_place,
2383 NULL, mar_draw_window, z_ob, XM_TOP | XM_BOTTOM | XM_SIZE);
2384 magx = tmp_magx;
2385 window_size(p_Gw->gw_window, &p_Gw->gw_window->curr);
2386 p_Gw->gw_dirty = TRUE;
2389 if (p_Gw->gw_dirty) {
2390 ob_pos(zz_oblist[MSGWIN], MSGLINES, &area);
2391 while (messages_pro_zug > 3) {
2392 messages_pro_zug -= 3;
2393 msg_pos += 3;
2394 redraw_window(p_Gw->gw_window, &area);
2395 mar_more();
2397 msg_pos += messages_pro_zug;
2398 messages_pro_zug = 0;
2399 if (msg_pos > msg_max)
2400 msg_pos = msg_max;
2401 redraw_window(p_Gw->gw_window, &area);
2402 mar_message_pause = FALSE;
2404 break;
2405 case NHW_STATUS:
2406 if (p_Gw->gw_window == NULL) {
2407 z_ob = zz_oblist[STATUSLINE];
2408 calc_std_winplace(NHW_STATUS, &p_Gw->gw_place);
2409 magx = 0; /* MAR -- Fake E_GEM to remove Backdropper */
2410 p_Gw->gw_window = open_window(
2411 NULL, NULL, NULL, NULL, 0, FALSE, 0, 0, NULL, &p_Gw->gw_place,
2412 NULL, mar_draw_window, z_ob, XM_TOP | XM_BOTTOM | XM_SIZE);
2413 magx = tmp_magx;
2414 /* Because 2*status_font.ch is smaller then e_gem expects the
2415 * minimum win_height */
2416 p_Gw->gw_window->min_h = z_ob[ROOT].ob_height;
2417 window_size(p_Gw->gw_window, &p_Gw->gw_place);
2418 p_Gw->gw_dirty = TRUE;
2419 add_dirty_rect(dr_stat, &p_Gw->gw_place);
2421 while (get_dirty_rect(dr_stat, &area)) {
2422 area.g_x = (area.g_x + p_Gw->gw_window->work.g_x
2423 + 2 * status_font.cw + 6) & ~7;
2424 area.g_y += p_Gw->gw_window->work.g_y;
2425 redraw_window(p_Gw->gw_window, &area);
2427 break;
2428 default:
2429 if (p_Gw->gw_dirty)
2430 redraw_window(p_Gw->gw_window, NULL);
2432 p_Gw->gw_dirty = FALSE;
2435 /************************* create_window *******************************/
2438 mar_hol_win_type(window)
2439 winid window;
2441 return (Gem_nhwindow[window].gw_type);
2444 winid
2445 mar_create_window(type)
2446 int type;
2448 winid newid;
2449 static char name[] = "Gem";
2450 int i;
2451 struct gw *p_Gw = &Gem_nhwindow[0];
2453 for (newid = 0; p_Gw->gw_type && newid < MAXWIN; newid++, p_Gw++)
2456 switch (type) {
2457 case NHW_MESSAGE:
2458 message_line = (char **) m_alloc(msg_anz * sizeof(char *));
2459 message_age = (int *) m_alloc(msg_anz * sizeof(int));
2460 for (i = 0; i < msg_anz; i++) {
2461 message_age[i] = FALSE;
2462 message_line[i] = (char *) m_alloc((MSGLEN + 1) * sizeof(char));
2463 *message_line[i] = 0;
2465 dr_msg = new_dirty_rect(10);
2466 if (!dr_msg)
2467 panic("Memory allocation failure (dr_msg)");
2468 break;
2469 case NHW_STATUS:
2470 status_line = (char **) m_alloc(2 * sizeof(char *));
2471 for (i = 0; i < 2; i++) {
2472 status_line[i] = (char *) m_alloc(status_w * sizeof(char));
2473 memset(status_line[i], 0, status_w);
2475 dr_stat = new_dirty_rect(10);
2476 if (!dr_stat)
2477 panic("Memory allocation failure (dr_stat)");
2478 break;
2479 case NHW_MAP:
2480 map_glyphs = (char **) m_alloc((long) ROWNO * sizeof(char *));
2481 for (i = 0; i < ROWNO; i++) {
2482 map_glyphs[i] = (char *) m_alloc((long) COLNO * sizeof(char));
2483 *map_glyphs[i] = map_glyphs[i][COLNO - 1] = 0;
2485 dr_map = new_dirty_rect(10);
2486 if (!dr_map)
2487 panic("Memory allocation failure (dr_map)");
2489 mar_clear_map();
2490 break;
2491 case NHW_MENU:
2492 case NHW_TEXT: /* They are no more treated as dialog */
2493 break;
2494 default:
2495 p_Gw->gw_window = open_window(
2496 "Sonst", name, NULL, NULL, NAME | MOVER | CLOSER, 0, 0, 0, NULL,
2497 &p_Gw->gw_place, NULL, NULL, NULL, XM_TOP | XM_BOTTOM | XM_SIZE);
2498 break;
2501 p_Gw->gw_type = type;
2503 return (newid);
2506 void
2507 mar_change_menu_2_text(win)
2508 winid win;
2510 Gem_nhwindow[win].gw_type = NHW_TEXT;
2513 /************************* mar_clear_map *******************************/
2515 void
2516 mar_clear_map()
2518 int pla[8];
2519 int x, y;
2521 pla[0] = pla[1] = pla[4] = pla[5] = 0;
2522 pla[2] = pla[6] = scroll_map.px_hline * (COLNO - 1) - 1;
2523 pla[3] = pla[7] = scroll_map.px_vline * ROWNO - 1;
2524 for (y = 0; y < ROWNO; y++)
2525 for (x = 0; x < COLNO - 1; x++)
2526 map_glyphs[y][x] = ' ';
2527 vro_cpyfm(x_handle, ALL_BLACK, pla, &Tile_bilder,
2528 &Map_bild); /* MAR -- 17.Mar 2002 Hmm, what if FontCol_Bild is
2529 bigger? */
2530 if (WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window)
2531 redraw_window(Gem_nhwindow[WIN_MAP].gw_window, NULL);
2534 /************************* destroy_window *******************************/
2536 void
2537 mar_destroy_nhwindow(window)
2538 winid window;
2540 int i;
2542 switch (Gem_nhwindow[window].gw_type) {
2543 case NHW_TEXT:
2544 for (i = 0; i < Anz_text_lines; i++)
2545 free(text_lines[i]);
2546 null_free(text_lines);
2547 Anz_text_lines = 0;
2548 use_rip = FALSE;
2549 break;
2550 case NHW_MENU:
2551 Gem_start_menu(window); /* delete invent_list */
2552 test_free(Menu_title);
2553 break;
2554 case 0: /* No window available, probably an error message? */
2555 break;
2556 default:
2557 close_window(Gem_nhwindow[window].gw_window, 0);
2558 break;
2560 Gem_nhwindow[window].gw_window = NULL;
2561 Gem_nhwindow[window].gw_type = 0;
2562 Gem_nhwindow[window].gw_dirty = FALSE;
2564 if (window == WIN_MAP) {
2565 for (i = 0; i < ROWNO; i++) {
2566 free(map_glyphs[i]);
2568 null_free(map_glyphs);
2569 WIN_MAP = WIN_ERR;
2571 if (window == WIN_STATUS) {
2572 for (i = 0; i < 2; i++)
2573 free(status_line[i]);
2574 null_free(status_line);
2575 WIN_STATUS = WIN_ERR;
2577 if (window == WIN_MESSAGE) {
2578 for (i = 0; i < msg_anz; i++)
2579 free(message_line[i]);
2580 null_free(message_line);
2581 null_free(message_age);
2582 WIN_MESSAGE = WIN_ERR;
2584 if (window == WIN_INVEN)
2585 WIN_INVEN = WIN_ERR;
2588 /************************* nh_poskey *******************************/
2590 void
2591 mar_set_margin(int m)
2593 Max(&m, 0);
2594 Min(&m,
2595 min(ROWNO, COLNO)); /* MAR 16.Mar 2002 -- the larger the less sense */
2596 scroll_margin = m;
2598 void
2599 mar_cliparound()
2601 if (WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window) {
2602 int breite = scroll_margin > 0 ? scroll_margin
2603 : max(scroll_map.hpage / 4, 1),
2604 hoehe = scroll_margin > 0 ? scroll_margin
2605 : max(scroll_map.vpage / 4, 1),
2606 adjust_needed;
2607 adjust_needed = FALSE;
2608 if ((map_cursx < scroll_map.hpos + breite)
2609 || (map_cursx >= scroll_map.hpos + scroll_map.hpage - breite)) {
2610 scroll_map.hpos = map_cursx - scroll_map.hpage / 2;
2611 adjust_needed = TRUE;
2613 if ((map_cursy < scroll_map.vpos + hoehe)
2614 || (map_cursy >= scroll_map.vpos + scroll_map.vpage - hoehe)) {
2615 scroll_map.vpos = map_cursy - scroll_map.vpage / 2;
2616 adjust_needed = TRUE;
2618 if (adjust_needed)
2619 scroll_window(Gem_nhwindow[WIN_MAP].gw_window, WIN_SCROLL, NULL);
2623 void
2624 mar_update_value()
2626 if (WIN_MESSAGE != WIN_ERR) {
2627 mar_message_pause = FALSE;
2628 mar_esc_pressed = FALSE;
2629 mar_display_nhwindow(WIN_MESSAGE);
2632 if (WIN_MAP != WIN_ERR)
2633 mar_cliparound();
2635 if (WIN_STATUS != WIN_ERR) {
2636 mar_check_hilight_status();
2637 mar_display_nhwindow(WIN_STATUS);
2642 Main_Init(xev, availiable)
2643 XEVENT *xev;
2644 int availiable;
2646 xev->ev_mb1mask = xev->ev_mb1state = 1;
2647 xev->ev_mb1clicks = xev->ev_mb2clicks = xev->ev_mb2mask =
2648 xev->ev_mb2state = 2;
2649 return ((MU_KEYBD | MU_BUTTON1 | MU_BUTTON2 | MU_MESAG) & availiable);
2653 * return a key, or 0, in which case a mouse button was pressed
2654 * mouse events should be returned as character postitions in the map window.
2656 /*ARGSUSED*/
2658 mar_nh_poskey(x, y, mod)
2659 int *x, *y, *mod;
2661 static XEVENT xev;
2662 int retval, ev;
2664 xev.ev_mflags = Main_Init(&xev, 0xFFFF);
2665 ev = Event_Multi(&xev);
2667 retval = FAIL;
2669 if (ev & MU_KEYBD) {
2670 char ch = xev.ev_mkreturn & 0x00FF;
2671 char scan = (xev.ev_mkreturn & 0xff00) >> 8;
2672 int shift = xev.ev_mmokstate;
2673 const struct pad *kpad;
2675 /* Translate keypad keys */
2676 if (iskeypad(scan)) {
2677 kpad = mar_iflags_numpad() == 1 ? numpad : keypad;
2678 if (shift & K_SHIFT)
2679 ch = kpad[scan - KEYPADLO].shift;
2680 else if (shift & K_CTRL) {
2681 if (scan >= 0x67 && scan <= 0x6f && scan != 0x6b) {
2682 send_key(kpad[scan - KEYPADLO].normal);
2683 ch = 'g';
2684 } else {
2685 ch = kpad[scan - KEYPADLO].cntrl;
2687 } else
2688 ch = kpad[scan - KEYPADLO].normal;
2690 if (scan == SCANHOME)
2691 mar_cliparound();
2692 else if (scan == SCANF1)
2693 retval = 'h';
2694 else if (scan == SCANF2) {
2695 mar_set_tile_mode(!mar_set_tile_mode(FAIL));
2696 retval = C('l'); /* trigger full-redraw */
2697 } else if (scan == SCANF3) {
2698 draw_cursor = !draw_cursor;
2699 mar_curs(map_cursx, map_cursy);
2700 mar_display_nhwindow(WIN_MAP);
2701 } else if (scan == SCANF4) { /* Font-Selector */
2702 if (!CallFontSelector(0, FAIL, FAIL, FAIL, FAIL)) {
2703 xalert(1, 1, X_ICN_ALERT, NULL, SYS_MODAL, BUTTONS_RIGHT,
2704 TRUE, "Hello", "Fontselector not available!", NULL);
2706 } else if (!ch && shift & K_CTRL && scan == -57) {
2707 /* MAR -- nothing ignore Ctrl-Alt-Clr/Home == MagiC's restore
2708 * screen */
2709 } else {
2710 if (!ch)
2711 ch = (char) M(tolower(scan_2_ascii(xev.ev_mkreturn, shift)));
2712 if (((int) ch) == -128)
2713 ch = '\033';
2714 retval = ch;
2718 if (ev & MU_BUTTON1 || ev & MU_BUTTON2) {
2719 int ex = xev.ev_mmox, ey = xev.ev_mmoy;
2720 WIN *akt_win = window_find(ex, ey);
2722 if (WIN_MAP != WIN_ERR
2723 && akt_win == Gem_nhwindow[WIN_MAP].gw_window) {
2724 *x = max(min((ex - akt_win->work.g_x) / scroll_map.px_hline
2725 + scroll_map.hpos,
2726 COLNO - 1),
2727 0) + 1;
2728 *y = max(min((ey - akt_win->work.g_y) / scroll_map.px_vline
2729 + scroll_map.vpos,
2730 ROWNO),
2732 *mod = xev.ev_mmobutton;
2733 retval = 0;
2734 } else if (WIN_STATUS != WIN_ERR
2735 && akt_win == Gem_nhwindow[WIN_STATUS].gw_window) {
2736 move_win(akt_win);
2737 } else if (WIN_MESSAGE != WIN_ERR
2738 && akt_win == Gem_nhwindow[WIN_MESSAGE].gw_window) {
2739 message_handler(ex, ey);
2743 if (ev & MU_MESAG) {
2744 int *buf = xev.ev_mmgpbuf;
2745 char *str;
2746 OBJECT *z_ob = zz_oblist[MENU];
2748 switch (*buf) {
2749 case MN_SELECTED:
2750 menu_tnormal(z_ob, buf[3], TRUE); /* unselect menu header */
2751 str = ob_get_text(z_ob, buf[4], 0);
2752 str += strlen(str) - 2;
2753 switch (*str) {
2754 case ' ': /* just that command */
2755 retval = str[1];
2756 break;
2757 case '\005': /* Alt command */
2758 case '\007':
2759 retval = M(str[1]);
2760 break;
2761 case '^': /* Ctrl command */
2762 retval = C(str[1]);
2763 break;
2764 case 'f': /* Func Key */
2765 switch (str[1]) {
2766 case '1':
2767 retval = 'h';
2768 break;
2769 case '2':
2770 mar_set_tile_mode(!mar_set_tile_mode(FAIL));
2771 retval = C('l'); /* trigger full-redraw */
2772 break;
2773 case '3':
2774 draw_cursor = !draw_cursor;
2775 mar_curs(map_cursx, map_cursy);
2776 mar_display_nhwindow(WIN_MAP);
2777 break;
2778 default:
2780 break;
2781 default:
2782 mar_about();
2783 break;
2785 break; /* MN_SELECTED */
2786 case WM_CLOSED:
2787 WindowHandler(W_ICONIFYALL, NULL, NULL);
2788 break;
2789 case AP_TERM:
2790 retval = 'S';
2791 break;
2792 case FONT_CHANGED:
2793 if (buf[3] >= 0) {
2794 if (buf[3] == Gem_nhwindow[WIN_MESSAGE].gw_window->handle) {
2795 mar_set_fontbyid(NHW_MESSAGE, buf[4], buf[5]);
2796 mar_display_nhwindow(WIN_MESSAGE);
2797 } else if (buf[3]
2798 == Gem_nhwindow[WIN_MAP].gw_window->handle) {
2799 mar_set_fontbyid(NHW_MAP, buf[4], buf[5]);
2800 mar_display_nhwindow(WIN_MAP);
2801 } else if (buf[3]
2802 == Gem_nhwindow[WIN_STATUS].gw_window->handle) {
2803 mar_set_fontbyid(NHW_STATUS, buf[4], buf[5]);
2804 mar_display_nhwindow(WIN_STATUS);
2806 FontAck(buf[1], 1);
2808 break;
2809 default:
2810 break;
2812 } /* MU_MESAG */
2814 if (retval == FAIL)
2815 retval = mar_nh_poskey(x, y, mod);
2817 return (retval);
2821 Gem_nh_poskey(x, y, mod)
2822 int *x, *y, *mod;
2824 mar_update_value();
2825 return (mar_nh_poskey(x, y, mod));
2828 void
2829 Gem_delay_output()
2831 Event_Timer(50, 0, FALSE); /* wait 50ms */
2835 Gem_doprev_message()
2837 if (msg_pos > 2) {
2838 msg_pos--;
2839 if (WIN_MESSAGE != WIN_ERR)
2840 Gem_nhwindow[WIN_MESSAGE].gw_dirty = TRUE;
2841 mar_display_nhwindow(WIN_MESSAGE);
2843 return (0);
2846 /************************* print_glyph *******************************/
2848 int mar_set_rogue(int);
2851 mar_set_tile_mode(tiles)
2852 int tiles;
2854 static int tile_mode = TRUE;
2855 static GRECT prev;
2856 WIN *z_w = WIN_MAP != WIN_ERR ? Gem_nhwindow[WIN_MAP].gw_window : NULL;
2858 if (tiles < 0)
2859 return (tile_mode);
2860 else if (!z_w)
2861 tile_mode = tiles;
2862 else if (tile_mode == tiles || (mar_set_rogue(FAIL) && tiles))
2863 return (FAIL);
2864 else {
2865 GRECT tmp;
2867 tile_mode = tiles;
2868 scroll_map.px_hline = tiles ? Tile_width : map_font.cw;
2869 scroll_map.px_vline = tiles ? Tile_heigth : map_font.ch;
2870 window_border(MAP_GADGETS, 0, 0, scroll_map.px_hline * (COLNO - 1),
2871 scroll_map.px_vline * ROWNO, &tmp);
2872 z_w->max.g_w = tmp.g_w;
2873 z_w->max.g_h = tmp.g_h;
2874 if (tiles)
2875 z_w->curr = prev;
2876 else
2877 prev = z_w->curr;
2879 window_reinit(z_w, md, md, NULL, FALSE, FALSE);
2881 return (FAIL);
2885 mar_set_rogue(what)
2886 int what;
2888 static int rogue = FALSE, prev_mode = TRUE;
2890 if (what < 0)
2891 return (rogue);
2892 if (what != rogue) {
2893 rogue = what;
2894 if (rogue) {
2895 prev_mode = mar_set_tile_mode(FAIL);
2896 mar_set_tile_mode(FALSE);
2897 } else
2898 mar_set_tile_mode(prev_mode);
2900 return (FAIL);
2903 void
2904 mar_add_pet_sign(window, x, y)
2905 winid window;
2906 int x, y;
2908 if (window != WIN_ERR && window == WIN_MAP) {
2909 static int pla[8] = { 0, 0, 7, 7, 0, 0, 0, 0 },
2910 colindex[2] = { RED, WHITE };
2912 pla[4] = pla[6] = scroll_map.px_hline * x;
2913 pla[5] = pla[7] = scroll_map.px_vline * y;
2914 pla[6] += 7;
2915 pla[7] += 6;
2916 vrt_cpyfm(x_handle, MD_TRANS, pla, &Pet_Mark, &Map_bild, colindex);
2920 void
2921 mar_print_glyph(window, x, y, gl, bkgl)
2922 winid window;
2923 int x, y, gl, bkgl;
2925 if (window != WIN_ERR && window == WIN_MAP) {
2926 static int pla[8];
2928 pla[2] = pla[0] = (gl % Tiles_per_line) * Tile_width;
2929 pla[3] = pla[1] = (gl / Tiles_per_line) * Tile_heigth;
2930 pla[2] += Tile_width - 1;
2931 pla[3] += Tile_heigth - 1;
2932 pla[6] = pla[4] = Tile_width * x; /* x_wert to */
2933 pla[7] = pla[5] = Tile_heigth * y; /* y_wert to */
2934 pla[6] += Tile_width - 1;
2935 pla[7] += Tile_heigth - 1;
2937 vro_cpyfm(x_handle, gl != -1 ? S_ONLY : ALL_BLACK, pla, &Tile_bilder,
2938 &Map_bild);
2942 void
2943 mar_print_char(window, x, y, ch, col)
2944 winid window;
2945 int x, y;
2946 char ch;
2947 int col;
2949 if (window != WIN_ERR && window == WIN_MAP) {
2950 static int gem_color[16] = { 9, 2, 11, 10, 4, 7, 8, 15,
2951 0, 14, 3, 6, 5, 13, 15, 0 };
2952 int pla[8], colindex[2];
2954 map_glyphs[y][x] = ch;
2956 pla[0] = pla[1] = 0;
2957 pla[2] = map_font.cw - 1;
2958 pla[3] = map_font.ch - 1;
2959 pla[6] = pla[4] = map_font.cw * x;
2960 pla[7] = pla[5] = map_font.ch * y;
2961 pla[6] += map_font.cw - 1;
2962 pla[7] += map_font.ch - 1;
2963 colindex[0] = gem_color[col];
2964 colindex[1] = WHITE;
2965 vrt_cpyfm(x_handle, MD_REPLACE, pla, &Black_bild, &FontCol_Bild,
2966 colindex);
2970 /************************* getlin *******************************/
2972 void
2973 Gem_getlin(ques, input)
2974 const char *ques;
2975 char *input;
2977 OBJECT *z_ob = zz_oblist[LINEGET];
2978 int d_exit, length;
2979 char *pr[2], *tmp;
2981 if (WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2982 mar_display_nhwindow(WIN_MESSAGE);
2984 z_ob[LGPROMPT].ob_type = G_USERDEF;
2985 z_ob[LGPROMPT].ob_spec.userblk = &ub_prompt;
2986 z_ob[LGPROMPT].ob_height = 2 * gr_ch;
2988 length = z_ob[LGPROMPT].ob_width / gr_cw;
2989 if (strlen(ques) > length) {
2990 tmp = ques + length;
2991 while (*tmp != ' ' && tmp >= ques) {
2992 tmp--;
2994 if (tmp <= ques)
2995 tmp = ques + length; /* Mar -- Oops, what a word :-) */
2996 pr[0] = ques;
2997 *tmp = 0;
2998 pr[1] = ++tmp;
2999 } else {
3000 pr[0] = ques;
3001 pr[1] = NULL;
3003 ub_prompt.ub_parm = (long) pr;
3005 ob_clear_edit(z_ob);
3006 d_exit = xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE,
3007 DIALOG_MODE);
3008 Event_Timer(0, 0, TRUE);
3010 if (d_exit == W_CLOSED || d_exit == W_ABANDON
3011 || (d_exit & NO_CLICK) == QLG) {
3012 *input = '\033';
3013 input[1] = 0;
3014 } else
3015 strncpy(input, ob_get_text(z_ob, LGREPLY, 0), length);
3018 /************************* ask_direction *******************************/
3020 #define Dia_Init K_Init
3023 Dia_Handler(xev)
3024 XEVENT *xev;
3026 int ev = xev->ev_mwich;
3027 char ch = (char) (xev->ev_mkreturn & 0x00FF);
3029 if (ev & MU_KEYBD) {
3030 WIN *w;
3031 DIAINFO *dinf;
3033 switch (ch) {
3034 case 's':
3035 send_key((int) (mar_iflags_numpad() ? '5' : '.'));
3036 break;
3037 case '.':
3038 send_key('5'); /* MAR -- '.' is a button if numpad isn't set */
3039 break;
3040 case '\033': /*ESC*/
3041 if ((w = get_top_window()) && (dinf = (DIAINFO *) w->dialog)
3042 && dinf->di_tree == zz_oblist[DIRECTION]) {
3043 my_close_dialog(dinf, FALSE);
3044 break;
3046 /* Fall thru */
3047 default:
3048 ev &= ~MU_KEYBD; /* let the dialog handle it */
3049 break;
3052 return (ev);
3056 mar_ask_direction()
3058 int d_exit;
3059 OBJECT *z_ob = zz_oblist[DIRECTION];
3061 Event_Handler(Dia_Init, Dia_Handler);
3062 mar_set_dir_keys();
3063 d_exit = xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE,
3064 DIALOG_MODE);
3065 Event_Timer(0, 0, TRUE);
3066 Event_Handler(NULL, NULL);
3068 if (d_exit == W_CLOSED || d_exit == W_ABANDON)
3069 return ('\033');
3070 if ((d_exit & NO_CLICK) == DIRDOWN)
3071 return ('>');
3072 if ((d_exit & NO_CLICK) == DIRUP)
3073 return ('<');
3074 if ((d_exit & NO_CLICK) == (DIR1 + 8)) /* 5 or . */
3075 return ('.');
3076 return (*ob_get_text(z_ob, d_exit & NO_CLICK, 0));
3079 /************************* yn_function *******************************/
3081 #define any_init M_Init
3083 static int
3084 any_handler(xev)
3085 XEVENT *xev;
3087 int ev = xev->ev_mwich;
3089 if (ev & MU_MESAG) {
3090 int *buf = xev->ev_mmgpbuf;
3092 if (*buf == OBJC_EDITED)
3093 my_close_dialog(*(DIAINFO **) &buf[4], FALSE);
3094 else
3095 ev &= ~MU_MESAG;
3097 return (ev);
3101 send_yn_esc(char ch)
3103 static char esc_char = 0;
3105 if (ch < 0) {
3106 if (esc_char) {
3107 send_key((int) esc_char);
3108 return (TRUE);
3110 return (FALSE);
3111 } else
3112 esc_char = ch;
3113 return (TRUE);
3116 #define single_init K_Init
3118 static int
3119 single_handler(xev)
3120 XEVENT *xev;
3122 int ev = xev->ev_mwich;
3124 if (ev & MU_KEYBD) {
3125 char ch = (char) xev->ev_mkreturn & 0x00FF;
3126 WIN *w;
3127 DIAINFO *dinf;
3129 switch (ch) {
3130 case ' ':
3131 send_return();
3132 break;
3133 case '\033':
3134 if ((w = get_top_window()) && (dinf = (DIAINFO *) w->dialog)
3135 && dinf->di_tree == zz_oblist[YNCHOICE]) {
3136 if (!send_yn_esc(FAIL))
3137 my_close_dialog(dinf, FALSE);
3138 break;
3140 /* Fall thru */
3141 default:
3142 ev &= ~MU_MESAG;
3145 return (ev);
3148 char
3149 Gem_yn_function(query, resp, def)
3150 const char *query, *resp;
3151 char def;
3153 OBJECT *z_ob = zz_oblist[YNCHOICE];
3154 int d_exit, i, len;
3155 long anzahl;
3156 char *tmp;
3157 const char *ptr;
3159 if (WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
3160 mar_display_nhwindow(WIN_MESSAGE);
3162 /* if query for direction the special dialog */
3163 if (strstr(query, "irect"))
3164 return (mar_ask_direction());
3166 len = min(strlen(query), (max_w - 8 * gr_cw) / gr_cw);
3167 z_ob[ROOT].ob_width = (len + 8) * gr_cw;
3168 z_ob[YNPROMPT].ob_width = gr_cw * len + 8;
3169 tmp = ob_get_text(z_ob, YNPROMPT, 0);
3170 ob_set_text(z_ob, YNPROMPT, mar_copy_of(query));
3172 if (resp) { /* single inputs */
3173 ob_hide(z_ob, SOMECHARS, FALSE);
3174 ob_hide(z_ob, ANYCHAR, TRUE);
3176 if (strchr(resp, 'q'))
3177 send_yn_esc('q');
3178 else if (strchr(resp, 'n'))
3179 send_yn_esc('n');
3180 else
3181 send_yn_esc(
3182 def); /* strictly def should be returned, but in trad. I it's
3183 0 */
3185 if (strchr(resp, '#')) { /* count possible */
3186 ob_hide(z_ob, YNOK, FALSE);
3187 ob_hide(z_ob, COUNT, FALSE);
3188 } else { /* no count */
3189 ob_hide(z_ob, YNOK, TRUE);
3190 ob_hide(z_ob, COUNT, TRUE);
3193 if ((anzahl = (long) strchr(resp, '\033'))) {
3194 anzahl -= (long) resp;
3195 } else {
3196 anzahl = strlen(resp);
3198 for (i = 0, ptr = resp; i < 2 * anzahl; i += 2, ptr++) {
3199 ob_hide(z_ob, YN1 + i, FALSE);
3200 mar_change_button_char(z_ob, YN1 + i, *ptr);
3201 ob_undoflag(z_ob, YN1 + i, DEFAULT);
3202 if (*ptr == def)
3203 ob_doflag(z_ob, YN1 + i, DEFAULT);
3206 z_ob[SOMECHARS].ob_width = z_ob[YN1 + i].ob_x + 8;
3207 z_ob[SOMECHARS].ob_height = z_ob[YN1 + i].ob_y + gr_ch + gr_ch / 2;
3208 Max((int *) &z_ob[ROOT].ob_width,
3209 z_ob[SOMECHARS].ob_width + 4 * gr_cw);
3210 z_ob[ROOT].ob_height = z_ob[SOMECHARS].ob_height + 4 * gr_ch;
3211 if (strchr(resp, '#'))
3212 z_ob[ROOT].ob_height = z_ob[YNOK].ob_y + 2 * gr_ch;
3214 for (i += YN1; i < (YNN + 1); i += 2) {
3215 ob_hide(z_ob, i, TRUE);
3217 Event_Handler(single_init, single_handler);
3218 } else { /* any input */
3219 ob_hide(z_ob, SOMECHARS, TRUE);
3220 ob_hide(z_ob, ANYCHAR, FALSE);
3221 ob_hide(z_ob, YNOK, TRUE);
3222 ob_hide(z_ob, COUNT, TRUE);
3223 z_ob[ANYCHAR].ob_height = 2 * gr_ch;
3224 z_ob[CHOSENCH].ob_y = z_ob[CHOSENCH + 1].ob_y = gr_ch / 2;
3225 z_ob[ROOT].ob_width =
3226 max(z_ob[YNPROMPT].ob_width + z_ob[YNPROMPT].ob_x,
3227 z_ob[ANYCHAR].ob_width + z_ob[ANYCHAR].ob_x) + 2 * gr_cw;
3228 z_ob[ROOT].ob_height =
3229 z_ob[ANYCHAR].ob_height + z_ob[ANYCHAR].ob_y + gr_ch / 2;
3230 *ob_get_text(z_ob, CHOSENCH, 0) = '?';
3231 Event_Handler(any_init, any_handler);
3234 d_exit = xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE,
3235 DIALOG_MODE);
3236 Event_Timer(0, 0, TRUE);
3237 Event_Handler(NULL, NULL);
3238 /* display of count is missing (through the core too) */
3240 free(ob_get_text(z_ob, YNPROMPT, 0));
3241 ob_set_text(z_ob, YNPROMPT, tmp);
3243 if (resp && (d_exit == W_CLOSED || d_exit == W_ABANDON))
3244 return ('\033');
3245 if ((d_exit & NO_CLICK) == YNOK) {
3246 yn_number = atol(ob_get_text(z_ob, COUNT, 0));
3247 return ('#');
3249 if (!resp)
3250 return (*ob_get_text(z_ob, CHOSENCH, 0));
3251 return (*ob_get_text(z_ob, d_exit & NO_CLICK, 0));
3255 * Allocate a copy of the given string. If null, return a string of
3256 * zero length.
3258 * This is an exact duplicate of copy_of() in X11/winmenu.c.
3260 static char *
3261 mar_copy_of(s)
3262 const char *s;
3264 if (!s)
3265 s = nullstr;
3266 return strcpy((char *) m_alloc((unsigned) (strlen(s) + 1)), s);
3269 const char *strRP = "raw_print", *strRPB = "raw_print_bold";
3271 void
3272 mar_raw_print(str)
3273 const char *str;
3275 xalert(1, FAIL, X_ICN_INFO, NULL, APPL_MODAL, BUTTONS_CENTERED, TRUE,
3276 strRP, str, NULL);
3279 void
3280 mar_raw_print_bold(str)
3281 const char *str;
3283 char buf[BUFSZ];
3285 sprintf(buf, "!%s", str);
3286 xalert(1, FAIL, X_ICN_INFO, NULL, APPL_MODAL, BUTTONS_CENTERED, TRUE,
3287 strRPB, buf, NULL);
3290 /*wingem1.c*/