1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef GLK_WINDOWS_H
24 #define GLK_WINDOWS_H
25 
26 #include "common/array.h"
27 #include "common/list.h"
28 #include "common/rect.h"
29 #include "graphics/screen.h"
30 #include "glk/events.h"
31 #include "glk/fonts.h"
32 #include "glk/glk_types.h"
33 #include "glk/screen.h"
34 #include "glk/selection.h"
35 #include "glk/streams.h"
36 
37 namespace Glk {
38 
39 class Window;
40 class PairWindow;
41 
42 #define HISTORYLEN 100
43 #define SCROLLBACK 512
44 #define TBLINELEN 300
45 #define GLI_SUBPIX 8
46 
47 
48 /**
49  * Main windows manager
50  */
51 class Windows {
52 	friend class Window;
53 public:
54 	class iterator {
55 	private:
56 		Windows *_windows;
57 		Window *_current;
58 	public:
59 		/**
60 		 * Constructor
61 		 */
iterator(Windows * windows,Window * start)62 		iterator(Windows *windows, Window *start) : _current(start) { _windows = windows; }
63 
64 		/**
65 		 * Dereference
66 		 */
67 		Window *operator*() const {
68 			return _current;
69 		}
70 
71 		/**
72 		 * Move to next
73 		 */
74 		iterator &operator++();
75 
76 		/**
77 		 * Move to previous
78 		 */
79 		iterator &operator--();
80 
81 		/**
82 		 * Equality test
83 		 */
84 		bool operator==(const iterator &i) {
85 			return _current == i._current;
86 		}
87 
88 		/**
89 		 * Inequality test
90 		 */
91 		bool operator!=(const iterator &i) {
92 			return _current != i._current;
93 		}
94 	};
95 	friend class iterator;
96 private:
97 	Graphics::Screen *_screen;
98 	Window *_windowList;       ///< List of all windows
99 	Window *_rootWin;          ///< The topmost window
100 	Window *_focusWin;         ///< The window selected by the player
101 	bool _drawSelect;
102 private:
103 	/**
104 	 * Create a new window
105 	 */
106 	Window *newWindow(uint type, uint rock);
107 
108 	/**
109 	 * Create a new pair window
110 	 */
111 	PairWindow *newPairWindow(uint method, Window *key, uint size);
112 
113 	/**
114 	 * Set the window focus
115 	 */
116 	void refocus(Window *win);
117 
118 	/**
119 	 * Used to loop over windows in tree order
120 	 */
121 	Window *iterateTreeOrder(Window *win);
122 
123 	/**
124 	 * Pick first window which has a more request
125 	 */
126 	void inputMoreFocus();
127 
128 	/**
129 	 *
130 	 */
131 	void inputNextFocus();
132 
133 	/**
134 	 * Pick first window which might want scrolling.
135 	 * This is called after pressing page keys.
136 	 */
137 	void inputScrollFocus();
138 public:
139 	static bool _overrideReverse;
140 	static bool _overrideFgSet;
141 	static bool _overrideBgSet;
142 	static bool _forceRedraw;
143 	static bool _claimSelect;
144 	static bool _moreFocus;
145 	static uint _overrideFgVal;
146 	static uint _overrideBgVal;
147 	static uint _zcolor_fg, _zcolor_bg;
148 	static uint _zcolor_LightGrey;
149 	static uint _zcolor_Foreground;
150 	static uint _zcolor_Background;
151 	static uint _zcolor_Bright;
152 
153 	static uint rgbShift(uint color);
154 public:
155 	/**
156 	 * Constructor
157 	 */
158 	Windows(Graphics::Screen *screen);
159 
160 	/**
161 	 * Destructor
162 	 */
163 	~Windows();
164 
165 	/**
166 	 * Open a new window
167 	 */
168 	Window *windowOpen(Window *splitwin, uint method, uint size,
169 					   uint wintype, uint rock);
170 
171 	/**
172 	 * Close an existing window
173 	 */
174 	void windowClose(Window *win, StreamResult *result = nullptr);
175 
176 	/**
177 	 * Return the root window
178 	 */
getRoot()179 	Window *getRoot() const {
180 		return _rootWin;
181 	}
182 
183 	/**
184 	 * Gets the focused window
185 	 */
getFocusWindow()186 	Window *getFocusWindow() const {
187 		return _focusWin;
188 	}
189 
190 	/**
191 	 * Setst the focused window
192 	 */
setFocus(Window * win)193 	void setFocus(Window *win) {
194 		_focusWin = win;
195 	}
196 
197 	/**
198 	 * Pick first window which might want input. This is called after every keystroke.
199 	 */
200 	void inputGuessFocus();
201 
202 	/**
203 	 * Handle input keypress
204 	 */
205 	void inputHandleKey(uint key);
206 
207 	/**
208 	 * Handle mouse clicks
209 	 */
210 	void inputHandleClick(const Point &pos);
211 
212 	void selectionChanged();
213 
clearClaimSelect()214 	void clearClaimSelect() {
215 		_claimSelect = false;
216 	}
217 
218 	/**
219 	 * Rearrange windows
220 	 */
221 	void rearrange();
222 
223 	void redraw();
224 
225 	void redrawRect(const Rect &r);
226 
227 	/**
228 	 * Repaint an area of the windows
229 	 */
230 	void repaint(const Rect &box);
231 
232 	/**
233 	 * Get an iterator that will move over the tree
234 	 */
begin()235 	iterator begin() {
236 		return iterator(this, _windowList);
237 	}
238 
239 	/**
240 	 * Returns the end point of window iteration
241 	 */
end()242 	iterator end() {
243 		return iterator(this, nullptr);
244 	}
245 };
246 
247 /**
248  * Used for the static definition of default styles
249  */
250 struct WindowStyleStatic {
251 	FACES font;
252 	byte bg[3];
253 	byte fg[3];
254 	bool reverse;
255 };
256 
257 /**
258  * Window styles
259  */
260 struct WindowStyle {
261 	FACES font;
262 	uint bg;
263 	uint fg;
264 	bool reverse;
265 
266 	/**
267 	 * Constructor
268 	 */
WindowStyleWindowStyle269 	WindowStyle() : font(MONOR), fg(0), bg(0), reverse(false) {}
270 
271 	/**
272 	 * Constructor
273 	 */
274 	WindowStyle(const WindowStyleStatic &src);
275 
276 	/**
277 	 * Equality comparison
278 	 */
279 	bool operator==(const WindowStyle &src) const {
280 		return !memcmp(this, &src, sizeof(WindowStyle));
281 	}
282 
283 	/**
284 	 * Returns true if the font is proportinate
285 	 */
isPropWindowStyle286 	bool isProp() const {
287 		return font == PROPR || font == PROPI || font == PROPB || font == PROPZ;
288 	}
289 
290 	/**
291 	 * Returns true ifont the font is bold
292 	 */
isBoldWindowStyle293 	bool isBold() const {
294 		return font == PROPB || font == PROPZ || font == MONOB || font == MONOZ;
295 	}
296 
297 	/**
298 	 * Returns true ifont the font is italic
299 	 */
isItalicWindowStyle300 	bool isItalic() const {
301 		return font == PROPI || font == PROPZ || font == MONOI || font == MONOZ;
302 	}
303 
304 	/**
305 	 * Returns a font that has the following combination of proportinate, bold, and italic
306 	 */
makeFontWindowStyle307 	static FACES makeFont(bool p, bool b, bool i) {
308 		if (p && !b && !i) return PROPR;
309 		if (p && !b &&  i) return PROPI;
310 		if (p &&  b && !i) return PROPB;
311 		if (p &&  b &&  i) return PROPZ;
312 		if (!p && !b && !i) return MONOR;
313 		if (!p && !b &&  i) return MONOI;
314 		if (!p &&  b && !i) return MONOB;
315 		if (!p &&  b &&  i) return MONOZ;
316 		return PROPR;
317 	}
318 };
319 
320 /**
321  * Window attributes
322  */
323 struct Attributes {
324 	bool fgset      : 1;
325 	bool bgset      : 1;
326 	bool reverse    : 1;
327 	unsigned unused : 1; // needed to pad structure
328 	unsigned style  : 4;
329 	uint fgcolor;
330 	uint bgcolor;
331 	uint hyper;
332 
333 	/**
334 	 * Constructor
335 	 */
AttributesAttributes336 	Attributes() {
337 		clear();
338 	}
339 
340 	/**
341 	 * Clear
342 	 */
343 	void clear();
344 
345 	/**
346 	 * Set the style
347 	 */
setAttributes348 	void set(uint s) {
349 		clear();
350 		style = s;
351 	}
352 
353 	/**
354 	 * Equality comparison
355 	 */
356 	bool operator==(const Attributes &src) const {
357 		return fgset == src.fgset && bgset == src.bgset && reverse == src.reverse
358 			   && style == src.style && fgcolor == src.fgcolor && bgcolor == src.bgcolor
359 			   && hyper == src.hyper;
360 	}
361 	/**
362 	 * Inequality comparison
363 	 */
364 	bool operator!=(const Attributes &src) const {
365 		return fgset != src.fgset || bgset != src.bgset || reverse != src.reverse
366 			   || style != src.style || fgcolor != src.fgcolor || bgcolor != src.bgcolor
367 			   || hyper != src.hyper;
368 	}
369 
370 	/**
371 	 * Return the background color for the current font style
372 	 */
373 	uint attrBg(const WindowStyle *styles);
374 
375 	/**
376 	 * Return the foreground color for the current font style
377 	 */
378 	uint attrFg(const WindowStyle *styles);
379 
380 	/**
381 	 * Get the font for the current font style
382 	 */
attrFontAttributes383 	FACES attrFont(const WindowStyle *styles) const {
384 		return styles[style].font;
385 	}
386 };
387 
388 /**
389  * Window definition
390  */
391 class Window {
392 public:
393 	Windows *_windows;
394 	uint _rock;
395 	uint _type;
396 
397 	Window *_parent;       ///< pair window which contains this one
398 	Window *_next, *_prev; ///< in the big linked list of windows
399 	Rect _bbox;
400 	int _yAdj;
401 
402 	Stream *_stream;       ///< the window stream.
403 	Stream *_echoStream;   ///< the window's echo stream, if any.
404 
405 	bool _lineRequest;
406 	bool _lineRequestUni;
407 	bool _charRequest;
408 	bool _charRequestUni;
409 	bool _mouseRequest;
410 	bool _hyperRequest;
411 	bool _moreRequest;
412 	bool _scrollRequest;
413 	bool _imageLoaded;
414 
415 	uint _echoLineInputBase;
416 	uint *_lineTerminatorsBase;
417 	uint _termCt;
418 
419 	Attributes _attr;
420 	uint _bgColor, _fgColor;
421 
422 	gidispatch_rock_t _dispRock;
423 public:
424 	static bool checkBasicTerminators(uint32 ch);
425 public:
426 	/**
427 	 * Constructor
428 	 */
429 	Window(Windows *windows, uint rock);
430 
431 	/**
432 	 * Destructor
433 	 */
434 	virtual ~Window();
435 
436 	/**
437 	 * Close and delete the window
438 	 */
439 	void close(bool recurse = true);
440 
441 	/**
442 	 * Get the font info structure associated with the window
443 	 */
444 	virtual FontInfo *getFontInfo();
445 
446 	/**
447 	 * Rearranges the window
448 	 */
rearrange(const Rect & box)449 	virtual void rearrange(const Rect &box) {
450 		_bbox = box;
451 	}
452 
453 	/**
454 	 * Set the size of a window
455 	 */
setSize(const Point & newSize)456 	virtual void setSize(const Point &newSize) {
457 		_bbox.setWidth(newSize.x);
458 		_bbox.setHeight(newSize.y);
459 		rearrange(_bbox);
460 	}
461 
462 	/**
463 	 * Sets the position of a window
464 	 */
setPosition(const Point & newPos)465 	virtual void setPosition(const Point &newPos) {
466 		_bbox.moveTo(newPos);
467 		rearrange(_bbox);
468 	}
469 
470 	/**
471 	 * Get window split size within parent pair window
472 	 */
getSplit(uint size,bool vertical)473 	virtual uint getSplit(uint size, bool vertical) const {
474 		return 0;
475 	}
476 
477 	/**
478 	 * Write a character
479 	 */
putCharUni(uint32 ch)480 	virtual void putCharUni(uint32 ch) {}
481 
482 	/**
483 	 * Unput a unicode character
484 	 */
unputCharUni(uint32 ch)485 	virtual bool unputCharUni(uint32 ch) {
486 		return false;
487 	}
488 
489 	/**
490 	 * Get the cursor position
491 	 */
getCursor()492 	virtual Point getCursor() const { return Point(); }
493 
494 	/**
495 	 * Move the cursor
496 	 */
497 	virtual void moveCursor(const Point &newPos);
498 
499 	/**
500 	 * Clear the window
501 	 */
clear()502 	virtual void clear() {}
503 
504 	/**
505 	 * Click the window
506 	 */
click(const Point & newPos)507 	virtual void click(const Point &newPos) {}
508 
509 	/**
510 	 * Prepare for inputing a line
511 	 */
512 	virtual void requestLineEvent(char *buf, uint maxlen, uint initlen);
513 
514 	/**
515 	 * Prepare for inputing a line
516 	 */
517 	virtual void requestLineEventUni(uint32 *buf, uint maxlen, uint initlen);
518 
519 	/**
520 	 * Cancel an input line event
521 	 */
522 	virtual void cancelLineEvent(Event *ev);
523 
524 	/**
525 	 * Cancel a character event
526 	 */
cancelCharEvent()527 	virtual void cancelCharEvent() {}
528 
529 	/**
530 	 * Cancel a mouse event
531 	 */
cancelMouseEvent()532 	virtual void cancelMouseEvent() {}
533 
534 	/**
535 	 * Cancel a hyperlink event
536 	 */
cancelHyperlinkEvent()537 	virtual void cancelHyperlinkEvent() {}
538 
539 	/**
540 	 * Redraw the window
541 	 */
542 	virtual void redraw();
543 
544 	bool imageDraw(uint image, uint align, int val1, int val2);
545 	bool imageDraw(const Common::String &image, uint align, int val1, int val2);
546 
547 	int acceptScroll(uint arg);
548 
549 	bool checkTerminators(uint32 ch);
550 
551 	void setTerminatorsLineEvent(const uint32 *keycodes, uint count);
552 
553 	virtual void acceptReadLine(uint32 arg);
554 
555 	virtual void acceptReadChar(uint arg);
556 
557 	virtual void getArrangement(uint *method, uint *size, Window **keyWin);
558 
559 	virtual void setArrangement(uint method, uint size, Window *keyWin);
560 
561 	virtual void getSize(uint *width, uint *height) const;
562 
563 	virtual void requestCharEvent();
564 
565 	virtual void requestCharEventUni();
566 
setEchoLineEvent(uint val)567 	virtual void setEchoLineEvent(uint val) {}
568 
requestMouseEvent()569 	virtual void requestMouseEvent() {}
570 
requestHyperlinkEvent()571 	virtual void requestHyperlinkEvent() {}
572 
573 	virtual void flowBreak();
574 
575 	virtual void eraseRect(bool whole, const Rect &box);
576 
577 	virtual void fillRect(uint color, const Rect &box);
578 
579 	virtual void setBackgroundColor(uint color);
580 
581 	/**
582 	 * Returns a pointer to the styles for the window
583 	 */
584 	virtual const WindowStyle *getStyles() const;
585 
586 	/**
587 	 * In arbitrary window positioning mode, brings a window to the front of all other windows
588 	 */
589 	void bringToFront();
590 
591 	/**
592 	 * In arbitrary window positioning mode, sends a window to the back of all other windows
593 	 */
594 	void sendToBack();
595 };
596 typedef Window *winid_t;
597 
598 /**
599  * Blank window
600  */
601 class BlankWindow : public Window {
602 public:
603 	/**
604 	 * Constructor
605 	 */
606 	BlankWindow(Windows *windows, uint rock);
607 };
608 
609 /**
610  * Abstract common base for the text window classes
611  */
612 class TextWindow : public Window {
613 public:
614 	/**
615 	 * Constructor
616 	 */
TextWindow(Windows * windows,uint rock)617 	TextWindow(Windows *windows, uint rock) : Window(windows, rock) {}
618 };
619 
620 } // End of namespace Glk
621 
622 #endif
623