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