aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2018-10-24 21:39:17 -0700
committerPaul Gilbert2018-12-08 19:05:59 -0800
commit3d8626081ce6a03d533009e07699b397f70b834b (patch)
tree419ac75e84c07549b2a42a668ae8d331006a7a18 /engines
parentfdfb1a55028400c976a7b0aa2df2e8cee0428b7d (diff)
downloadscummvm-rg350-3d8626081ce6a03d533009e07699b397f70b834b.tar.gz
scummvm-rg350-3d8626081ce6a03d533009e07699b397f70b834b.tar.bz2
scummvm-rg350-3d8626081ce6a03d533009e07699b397f70b834b.zip
GLK: Added window closing, some structures cleanup
Diffstat (limited to 'engines')
-rw-r--r--engines/gargoyle/events.h9
-rw-r--r--engines/gargoyle/glk.cpp8
-rw-r--r--engines/gargoyle/glk_types.h13
-rw-r--r--engines/gargoyle/streams.h1
-rw-r--r--engines/gargoyle/window_text_buffer.cpp8
-rw-r--r--engines/gargoyle/window_text_grid.cpp8
-rw-r--r--engines/gargoyle/windows.cpp102
-rw-r--r--engines/gargoyle/windows.h10
8 files changed, 122 insertions, 37 deletions
diff --git a/engines/gargoyle/events.h b/engines/gargoyle/events.h
index 4ee94707ea..939e691f78 100644
--- a/engines/gargoyle/events.h
+++ b/engines/gargoyle/events.h
@@ -93,15 +93,16 @@ enum Keycode {
* Event structure
*/
struct Event {
- EvType _type;
- Window *_window;
- uint32 _val1, _val2;
+ EvType type;
+ Window *window;
+ uint32 val1, val2;
/**
* Constructor
*/
- Event() : _type(evtype_None), _window(nullptr), _val1(0), _val2(0) {}
+ Event() : type(evtype_None), window(nullptr), val1(0), val2(0) {}
};
+typedef Event event_t;
class Events {
public:
diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp
index ba62de1573..26b8349d75 100644
--- a/engines/gargoyle/glk.cpp
+++ b/engines/gargoyle/glk.cpp
@@ -73,7 +73,13 @@ winid_t Glk::glk_window_open(winid_t split, glui32 method, glui32 size, glui32 w
}
void Glk::glk_window_close(winid_t win, stream_result_t *result) {
- // TODO
+ _windows->_forceRedraw = true;
+
+ if (!win) {
+ warning("glk_window_close: invalid ref");
+ } else {
+ _windows->windowClose(win, result);
+ }
}
void Glk::glk_window_get_size(winid_t win, glui32 *widthptr, glui32 *heightptr) {
diff --git a/engines/gargoyle/glk_types.h b/engines/gargoyle/glk_types.h
index a25a413221..81d05ac391 100644
--- a/engines/gargoyle/glk_types.h
+++ b/engines/gargoyle/glk_types.h
@@ -220,19 +220,6 @@ enum ImageAlign {
#endif /* GLK_MODULE_IMAGE */
-struct event_struct {
- glui32 type;
- Window *win;
- glui32 val1, val2;
-};
-typedef event_struct event_t;
-
-struct stream_result_struct {
- glui32 readcount;
- glui32 writecount;
-};
-typedef stream_result_struct stream_result_t;
-
#ifdef GLK_MODULE_DATETIME
struct glktimeval_struct {
diff --git a/engines/gargoyle/streams.h b/engines/gargoyle/streams.h
index 82d6465eb2..51ab484eb7 100644
--- a/engines/gargoyle/streams.h
+++ b/engines/gargoyle/streams.h
@@ -36,6 +36,7 @@ struct StreamResult {
uint32 _readCount;
uint32 _writeCount;
};
+typedef StreamResult stream_result_t;
/**
* Base class for streams
diff --git a/engines/gargoyle/window_text_buffer.cpp b/engines/gargoyle/window_text_buffer.cpp
index b940fe60a7..a32a64f45a 100644
--- a/engines/gargoyle/window_text_buffer.cpp
+++ b/engines/gargoyle/window_text_buffer.cpp
@@ -756,10 +756,10 @@ void TextBufferWindow::cancelLineEvent(Event *ev) {
_attr = _origAttr;
- ev->_type = evtype_LineInput;
- ev->_window = this;
- ev->_val1 = len;
- ev->_val2 = 0;
+ ev->type = evtype_LineInput;
+ ev->window = this;
+ ev->val1 = len;
+ ev->val2 = 0;
_lineRequest = false;
_lineRequestUni = false;
diff --git a/engines/gargoyle/window_text_grid.cpp b/engines/gargoyle/window_text_grid.cpp
index bf0f39cb93..d9550bfab8 100644
--- a/engines/gargoyle/window_text_grid.cpp
+++ b/engines/gargoyle/window_text_grid.cpp
@@ -360,10 +360,10 @@ void TextGridWindow::cancelLineEvent(Event *ev) {
_curX = 0;
_attr = _origAttr;
- ev->_type = evtype_LineInput;
- ev->_window = this;
- ev->_val1 = _inLen;
- ev->_val2 = 0;
+ ev->type = evtype_LineInput;
+ ev->window = this;
+ ev->val1 = _inLen;
+ ev->val2 = 0;
_lineRequest = false;
_lineRequestUni = false;
diff --git a/engines/gargoyle/windows.cpp b/engines/gargoyle/windows.cpp
index 6fb834d381..42db6f72f6 100644
--- a/engines/gargoyle/windows.cpp
+++ b/engines/gargoyle/windows.cpp
@@ -73,7 +73,7 @@ Windows::Windows(Graphics::Screen *screen) : _screen(screen), _windowList(nullpt
Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size,
glui32 wintype, glui32 rock) {
Window *newwin, *oldparent;
- PairWindow *pairwin;
+ PairWindow *pairWin;
glui32 val;
_forceRedraw = true;
@@ -125,24 +125,24 @@ Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size,
if (!splitwin) {
_rootWin = newwin;
} else {
- // create pairwin, with newwin as the key
- pairwin = newPairWindow(method, newwin, size);
- pairwin->_child1 = splitwin;
- pairwin->_child2 = newwin;
+ // create pairWin, with newwin as the key
+ pairWin = newPairWindow(method, newwin, size);
+ pairWin->_child1 = splitwin;
+ pairWin->_child2 = newwin;
- splitwin->_parent = pairwin;
- newwin->_parent = pairwin;
- pairwin->_parent = oldparent;
+ splitwin->_parent = pairWin;
+ newwin->_parent = pairWin;
+ pairWin->_parent = oldparent;
if (oldparent) {
PairWindow *parentWin = dynamic_cast<PairWindow *>(oldparent);
assert(parentWin);
if (parentWin->_child1 == splitwin)
- parentWin->_child1 = pairwin;
+ parentWin->_child1 = pairWin;
else
- parentWin->_child2 = pairwin;
+ parentWin->_child2 = pairWin;
} else {
- _rootWin = pairwin;
+ _rootWin = pairWin;
}
}
@@ -151,6 +151,62 @@ Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size,
return newwin;
}
+void Windows::windowClose(Window *win, StreamResult *result) {
+ if (win == _rootWin || win->_parent == nullptr) {
+ // Close the root window, which means all windows.
+ _rootWin = nullptr;
+
+ // Begin (simpler) closation
+ win->_stream->fillResult(result);
+ win->close(true);
+ } else {
+ // Have to jigger parent
+ Window *sibWin;
+ PairWindow *pairWin = dynamic_cast<PairWindow *>(win->_parent);
+ PairWindow *grandparWin;
+
+ if (win == pairWin->_child1) {
+ sibWin = pairWin->_child2;
+ } else if (win == pairWin->_child2) {
+ sibWin = pairWin->_child1;
+ } else {
+ warning("windowClose: window tree is corrupted");
+ return;
+ }
+
+ grandparWin = dynamic_cast<PairWindow *>(pairWin->_parent);
+ if (!grandparWin) {
+ _rootWin = sibWin;
+ sibWin->_parent = nullptr;
+ } else {
+ if (grandparWin->_child1 == pairWin)
+ grandparWin->_child1 = sibWin;
+ else
+ grandparWin->_child2 = sibWin;
+ sibWin->_parent = grandparWin;
+ }
+
+ // Begin closation
+ win->_stream->fillResult(result);
+
+ // Close the child window (and descendants), so that key-deletion can
+ // crawl up the tree to the root window.
+ win->close(true);
+
+ // This probably isn't necessary, but the child *is* gone, so just in case.
+ if (win == pairWin->_child1)
+ pairWin->_child1 = nullptr;
+ else if (win == pairWin->_child2)
+ pairWin->_child2 = nullptr;
+
+ // Now we can delete the parent pair.
+ pairWin->close(false);
+
+ // Sort out the arrangements
+ rearrange();
+ }
+}
+
Window *Windows::newWindow(glui32 type, glui32 rock) {
Window *win;
@@ -355,6 +411,30 @@ Window::~Window() {
next->_prev = prev;
}
+void Window::close(bool recurse) {
+ if (_windows->getFocusWindow() == this)
+ // Focused window is being removed
+ _windows->setFocus(nullptr);
+
+ for (Window *wx = _parent; wx; wx = wx->_parent) {
+ PairWindow *pairWin = dynamic_cast<PairWindow *>(wx);
+
+ if (pairWin && pairWin->_key == this) {
+ pairWin->_key = nullptr;
+ pairWin->_keyDamage = true;
+ }
+ }
+
+ PairWindow *pairWin = dynamic_cast<PairWindow *>(this);
+ if (pairWin) {
+ pairWin->_child1->close(recurse);
+ pairWin->_child2->close(recurse);
+ }
+
+ // Finally, delete the window
+ delete this;
+}
+
void Window::cancelLineEvent(Event *ev) {
Event dummyEv;
if (!ev)
diff --git a/engines/gargoyle/windows.h b/engines/gargoyle/windows.h
index ba9cb9210d..f52bbdd155 100644
--- a/engines/gargoyle/windows.h
+++ b/engines/gargoyle/windows.h
@@ -135,6 +135,11 @@ public:
glui32 wintype, glui32 rock);
/**
+ * Close an existing window
+ */
+ void windowClose(Window *win, StreamResult *result = nullptr);
+
+ /**
* Return the root window
*/
Window *getRoot() const { return _rootWin; }
@@ -284,6 +289,11 @@ public:
virtual ~Window();
/**
+ * Close and delete the window
+ */
+ void close(bool recurse = true);
+
+ /**
* Rearranges the window
*/
virtual void rearrange(const Common::Rect &box) { _bbox = box; }