1 /*	SCCS Id: @(#)wingem1.c	3.4	1999/12/10	*/
2 /* Copyright (c) Christian Bressler 1999 	  */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 #define __TCC_COMPAT__
6 
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>
14 
15 #include "gem_rsc.h"
16 #include "load_img.h"
17 #include "gr_rect.h"
18 
19 #define genericptr_t void *
20 typedef signed char schar;
21 #include "wintype.h"
22 #undef genericptr_t
23 
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
44 
45 static char nullstr[]="",  md[]="NetHack 3.4.3", strCancel[]="Cancel", strOk[]="Ok", strText[]="Text";
46 
47 extern winid WIN_MESSAGE, WIN_MAP, WIN_STATUS, WIN_INVEN;
48 
49 #define MAXWIN 20
50 #define ROWNO 21
51 #define COLNO 80
52 #define MSGLEN 100
53 
54 #define MAP_GADGETS NAME|MOVER|CLOSER|FULLER|LFARROW|RTARROW|UPARROW|DNARROW|VSLIDE|HSLIDE|SIZER|SMALLER
55 #define DIALOG_MODE AUTO_DIAL|MODAL|NO_ICONIFY
56 
57 /*
58  *  Keyboard translation tables.
59  */
60 #define C(c)	(0x1f & (c))
61 #define M(c)	(0x80 | (c))
62 
63 #define KEYPADLO	0x61
64 #define KEYPADHI	0x71
65 
66 #define PADKEYS 	(KEYPADHI - KEYPADLO + 1)
67 #define iskeypad(x)	(KEYPADLO <= (x) && (x) <= KEYPADHI)
68 
69 /*
70  * Keypad keys are translated to the normal values below.
71  * When iflags.BIOS is active, shifted keypad keys are translated to the
72  *    shift values below.
73  */
74 static const struct pad {
75 	char normal, shift, cntrl;
76 } keypad[PADKEYS] = {
77 			{C('['), 'Q', C('[')},		/* UNDO */
78 			{'?', '/', '?'},		/* HELP */
79 			{'(', 'a', '('},		/* ( */
80 			{')', 'w', ')'},		/* ) */
81 			{'/', '/', '/'},		/* / */
82 			{C('p'), '$', C('p')},		/* * */
83 			{'y', 'Y', C('y')},		/* 7 */
84 			{'k', 'K', C('k')},		/* 8 */
85 			{'u', 'U', C('u')},		/* 9 */
86 			{'h', 'H', C('h')},		/* 4 */
87 			{'.', '.', '.'},
88 			{'l', 'L', C('l')},		/* 6 */
89 			{'b', 'B', C('b')},		/* 1 */
90 			{'j', 'J', C('j')},		/* 2 */
91 			{'n', 'N', C('n')},		/* 3 */
92 			{'i', 'I', C('i')},		/* Ins */
93 			{'.', ':', ':'}			/* Del */
94 }, numpad[PADKEYS] = {
95 			{C('['), 'Q', C('[')}	,	/* UNDO */
96 			{'?', '/', '?'},		/* HELP */
97 			{'(', 'a', '('},		/* ( */
98 			{')', 'w', ')'},		/* ) */
99 			{'/', '/', '/'},		/* / */
100 			{C('p'), '$', C('p')},		/* * */
101 			{'7', M('7'), '7'},		/* 7 */
102 			{'8', M('8'), '8'},		/* 8 */
103 			{'9', M('9'), '9'},		/* 9 */
104 			{'4', M('4'), '4'},		/* 4 */
105 			{'.', '.', '.'},		/* 5 */
106 			{'6', M('6'), '6'},		/* 6 */
107 			{'1', M('1'), '1'},		/* 1 */
108 			{'2', M('2'), '2'},		/* 2 */
109 			{'3', M('3'), '3'},		/* 3 */
110 			{'i', 'I', C('i')},		/* Ins */
111 			{'.', ':', ':'}			/* Del */
112 };
113 
114 #define TBUFSZ 300
115 #define BUFSZ 256
116 extern int yn_number;							/* from decl.c */
117 extern char toplines[TBUFSZ];					/* from decl.c */
118 extern char mapped_menu_cmds[];				/* from options.c */
119 extern int mar_iflags_numpad(void);			/* from wingem.c */
120 extern void Gem_raw_print(const char *);	/* from wingem.c */
121 extern int mar_hp_query(void);				/* from wingem.c */
122 extern int mar_get_msg_history(void);		/* from wingem.c */
123 extern int mar_get_msg_visible(void);		/* from wingem.c */
124 extern void mar_get_font(int,char **,int *);/* from wingem.c */
125 extern int vdi2dev4[];							/* from load_img.c */
126 
127 void recalc_msg_win(GRECT*);
128 void recalc_status_win(GRECT*);
129 void calc_std_winplace(int, GRECT *);
130 int (*v_mtext)(int,int,int,char*);
131 static int no_glyph;	/* the int indicating there is no glyph */
132 IMG_header tile_image, titel_image, rip_image;
133 MFDB Tile_bilder, Map_bild, Titel_bild, Rip_bild, Black_bild, Pet_Mark, FontCol_Bild;
134 static int Tile_width=16, Tile_heigth=16, Tiles_per_line=20;
135 char *Tilefile=NULL;
136 /* pet_mark Design by Warwick Allison warwick@troll.no */
137 static int pet_mark_data[]={0x0000,0x3600,0x7F00,0x7F00,0x3E00,0x1C00,0x0800};
138 static short	*normal_palette=NULL;
139 
140 static struct gw{
141 	WIN *gw_window;
142 	int gw_type, gw_dirty;
143 	GRECT gw_place;
144 } Gem_nhwindow[MAXWIN];
145 
146 typedef struct {
147 	int id;
148 	int size;
149 	int cw, ch;
150 	int prop;
151 } NHGEM_FONT;
152 
153 /*struct gemmapdata {*/
154 	GRECT dirty_map_area={COLNO-1,ROWNO,0,0};
155 	int map_cursx=0, map_cursy=0, curs_col=WHITE;
156 	int draw_cursor=TRUE, scroll_margin=-1;
157 	NHGEM_FONT map_font;
158 	SCROLL 	scroll_map;
159 	char **map_glyphs=NULL;
160 	dirty_rect *dr_map;
161 /*};*/
162 
163 /*struct gemstatusdata{*/
164 	char **status_line;
165 	int Anz_status_lines, status_w, status_align=FALSE;
166 	NHGEM_FONT status_font;
167 	dirty_rect *dr_stat;
168 /*};*/
169 
170 /*struct gemmessagedata{*/
171 	int mar_message_pause=TRUE;
172 	int mar_esc_pressed=FALSE;
173 	int messages_pro_zug=0;
174 	char **message_line;
175 	int *message_age;
176 	int msg_pos=0, msg_max=0, msg_anz=0, msg_width=0, msg_vis=3, msg_align=TRUE;
177 	NHGEM_FONT msg_font;
178 	dirty_rect *dr_msg;
179 /*};*/
180 
181 /*struct geminvdata {*/
182 	SCROLL scroll_menu;
183 	Gem_menu_item *invent_list;
184 	int Anz_inv_lines=0, Inv_breite=16;
185 	NHGEM_FONT menu_font;
186 	int Inv_how;
187 /*};*/
188 
189 /*struct gemtextdata{*/
190 	char **text_lines;
191 	int Anz_text_lines=0, text_width;
192 	NHGEM_FONT text_font;
193 	int use_rip=FALSE;
194 	extern char** rip_line;
195 /*};*/
196 
197 static OBJECT *zz_oblist[NHICON+1];
198 
199 MITEM scroll_keys[]={
200 /* menu, key, state, mode, msg */
201 	{FAIL,key(CTRLLEFT,0),K_CTRL,PAGE_LEFT,FAIL},
202 	{FAIL,key(CTRLRIGHT,0),K_CTRL,PAGE_RIGHT,FAIL},
203 	{FAIL,key(SCANUP,0),K_SHIFT,PAGE_UP,FAIL},
204 	{FAIL,key(SCANDOWN,0),K_SHIFT,PAGE_DOWN,FAIL},
205 	{FAIL,key(SCANLEFT,0),0,LINE_LEFT,FAIL},
206 	{FAIL,key(SCANRIGHT,0),0,LINE_RIGHT,FAIL},
207 	{FAIL,key(SCANUP,0),0,LINE_UP,FAIL},
208 	{FAIL,key(SCANDOWN,0),0,LINE_DOWN,FAIL},
209 	{FAIL,key(SCANLEFT,0),K_SHIFT,LINE_START,FAIL},
210 	{FAIL,key(SCANRIGHT,0),K_SHIFT,LINE_END,FAIL},
211 	{FAIL,key(SCANUP,0),K_CTRL,WIN_START,FAIL},
212 	{FAIL,key(SCANDOWN,0),K_CTRL,WIN_END,FAIL},
213 	{FAIL,key(SCANHOME,0),K_SHIFT,WIN_END,FAIL},
214 	{FAIL,key(SCANHOME,0),0,WIN_START,FAIL}
215 };
216 #define SCROLL_KEYS	14
217 
218 static DIAINFO *Inv_dialog;
219 
220 #define null_free(ptr)	free(ptr), (ptr)=NULL
221 #define test_free(ptr)	if(ptr) null_free(ptr)
222 
223 static char *Menu_title=NULL;
224 
225 void mar_display_nhwindow(winid);
mar_check_hilight_status(void)226 void mar_check_hilight_status(void){}	/* to be filled :-) */
227 static char *mar_copy_of(const char *);
228 
229 extern void panic(const char *, ...);
m_alloc(size_t amt)230 void *m_alloc(size_t amt){
231 	void *ptr;
232 
233 	ptr=malloc(amt);
234 	if (!ptr) panic("Memory allocation failure; cannot get %lu bytes", amt);
235 	return(ptr);
236 }
237 
mar_clear_messagewin(void)238 void mar_clear_messagewin(void){
239 	int i, *ptr=message_age;
240 
241 	if(WIN_MESSAGE==WIN_ERR) return;
242 	for(i=msg_anz;--i>=0;ptr++){
243 		if(*ptr)
244 			Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
245 		*ptr=FALSE;
246 	}
247 	mar_message_pause=FALSE;
248 
249 	mar_display_nhwindow(WIN_MESSAGE);
250 }
251 
clipbrd_save(void * data,int cnt,boolean append,boolean is_inv)252 void clipbrd_save(void *data,int cnt,boolean append,boolean is_inv){
253 	char path[MAX_PATH],*text,*crlf="\r\n";
254 	long handle;
255 	int i;
256 
257 	if (data && cnt>0 && scrp_path(path,"scrap.txt") && (handle = append ? Fopen(path,1) : Fcreate(path,0))>0){
258 		if (append)
259 			Fseek(0L,(int) handle,SEEK_END);
260 		if(is_inv){
261 			Gem_menu_item *it=(Gem_menu_item *)data;
262 
263 			for(;it;it=it->Gmi_next){
264 				text=it->Gmi_str;
265 				Fwrite((int) handle,strlen(text),text);
266 				Fwrite((int) handle,2L,crlf);
267 			}
268 		}else{
269 			for(i=0;i<cnt;i++){
270 				text=((char **)data)[i]+1;
271 				Fwrite((int) handle,strlen(text),text);
272 				Fwrite((int) handle,2L,crlf);
273 			}
274 		}
275 		Fclose((int) handle);
276 
277 		scrp_changed(SCF_TEXT,0x2e545854l);	/* .TXT */
278 	}
279 }
280 
move_win(WIN * z_win)281 void move_win(WIN *z_win){
282 	GRECT frame=desk;
283 
284 	v_set_mode(MD_XOR);
285 	v_set_line(BLACK,1,1,0,0);
286 	frame.g_w<<=1, frame.g_h<<=1;
287 	if(graf_rt_dragbox(FALSE,&z_win->curr,&frame,&z_win->curr.g_x,&z_win->curr.g_y,NULL))
288 		window_size(z_win,&z_win->curr);
289 	else
290 		window_top(z_win);
291 }
292 
message_handler(int x,int y)293 void message_handler(int x, int y){
294 	switch(objc_find(zz_oblist[MSGWIN],ROOT,MAX_DEPTH,x,y)){
295 	case UPMSG:
296 		if(msg_pos>msg_vis-1){
297 			msg_pos--;
298 			Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
299 			mar_display_nhwindow(WIN_MESSAGE);
300 		}
301 		Event_Timer(50,0,TRUE);
302 		break;
303 	case DNMSG:
304 		if(msg_pos<msg_max){
305 			msg_pos++;
306 			Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
307 			mar_display_nhwindow(WIN_MESSAGE);
308 		}
309 		Event_Timer(50,0,TRUE);
310 		break;
311 	case GRABMSGWIN:
312 	default:
313 		move_win(Gem_nhwindow[WIN_MESSAGE].gw_window);
314 		break;
315 	case -1:
316 		break;
317 	}
318 }
319 
mar_ob_mapcenter(OBJECT * p_obj)320 int mar_ob_mapcenter(OBJECT *p_obj){
321 	WIN *p_w= WIN_MAP!=WIN_ERR ? Gem_nhwindow[WIN_MAP].gw_window : NULL;
322 
323 	if(p_obj && p_w){
324 		p_obj->ob_x=p_w->work.g_x+p_w->work.g_w/2-p_obj->ob_width/2;
325 		p_obj->ob_y=p_w->work.g_y+p_w->work.g_h/2-p_obj->ob_height/2;
326 		return(DIA_LASTPOS);
327 	}
328 	return(DIA_CENTERED);
329 }
330 
331 /****************************** set_no_glyph *************************************/
332 
333 void
mar_set_no_glyph(ng)334 mar_set_no_glyph(ng)
335 int ng;
336 {
337 	no_glyph=ng;
338 }
339 
340 void
mar_set_tilefile(name)341 mar_set_tilefile(name)
342 char* name;
343 {
344 	Tilefile=name;
345 }
346 void
mar_set_tilex(value)347 mar_set_tilex(value)
348 int value;
349 {
350 	Min(&value,32);
351 	Max(&value,1);
352 	Tile_width=value;
353 }
354 void
mar_set_tiley(value)355 mar_set_tiley(value)
356 int value;
357 {
358 	Min(&value,32);
359 	Max(&value,1);
360 	Tile_heigth=value;
361 }
362 /****************************** userdef_draw *************************************/
363 
364 void rearrange_windows(void);
mar_set_status_align(int sa)365 void mar_set_status_align(int sa){
366 	if(status_align!=sa){
367 		status_align=sa;
368 		rearrange_windows();
369 	}
370 }
mar_set_msg_align(int ma)371 void mar_set_msg_align(int ma){
372 	if(msg_align!=ma){
373 		msg_align=ma;
374 		rearrange_windows();
375 	}
376 }
mar_set_msg_visible(int mv)377 void mar_set_msg_visible(int mv){
378 	if(mv!=msg_vis){
379 		Max(&mv,1);
380 		Min(&mv,min(msg_anz,20));
381 		Min(&mv,desk.g_h/msg_font.ch/2);
382 		msg_vis=mv;
383 		rearrange_windows();
384 	}
385 }
386 /* size<0 cellheight; size>0 points */
mar_set_fontbyid(int type,int id,int size)387 void mar_set_fontbyid(int type, int id, int size){
388 	int chardim[4];
389 	if(id<=0)
390 		id=ibm_font_id;
391 	if((size>-3 && size<3) || size<-20 || size>20)
392 		size=-ibm_font;
393 	/* MAR -- 17.Mar 2002 For now allow FNT_PROP only with NHW_TEXT */
394 	if(type!=NHW_TEXT && (FontInfo(id)->type & (FNT_PROP|FNT_ASCII)))
395 		id=ibm_font_id;
396 	switch(type){
397 	case NHW_MESSAGE:
398 		if(msg_font.size==-size && msg_font.id==id)
399 			break;
400 		msg_font.size=-size;
401 		msg_font.id=id;
402 		msg_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
403 		v_set_text(msg_font.id,msg_font.size,BLACK,0,0,chardim);
404 		msg_font.ch=chardim[3] ? chardim[3] : 1;
405 		msg_font.cw=chardim[2] ? chardim[2] : 1;
406 		msg_width=min(max_w/msg_font.cw-3,MSGLEN);
407 		rearrange_windows();
408 		break;
409 	case NHW_MAP:
410 		if(map_font.size!=-size || map_font.id!=id){
411 			MFDB mtmp;
412 			map_font.size=-size;
413 			map_font.id=id;
414 			map_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
415 			v_set_text(map_font.id,map_font.size,BLACK,0,0,chardim);
416 			map_font.ch=chardim[3] ? chardim[3] : 1;
417 			map_font.cw=chardim[2] ? chardim[2] : 1;
418 			mfdb(&mtmp,NULL,(COLNO-1)*map_font.cw, ROWNO*map_font.ch, 0, planes);
419 			if(mfdb_size(&mtmp)>mfdb_size(&FontCol_Bild) && mfdb_size(&mtmp)>mfdb_size(&Map_bild)){
420 				FontCol_Bild.fd_addr=Map_bild.fd_addr=(int *)realloc(Map_bild.fd_addr,mfdb_size(&mtmp));
421 				if(!Map_bild.fd_addr)	/* FIXME -- Not really neccessary since the former space is still valid */
422 					panic("Not enough Space for the map.");
423 			}
424 			mfdb(&FontCol_Bild,FontCol_Bild.fd_addr,(COLNO-1)*map_font.cw, ROWNO*map_font.ch, 0, planes);
425 			rearrange_windows();
426 		}
427 		break;
428 	case NHW_STATUS:
429 		if(status_font.size==-size && status_font.id==id)
430 			break;
431 		status_font.size=-size;
432 		status_font.id=id;
433 		status_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
434 		v_set_text(status_font.id,status_font.size,BLACK,0,0,chardim);
435 		status_font.ch=chardim[3] ? chardim[3] : 1;
436 		status_font.cw=chardim[2] ? chardim[2] : 1;
437 		rearrange_windows();
438 		break;
439 	case NHW_MENU:
440 		if(menu_font.size==-size && menu_font.id==id)
441 			break;
442 		menu_font.size=-size;
443 		menu_font.id=id;
444 		menu_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
445 		v_set_text(menu_font.id,menu_font.size,BLACK,0,0,chardim);
446 		menu_font.ch=chardim[3] ? chardim[3] : 1;
447 		menu_font.cw=chardim[2] ? chardim[2] : 1;
448 		break;
449 	case NHW_TEXT:
450 		if(text_font.size==-size && text_font.id==id)
451 			break;
452 		text_font.size=-size;
453 		text_font.id=id;
454 		text_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
455 		v_set_text(text_font.id,text_font.size,BLACK,0,0,chardim);
456 		text_font.ch=chardim[3] ? chardim[3] : 1;
457 		text_font.cw=chardim[2] ? chardim[2] : 1;
458 		break;
459 	default:
460 		break;
461 	}
462 }
mar_set_font(int type,const char * font_name,int size)463 void mar_set_font(int type, const char *font_name, int size){
464 	int id=0;
465 	/* MAR -- 17.Mar 2002 usual Gem behavior, use the Font-ID */
466 	if(font_name && *font_name){
467 		id=atoi(font_name);
468 		if(id<=0){
469 			int i, tid;
470 			char name[32];
471 			for(i=fonts_loaded;--i>=0;){
472 				tid=vqt_name(x_handle,i,name);
473 				if(!stricmp(name,font_name)){
474 					id=tid;
475 					break;
476 				}
477 			}
478 		}
479 	}
480 	mar_set_fontbyid(type,id,size);
481 }
rearrange_windows(void)482 void rearrange_windows(void){
483 	GRECT area;
484 	int todo=TRUE;
485 	if(WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window){
486 		scroll_map.px_hline=mar_set_tile_mode(FAIL)?Tile_width:map_font.cw;
487 		scroll_map.px_vline=mar_set_tile_mode(FAIL)?Tile_heigth:map_font.ch;
488 		if(todo){
489 			calc_std_winplace(FAIL,&area);
490 			todo=FALSE;
491 		}
492 		calc_std_winplace(NHW_MAP,&area);
493 		Gem_nhwindow[WIN_MAP].gw_window->max.g_w=area.g_w;
494 		Gem_nhwindow[WIN_MAP].gw_window->max.g_h=area.g_h;
495 		Gem_nhwindow[WIN_MAP].gw_window->max.g_w=area.g_w;
496 		window_reinit(Gem_nhwindow[WIN_MAP].gw_window,md,md,NULL,FALSE,FALSE);
497 		{
498 			int buf[8];
499 			buf[3]=K_CTRL;
500 			buf[4]=C('L');
501 			AvSendMsg(ap_id,AV_SENDKEY,buf);
502 		}
503 	}
504 	if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window){
505 		if(todo){
506 			calc_std_winplace(FAIL,&area);
507 			todo=FALSE;
508 		}
509 		calc_std_winplace(NHW_MESSAGE,&area);
510 		Gem_nhwindow[WIN_MESSAGE].gw_window->min_h=area.g_h;
511 		window_size(Gem_nhwindow[WIN_MESSAGE].gw_window,&area);
512 		redraw_window(Gem_nhwindow[WIN_MESSAGE].gw_window,NULL);
513 	}
514 	if(WIN_STATUS != WIN_ERR && Gem_nhwindow[WIN_STATUS].gw_window){
515 		if(todo){
516 			calc_std_winplace(FAIL,&area);
517 			todo=FALSE;
518 		}
519 		calc_std_winplace(NHW_STATUS,&area);
520 		Gem_nhwindow[WIN_STATUS].gw_window->min_h=area.g_h;
521 		window_size(Gem_nhwindow[WIN_STATUS].gw_window,&area);
522 		redraw_window(Gem_nhwindow[WIN_STATUS].gw_window,NULL);
523 	}
524 }
my_color_area(GRECT * area,int col)525 void my_color_area(GRECT *area, int col){
526 	int pxy[4];
527 
528 	v_set_fill(col,1,IP_SOLID,0);
529 	rc_grect_to_array(area,pxy);
530 	v_bar(x_handle,pxy);
531 }
532 
my_clear_area(GRECT * area)533 void my_clear_area(GRECT *area){
534 	my_color_area(area, WHITE);
535 }
536 
537 int mar_set_tile_mode(int);
538 
win_draw_map(int first,WIN * win,GRECT * area)539 static void win_draw_map(int first, WIN *win, GRECT *area){
540 	int pla[8], w=area->g_w-1, h=area->g_h-1;
541 	int i, x, y;
542 	GRECT back=*area;
543 
544 	first=first;
545 
546 	if(!mar_set_tile_mode(FAIL)){
547 		int start=(area->g_x-win->work.g_x)/map_font.cw+scroll_map.hpos;
548 		int stop=(area->g_x+area->g_w+map_font.cw-1-win->work.g_x)/map_font.cw+scroll_map.hpos;
549 		int starty=(area->g_y-win->work.g_y)/map_font.ch+scroll_map.vpos;
550 		int stopy=min((area->g_y+area->g_h+map_font.ch-1-win->work.g_y)/map_font.ch+scroll_map.vpos,ROWNO);
551 		char tmp;
552 		v_set_text(map_font.id,map_font.size,WHITE,0,0,NULL);
553 		v_set_mode(MD_TRANS);
554 
555 		x=win->work.g_x-scroll_map.px_hpos+start*map_font.cw;
556 		y=win->work.g_y-scroll_map.px_vpos+starty*map_font.ch;
557 		pla[2]=pla[0]=scroll_map.px_hpos+area->g_x-win->work.g_x;
558 		pla[3]=pla[1]=starty*map_font.ch;
559 		pla[2]+=w;
560 		pla[3]+=map_font.ch-1;
561 		pla[6]=pla[4]=area->g_x;	/* x_wert to */
562 		pla[7]=pla[5]=y;	/* y_wert to */
563 		pla[6]+=w;
564 		pla[7]+=map_font.ch-1;
565 		back.g_h=map_font.ch;
566 		for(i=starty;i<stopy;i++,y+=map_font.ch,pla[1]+=map_font.ch,pla[3]+=map_font.ch,pla[5]+=map_font.ch,pla[7]+=map_font.ch){
567 			back.g_y=y;
568 			my_color_area(&back,BLACK);
569 			tmp=map_glyphs[i][stop];
570 			map_glyphs[i][stop]=0;
571 			(*v_mtext)(x_handle,x,y,&map_glyphs[i][start]);
572 			map_glyphs[i][stop]=tmp;
573 			vro_cpyfm(x_handle, S_OR_D, pla, &FontCol_Bild, screen);
574 		}
575 	}else{
576 		v_set_mode(MD_REPLACE);
577 		pla[2]=pla[0]=scroll_map.px_hpos+area->g_x-win->work.g_x;
578 		pla[3]=pla[1]=scroll_map.px_vpos+area->g_y-win->work.g_y;
579 		pla[2]+=w;
580 		pla[3]+=h;
581 		pla[6]=pla[4]=area->g_x;	/* x_wert to */
582 		pla[7]=pla[5]=area->g_y;	/* y_wert to */
583 		pla[6]+=w;
584 		pla[7]+=h;
585 		vro_cpyfm(x_handle, S_ONLY, pla, &Map_bild, screen);
586 	}
587 
588 	if(draw_cursor){
589 		v_set_line(curs_col,1,1,0,0);
590 		pla[0]=pla[2]=win->work.g_x+scroll_map.px_hline*(map_cursx-scroll_map.hpos);
591 		pla[1]=pla[3]=win->work.g_y+scroll_map.px_vline*(map_cursy-scroll_map.vpos);
592 		pla[2]+=scroll_map.px_hline-1;
593 		pla[3]+=scroll_map.px_vline-1;
594 		v_rect(pla[0],pla[1],pla[2],pla[3]);
595 	}
596 }
597 
draw_titel(PARMBLK * pb)598 static int draw_titel(PARMBLK *pb){
599 	static int pla[8];
600 	GRECT work=*(GRECT *) &pb->pb_x;
601 
602 	if(rc_intersect((GRECT *)&pb->pb_xc,&work)){
603 		pla[0]=pla[1]=0;
604 		pla[2]=pb->pb_w-1;
605 		pla[3]=pb->pb_h-1;
606 		pla[6]=pla[4]=pb->pb_x;	/* x_wert to */
607 		pla[7]=pla[5]=pb->pb_y;	/* y_wert to */
608 		pla[6]+=pb->pb_w-1;
609 		pla[7]+=pb->pb_h-1;
610 
611 		vro_cpyfm(x_handle, S_ONLY, pla, &Titel_bild, screen);
612 	}
613 
614 	return(0);
615 }
616 
draw_lines(PARMBLK * pb)617 static int draw_lines(PARMBLK *pb){
618 	GRECT area=*(GRECT *) &pb->pb_x;
619 
620 	if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
621 		char **ptr;
622 		int x=pb->pb_x,y=pb->pb_y,start_line=(area.g_y-y);
623 
624 		v_set_mode((text_font.cw&7)==0 && text_font.prop==0 ? MD_REPLACE : MD_TRANS);
625 
626 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4])	*/
627 		v_set_text(text_font.id,text_font.size,BLACK,0,0,NULL);
628 		start_line /= text_font.ch;
629 		y+=start_line*text_font.ch;
630 		x-=(int)scroll_menu.px_hpos;
631 		ptr=&text_lines[start_line+=scroll_menu.vpos];
632 		start_line = min((area.g_y-y+area.g_h+text_font.ch-1)/text_font.ch,Anz_text_lines-start_line);
633 		area.g_h=text_font.ch;
634 		Vsync();
635 /*		x=(x+7) & ~7;*/
636 		for(;--start_line>=0;y+=text_font.ch){
637 			area.g_y=y;
638 			my_clear_area(&area);
639 			if(**ptr-1){
640 				v_set_text(FAIL,0,BLUE,0x01,0,NULL);
641 				(*v_mtext)(x_handle,x,y,(*ptr++)+1);
642 				v_set_text(FAIL,0,BLACK,0x00,0,NULL);
643 			}else
644 				(*v_mtext)(x_handle,x,y,(*ptr++)+1);
645 		}
646 	}
647 	return(0);
648 }
649 
draw_rip(PARMBLK * pb)650 static int draw_rip(PARMBLK *pb){
651 	GRECT area=*(GRECT *) &pb->pb_x;
652 	if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
653 		char **ptr;
654 		int x=pb->pb_x,y=pb->pb_y,start_line=(area.g_y-y), chardim[4], pla[8],i;
655 		v_set_mode(MD_REPLACE);
656 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4])	*/
657 		v_set_text(text_font.id,text_font.size,BLACK,0,0,chardim);
658 		start_line /= text_font.ch;
659 		y+=start_line*text_font.ch;
660 		x-=scroll_menu.px_hpos;
661 		ptr=&text_lines[start_line+=scroll_menu.vpos];
662 		start_line = min((area.g_y-y+area.g_h+text_font.ch-1)/text_font.ch,Anz_text_lines-start_line);
663 		area.g_h=text_font.ch;
664 		Vsync();
665 		x=(x+7) & ~7;
666 		for(;--start_line>=0;y+=text_font.ch){
667 			area.g_y=y;
668 			my_clear_area(&area);
669 			if(**ptr-1){
670 				v_set_text(FAIL,0,BLUE,0x01,0,NULL);
671 				(*v_mtext)(x_handle,x,y,(*ptr++)+1);
672 				v_set_text(FAIL,0,BLACK,0x00,0,NULL);
673 			}else
674 				(*v_mtext)(x_handle,x,y,(*ptr++)+1);
675 		}
676 		pla[0]=pla[1]=0;
677 		pla[2]=min(pb->pb_w-1,Rip_bild.fd_w-1);
678 		pla[3]=min(pb->pb_h-1,Rip_bild.fd_h-1);
679 		pla[6]=pla[4]=pb->pb_x+(pb->pb_w-Rip_bild.fd_w)/2;	/* x_wert to */
680 		pla[7]=pla[5]=pb->pb_y;	/* y_wert to */
681 		pla[6]+=pla[2];
682 		pla[7]+=pla[3];
683 		vro_cpyfm(x_handle, S_ONLY, pla, &Rip_bild, screen);
684 		v_set_mode(MD_TRANS);
685 		vst_alignment(x_handle,1,5,&i,&i);
686 		pla[5]+=64;
687 		for(i=0;i<7;i++,pla[5]+=chardim[3]){
688 			v_set_text(text_font.id,(i==0 || i==6) ? text_font.size : 12,WHITE,1,0,chardim);
689 			(*v_mtext)(x_handle,pla[4]+157,pla[5],rip_line[i]);
690 			v_set_text(text_font.id,(i==0 || i==6) ? text_font.size : 12,BLACK,0,0,chardim);
691 			(*v_mtext)(x_handle,pla[4]+157,pla[5],rip_line[i]);
692 		}
693 		vst_alignment(x_handle,0,5,&i,&i);
694 	}
695 	return(0);
696 }
697 
draw_msgline(PARMBLK * pb)698 static int draw_msgline(PARMBLK *pb){
699 	GRECT area=*(GRECT *) &pb->pb_x;
700 
701 	if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
702 		int x=pb->pb_x, y=pb->pb_y+(msg_vis-1)*msg_font.ch, foo, i;
703 		char **ptr=&message_line[msg_pos], tmp;
704 		int startx, stopx, starty, stopy;
705 
706 		x=(x+7) & ~7;	/* Byte alignment speeds output up */
707 
708 		v_set_mode(MD_REPLACE);
709 
710 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4])	*/
711 		v_set_text(msg_font.id,msg_font.size,FAIL, FAIL,0,NULL);
712 		vst_alignment(x_handle,0,5,&foo,&foo);
713 		stopy=min(msg_pos,msg_vis);
714 /*		Vsync();*/
715 		startx=(area.g_x-x)/msg_font.cw-1;	/* MAR 06.02.2001 -- because italic covers the next char */
716 		Max(&startx,0);
717 		stopx=(area.g_x+area.g_w+msg_font.cw-x-1)/msg_font.cw;
718 		x+=startx*msg_font.cw;
719 		for(i=0;i<stopy;i++,y-=msg_font.ch,ptr--){
720 			if(message_age[msg_pos-i])
721 				v_set_text(FAIL,0,BLACK,0,0,NULL);
722 			else
723 				v_set_text(FAIL,0,LBLACK,4,0,NULL);
724 			tmp=(*ptr)[stopx];
725 			(*ptr)[stopx]=0;
726 			(*v_mtext)(x_handle,x,y,&(*ptr)[startx]);
727 			(*ptr)[stopx]=tmp;
728 		}
729 	}
730 	return(0);
731 }
732 
draw_status(PARMBLK * pb)733 static int draw_status(PARMBLK *pb){
734 	GRECT area=*(GRECT *) &pb->pb_x;
735 
736 	area.g_x+=2*status_font.cw-2;
737 	area.g_w-=2*status_font.cw-2;
738 	if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
739 		int x=pb->pb_x, y=pb->pb_y, startx, stopx, starty, stopy, i;
740 		char tmp;
741 
742 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4])	*/
743 		v_set_mode(MD_REPLACE);
744 		v_set_text(status_font.id,status_font.size,BLACK,0,0,NULL);
745 		x = (x+2*status_font.cw+6) & ~7;
746 
747 		startx=(area.g_x-x)/status_font.cw;
748 		starty=(area.g_y-y)/status_font.ch;
749 		stopx=(area.g_x+area.g_w+status_font.ch-1-x)/status_font.cw;
750 		stopy=(area.g_y+area.g_h+status_font.ch-1-y)/status_font.ch;
751 		Max(&startx,0);	/* MAR -- Hmm, area.g_x could end up 1 below x */
752 		Max(&stopx,0);
753 		x+=startx*status_font.cw;
754 		y+=starty*status_font.ch;
755 /*		Vsync();*/
756 		area.g_h=status_font.ch;
757 		for(i=starty;i<min(2,stopy);i++,area.g_y+=status_font.ch,y+=status_font.ch){
758 		my_clear_area(&area);
759 			tmp=status_line[i][stopx];
760 			status_line[i][stopx]=0;
761 			(*v_mtext)(x_handle,x,y,&status_line[i][startx]);
762 			status_line[i][stopx]=tmp;
763 		}
764 	}
765 	return(0);
766 }
767 
draw_inventory(PARMBLK * pb)768 static int draw_inventory(PARMBLK *pb){
769 	GRECT area=*(GRECT *) &pb->pb_x;
770 
771 	if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
772 		int gl, i, x=pb->pb_x, y=pb->pb_y,start_line=area.g_y-y;
773 		Gem_menu_item *it;
774 
775 		v_set_mode(MD_REPLACE);
776 		v_set_text(menu_font.id,menu_font.size,BLACK,0,0,NULL);
777 
778 		start_line /= menu_font.ch;
779 		y+=start_line*menu_font.ch;
780 		x-=scroll_menu.px_hpos;
781 		start_line+=scroll_menu.vpos;
782 
783 		for(it=invent_list,i=start_line; --i>=0 && it; it=it->Gmi_next);
784 
785 		i = min((area.g_y-y+area.g_h+menu_font.ch-1)/menu_font.ch,Anz_inv_lines-start_line);
786 
787 		Vsync();
788 		area.g_h=menu_font.ch;
789 
790 		for(;(--i>=0) && it;it=it->Gmi_next,y+=menu_font.ch){
791 			if(it->Gmi_attr)
792 				v_set_text(FAIL,FALSE,BLUE,1,FAIL,NULL);	/* Bold */
793 			else
794 				v_set_text(FAIL,FALSE,BLACK,0,FAIL,NULL);
795 
796 			area.g_y=y;
797 			my_clear_area(&area);
798 			if((gl=it->Gmi_glyph) != no_glyph){
799 				int pla[8], h=min(menu_font.ch,Tile_heigth)-1;
800 
801 				pla[0]=pla[2]=(gl%Tiles_per_line)*Tile_width;	/* x_wert from */
802 				pla[1]=pla[3]=(gl/Tiles_per_line)*Tile_heigth;	/* y_wert from */
803 				pla[4]=pla[6]=x;				/* x_wert to */
804 				pla[5]=pla[7]=y;				/* y_wert to */
805 				pla[2]+=Tile_width-1;
806 				pla[3]+=h;
807 				pla[6]+=Tile_heigth-1;
808 				pla[7]+=h;
809 
810 				vro_cpyfm(x_handle,S_ONLY,pla,&Tile_bilder,screen);
811 			}
812 			if(it->Gmi_identifier)
813 				it->Gmi_str[2]=it->Gmi_selected ? (it->Gmi_count == -1L ? '+' : '#') : '-';
814 			(*v_mtext)(x_handle,(x+23) & ~7,y,it->Gmi_str);
815 		}
816 	}
817 	return(0);
818 }
819 
draw_prompt(PARMBLK * pb)820 static int draw_prompt(PARMBLK *pb){
821 	GRECT area=*(GRECT *) &pb->pb_x;
822 
823 	if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
824 		char **ptr=(char **)pb->pb_parm;
825 		int x=pb->pb_x, y=pb->pb_y, chardim[4];
826 
827 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4])	*/
828 		v_set_mode(MD_TRANS);
829 		v_set_text(ibm_font_id,ibm_font,WHITE,0,0,chardim);
830 		Vsync();
831 		if(planes<4){
832 			int pxy[4];
833 			v_set_fill(BLACK,2,4,0);
834 			rc_grect_to_array(&area,pxy);
835 			v_bar(x_handle,pxy);
836 		}else
837 			my_color_area(&area,LWHITE);
838 		(*v_mtext)(x_handle,x,y,*(ptr++));
839 		if(*ptr)
840 			(*v_mtext)(x_handle,x,y+chardim[3],*ptr);
841 	}
842 	return(0);
843 }
844 
845 static USERBLK ub_lines={draw_lines, 0L}, ub_msg={draw_msgline, 0L},
846 					ub_inventory={draw_inventory, 0L}, ub_titel={draw_titel, 0L},
847 					ub_status={draw_status, 0L}, ub_prompt={draw_prompt, 0L};
848 
849 /**************************** rsc_funktionen *****************************/
850 
my_close_dialog(DIAINFO * dialog,boolean shrink_box)851 void my_close_dialog(DIAINFO *dialog,boolean shrink_box){
852 	close_dialog(dialog,shrink_box);
853 	Event_Timer(0,0,TRUE);
854 }
855 
856 void
mar_get_rsc_tree(obj_number,z_ob_obj)857 mar_get_rsc_tree(obj_number, z_ob_obj)
858 int obj_number;
859 OBJECT **z_ob_obj;
860 {
861    rsrc_gaddr( R_TREE, obj_number, z_ob_obj );
862 	fix_objects(*z_ob_obj,SCALING,0,0);
863 }
864 
865 void mar_clear_map(void);
866 
867 void
img_error(errnumber)868 img_error(errnumber)
869 int errnumber;
870 {
871 	char buf[BUFSZ];
872 
873 	switch(errnumber){
874 	case ERR_HEADER :
875 		sprintf(buf,"%s","[1][ Image Header | corrupt. ][ Oops ]");
876 		break;
877 	case ERR_ALLOC :
878 		sprintf(buf,"%s","[1][ Not enough | memory for | an image. ][ Oops ]");
879 		break;
880 	case ERR_FILE :
881 		sprintf(buf,"%s","[1][ The Image-file | is not available ][ Oops ]");
882 		break;
883 	case ERR_DEPACK :
884 		sprintf(buf,"%s","[1][ The Image-file | is corrupt ][ Oops ]");
885 		break;
886 	case ERR_COLOR :
887 		sprintf(buf,"%s","[1][ Number of colors | not supported ][ Oops ]");
888 		break;
889 	default:
890 		sprintf(buf,"[1][ img_error | strange error | number: %i ][ Hmm ]",errnumber);
891 		break;
892 	}
893 	form_alert(1,buf);
894 }
895 
mar_change_button_char(OBJECT * z_ob,int nr,char ch)896 void mar_change_button_char(OBJECT *z_ob, int nr, char ch){
897 	*ob_get_text(z_ob,nr,0)=ch;
898 	ob_set_hotkey(z_ob,nr,ch);
899 }
900 
901 void
mar_set_dir_keys()902 mar_set_dir_keys()
903 {
904 	static int mi_numpad=FAIL;
905 	char mcmd[]="bjnh.lyku", npcmd[]="123456789", *p_cmd;
906 
907 	if(mi_numpad!=mar_iflags_numpad()){
908 		OBJECT *z_ob=zz_oblist[DIRECTION];
909 		int i;
910 		mi_numpad=mar_iflags_numpad();
911 		ob_set_hotkey(z_ob,DIRDOWN,'>');
912 		ob_set_hotkey(z_ob,DIRUP,'<');
913 		p_cmd= mi_numpad ? npcmd : mcmd;
914 		for(i=0;i<9;i++)
915 			mar_change_button_char(z_ob,DIR1+2*i,p_cmd[i]);
916 	}
917 }
918 
919 extern int total_tiles_used;	/* tile.c */
920 
921 int
mar_gem_init()922 mar_gem_init()
923 {
924 	int i, bild_fehler=FALSE, fsize;
925 	char *fname;
926 	static MITEM wish_workaround= {FAIL,key(0,'J'),K_CTRL,W_CYCLE,FAIL};
927 	OBJECT *z_ob;
928 
929 	if((i=open_rsc("gem_rsc.rsc",NULL,md,md,md,0,0,0))<=0){
930 		graf_mouse(M_OFF,NULL);
931 		if(i<0)
932 			form_alert(1,"[3][| Fatal Error | File: GEM_RSC.RSC | not found. ][ grumble ]");
933 		else
934 			form_alert(1,"[3][| Fatal Error | GEM initialisation | failed. ][ a pity ]");
935 		return(0);
936 	}
937 	if(planes<1 || planes>8){
938 		form_alert(1,"[3][ Color-depth | not supported, | try 2-256 colors. ][ Ok ]");
939 		return(0);
940 	}
941 	MouseBee();
942 
943 	/* MAR -- 17.Mar 2002 NVDI 3.0 or better uses v_ftext */
944 	v_mtext= speedo==3 ? &v_ftext : &v_gtext;
945 	for(i=0;i<NHICON;i++)
946 		mar_get_rsc_tree(i, &zz_oblist[i]);
947 
948 	z_ob=zz_oblist[ABOUT];
949 	ob_hide(z_ob,OKABOUT,TRUE);
950 	ob_draw_dialog(z_ob,0,0,0,0);
951 
952 	mar_get_font(NHW_MESSAGE,&fname,&fsize);
953 	mar_set_font(NHW_MESSAGE,fname,fsize);
954 	mar_get_font(NHW_MAP,&fname,&fsize);
955 	mar_set_font(NHW_MAP,fname,fsize);
956 	mar_get_font(NHW_STATUS,&fname,&fsize);
957 	mar_set_font(NHW_STATUS,fname,fsize);
958 	mar_get_font(NHW_MENU,&fname,&fsize);
959 	mar_set_font(NHW_MENU,fname,fsize);
960 	mar_get_font(NHW_TEXT,&fname,&fsize);
961 	mar_set_font(NHW_TEXT,fname,fsize);
962 	msg_anz=mar_get_msg_history();
963 	mar_set_msg_visible(mar_get_msg_visible());
964 	msg_width=min(max_w/msg_font.cw-3,MSGLEN);
965 
966 	if(max_w/status_font.cw<COLNO-1)
967 		mar_set_fontbyid(NHW_STATUS,small_font_id,-small_font);
968 	status_w=min(max_w/status_font.cw-3,MSGLEN);
969 
970 	if(planes>0 && planes<9){
971 		normal_palette=(short *)m_alloc(3*colors*sizeof(short));
972 		get_colors(x_handle,normal_palette, colors);
973 	}
974 
975 loadimg:
976 	bild_fehler=depack_img(Tilefile?Tilefile:(planes>=4)?"NH16.IMG":"NH2.IMG",&tile_image);
977 	if(bild_fehler){
978 		z_ob=zz_oblist[ABOUT];
979 		ob_undraw_dialog(z_ob,0,0,0,0);
980 		ob_hide(z_ob,OKABOUT,FALSE);
981 		img_error(bild_fehler);
982 		return(0);
983 	}
984 	if(tile_image.img_w%Tile_width || tile_image.img_h%Tile_heigth){
985 		Tilefile=NULL;
986 		Tile_width=Tile_heigth=16;
987 		printf("size didn't match.\n");
988 		goto loadimg;
989 	}
990 	if((tile_image.img_w/Tile_width)*(tile_image.img_h/Tile_heigth)<total_tiles_used){
991 		Tilefile=NULL;
992 		Tile_width=Tile_heigth=16;
993 		printf("Too few Tiles in Image.\n");
994 		goto loadimg;
995 	}
996 	Tiles_per_line=tile_image.img_w/Tile_width;
997 
998 	if(planes>=4){
999 		if(tile_image.planes>1)
1000 			img_set_colors(x_handle, tile_image.palette, tile_image.planes);
1001 #if 0
1002 		else{
1003 			int mypalette[]={};
1004 			img_set_colors(x_handle, mypalette, 4);
1005 		}
1006 #endif
1007 	}
1008 
1009 	mfdb(&Tile_bilder, (int *)tile_image.addr, tile_image.img_w, tile_image.img_h, 1, tile_image.planes);
1010 	transform_img(&Tile_bilder);
1011 
1012 	mfdb(&Map_bild,NULL,(COLNO-1)*Tile_width, ROWNO*Tile_heigth, 0, planes);
1013 	mfdb(&FontCol_Bild,NULL,(COLNO-1)*map_font.cw, ROWNO*map_font.ch, 0, planes);
1014 	Map_bild.fd_addr=(int *)m_alloc(mfdb_size(&Map_bild)>mfdb_size(&FontCol_Bild)?mfdb_size(&Map_bild):mfdb_size(&FontCol_Bild));
1015 	FontCol_Bild.fd_addr=Map_bild.fd_addr;
1016 
1017 	mfdb(&Pet_Mark,pet_mark_data,8, 7, 1, 1);
1018 	vr_trnfm(x_handle,&Pet_Mark,&Pet_Mark);
1019 
1020 	mfdb(&Black_bild,NULL,16, 32, 1, 1);	/* MAR -- 17.Mar 2002 that should cover the biggest map-font */
1021 	Black_bild.fd_addr=(int *)m_alloc(mfdb_size(&Black_bild));
1022 	memset(Black_bild.fd_addr,255,mfdb_size(&Black_bild));
1023 	vr_trnfm(x_handle,&Black_bild,&Black_bild);
1024 
1025 	for(i=0;i<MAXWIN;i++){
1026 		Gem_nhwindow[i].gw_window=NULL;
1027 		Gem_nhwindow[i].gw_type=0;
1028 		Gem_nhwindow[i].gw_dirty=TRUE;
1029 	}
1030 
1031 	memset(&scroll_menu,0,sizeof(scroll_menu));
1032 	scroll_menu.scroll=AUTO_SCROLL;
1033 	scroll_menu.obj=LINESLIST;
1034 	scroll_menu.px_hline=menu_font.cw;
1035 	scroll_menu.px_vline=menu_font.ch;
1036 	scroll_menu.hscroll=
1037 	scroll_menu.vscroll=1;
1038 	scroll_menu.tbar_d=2*gr_ch-2;
1039 
1040 	mar_set_dir_keys();
1041 
1042 	memset(&scroll_map,0,sizeof(scroll_map));
1043 	scroll_map.scroll=AUTO_SCROLL;
1044 	scroll_map.obj=ROOT;
1045 	scroll_map.px_hline=mar_set_tile_mode(FAIL)?Tile_width:map_font.cw;
1046 	scroll_map.px_vline=mar_set_tile_mode(FAIL)?Tile_heigth:map_font.ch;
1047 	scroll_map.hsize=COLNO-1;
1048 	scroll_map.vsize=ROWNO;
1049 	scroll_map.hpage=8;
1050 	scroll_map.vpage=8;
1051 	scroll_map.hscroll=1;
1052 	scroll_map.vscroll=1;
1053 
1054 	/* dial_options( round, niceline, standard, return_default, background, nonselectable,
1055 		always_keys, toMouse, clipboard, hz);	*/
1056 	dial_options(TRUE,TRUE,FALSE,RETURN_DEFAULT,AES_BACK,TRUE,KEY_ALWAYS,FALSE,TRUE,3);
1057 	/*	dial_colors( dial_pattern, dial_color, dial_frame, hotkey, alert, cycle_button,
1058 		check_box, radio_button, arrow, cycle_backgrnd, check_backgrnd, radio_backgrnd,
1059 		arrow_backgrnd, edit_3d, draw_3d)	*/
1060 	if(planes<4)
1061 		dial_colors(4,BLACK,WHITE,RED,RED,WHITE,BLACK,BLACK,BLACK,FAIL,FAIL,FAIL,FAIL,TRUE,TRUE);
1062 	else
1063 		dial_colors(7,LWHITE,BLACK,RED,RED,BLACK,BLACK,BLACK,BLACK,WHITE,WHITE,WHITE,WHITE,TRUE,TRUE);
1064 
1065 	/* void MenuItems(MITEM *close,MITEM *closeall,MITEM *cycle,MITEM *invcycle,
1066 		MITEM *globcycle,MITEM *full,MITEM *bottom,MITEM *iconify,MITEM *iconify_all,
1067 		MITEM *menu,int menu_cnt) */
1068 	/* Ctrl-W ist normaly bound to cycle */
1069 	MenuItems(NULL,NULL,&wish_workaround,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);
1070 
1071 	menu_install(zz_oblist[MENU],TRUE);
1072 
1073 	z_ob=zz_oblist[ABOUT];
1074 	ob_undraw_dialog(z_ob,0,0,0,0);
1075 	ob_hide(z_ob,OKABOUT,FALSE);
1076 
1077 	return(1);
1078 }
1079 
1080 /************************* mar_exit_nhwindows *******************************/
1081 
1082 void
mar_exit_nhwindows()1083 mar_exit_nhwindows()
1084 {
1085 	int i;
1086 
1087 	for(i=MAXWIN;--i>=0;)
1088 		if(Gem_nhwindow[i].gw_type)
1089 			mar_destroy_nhwindow(i);
1090 
1091 	if(normal_palette){
1092 		img_set_colors(x_handle,normal_palette,tile_image.planes);
1093 		null_free(normal_palette);
1094 	}
1095 	test_free(tile_image.palette);
1096 	test_free(tile_image.addr);
1097 	test_free(titel_image.palette);
1098 	test_free(titel_image.addr);
1099 }
1100 
1101 /************************* mar_curs *******************************/
1102 
1103 void
mar_curs(x,y)1104 mar_curs(x,y)
1105 int x, y;
1106 {
1107 	Min(&dirty_map_area.g_x,x);
1108 	Min(&dirty_map_area.g_y,y);
1109 	Max(&dirty_map_area.g_w,x);
1110 	Max(&dirty_map_area.g_h,y);
1111 	Min(&dirty_map_area.g_x,map_cursx);
1112 	Min(&dirty_map_area.g_y,map_cursy);
1113 	Max(&dirty_map_area.g_w,map_cursx);
1114 	Max(&dirty_map_area.g_h,map_cursy);
1115 
1116 	map_cursx=x;
1117 	map_cursy=y;
1118 
1119 	if(WIN_MAP!=WIN_ERR)
1120 		Gem_nhwindow[WIN_MAP].gw_dirty=TRUE;
1121 }
1122 
1123 void mar_cliparound(void);
mar_map_curs_weiter(void)1124 void mar_map_curs_weiter(void)
1125 {
1126 	static int once=TRUE;
1127 
1128 	if(once){
1129 		redraw_window(Gem_nhwindow[WIN_STATUS].gw_window,NULL);
1130 		redraw_window(Gem_nhwindow[WIN_MESSAGE].gw_window,NULL);
1131 		once=FALSE;
1132 	}
1133 	mar_curs(map_cursx+1,map_cursy);
1134 	mar_cliparound();
1135 }
1136 
1137 /************************* about *******************************/
1138 
1139 void
mar_about()1140 mar_about()
1141 {
1142 	xdialog(zz_oblist[ABOUT], md, NULL, NULL, DIA_CENTERED, FALSE, DIALOG_MODE);
1143 	Event_Timer(0,0,TRUE);
1144 }
1145 
1146 /************************* ask_name *******************************/
1147 
1148 char *
mar_ask_name()1149 mar_ask_name()
1150 {
1151 	OBJECT *z_ob=zz_oblist[NAMEGET];
1152 	int bild_fehler;
1153 	char who_are_you[] = "Who are you? ";
1154 
1155 	bild_fehler=depack_img(planes<4 ? "TITLE2.IMG" : "TITLE.IMG", &titel_image);
1156 	if(bild_fehler ){	/* MAR -- this isn't lethal */
1157 		ob_set_text(z_ob,NETHACKPICTURE,"missing title.img.");
1158 	}else{
1159 		mfdb(&Titel_bild, (int *)titel_image.addr, titel_image.img_w, titel_image.img_h, 1, titel_image.planes);
1160 		transform_img(&Titel_bild);
1161 		z_ob[NETHACKPICTURE].ob_type=G_USERDEF;
1162 		z_ob[NETHACKPICTURE].ob_spec.userblk=&ub_titel;
1163 	}
1164 
1165 	ob_clear_edit(z_ob);
1166 	xdialog(z_ob,who_are_you, NULL, NULL, DIA_CENTERED, FALSE, DIALOG_MODE);
1167 	Event_Timer(0,0,TRUE);
1168 
1169 	test_free(titel_image.palette);
1170 	test_free(titel_image.addr);
1171 	test_free(Titel_bild.fd_addr);
1172 	return(ob_get_text(z_ob,PLNAME,0));
1173 }
1174 
1175 /************************* more *******************************/
1176 
1177 void
send_key(int key)1178 send_key(int key)
1179 {
1180 	int buf[8];
1181 
1182 	buf[3]=0;	/* No Shift/Ctrl/Alt */
1183 	buf[4]=key;
1184 	AvSendMsg(ap_id,AV_SENDKEY,buf);
1185 }
1186 
1187 void
send_return()1188 send_return()
1189 {
1190 	send_key(key(SCANRET,0));
1191 }
1192 
1193 int
K_Init(xev,availiable)1194 K_Init(xev,availiable)
1195 XEVENT *xev;
1196 int availiable;
1197 {
1198 	xev=xev;
1199 	return(MU_KEYBD&availiable);
1200 }
1201 
1202 int
KM_Init(xev,availiable)1203 KM_Init(xev,availiable)
1204 XEVENT *xev;
1205 int availiable;
1206 {
1207 	xev=xev;
1208 	return((MU_KEYBD|MU_MESAG)&availiable);
1209 }
1210 
1211 int
M_Init(xev,availiable)1212 M_Init(xev,availiable)
1213 XEVENT *xev;
1214 int availiable;
1215 {
1216 	xev=xev;
1217 	return(MU_MESAG&availiable);
1218 }
1219 
1220 #define More_Init K_Init
1221 
1222 int
More_Handler(xev)1223 More_Handler(xev)
1224 XEVENT *xev;
1225 {
1226 	int ev=xev->ev_mwich;
1227 
1228 	if(ev&MU_KEYBD){
1229 		char ch=(char)(xev->ev_mkreturn&0x00FF);
1230 		DIAINFO *dinf;
1231 		WIN *w;
1232 
1233 		switch(ch){
1234 		case '\033':	/* no more more more */
1235 		case ' ':
1236 			if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[PAGER]){
1237 				if(ch=='\033')
1238 					mar_esc_pressed=TRUE;
1239 				send_return();
1240 			break;
1241 			}
1242 			/* Fall thru */
1243 		default:
1244 			ev &= ~MU_KEYBD;	/* unknown key */
1245 			break;
1246 		}
1247 	}
1248 	return(ev);
1249 }
1250 
1251 void
mar_more()1252 mar_more()
1253 {
1254 	if(!mar_esc_pressed){
1255 		OBJECT *z_ob=zz_oblist[PAGER];
1256 		WIN *p_w;
1257 
1258 		Event_Handler(More_Init,More_Handler);
1259 		dial_colors(7,RED,BLACK,RED,RED,BLACK,BLACK,BLACK,BLACK,WHITE,WHITE,WHITE,WHITE,TRUE,TRUE);
1260 		if(WIN_MESSAGE!=WIN_ERR && (p_w=Gem_nhwindow[WIN_MESSAGE].gw_window)){
1261 			z_ob->ob_x=p_w->work.g_x;
1262 			z_ob->ob_y=p_w->curr.g_y+p_w->curr.g_h+gr_ch;
1263 		}
1264 		xdialog(z_ob,NULL, NULL, NULL, DIA_LASTPOS, FALSE, DIALOG_MODE);
1265 		Event_Timer(0,0,TRUE);
1266 		Event_Handler(NULL,NULL);
1267 
1268 		if(planes<4)
1269 			dial_colors(4,BLACK,WHITE,RED,RED,WHITE,BLACK,BLACK,BLACK,FAIL,FAIL,FAIL,FAIL,TRUE,TRUE);
1270 		else
1271 			dial_colors(7,LWHITE,BLACK,RED,RED,BLACK,BLACK,BLACK,BLACK,WHITE,WHITE,WHITE,WHITE,TRUE,TRUE);
1272 	}
1273 }
1274 
1275 /************************* Gem_start_menu *******************************/
1276 void
Gem_start_menu(win)1277 Gem_start_menu(win)
1278 winid win;
1279 {
1280 	win=win;
1281 	if(invent_list){
1282 		Gem_menu_item *curr, *next;
1283 
1284 		for(curr=invent_list;curr;curr=next){
1285 			next=curr->Gmi_next;
1286 			free(curr->Gmi_str);
1287 			free(curr);
1288 		}
1289 	}
1290 	invent_list=NULL;
1291 	Anz_inv_lines=0;
1292 	Inv_breite=16;
1293 }
1294 
1295 /************************* mar_add_menu *******************************/
1296 
1297 void
mar_add_menu(win,item)1298 mar_add_menu(win, item)
1299 winid win;
1300 Gem_menu_item *item;
1301 {
1302 	win=win;
1303 	item->Gmi_next = invent_list;
1304 	invent_list = item;
1305 	Anz_inv_lines++;
1306 }
1307 
1308 void
mar_reverse_menu()1309 mar_reverse_menu()
1310 {
1311 	Gem_menu_item *next, *head = 0, *curr=invent_list;
1312 
1313 	while (curr) {
1314 		next = curr->Gmi_next;
1315 		curr->Gmi_next = head;
1316 		head = curr;
1317 		curr = next;
1318 	}
1319 	invent_list=head;
1320 }
1321 
1322 void
mar_set_accelerators()1323 mar_set_accelerators()
1324 {
1325 	char ch='a';
1326 	Gem_menu_item *curr;
1327 
1328 	for(curr=invent_list;curr;curr=curr->Gmi_next){
1329 		int extent[8];
1330 		v_set_text(menu_font.id,menu_font.size,BLACK,0,0,NULL);
1331 		vqt_extent(x_handle,curr->Gmi_str,extent);
1332 		Max(&Inv_breite,extent[4]+Tile_width+menu_font.cw);
1333 		if(ch && curr->Gmi_accelerator==0 && curr->Gmi_identifier){
1334 			curr->Gmi_accelerator=ch;
1335 			curr->Gmi_str[0]=ch;
1336 			if(ch=='z') ch='A';
1337 			else if(ch=='Z') ch=0;
1338 			else ch++;
1339 		}
1340 	}
1341 }
1342 
1343 Gem_menu_item *
mar_hol_inv()1344 mar_hol_inv()
1345 {
1346 	return(invent_list);
1347 }
1348 
1349 /************************* mar_putstr_text *********************/
1350 
1351 void mar_raw_print(const char *);
1352 
mar_set_text_to_rip(winid w)1353 void mar_set_text_to_rip(winid w){
1354 	use_rip=TRUE;
1355 }
1356 void
mar_putstr_text(winid window,int attr,const char * str)1357 mar_putstr_text(winid window, int attr, const char *str)
1358 {
1359 	static int zeilen_frei=0;
1360 	int breite;
1361 	char *ptr;
1362 
1363 	window=window;
1364 	if(!text_lines){
1365 		text_lines=(char **)m_alloc(12*sizeof(char *));
1366 		zeilen_frei=12;
1367 	}
1368 	if(!zeilen_frei){
1369 		text_lines=(char **)realloc(text_lines,(Anz_text_lines+12)*sizeof(char *));
1370 		zeilen_frei=12;
1371 	}
1372 	if(!text_lines){
1373 		mar_raw_print("No room for Text");
1374 		return;
1375 	}
1376 
1377 	if(str)
1378 		breite=strlen(str);
1379 	Min(&breite,80);
1380 	ptr=text_lines[Anz_text_lines]=(char *)m_alloc(breite*sizeof(char)+2);
1381 	*ptr=(char)(attr+1);	/* avoid 0 */
1382 	strncpy(ptr+1,str,breite);
1383 	ptr[breite+1]=0;
1384 	Anz_text_lines++;
1385 	zeilen_frei--;
1386 }
1387 
1388 int
mar_set_inv_win(Anzahl,Breite)1389 mar_set_inv_win(Anzahl, Breite)
1390 int Anzahl, Breite;
1391 {
1392 	OBJECT *z_ob=zz_oblist[LINES];
1393 	int retval=WIN_DIAL|MODAL|NO_ICONIFY;
1394 
1395 	scroll_menu.hsize=0;
1396 	scroll_menu.vpage= (desk.g_h-3*gr_ch)/scroll_menu.px_vline;
1397 	if(Anzahl>scroll_menu.vpage){
1398 		retval |= WD_VSLIDER;
1399 		if(Breite>max_w-3*scroll_menu.px_hline){
1400 			retval|=WD_HSLIDER;
1401 			scroll_menu.hpage=(max_w-3*scroll_menu.px_hline)/scroll_menu.px_hline;
1402 			scroll_menu.hpos=0;
1403 			scroll_menu.hsize=Breite/scroll_menu.px_hline;
1404 			scroll_menu.vpage=(desk.g_h-4*gr_ch-1)/scroll_menu.px_vline;
1405 		}
1406 		Anzahl=scroll_menu.vpage;
1407 	}else{
1408 		if(Breite>max_w-scroll_menu.px_hline){
1409 			retval|=WD_HSLIDER;
1410 			scroll_menu.hpage=(max_w-scroll_menu.px_hline)/scroll_menu.px_hline;
1411 			scroll_menu.hpos=0;
1412 			scroll_menu.hsize=Breite/scroll_menu.px_hline;
1413 			scroll_menu.vpage= (desk.g_h-4*gr_ch-1)/scroll_menu.px_vline;
1414 			if(Anzahl>scroll_menu.vpage){
1415 				retval |= WD_VSLIDER;
1416 				Anzahl=scroll_menu.vpage;
1417 			}
1418 		}
1419 		scroll_menu.vpage=Anzahl;
1420 	}
1421 	if((scroll_menu.hmax=scroll_menu.hsize-scroll_menu.hpage)<0)
1422 		scroll_menu.hmax=0;
1423 	if((scroll_menu.vmax=scroll_menu.vsize-scroll_menu.vpage)<0)
1424 		scroll_menu.vmax=0;
1425 
1426 	/* left/right/up 2 pixel border down 2gr_ch toolbar */
1427 	z_ob[ROOT].ob_width=z_ob[LINESLIST].ob_width=Breite;
1428 	z_ob[ROOT].ob_height=
1429 	z_ob[QLINE].ob_y=
1430 	z_ob[LINESLIST].ob_height=scroll_menu.px_vline*Anzahl;
1431 	z_ob[QLINE].ob_y+=gr_ch/2;
1432 	z_ob[ROOT].ob_width+=4;
1433 	z_ob[ROOT].ob_height+=2*gr_ch+2;
1434 
1435 	return(retval);
1436 }
1437 
1438 /************************* mar_status_dirty *******************************/
1439 
1440 void
mar_status_dirty()1441 mar_status_dirty()
1442 {
1443 	int ccol;
1444 
1445 	ccol=mar_hp_query();
1446 
1447 	if(ccol<2)	curs_col=WHITE;		/* 50-100% : 0 */
1448 	else if(ccol<3)	curs_col=YELLOW;		/* 33-50% : 6 */
1449 	else if(ccol<5)	curs_col=LYELLOW;		/* 20-33% : 14*/
1450 	else if(ccol<10)	curs_col=RED;		/* 10-20% : 2 */
1451 	else	curs_col=MAGENTA;		/* <10% : 7*/
1452 }
1453 
1454 /************************* mar_add_message *******************************/
1455 
1456 void
mar_add_message(str)1457 mar_add_message(str)
1458 const char *str;
1459 {
1460 	int i, mesg_hist=mar_get_msg_history();
1461 	char *tmp, *rest, buf[TBUFSZ];
1462 
1463 	if(WIN_MESSAGE == WIN_ERR)
1464 		return;
1465 
1466 	if(!mar_message_pause){
1467 		mar_message_pause=TRUE;
1468 		messages_pro_zug=0;
1469 		msg_pos=msg_max;
1470 	}
1471 
1472 	if(msg_max>mesg_hist-2){
1473 		msg_max=mesg_hist-2;
1474 		msg_pos--;
1475 		if(msg_pos<0) msg_pos=0;
1476 		tmp=message_line[0];
1477 		for(i=0;i<mesg_hist-1;i++){
1478 			message_line[i]=message_line[i+1];
1479 			message_age[i]=message_age[i+1];
1480 		}
1481 		message_line[mesg_hist-1]=tmp;
1482 	}
1483 	strcpy(toplines,str);
1484 	messages_pro_zug++;
1485 	msg_max++;
1486 
1487 	if((int)strlen(toplines)>=msg_width){
1488 		int pos=msg_width;
1489 		tmp=toplines+msg_width;
1490 		while(*tmp!=' ' && pos>=0){
1491 			tmp--;
1492 			pos--;
1493 		}
1494 		if(pos<=0) pos=msg_width;	/* Mar -- Oops, what a word :-) */
1495 		message_age[msg_max]=TRUE;
1496 		strncpy(message_line[msg_max],toplines,pos);
1497 		message_line[msg_max][pos]=0;
1498 		rest=strcpy(buf,toplines+pos);
1499 	}else{
1500 		message_age[msg_max]=TRUE;
1501 		strncpy(message_line[msg_max],toplines,msg_width);
1502 		rest=0;
1503 	}
1504 
1505 	Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
1506 	if(messages_pro_zug>=mesg_hist){ /* MAR -- Greater then should never happen */
1507 		messages_pro_zug=mesg_hist;
1508 		mar_display_nhwindow(WIN_MESSAGE);
1509 	}
1510 
1511 	if(rest)
1512 		mar_add_message(rest);
1513 }
1514 
1515 /************************* mar_add_status_str *******************************/
1516 
1517 void
mar_add_status_str(str,line)1518 mar_add_status_str(str,line)
1519 const char *str;
1520 int line;
1521 {
1522 	int i,last_diff=-1;
1523 	GRECT area={0,line*status_font.ch,status_font.cw,status_font.ch};
1524 	for(i=0;(i<status_w-2) && str[i];i++)
1525 		if(str[i]!=status_line[line][i]){
1526 			if(last_diff==-1) area.g_x=i*status_font.cw;
1527 			else area.g_w+=status_font.cw;
1528 			last_diff=i;
1529 			status_line[line][i]=str[i];
1530 		}else if(last_diff>=0){
1531 			add_dirty_rect(dr_stat,&area);
1532 			last_diff=-1;
1533 			area.g_w=status_font.cw;
1534 		}
1535 		for(;i<status_w-1;i++){
1536 			if(status_line[line][i]){
1537 				if(last_diff==-1) area.g_x=i*status_font.cw;
1538 				else area.g_w+=status_font.cw;
1539 				last_diff=i;
1540 			}
1541 			status_line[line][i]=0;
1542 		}
1543 	if(last_diff>=0)
1544 		add_dirty_rect(dr_stat,&area);
1545 }
1546 
1547 /************************* mar_set_menu_title *******************************/
1548 
1549 void
mar_set_menu_title(str)1550 mar_set_menu_title(str)
1551 const char *str;
1552 {
1553 	test_free(Menu_title);	/* just in case */
1554 	Menu_title=mar_copy_of(str ? str : nullstr);
1555 }
1556 
1557 /************************* mar_set_menu_type *******************************/
1558 
1559 void
mar_set_menu_type(how)1560 mar_set_menu_type(how)
1561 int how;
1562 {
1563 	Inv_how=how;
1564 }
1565 
1566 /************************* Inventory Utils *******************************/
1567 
1568 void
set_all_on_page(start,page)1569 set_all_on_page(start, page)
1570 int start, page;
1571 {
1572 	Gem_menu_item *curr;
1573 
1574 	if(start<0 || page<0)
1575 		return;
1576 
1577 	for(curr=invent_list; start--&&curr; curr=curr->Gmi_next);
1578 	for(; page--&&curr; curr=curr->Gmi_next)
1579 		if (curr->Gmi_identifier && !curr->Gmi_selected)
1580 			curr->Gmi_selected = TRUE;
1581 }
1582 
1583 void
unset_all_on_page(start,page)1584 unset_all_on_page(start, page)
1585 int start, page;
1586 {
1587 	Gem_menu_item *curr;
1588 
1589 	if(start<0 || page<0)
1590 		return;
1591 
1592 	for(curr=invent_list; start--&&curr; curr=curr->Gmi_next);
1593 	for(; page--&&curr; curr=curr->Gmi_next)
1594 		if (curr->Gmi_identifier && curr->Gmi_selected) {
1595 			curr->Gmi_selected = FALSE;
1596 			curr->Gmi_count = -1L;
1597 		}
1598 }
1599 
1600 void
invert_all_on_page(start,page,acc)1601 invert_all_on_page(start, page, acc)
1602 int start, page;
1603 char acc;
1604 {
1605 	Gem_menu_item *curr;
1606 
1607 	if(start<0 || page<0)
1608 		return;
1609 
1610 	for(curr=invent_list; start--&&curr; curr=curr->Gmi_next);
1611 	for(; page--&&curr; curr=curr->Gmi_next)
1612 		if (curr->Gmi_identifier && (acc == 0 || curr->Gmi_groupacc == acc)) {
1613 			if (curr->Gmi_selected) {
1614 				curr->Gmi_selected = FALSE;
1615 				curr->Gmi_count = -1L;
1616 			} else
1617 				curr->Gmi_selected = TRUE;
1618 		}
1619 }
1620 
1621 /************************* Inv_Handler and Inv_Init *******************************/
1622 
scroll_top_dialog(char ch)1623 int scroll_top_dialog(char ch){
1624 	WIN *w;
1625 	DIAINFO *dinf;
1626 
1627 	if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[LINES]){
1628 		switch(ch){
1629 		case ' ':
1630 			if(scroll_menu.vpos==scroll_menu.vmax){
1631 				send_return();
1632 				break;
1633 			}
1634 			/* Fall thru */
1635 		case MENU_NEXT_PAGE:
1636 			scroll_window(w,PAGE_DOWN,NULL);
1637 			break;
1638 		case MENU_PREVIOUS_PAGE:
1639 			scroll_window(w,PAGE_UP,NULL);
1640 			break;
1641 		case MENU_FIRST_PAGE:
1642 			scroll_window(w,WIN_START,NULL);
1643 			break;
1644 		case MENU_LAST_PAGE:
1645 			scroll_window(w,WIN_END,NULL);
1646 			break;
1647 		default:
1648 			return(FALSE);
1649 		}
1650 		return(TRUE);
1651 	}
1652 	return(FALSE);
1653 }
1654 
1655 #define Text_Init KM_Init
1656 
1657 int
Text_Handler(xev)1658 Text_Handler(xev)
1659 XEVENT *xev;
1660 {
1661 	int ev=xev->ev_mwich;
1662 
1663 	if(ev&MU_MESAG){
1664 		int *buf=xev->ev_mmgpbuf, y_wo, i;
1665 		if(*buf==FONT_CHANGED){
1666 			if(buf[3]>=0){
1667 				mar_set_fontbyid(NHW_TEXT,buf[4],buf[5]);
1668 				FontAck(buf[1],1);
1669 			}
1670 		}
1671 	}
1672 	if(ev&MU_KEYBD){
1673 		char ch=(char)(xev->ev_mkreturn&0x00FF);
1674 
1675 		if(!scroll_top_dialog(ch))
1676 			switch(ch){
1677 			case '\033':
1678 				send_return();	/* just closes the textwin */
1679 				break;
1680 			case C('c'):
1681 				clipbrd_save(text_lines,Anz_text_lines,xev->ev_mmokstate&K_SHIFT,FALSE);
1682 				break;
1683 			default:
1684 				ev &= ~MU_KEYBD;	/* unknown key */
1685 				break;
1686 			}
1687 	}
1688 	return(ev);
1689 }
1690 
1691 #define Inv_Init KM_Init
1692 
1693 static long count=0;
1694 int
Inv_Handler(xev)1695 Inv_Handler(xev)
1696 XEVENT *xev;
1697 {
1698 	int ev=xev->ev_mwich;
1699 	Gem_menu_item *it;
1700 	GRECT area;
1701 	OBJECT *z_ob=zz_oblist[LINES];
1702 
1703 	ob_pos(z_ob,LINESLIST,&area);
1704 	if(ev&MU_MESAG){
1705 		int *buf=xev->ev_mmgpbuf, y_wo, i;
1706 
1707 		if(*buf==FONT_CHANGED){
1708 			if(buf[3]>=0){
1709 				mar_set_fontbyid(NHW_MENU,buf[4],buf[5]);
1710 				FontAck(buf[1],1);
1711 			}
1712 		}else
1713 		if(*buf==OBJC_CHANGED && buf[3]==LINESLIST){
1714 			ob_undostate(z_ob,LINESLIST,SELECTED);
1715 			mouse(NULL,&y_wo);
1716 			y_wo=(y_wo-area.g_y)/menu_font.ch+scroll_menu.vpos;
1717 			for(it=invent_list,i=0;i<y_wo && it;it=it->Gmi_next,i++);
1718 			if(it->Gmi_identifier){
1719 				it->Gmi_selected=!it->Gmi_selected;
1720 				it->Gmi_count= count==0L ? -1L : count;
1721 				count = 0L;
1722 				if(Inv_how!=PICK_ANY){
1723 					/*my_close_dialog(Inv_dialog,TRUE);*/
1724 					send_return();
1725 				}else{
1726 					area.g_x=(area.g_x+23+2*menu_font.cw) & ~7;
1727 					area.g_w=menu_font.cw;
1728 					area.g_h=menu_font.ch;
1729 					area.g_y+=(y_wo-scroll_menu.vpos)*menu_font.ch;
1730 					ob_draw_chg(Inv_dialog,LINESLIST,&area,FAIL);
1731 				}	/* how != PICK_ANY */
1732 			}	/* identifier */
1733 		}else	/* LINESLIST changed */
1734 			ev &= ~MU_MESAG;	/* unknown message not used */
1735 	}	/* MU_MESAG */
1736 
1737 	if(ev&MU_KEYBD){
1738 		char ch=(char)(xev->ev_mkreturn&0x00FF);
1739 
1740 		if(!scroll_top_dialog(ch)){
1741 			switch(ch){
1742 			case '0':	/* special 0 is also groupaccelerator for balls */
1743 				if(count<=0)
1744 					goto find_acc;
1745 			case '1': case '2': case '3': case '4':
1746 			case '5': case '6': case '7': case '8': case '9':
1747 				if(Inv_how==PICK_NONE)
1748 					goto find_acc;
1749 				count = (count * 10L) + (long) (ch - '0');
1750 				break;
1751 			case '\033':	/* cancel - from counting or loop */
1752 				if(count>0L)
1753 				count=0L;
1754 				else{
1755 					unset_all_on_page(0, (int)scroll_menu.vsize);
1756 					my_close_dialog(Inv_dialog,TRUE);
1757 					return(ev);
1758 				}
1759 				break;
1760 			case '\0':		/* finished (commit) */
1761 			case '\n':
1762 			case '\r':
1763 				break;
1764 			case MENU_SELECT_PAGE:
1765 				if(Inv_how==PICK_NONE)
1766 					goto find_acc;
1767 				if (Inv_how == PICK_ANY)
1768 					set_all_on_page((int)scroll_menu.vpos, scroll_menu.vpage);
1769 				break;
1770 			case MENU_SELECT_ALL:
1771 				if(Inv_how==PICK_NONE)
1772 					goto find_acc;
1773 				if (Inv_how == PICK_ANY)
1774 					set_all_on_page(0, (int)scroll_menu.vsize);
1775 				break;
1776 			case MENU_UNSELECT_PAGE:
1777 				unset_all_on_page((int)scroll_menu.vpos, scroll_menu.vpage);
1778 				break;
1779 			case MENU_UNSELECT_ALL:
1780 				unset_all_on_page(0, (int)scroll_menu.vsize);
1781 				break;
1782 			case MENU_INVERT_PAGE:
1783 				if(Inv_how==PICK_NONE)
1784 					goto find_acc;
1785 				if (Inv_how == PICK_ANY)
1786 					invert_all_on_page((int)scroll_menu.vpos, scroll_menu.vpage, 0);
1787 				break;
1788 			case MENU_INVERT_ALL:
1789 				if(Inv_how==PICK_NONE)
1790 					goto find_acc;
1791 				if (Inv_how == PICK_ANY)
1792 					invert_all_on_page(0, (int)scroll_menu.vsize, 0);
1793 				break;
1794 			case MENU_SEARCH:
1795 				if(Inv_how!=PICK_NONE){
1796 					char buf[BUFSZ];
1797 					Gem_getlin("Search for:",buf);
1798 					if(!*buf || buf[0]=='\033')
1799 						break;
1800 					for(it=invent_list;it;it=it->Gmi_next){
1801 						if(it->Gmi_identifier && strstr(it->Gmi_str,buf)){
1802 							it->Gmi_selected=TRUE;
1803 							if(Inv_how!=PICK_ANY){
1804 								my_close_dialog(Inv_dialog,FALSE);
1805 								break;
1806 							}
1807 						}
1808 					}
1809 				}
1810 				break;
1811 			case C('c'):
1812 				clipbrd_save(invent_list,Anz_inv_lines,xev->ev_mmokstate&K_SHIFT,TRUE);
1813 				break;
1814 			default:
1815 			find_acc:
1816 				if(Inv_how==PICK_NONE)
1817 					my_close_dialog(Inv_dialog,TRUE);
1818 				else
1819 					for(it=invent_list;it;it=it->Gmi_next){
1820 						if(it->Gmi_identifier && (it->Gmi_accelerator==ch || it->Gmi_groupacc==ch)){
1821 							it->Gmi_selected=!it->Gmi_selected;
1822 							it->Gmi_count= count==0L ? -1L : count;
1823 							count = 0L;
1824 							if(Inv_how!=PICK_ANY)
1825 								my_close_dialog(Inv_dialog,TRUE);
1826 						}
1827 					}
1828 				break;
1829 			}	/* end switch(ch) */
1830 			if(Inv_how==PICK_ANY){
1831 				area.g_x=(area.g_x+23+2*menu_font.cw) & ~7;
1832 				area.g_w=menu_font.cw;
1833 				ob_draw_chg(Inv_dialog,LINESLIST,&area,FAIL);
1834 			}
1835 		}	/* !scroll_Inv_dialog */
1836 	}	/* MU_KEYBD */
1837 
1838 	if(Inv_how==PICK_ANY){
1839 		ob_set_text(Inv_dialog->di_tree,QLINE,strCancel);
1840 		for(it=invent_list;it;it=it->Gmi_next)
1841 			if(it->Gmi_identifier && it->Gmi_selected){
1842 				ob_set_text(Inv_dialog->di_tree,QLINE,strOk);
1843 				break;
1844 			}
1845 		ob_draw_chg(Inv_dialog,QLINE,NULL,FAIL);
1846 	}
1847 	return(ev);
1848 }
1849 
1850 /************************* draw_window *******************************/
1851 
1852 static void
mar_draw_window(first,win,area)1853 mar_draw_window( first, win, area)
1854 int first;
1855 WIN *win;
1856 GRECT *area;
1857 {
1858 	OBJECT *obj=(OBJECT *)win->para;
1859 
1860 	if(obj){
1861 		if(first){
1862 		obj->ob_x=win->work.g_x;
1863 		obj->ob_y=win->work.g_y;
1864 		}
1865 		if(area==NULL)
1866 			area=&(win->work);
1867 		objc_draw(obj, ROOT, MAX_DEPTH, area->g_x, area->g_y, area->g_w, area->g_h);
1868 	}
1869 }
1870 
1871 /************************* mar_display_nhwindow *******************************/
1872 
redraw_winwork(WIN * w,GRECT * area)1873 void redraw_winwork(WIN *w,GRECT *area){
1874 	area->g_x+=w->work.g_x;
1875 	area->g_y+=w->work.g_y;
1876 	redraw_window(w,area);
1877 }
mar_menu_set_slider(WIN * p_win)1878 void mar_menu_set_slider(WIN *p_win){
1879 	if(p_win){
1880 		SCROLL *sc=p_win->scroll;
1881 
1882 		if(!sc)
1883 			return;
1884 
1885 		if(p_win->gadgets&HSLIDE){
1886 			long hsize=1000l;
1887 
1888 			if(sc->hsize>0 && sc->hpage>0){
1889 				hsize *= sc->hpage;
1890 				hsize /= sc->hsize;
1891 			}
1892 			window_slider(p_win,HOR_SLIDER,0,(int)hsize);
1893 		}
1894 		if(p_win->gadgets&VSLIDE){
1895 			long vsize=1000l;
1896 
1897 			if(sc->vsize>0 && sc->vpage>0){
1898 				vsize *= sc->vpage;
1899 				vsize /= sc->vsize;
1900 			}
1901 			window_slider(p_win,VERT_SLIDER,0,(int)vsize);
1902 		}
1903 	}
1904 }
1905 
recalc_msg_win(GRECT * area)1906 void recalc_msg_win(GRECT *area){
1907 	OBJECT *z_ob;
1908 	z_ob=zz_oblist[MSGWIN];
1909 	z_ob[MSGLINES].ob_spec.userblk=&ub_msg;
1910 	z_ob[MSGLINES].ob_width=
1911 	z_ob[ROOT].ob_width=		(msg_width+3)*msg_font.cw;
1912 	z_ob[MSGLINES].ob_width-=z_ob[UPMSG].ob_width;
1913 	z_ob[ROOT].ob_height=
1914 	z_ob[GRABMSGWIN].ob_height=
1915 	z_ob[MSGLINES].ob_height=msg_vis*msg_font.ch;
1916 	z_ob[DNMSG].ob_y=z_ob[GRABMSGWIN].ob_height-z_ob[DNMSG].ob_height;
1917 	window_border(0,0,0,z_ob->ob_width,z_ob->ob_height, area);
1918 }
recalc_status_win(GRECT * area)1919 void recalc_status_win(GRECT *area){
1920 	OBJECT *z_ob;
1921 	z_ob=zz_oblist[STATUSLINE];
1922 	z_ob[ROOT].ob_type=G_USERDEF;
1923 	z_ob[ROOT].ob_spec.userblk=&ub_status;
1924 	z_ob[ROOT].ob_width=(status_w+2)*status_font.cw;
1925 	z_ob[ROOT].ob_height=
1926 	z_ob[GRABSTATUS].ob_height=2*status_font.ch;
1927 	z_ob[GRABSTATUS].ob_width=2*status_font.cw-2;
1928 	window_border(0,0,0,z_ob->ob_width,z_ob->ob_height,area);
1929 }
calc_std_winplace(int which,GRECT * place)1930 void calc_std_winplace(int which, GRECT *place){
1931 	static int todo=TRUE;
1932 	static GRECT me, ma, st;
1933 
1934 	if(todo || which<0){
1935 		OBJECT *z_ob;
1936 		int map_h_off, foo;
1937 
1938 		/* First the messagewin */
1939 		recalc_msg_win(&me);
1940 
1941 		/* Now the map */
1942 		wind_calc(WC_BORDER,MAP_GADGETS,0,0,scroll_map.px_hline*(COLNO-1),scroll_map.px_vline*ROWNO,&foo,&foo,&foo,&map_h_off);
1943 		map_h_off-=scroll_map.px_vline*ROWNO;
1944 		window_border(MAP_GADGETS,0,0,scroll_map.px_hline*(COLNO-1),scroll_map.px_vline*ROWNO, &ma);
1945 
1946 		/* Next the statuswin */
1947 		recalc_status_win(&st);
1948 
1949 		/* And last but not least a final test */
1950 		ma.g_h=map_h_off+scroll_map.px_vline*ROWNO;
1951 		while(me.g_h+ma.g_h+st.g_h>=desk.g_h)
1952 			ma.g_h-=scroll_map.px_vline;
1953 		/* stack the windows */
1954 		ma.g_y=me.g_y=st.g_y=desk.g_y;
1955 		if(status_align){
1956 			ma.g_y+=st.g_h;
1957 			if(msg_align){
1958 				st.g_y+=me.g_h;
1959 				ma.g_y+=me.g_h;
1960 			}else{
1961 				me.g_y+=st.g_h+ma.g_h;
1962 			}
1963 		}else{
1964 			if(msg_align){
1965 				ma.g_y+=me.g_h;
1966 			}else{
1967 				me.g_y+=ma.g_h;
1968 			}
1969 			st.g_y+=me.g_h+ma.g_h;
1970 		}
1971 
1972 		if(which) todo=FALSE;
1973 	}
1974 	switch(which){
1975 	case NHW_MESSAGE:
1976 		*place=me;
1977 		break;
1978 	case NHW_MAP:
1979 		*place=ma;
1980 		break;
1981 	case NHW_STATUS:
1982 		*place=st;
1983 		break;
1984 	default:
1985 		break;
1986 	}
1987 }
1988 
1989 void
mar_display_nhwindow(wind)1990 mar_display_nhwindow(wind)
1991 winid wind;
1992 {
1993 	DIAINFO *dlg_info;
1994 	OBJECT *z_ob;
1995 	int d_exit=W_ABANDON, i, breite, mar_di_mode, tmp_magx=magx;
1996 	GRECT g_mapmax, area;
1997 	char *tmp_button;
1998 	struct gw *p_Gw;
1999 
2000 	if(wind == WIN_ERR)	return;
2001 
2002 	p_Gw=&Gem_nhwindow[wind];
2003 	switch(p_Gw->gw_type){
2004 	case NHW_TEXT:
2005 		if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2006 			mar_display_nhwindow(WIN_MESSAGE);
2007 		z_ob=zz_oblist[LINES];
2008 		scroll_menu.vsize=Anz_text_lines;
2009 		scroll_menu.vpos=0;
2010 		if(use_rip){
2011 			if(!depack_img(planes<4 ? "RIP2.IMG" : "RIP.IMG", &rip_image)){
2012 				mfdb(&Rip_bild, (int *)rip_image.addr, rip_image.img_w, rip_image.img_h, 1, rip_image.planes);
2013 				transform_img(&Rip_bild);
2014 			}
2015 			ub_lines.ub_code=draw_rip;
2016 		}else
2017 			ub_lines.ub_code=draw_lines;
2018 		z_ob[LINESLIST].ob_spec.userblk=&ub_lines;
2019 		breite=16;
2020 		v_set_text(text_font.id,text_font.size,BLACK,0,0,NULL);
2021 		for(i=0;i<Anz_text_lines;i++){
2022 			int eout[8];
2023 			vqt_extent(x_handle,text_lines[i],eout);
2024 			Max(&breite,eout[4]);
2025 		}
2026 		scroll_menu.px_vline=text_font.ch;
2027 		scroll_menu.px_hline=text_font.cw;
2028 		mar_di_mode=mar_set_inv_win(Anz_text_lines, breite);
2029 		tmp_button=ob_get_text(z_ob,QLINE,0);
2030 		ob_set_text(z_ob,QLINE,strOk);
2031 		ob_undoflag(z_ob,LINESLIST,TOUCHEXIT);
2032 		Event_Handler(Text_Init,Text_Handler);
2033 		if((dlg_info=open_dialog(z_ob,strText, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, mar_di_mode, FAIL, NULL, NULL))!=NULL){
2034 			WIN *ptr_win=dlg_info->di_win;
2035 
2036 			ptr_win->scroll=&scroll_menu;
2037 			mar_menu_set_slider(ptr_win);
2038 			WindowItems(ptr_win,SCROLL_KEYS,scroll_keys);
2039 			if((d_exit=X_Form_Do(NULL))!=W_ABANDON){
2040 				my_close_dialog(dlg_info,FALSE);
2041 				if(d_exit!=W_CLOSED)
2042 					ob_undostate(z_ob,d_exit&NO_CLICK,SELECTED);
2043 			}
2044 		}
2045 		Event_Handler(NULL,NULL);
2046 		ob_set_text(z_ob,QLINE,tmp_button);
2047 		break;
2048 	case NHW_MENU:
2049 		if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2050 			mar_display_nhwindow(WIN_MESSAGE);
2051 		z_ob=zz_oblist[LINES];
2052 		scroll_menu.vsize=Anz_inv_lines;
2053 		scroll_menu.vpos=0;
2054 		z_ob[LINESLIST].ob_spec.userblk=&ub_inventory;
2055 		if((Menu_title)&&(wind!=WIN_INVEN))	/* because I sets no Menu_title */
2056 			Max(&Inv_breite,gr_cw*strlen(Menu_title)+16);
2057 		scroll_menu.px_vline=menu_font.ch;
2058 		scroll_menu.px_hline=menu_font.cw;
2059 		mar_di_mode=mar_set_inv_win(Anz_inv_lines, Inv_breite, NHW_MENU);
2060 		tmp_button=ob_get_text(z_ob,QLINE,0);
2061 		ob_set_text(z_ob,QLINE,Inv_how!=PICK_NONE ? strCancel : strOk );
2062 		ob_doflag(z_ob,LINESLIST,TOUCHEXIT);
2063 		Event_Handler(Inv_Init, Inv_Handler);
2064 		if((Inv_dialog=open_dialog(z_ob,(wind==WIN_INVEN) ? "Inventory" : (Menu_title ? Menu_title : "Staun"), NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, mar_di_mode, FAIL, NULL, NULL))!=NULL){
2065 			WIN *ptr_win=Inv_dialog->di_win;
2066 
2067 			ptr_win->scroll=&scroll_menu;
2068 			mar_menu_set_slider(ptr_win);
2069 			WindowItems(ptr_win,SCROLL_KEYS,scroll_keys);
2070 			do{
2071 				int y_wo,x_wo,ru_w=1,ru_h=1;
2072 				GRECT oarea;
2073 				Gem_menu_item *it;
2074 				d_exit=X_Form_Do(NULL);
2075 				if((d_exit&NO_CLICK)==LINESLIST){
2076 					ob_pos(z_ob,LINESLIST,&oarea);
2077 					if(mouse(&x_wo,&y_wo) && Inv_how==PICK_ANY){
2078 						graf_rt_rubberbox(FALSE,x_wo,y_wo,FAIL,FAIL,&oarea,&ru_w,&ru_h,NULL);
2079 						invert_all_on_page((int)((y_wo-oarea.g_y)/menu_font.ch+scroll_menu.vpos),(ru_h+menu_font.ch-1)/menu_font.ch,0);
2080 					}else{
2081 						for(it=invent_list,i=0;i<((y_wo-oarea.g_y)/menu_font.ch+scroll_menu.vpos) && it;it=it->Gmi_next,i++);
2082 						if(it && it->Gmi_identifier){
2083 							it->Gmi_selected=!it->Gmi_selected;
2084 							it->Gmi_count= count==0L ? -1L : count;
2085 							count = 0L;
2086 							if(Inv_how!=PICK_ANY)
2087 								break;
2088 						}	/* identifier */
2089 					}
2090 					oarea.g_x=(oarea.g_x+23+2*menu_font.cw) & ~7;
2091 					oarea.g_y=y_wo-(y_wo-oarea.g_y)%menu_font.ch;
2092 					oarea.g_w=menu_font.cw;
2093 					oarea.g_h=((ru_h+menu_font.ch-1)/menu_font.ch)*menu_font.ch;
2094 					ob_draw_chg(Inv_dialog,LINESLIST,&oarea,FAIL);
2095 				}
2096 				if(Inv_how==PICK_ANY){
2097 					ob_set_text(Inv_dialog->di_tree,QLINE,strCancel);
2098 					for(it=invent_list;it;it=it->Gmi_next)
2099 						if(it->Gmi_identifier && it->Gmi_selected){
2100 							ob_set_text(Inv_dialog->di_tree,QLINE,strOk);
2101 							break;
2102 						}
2103 					ob_draw_chg(Inv_dialog,QLINE,NULL,FAIL);
2104 				}
2105 			}while((d_exit&NO_CLICK)==LINESLIST);
2106 			if(d_exit!=W_ABANDON){
2107 				my_close_dialog(Inv_dialog,FALSE);
2108 				if(d_exit!=W_CLOSED)
2109 					ob_undostate(z_ob,d_exit&NO_CLICK,SELECTED);
2110 			}
2111 		}
2112 		Event_Handler(NULL,NULL);
2113 		ob_set_text(z_ob,QLINE,tmp_button);
2114 		break;
2115 	case NHW_MAP:
2116 		if(p_Gw->gw_window==NULL){
2117 			calc_std_winplace(NHW_MAP,&p_Gw->gw_place);
2118 			window_border(MAP_GADGETS,0,0,Tile_width*(COLNO-1),Tile_heigth*ROWNO, &g_mapmax);
2119 			p_Gw->gw_window=open_window(md, md, NULL, zz_oblist[NHICON], MAP_GADGETS, TRUE, 128, 128, &g_mapmax, &p_Gw->gw_place, &scroll_map, win_draw_map, NULL, XM_TOP|XM_BOTTOM|XM_SIZE);
2120 			WindowItems(p_Gw->gw_window,SCROLL_KEYS-1,scroll_keys);	/* ClrHome centers on u */
2121 			mar_clear_map();
2122 		}
2123 		if(p_Gw->gw_dirty){
2124 			area.g_x=p_Gw->gw_window->work.g_x+scroll_map.px_hline*(dirty_map_area.g_x-scroll_map.hpos);
2125 			area.g_y=p_Gw->gw_window->work.g_y+scroll_map.px_vline*(dirty_map_area.g_y-scroll_map.vpos);
2126 			area.g_w=(dirty_map_area.g_w-dirty_map_area.g_x+1)*scroll_map.px_hline;
2127 			area.g_h=(dirty_map_area.g_h-dirty_map_area.g_y+1)*scroll_map.px_vline;
2128 
2129 			redraw_window(p_Gw->gw_window,&area);
2130 
2131 			dirty_map_area.g_x=COLNO-1;
2132 			dirty_map_area.g_y=ROWNO;
2133 			dirty_map_area.g_w=
2134 			dirty_map_area.g_h=0;
2135 		}
2136 		break;
2137 	case NHW_MESSAGE:
2138 		if(p_Gw->gw_window==NULL){
2139 			calc_std_winplace(NHW_MESSAGE,&p_Gw->gw_place);
2140 			z_ob=zz_oblist[MSGWIN];
2141 			magx=0;	/* MAR -- Fake E_GEM to remove Backdropper */
2142 			p_Gw->gw_window=open_window(NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, &p_Gw->gw_place, NULL, mar_draw_window, z_ob, XM_TOP|XM_BOTTOM|XM_SIZE);
2143 			magx=tmp_magx;
2144 			window_size(p_Gw->gw_window,&p_Gw->gw_window->curr);
2145 			p_Gw->gw_dirty=TRUE;
2146 		}
2147 
2148 		if(p_Gw->gw_dirty){
2149 			ob_pos(zz_oblist[MSGWIN],MSGLINES,&area);
2150 			while(messages_pro_zug>3){
2151 				messages_pro_zug-=3;
2152 				msg_pos+=3;
2153 				redraw_window(p_Gw->gw_window,&area);
2154 				mar_more();
2155 			}
2156 			msg_pos+=messages_pro_zug;
2157 			messages_pro_zug=0;
2158 			if(msg_pos>msg_max) msg_pos=msg_max;
2159 			redraw_window(p_Gw->gw_window,&area);
2160 			mar_message_pause=FALSE;
2161 		}
2162 		break;
2163 	case NHW_STATUS:
2164 		if(p_Gw->gw_window==NULL){
2165 			z_ob=zz_oblist[STATUSLINE];
2166 			calc_std_winplace(NHW_STATUS,&p_Gw->gw_place);
2167 			magx=0;	/* MAR -- Fake E_GEM to remove Backdropper */
2168 			p_Gw->gw_window=open_window(NULL, NULL, NULL, NULL, 0, FALSE, 0, 0, NULL, &p_Gw->gw_place, NULL, mar_draw_window, z_ob, XM_TOP|XM_BOTTOM|XM_SIZE);
2169 			magx=tmp_magx;
2170 			/* Because 2*status_font.ch is smaller then e_gem expects the minimum win_height */
2171 			p_Gw->gw_window->min_h=z_ob[ROOT].ob_height;
2172 			window_size(p_Gw->gw_window,&p_Gw->gw_place);
2173 			p_Gw->gw_dirty=TRUE;
2174 			add_dirty_rect(dr_stat,&p_Gw->gw_place);
2175 		}
2176 		while(get_dirty_rect(dr_stat,&area)){
2177 			area.g_x=(area.g_x+p_Gw->gw_window->work.g_x+2*status_font.cw+6)&~7;
2178 			area.g_y+=p_Gw->gw_window->work.g_y;
2179 			redraw_window(p_Gw->gw_window,&area);
2180 		}
2181 		break;
2182 	default:
2183 		if(p_Gw->gw_dirty)
2184 			redraw_window(p_Gw->gw_window,NULL);
2185 	}
2186 	p_Gw->gw_dirty=FALSE;
2187 }
2188 
2189 /************************* create_window *******************************/
2190 
mar_hol_win_type(window)2191 int mar_hol_win_type(window)
2192 winid	window;
2193 {
2194 	return(Gem_nhwindow[window].gw_type);
2195 }
2196 
2197 winid
mar_create_window(type)2198 mar_create_window(type)
2199 int type;
2200 {
2201 	winid newid;
2202 	static char name[]="Gem";
2203 	int i;
2204 	struct gw *p_Gw=&Gem_nhwindow[0];
2205 
2206 	for(newid = 0; p_Gw->gw_type && newid < MAXWIN; newid++, p_Gw++);
2207 
2208 	switch(type){
2209 	case NHW_MESSAGE:
2210 		message_line=(char **)m_alloc(msg_anz*sizeof(char *));
2211 		message_age=(int *)m_alloc(msg_anz*sizeof(int));
2212 		for(i=0;i<msg_anz;i++){
2213 			message_age[i]=FALSE;
2214 			message_line[i]=(char *)m_alloc((MSGLEN+1)*sizeof(char));
2215 			*message_line[i]=0;
2216 		}
2217 		dr_msg=new_dirty_rect(10);
2218 		if (!dr_msg) panic("Memory allocation failure (dr_msg)");
2219 		break;
2220 	case NHW_STATUS:
2221 		status_line=(char **)m_alloc(2*sizeof(char *));
2222 		for(i=0;i<2;i++){
2223 			status_line[i]=(char *)m_alloc(status_w*sizeof(char));
2224 			memset(status_line[i],0,status_w);
2225 		}
2226 		dr_stat=new_dirty_rect(10);
2227 		if (!dr_stat) panic("Memory allocation failure (dr_stat)");
2228 		break;
2229 	case NHW_MAP:
2230 		map_glyphs=(char **)m_alloc((long)ROWNO*sizeof(char *));
2231 		for(i=0;i<ROWNO;i++){
2232 			map_glyphs[i]=(char *)m_alloc((long)COLNO*sizeof(char));
2233 			*map_glyphs[i]=map_glyphs[i][COLNO-1]=0;
2234 		}
2235 		dr_map=new_dirty_rect(10);
2236 		if (!dr_map) panic("Memory allocation failure (dr_map)");
2237 
2238 		mar_clear_map();
2239 		break;
2240 	case NHW_MENU:
2241 	case NHW_TEXT:	/* They are no more treated as dialog */
2242 		break;
2243 	default:
2244 		p_Gw->gw_window=open_window("Sonst", name, NULL, NULL, NAME|MOVER|CLOSER, 0, 0, 0, NULL, &p_Gw->gw_place, NULL, NULL, NULL, XM_TOP|XM_BOTTOM|XM_SIZE);
2245 		break;
2246 	}
2247 
2248 	p_Gw->gw_type=type;
2249 
2250 	return(newid);
2251 }
2252 
2253 void
mar_change_menu_2_text(win)2254 mar_change_menu_2_text(win)
2255 winid win;
2256 {
2257 	Gem_nhwindow[win].gw_type=NHW_TEXT;
2258 }
2259 
2260 /************************* mar_clear_map *******************************/
2261 
2262 void
mar_clear_map()2263 mar_clear_map()
2264 {
2265 	int pla[8];
2266 	int x,y;
2267 
2268 	pla[0]=pla[1]=pla[4]=pla[5]=0;
2269 	pla[2]=pla[6]=scroll_map.px_hline*(COLNO-1)-1;
2270 	pla[3]=pla[7]=scroll_map.px_vline*ROWNO-1;
2271 	for(y=0;y<ROWNO;y++) for(x=0;x<COLNO-1;x++)
2272 		map_glyphs[y][x]=' ';
2273 	vro_cpyfm(x_handle, ALL_BLACK,pla,&Tile_bilder,&Map_bild);	/* MAR -- 17.Mar 2002 Hmm, what if FontCol_Bild is bigger? */
2274 	if(WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window)
2275 		redraw_window(Gem_nhwindow[WIN_MAP].gw_window,NULL);
2276 }
2277 
2278 /************************* destroy_window *******************************/
2279 
2280 void
mar_destroy_nhwindow(window)2281 mar_destroy_nhwindow(window)
2282 winid window;
2283 {
2284 	int i;
2285 
2286 	switch(Gem_nhwindow[window].gw_type){
2287 	case NHW_TEXT:
2288 		for(i=0;i<Anz_text_lines;i++)
2289 			free(text_lines[i]);
2290 		null_free(text_lines);
2291 		Anz_text_lines=0;
2292 		use_rip=FALSE;
2293 		break;
2294 	case NHW_MENU:
2295 		Gem_start_menu(window);	/* delete invent_list */
2296 		test_free(Menu_title);
2297 		break;
2298 	case 0:	/* No window available, probably an error message? */
2299 		break;
2300 	default:
2301 		close_window( Gem_nhwindow[window].gw_window, 0 );
2302 		break;
2303 	}
2304 	Gem_nhwindow[window].gw_window=NULL;
2305 	Gem_nhwindow[window].gw_type=0;
2306 	Gem_nhwindow[window].gw_dirty=FALSE;
2307 
2308 	if(window==WIN_MAP){
2309 		for(i=0;i<ROWNO;i++){
2310 			free(map_glyphs[i]);
2311 		}
2312 		null_free(map_glyphs);
2313 		WIN_MAP=WIN_ERR;
2314 	}
2315 	if(window==WIN_STATUS){
2316 		for(i=0;i<2;i++)
2317 			free(status_line[i]);
2318 		null_free(status_line);
2319 		WIN_STATUS=WIN_ERR;
2320 	}
2321 	if(window==WIN_MESSAGE){
2322 		for(i=0;i<msg_anz;i++)
2323 			free(message_line[i]);
2324 		null_free(message_line);
2325 		null_free(message_age);
2326 		WIN_MESSAGE=WIN_ERR;
2327 	}
2328 	if(window==WIN_INVEN)
2329 		WIN_INVEN=WIN_ERR;
2330 }
2331 
2332 /************************* nh_poskey *******************************/
2333 
mar_set_margin(int m)2334 void mar_set_margin(int m){
2335 	Max(&m,0);
2336 	Min(&m,min(ROWNO,COLNO));	/* MAR 16.Mar 2002 -- the larger the less sense */
2337 	scroll_margin=m;
2338 }
2339 void
mar_cliparound()2340 mar_cliparound()
2341 {
2342 	if(WIN_MAP!=WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window){
2343 		int	breite=scroll_margin>0 ? scroll_margin : max(scroll_map.hpage/4,1),
2344 				hoehe=scroll_margin>0 ? scroll_margin : max(scroll_map.vpage/4,1),
2345 				adjust_needed;
2346 		adjust_needed=FALSE;
2347 		if ((map_cursx < scroll_map.hpos + breite) || (map_cursx >= scroll_map.hpos + scroll_map.hpage - breite)){
2348 			scroll_map.hpos=map_cursx - scroll_map.hpage/2;
2349 			adjust_needed=TRUE;
2350 		}
2351 		if ((map_cursy < scroll_map.vpos + hoehe) || (map_cursy >= scroll_map.vpos + scroll_map.vpage - hoehe)){
2352 			scroll_map.vpos=map_cursy - scroll_map.vpage/2;
2353 			adjust_needed=TRUE;
2354 		}
2355 		if(adjust_needed)
2356 			scroll_window(Gem_nhwindow[WIN_MAP].gw_window,WIN_SCROLL,NULL);
2357 	}
2358 }
2359 
2360 void
mar_update_value()2361 mar_update_value()
2362 {
2363 	if(WIN_MESSAGE!=WIN_ERR){
2364 		mar_message_pause=FALSE;
2365 		mar_esc_pressed=FALSE;
2366 		mar_display_nhwindow(WIN_MESSAGE);
2367 	}
2368 
2369 	if(WIN_MAP!=WIN_ERR)
2370 		mar_cliparound();
2371 
2372 	if(WIN_STATUS!=WIN_ERR){
2373 		mar_check_hilight_status();
2374 		mar_display_nhwindow(WIN_STATUS);
2375 	}
2376 }
2377 
2378 int
Main_Init(xev,availiable)2379 Main_Init(xev,availiable)
2380 XEVENT *xev;
2381 int availiable;
2382 {
2383 	xev->ev_mb1mask=
2384 	xev->ev_mb1state=1;
2385 	xev->ev_mb1clicks=
2386 	xev->ev_mb2clicks=
2387 	xev->ev_mb2mask=
2388 	xev->ev_mb2state=2;
2389 	return((MU_KEYBD|MU_BUTTON1|MU_BUTTON2|MU_MESAG)&availiable);
2390 }
2391 
2392 /*
2393  * return a key, or 0, in which case a mouse button was pressed
2394  * mouse events should be returned as character postitions in the map window.
2395  */
2396 /*ARGSUSED*/
2397 int
mar_nh_poskey(x,y,mod)2398 mar_nh_poskey(x, y, mod)
2399     int *x, *y, *mod;
2400 {
2401 	static XEVENT xev;
2402 	int retval, ev;
2403 
2404 	xev.ev_mflags=Main_Init(&xev,0xFFFF);
2405 	ev=Event_Multi(&xev);
2406 
2407 	retval=FAIL;
2408 
2409 	if(ev&MU_KEYBD){
2410 		char ch = xev.ev_mkreturn&0x00FF;
2411 		char scan = (xev.ev_mkreturn & 0xff00) >> 8;
2412 		int shift = xev.ev_mmokstate;
2413 		const struct pad *kpad;
2414 
2415 		/* Translate keypad keys */
2416 		if (iskeypad(scan)) {
2417 			kpad = mar_iflags_numpad()==1 ? numpad : keypad;
2418 			if (shift & K_SHIFT)
2419 				ch = kpad[scan - KEYPADLO].shift;
2420 			else if (shift & K_CTRL){
2421 				if(scan>=0x67 && scan<=0x6f && scan!=0x6b){
2422 					send_key(kpad[scan - KEYPADLO].normal);
2423 					ch = 'g';
2424 				}else{
2425 				ch = kpad[scan - KEYPADLO].cntrl;
2426 				}
2427 			}else
2428 				ch = kpad[scan - KEYPADLO].normal;
2429 		}
2430 		if(scan==SCANHOME)
2431 			mar_cliparound();
2432 		else if(scan == SCANF1)
2433 			retval='h';
2434 		else if(scan == SCANF2){
2435 			mar_set_tile_mode(!mar_set_tile_mode(FAIL));
2436 			retval=C('l');	/* trigger full-redraw */
2437 		}else if(scan == SCANF3){
2438 			draw_cursor=!draw_cursor;
2439 			mar_curs(map_cursx,map_cursy);
2440 			mar_display_nhwindow(WIN_MAP);
2441 		}else if(scan == SCANF4){	/* Font-Selector */
2442 			if(!CallFontSelector(0,FAIL,FAIL,FAIL,FAIL)){
2443 				xalert(1,1,X_ICN_ALERT,NULL,SYS_MODAL,BUTTONS_RIGHT,TRUE,"Hello","Fontselector not available!",NULL);
2444 			}
2445 		}else if(!ch && shift&K_CTRL && scan==-57){
2446 			/* MAR -- nothing ignore Ctrl-Alt-Clr/Home == MagiC's restore screen */
2447 		}else{
2448 			if(!ch)
2449 				ch=(char)M(tolower(scan_2_ascii(xev.ev_mkreturn,shift)));
2450 			if(((int)ch)==-128)
2451 				ch='\033';
2452 			retval=ch;
2453 		}
2454 	}
2455 
2456 	if(ev&MU_BUTTON1 || ev&MU_BUTTON2){
2457 		int ex=xev.ev_mmox, ey=xev.ev_mmoy;
2458 		WIN *akt_win=window_find(ex,ey);
2459 
2460 		if(WIN_MAP != WIN_ERR && akt_win==Gem_nhwindow[WIN_MAP].gw_window){
2461 			*x=max(min((ex-akt_win->work.g_x)/scroll_map.px_hline+scroll_map.hpos,COLNO-1),0)+1;
2462 			*y=max(min((ey-akt_win->work.g_y)/scroll_map.px_vline+scroll_map.vpos,ROWNO),0);
2463 			*mod=xev.ev_mmobutton;
2464 			retval=0;
2465 		}else if(WIN_STATUS != WIN_ERR && akt_win==Gem_nhwindow[WIN_STATUS].gw_window){
2466 			move_win(akt_win);
2467 		}else if(WIN_MESSAGE != WIN_ERR && akt_win==Gem_nhwindow[WIN_MESSAGE].gw_window){
2468 			message_handler(ex,ey);
2469 		}
2470 	}
2471 
2472 	if(ev&MU_MESAG){
2473 		int *buf=xev.ev_mmgpbuf;
2474 		char *str;
2475 		OBJECT *z_ob=zz_oblist[MENU];
2476 
2477 	   switch(*buf) {
2478 		case MN_SELECTED :
2479 			menu_tnormal(z_ob,buf[3],TRUE);	/* unselect menu header */
2480 			str=ob_get_text(z_ob,buf[4],0);
2481 			str+=strlen(str)-2;
2482 			switch(*str){
2483 			case ' ':	/* just that command */
2484 				retval=str[1];
2485 				break;
2486 			case '\005':	/* Alt command */
2487 			case '\007':
2488 				retval=M(str[1]);
2489 				break;
2490 			case '^':	/* Ctrl command */
2491 				retval=C(str[1]);
2492 				break;
2493 			case 'f':	/* Func Key */
2494 				switch(str[1]){
2495 				case '1':
2496 					retval='h';
2497 					break;
2498 				case '2':
2499 					mar_set_tile_mode(!mar_set_tile_mode(FAIL));
2500 					retval=C('l');	/* trigger full-redraw */
2501 					break;
2502 				case '3':
2503 					draw_cursor=!draw_cursor;
2504 					mar_curs(map_cursx,map_cursy);
2505 					mar_display_nhwindow(WIN_MAP);
2506 					break;
2507 				default:
2508 				}
2509 				break;
2510 			default:
2511 				mar_about();
2512 				break;
2513 			}
2514 			break;	/* MN_SELECTED */
2515 		case WM_CLOSED:
2516 			WindowHandler(W_ICONIFYALL,NULL,NULL);
2517 			break;
2518 		case AP_TERM:
2519 			retval='S';
2520 			break;
2521 		case FONT_CHANGED:
2522 			if(buf[3]>=0){
2523 				if(buf[3]==Gem_nhwindow[WIN_MESSAGE].gw_window->handle){
2524 					mar_set_fontbyid(NHW_MESSAGE,buf[4],buf[5]);
2525 					mar_display_nhwindow(WIN_MESSAGE);
2526 				}else if(buf[3]==Gem_nhwindow[WIN_MAP].gw_window->handle){
2527 					mar_set_fontbyid(NHW_MAP,buf[4],buf[5]);
2528 					mar_display_nhwindow(WIN_MAP);
2529 				}else if(buf[3]==Gem_nhwindow[WIN_STATUS].gw_window->handle){
2530 					mar_set_fontbyid(NHW_STATUS,buf[4],buf[5]);
2531 					mar_display_nhwindow(WIN_STATUS);
2532 				}
2533 				FontAck(buf[1],1);
2534 			}
2535 			break;
2536 		default:
2537 			break;
2538 		}
2539 	}	/* MU_MESAG */
2540 
2541 	if(retval==FAIL)
2542 		retval=mar_nh_poskey(x,y,mod);
2543 
2544 	return(retval);
2545 }
2546 
2547 int
Gem_nh_poskey(x,y,mod)2548 Gem_nh_poskey(x, y, mod)
2549     int *x, *y, *mod;
2550 {
2551 	mar_update_value();
2552 	return(mar_nh_poskey(x, y, mod));
2553 }
2554 
2555 void
Gem_delay_output()2556 Gem_delay_output()
2557 {
2558 	Event_Timer(50,0,FALSE);	/* wait 50ms */
2559 }
2560 
2561 int
Gem_doprev_message()2562 Gem_doprev_message()
2563 {
2564 	if(msg_pos>2){
2565 		msg_pos--;
2566 	if(WIN_MESSAGE != WIN_ERR)
2567 		Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
2568 	mar_display_nhwindow(WIN_MESSAGE);
2569 	}
2570 	return(0);
2571 }
2572 
2573 /************************* print_glyph *******************************/
2574 
2575 int mar_set_rogue(int);
2576 
2577 int
mar_set_tile_mode(tiles)2578 mar_set_tile_mode(tiles)
2579 int tiles;
2580 {
2581 	static int tile_mode=TRUE;
2582 	static GRECT prev;
2583 	WIN *z_w=WIN_MAP!=WIN_ERR ? Gem_nhwindow[WIN_MAP].gw_window : NULL;
2584 
2585 	if(tiles<0)
2586 		return(tile_mode);
2587 	else if(!z_w)
2588 		tile_mode=tiles;
2589 	else if(tile_mode==tiles || (mar_set_rogue(FAIL) && tiles))
2590 			return(FAIL);
2591 	else{
2592 		GRECT tmp;
2593 
2594 		tile_mode=tiles;
2595 		scroll_map.px_hline= tiles ? Tile_width : map_font.cw;
2596 		scroll_map.px_vline= tiles ? Tile_heigth : map_font.ch;
2597 		window_border(MAP_GADGETS,0,0,scroll_map.px_hline*(COLNO-1),scroll_map.px_vline*ROWNO, &tmp);
2598 		z_w->max.g_w=tmp.g_w;
2599 		z_w->max.g_h=tmp.g_h;
2600 		if(tiles)
2601 			z_w->curr=prev;
2602 		else
2603 			prev=z_w->curr;
2604 
2605 		window_reinit(z_w,md,md,NULL,FALSE,FALSE);
2606 	}
2607 	return(FAIL);
2608 }
2609 
2610 int
mar_set_rogue(what)2611 mar_set_rogue(what)
2612 int what;
2613 {
2614 	static int rogue=FALSE, prev_mode=TRUE;
2615 
2616 	if(what<0) return(rogue);
2617 	if(what!=rogue){
2618 		rogue=what;
2619 		if(rogue){
2620 			prev_mode=mar_set_tile_mode(FAIL);
2621 			mar_set_tile_mode(FALSE);
2622 		}else
2623 			mar_set_tile_mode(prev_mode);
2624 	}
2625 	return(FAIL);
2626 }
2627 
2628 void
mar_add_pet_sign(window,x,y)2629 mar_add_pet_sign(window,x,y)
2630 winid window;
2631 int x, y;
2632 {
2633 	if(window != WIN_ERR && window==WIN_MAP){
2634 		static int pla[8]={0,0,7,7,0,0,0,0}, colindex[2]={RED,WHITE};
2635 
2636 		pla[4]=pla[6]=scroll_map.px_hline*x;
2637 		pla[5]=pla[7]=scroll_map.px_vline*y;
2638 		pla[6]+=7;
2639 		pla[7]+=6;
2640 		vrt_cpyfm(x_handle,MD_TRANS,pla,&Pet_Mark,&Map_bild,colindex);
2641 	}
2642 }
2643 
2644 void
mar_print_glyph(window,x,y,gl)2645 mar_print_glyph(window, x, y, gl)
2646 winid window;
2647 int x, y, gl;
2648 {
2649 	if(window != WIN_ERR && window==WIN_MAP){
2650 	static int pla[8];
2651 
2652 			pla[2]=pla[0]=(gl%Tiles_per_line)*Tile_width;
2653 			pla[3]=pla[1]=(gl/Tiles_per_line)*Tile_heigth;
2654 			pla[2]+=Tile_width-1;
2655 			pla[3]+=Tile_heigth-1;
2656 			pla[6]=pla[4]=Tile_width*x;	/* x_wert to */
2657 			pla[7]=pla[5]=Tile_heigth*y;	/* y_wert to */
2658 			pla[6]+=Tile_width-1;
2659 			pla[7]+=Tile_heigth-1;
2660 
2661 			vro_cpyfm(x_handle, gl!=-1 ? S_ONLY : ALL_BLACK, pla, &Tile_bilder, &Map_bild);
2662 		}
2663 	}
2664 
2665 void
mar_print_char(window,x,y,ch,col)2666 mar_print_char(window, x, y, ch, col)
2667 winid window;
2668 int x, y;
2669 char ch;
2670 int col;
2671 {
2672 	if(window != WIN_ERR && window==WIN_MAP){
2673 		static int gem_color[16]={ 9, 2,11,10, 4, 7, 8, 15,0,14, 3, 6, 5, 13,15, 0};
2674 		int pla[8], colindex[2];
2675 
2676 		map_glyphs[y][x]=ch;
2677 
2678 		pla[0]=
2679 		pla[1]=0;
2680 		pla[2]=map_font.cw-1;
2681 		pla[3]=map_font.ch-1;
2682 		pla[6]=pla[4]=map_font.cw*x;
2683 		pla[7]=pla[5]=map_font.ch*y;
2684 		pla[6]+=map_font.cw-1;
2685 		pla[7]+=map_font.ch-1;
2686 		colindex[0]=gem_color[col];
2687 		colindex[1]=WHITE;
2688 		vrt_cpyfm(x_handle,MD_REPLACE,pla,&Black_bild,&FontCol_Bild,colindex);
2689 	}
2690 }
2691 
2692 /************************* getlin *******************************/
2693 
2694 void
Gem_getlin(ques,input)2695 Gem_getlin(ques, input)
2696 const char *ques;
2697 char *input;
2698 {
2699 	OBJECT *z_ob=zz_oblist[LINEGET];
2700 	int d_exit, length;
2701 	char *pr[2], *tmp;
2702 
2703 	if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2704 		mar_display_nhwindow(WIN_MESSAGE);
2705 
2706 	z_ob[LGPROMPT].ob_type=G_USERDEF;
2707 	z_ob[LGPROMPT].ob_spec.userblk=&ub_prompt;
2708 	z_ob[LGPROMPT].ob_height=2*gr_ch;
2709 
2710 	length=z_ob[LGPROMPT].ob_width/gr_cw;
2711 	if(strlen(ques)>length){
2712 		tmp=ques+length;
2713 		while(*tmp!=' ' && tmp>=ques){
2714 			tmp--;
2715 		}
2716 		if(tmp<=ques) tmp=ques+length;	/* Mar -- Oops, what a word :-) */
2717 		pr[0]=ques;
2718 		*tmp=0;
2719 		pr[1]=++tmp;
2720 	}else{
2721 		pr[0]=ques;
2722 		pr[1]=NULL;
2723 	}
2724 	ub_prompt.ub_parm=(long)pr;
2725 
2726 	ob_clear_edit(z_ob);
2727 	d_exit=xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, DIALOG_MODE);
2728 	Event_Timer(0,0,TRUE);
2729 
2730 	if(d_exit==W_CLOSED || d_exit==W_ABANDON || (d_exit&NO_CLICK)==QLG){
2731 		*input='\033';
2732 		input[1]=0;
2733 	}else
2734 		strncpy(input,ob_get_text(z_ob,LGREPLY, 0),length);
2735 }
2736 
2737 /************************* ask_direction *******************************/
2738 
2739 #define Dia_Init K_Init
2740 
2741 int
Dia_Handler(xev)2742 Dia_Handler(xev)
2743 XEVENT *xev;
2744 {
2745 	int ev=xev->ev_mwich;
2746 	char ch=(char)(xev->ev_mkreturn&0x00FF);
2747 
2748 	if(ev&MU_KEYBD){
2749 		WIN *w;
2750 		DIAINFO *dinf;
2751 
2752 		switch(ch){
2753 		case 's':
2754 			send_key((int)(mar_iflags_numpad() ? '5' : '.'));
2755 			break;
2756 		case '.':
2757 			send_key('5');	/* MAR -- '.' is a button if numpad isn't set */
2758 			break;
2759 		case '\033':	/*ESC*/
2760 			if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[DIRECTION]){
2761 				my_close_dialog(dinf,FALSE);
2762 				break;
2763 			}
2764 			/* Fall thru */
2765 		default:
2766 			ev &= ~MU_KEYBD;	/* let the dialog handle it */
2767 			break;
2768 		}
2769 	}
2770 	return(ev);
2771 }
2772 
2773 int
mar_ask_direction()2774 mar_ask_direction()
2775 {
2776 	int d_exit;
2777 	OBJECT *z_ob=zz_oblist[DIRECTION];
2778 
2779 	Event_Handler(Dia_Init,Dia_Handler);
2780 	mar_set_dir_keys();
2781 	d_exit=xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, DIALOG_MODE);
2782 	Event_Timer(0,0,TRUE);
2783 	Event_Handler(NULL,NULL);
2784 
2785 	if(d_exit==W_CLOSED || d_exit==W_ABANDON)
2786 		return('\033');
2787 	if((d_exit&NO_CLICK)==DIRDOWN)
2788 		return('>');
2789 	if((d_exit&NO_CLICK)==DIRUP)
2790 		return('<');
2791 	if((d_exit&NO_CLICK)==(DIR1+8))	/* 5 or . */
2792 		return('.');
2793 	return(*ob_get_text(z_ob,d_exit&NO_CLICK,0));
2794 }
2795 
2796 /************************* yn_function *******************************/
2797 
2798 
2799 #define any_init M_Init
2800 
2801 static int
any_handler(xev)2802 any_handler(xev)
2803 XEVENT *xev;
2804 {
2805 	int ev=xev->ev_mwich;
2806 
2807 	if(ev&MU_MESAG){
2808 		int *buf=xev->ev_mmgpbuf;
2809 
2810 		if(*buf==OBJC_EDITED)
2811 			my_close_dialog(*(DIAINFO **)&buf[4], FALSE);
2812 		else
2813 			ev &= ~MU_MESAG;
2814 	}
2815 	return(ev);
2816 }
2817 
2818 int
send_yn_esc(char ch)2819 send_yn_esc(char ch)
2820 {
2821 	static char esc_char=0;
2822 
2823 	if(ch<0){
2824 		if(esc_char){
2825 			send_key((int)esc_char);
2826 			return(TRUE);
2827 		}
2828 		return(FALSE);
2829 	}else
2830 		esc_char=ch;
2831 	return(TRUE);
2832 }
2833 
2834 #define single_init K_Init
2835 
2836 static int
single_handler(xev)2837 single_handler(xev)
2838 XEVENT *xev;
2839 {
2840 	int ev=xev->ev_mwich;
2841 
2842 	if(ev&MU_KEYBD){
2843 		char ch=(char)xev->ev_mkreturn&0x00FF;
2844 		WIN *w;
2845 		DIAINFO *dinf;
2846 
2847 		switch(ch){
2848 		case ' ':
2849 			send_return();
2850 			break;
2851 		case '\033':
2852 			if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[YNCHOICE]){
2853 				if(!send_yn_esc(FAIL))
2854 					my_close_dialog(dinf,FALSE);
2855 				break;
2856 			}
2857 			/* Fall thru */
2858 		default:
2859 			ev &= ~MU_MESAG;
2860 		}
2861 	}
2862 	return(ev);
2863 }
2864 
2865 char
Gem_yn_function(query,resp,def)2866 Gem_yn_function(query,resp, def)
2867 const char *query,*resp;
2868 char def;
2869 {
2870 	OBJECT *z_ob=zz_oblist[YNCHOICE];
2871 	int d_exit, i, len;
2872 	long anzahl;
2873 	char *tmp;
2874 	const char *ptr;
2875 
2876 	if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2877 		mar_display_nhwindow(WIN_MESSAGE);
2878 
2879 	/* if query for direction the special dialog */
2880 	if(strstr(query,"irect"))
2881 		return(mar_ask_direction());
2882 
2883 	len=min(strlen(query),(max_w-8*gr_cw)/gr_cw);
2884 	z_ob[ROOT].ob_width=(len+8)*gr_cw;
2885 	z_ob[YNPROMPT].ob_width=gr_cw*len+8;
2886 	tmp=ob_get_text(z_ob,YNPROMPT,0);
2887 	ob_set_text(z_ob,YNPROMPT,mar_copy_of(query));
2888 
2889 	if(resp){	/* single inputs */
2890 		ob_hide(z_ob,SOMECHARS,FALSE);
2891 		ob_hide(z_ob,ANYCHAR,TRUE);
2892 
2893 		if(strchr(resp,'q')) send_yn_esc('q');
2894 		else if(strchr(resp,'n')) send_yn_esc('n');
2895 		else send_yn_esc(def);	/* strictly def should be returned, but in trad. I it's 0 */
2896 
2897 		if(strchr(resp,'#')){	/* count possible */
2898 			ob_hide(z_ob,YNOK,FALSE);
2899 			ob_hide(z_ob,COUNT,FALSE);
2900 		}else{	/* no count */
2901 			ob_hide(z_ob,YNOK,TRUE);
2902 			ob_hide(z_ob,COUNT,TRUE);
2903 		}
2904 
2905 		if((anzahl=(long)strchr(resp,'\033'))){
2906 			anzahl-=(long)resp;
2907 		}else{
2908 			anzahl=strlen(resp);
2909 		}
2910 		for(i=0,ptr=resp;i<2*anzahl;i+=2,ptr++){
2911 			ob_hide(z_ob,YN1+i,FALSE);
2912 			mar_change_button_char(z_ob,YN1+i,*ptr);
2913 			ob_undoflag(z_ob,YN1+i,DEFAULT);
2914 			if(*ptr==def)
2915 				ob_doflag(z_ob,YN1+i,DEFAULT);
2916 		}
2917 
2918 		z_ob[SOMECHARS].ob_width=z_ob[YN1+i].ob_x+8;
2919 		z_ob[SOMECHARS].ob_height=z_ob[YN1+i].ob_y+gr_ch+gr_ch/2;
2920 		Max((int *)&z_ob[ROOT].ob_width,z_ob[SOMECHARS].ob_width+4*gr_cw);
2921 		z_ob[ROOT].ob_height=z_ob[SOMECHARS].ob_height+4*gr_ch;
2922 		if(strchr(resp,'#'))
2923 			z_ob[ROOT].ob_height=z_ob[YNOK].ob_y+2*gr_ch;
2924 
2925 		for(i+=YN1;i<(YNN+1);i+=2){
2926 			ob_hide(z_ob,i,TRUE);
2927 		}
2928 		Event_Handler(single_init,single_handler);
2929 	}else{	/* any input */
2930 		ob_hide(z_ob,SOMECHARS,TRUE);
2931 		ob_hide(z_ob,ANYCHAR,FALSE);
2932 		ob_hide(z_ob,YNOK,TRUE);
2933 		ob_hide(z_ob,COUNT,TRUE);
2934 		z_ob[ANYCHAR].ob_height=2*gr_ch;
2935 		z_ob[CHOSENCH].ob_y=
2936 		z_ob[CHOSENCH+1].ob_y=gr_ch/2;
2937 		z_ob[ROOT].ob_width=max(z_ob[YNPROMPT].ob_width+z_ob[YNPROMPT].ob_x,z_ob[ANYCHAR].ob_width+z_ob[ANYCHAR].ob_x)+2*gr_cw;
2938 		z_ob[ROOT].ob_height=z_ob[ANYCHAR].ob_height+z_ob[ANYCHAR].ob_y+gr_ch/2;
2939 		*ob_get_text(z_ob,CHOSENCH,0)='?';
2940 		Event_Handler(any_init,any_handler);
2941 	}
2942 
2943 	d_exit=xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, DIALOG_MODE);
2944 	Event_Timer(0,0,TRUE);
2945 	Event_Handler(NULL,NULL);
2946 	/* display of count is missing (through the core too) */
2947 
2948 	free(ob_get_text(z_ob,YNPROMPT,0));
2949 	ob_set_text(z_ob,YNPROMPT,tmp);
2950 
2951 	if(resp && (d_exit==W_CLOSED || d_exit==W_ABANDON))
2952 		return('\033');
2953 	if((d_exit&NO_CLICK)==YNOK){
2954 		yn_number=atol(ob_get_text(z_ob,COUNT,0));
2955 		return('#');
2956 	}
2957 	if(!resp)
2958 		return(*ob_get_text(z_ob,CHOSENCH,0));
2959 	return(*ob_get_text(z_ob,d_exit&NO_CLICK,0));
2960 }
2961 
2962 /*
2963  * Allocate a copy of the given string.  If null, return a string of
2964  * zero length.
2965  *
2966  * This is an exact duplicate of copy_of() in X11/winmenu.c.
2967  */
2968 static char *
mar_copy_of(s)2969 mar_copy_of(s)
2970     const char *s;
2971 {
2972     if (!s) s = nullstr;
2973     return strcpy((char *) m_alloc((unsigned) (strlen(s) + 1)), s);
2974 }
2975 
2976 const char *strRP="raw_print", *strRPB="raw_print_bold";
2977 
2978 void
mar_raw_print(str)2979 mar_raw_print(str)
2980 const char *str;
2981 {
2982 		xalert(1,FAIL,X_ICN_INFO,NULL,APPL_MODAL,BUTTONS_CENTERED,TRUE,strRP,str,NULL);
2983 }
2984 
2985 void
mar_raw_print_bold(str)2986 mar_raw_print_bold(str)
2987 const char *str;
2988 {
2989 	char buf[BUFSZ];
2990 
2991 	sprintf(buf,"!%s",str);
2992 	xalert(1,FAIL,X_ICN_INFO,NULL,APPL_MODAL,BUTTONS_CENTERED,TRUE,strRPB,buf,NULL);
2993 }
2994 
2995 /*wingem1.c*/
2996