aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/xlaunch/window/window.cc
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/xlaunch/window/window.cc')
-rw-r--r--xorg-server/hw/xwin/xlaunch/window/window.cc284
1 files changed, 284 insertions, 0 deletions
diff --git a/xorg-server/hw/xwin/xlaunch/window/window.cc b/xorg-server/hw/xwin/xlaunch/window/window.cc
new file mode 100644
index 000000000..cca3a485a
--- /dev/null
+++ b/xorg-server/hw/xwin/xlaunch/window/window.cc
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2005 Alexander Gottwald
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#include "window.h"
+#include "util.h"
+#include <stdio.h>
+#include <stdexcept>
+
+CWindow::CWindowClass CWindow::windowClass("CWINDOWCLASS", DefWindowProc);
+
+CWindow::CWindowClass::CWindowClass(const char *_name, WNDPROC _wndproc) :
+ wndproc(_wndproc), atom(0), classname(_name)
+{
+ Register();
+}
+
+CWindow::CWindowClass::~CWindowClass()
+{
+ UnregisterClass(classname.c_str(), GetModuleHandle(NULL));
+}
+
+void CWindow::CWindowClass::Register()
+{
+ WNDCLASSEX wndclass;
+ memset(&wndclass, 0, sizeof(wndclass));
+ wndclass.cbSize = sizeof(wndclass);
+ wndclass.style = 0;
+ wndclass.lpfnWndProc = wndproc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = GetModuleHandle(NULL);
+ wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = classname.c_str();
+ wndclass.hIconSm = NULL;
+ atom = RegisterClassEx(&wndclass);
+ if (atom == 0)
+ throw win32_error("RegisterClassEx failed");
+}
+
+CWindow::CWindow(const char *_title) : title(_title), hwnd(NULL), parent(NULL), bounds(), owndproc(NULL), showing(FALSE)
+{
+ style = WS_CHILD;
+ exstyle = 0;
+}
+
+HWND CWindow::CreateWindowHandle()
+{
+ HWND ret = CreateWindowEx(
+ exstyle,
+ GetClassName(),
+ title.c_str(),
+ style,
+ bounds.left,
+ bounds.top,
+ bounds.width,
+ bounds.height,
+ parent,
+ NULL,
+ GetModuleHandle(NULL),
+ 0
+ );
+ if (ret == NULL)
+ throw win32_error("CreateWindowEx failed");
+ return ret;
+}
+
+void CWindow::Create()
+{
+ if (hwnd != NULL)
+ return;
+ hwnd = CreateWindowHandle();
+ if (hwnd == NULL)
+ throw win32_error("Could not create window");
+
+ // Reset the error code
+ DWORD err = 0;
+ SetLastError(err);
+
+ // Attach the object reference to the window handle
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
+ err = GetLastError();
+ if (err != 0)
+ throw win32_error("SetWindowLongPtr failed",err);
+
+ // Set the window proc
+ owndproc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WindowProc);
+ err = GetLastError();
+ if (err != 0)
+ throw win32_error("SetWindowLongPtr failed",err);
+}
+
+const char *CWindow::GetClassName()
+{
+ return windowClass.GetClassName();
+}
+
+LRESULT CALLBACK CWindow::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ MessageDebug::debug(hwnd, uMsg, wParam, lParam, __FUNCTION__);
+ CWindow* window = (CWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if (window != NULL)
+ return window->Dispatch(hwnd, uMsg, wParam, lParam);
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+LRESULT CWindow::Dispatch(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_SIZE:
+ bounds.width = LOWORD(lParam);
+ bounds.height = LOWORD(lParam);
+ break;
+ case WM_MOVE:
+ bounds.left = LOWORD(lParam);
+ bounds.top = LOWORD(lParam);
+ break;
+ case WM_DESTROY:
+ showing = FALSE;
+ break;
+ }
+ if (owndproc)
+ return CallWindowProc(owndproc, hwnd, uMsg, wParam, lParam);
+ else
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+void CWindow::Show()
+{
+ if (hwnd == NULL)
+ Create();
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+}
+
+int CWindow::ShowModal()
+{
+ MSG msg;
+ BOOL bRet;
+ showing = TRUE;
+ Show();
+
+ while( showing && (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
+ {
+ if (bRet == -1)
+ {
+ // handle the error and possibly exit
+ }
+ else
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ return 0;
+}
+
+void CWindow::SetLeft(int left)
+{
+ bounds.left = left;
+ if (hwnd)
+ if (!SetWindowPos(hwnd, NULL,
+ bounds.left, bounds.top,
+ 0, 0,
+ SWP_NOZORDER | SWP_NOSIZE))
+ throw win32_error("SetWindowPos failed");
+}
+
+void CWindow::SetTop(int top)
+{
+ bounds.top = top;
+ if (hwnd)
+ if (!SetWindowPos(hwnd, NULL,
+ bounds.left, bounds.top,
+ 0, 0,
+ SWP_NOZORDER | SWP_NOSIZE))
+ throw win32_error("SetWindowPos failed");
+}
+
+void CWindow::SetWidth(int width)
+{
+ bounds.width = width;
+ if (hwnd)
+ if (!SetWindowPos(hwnd, NULL,
+ 0, 0,
+ bounds.width, bounds.height,
+ SWP_NOZORDER | SWP_NOMOVE))
+ throw win32_error("SetWindowPos failed");
+}
+void CWindow::SetHeight(int height)
+{
+ bounds.height = height;
+ if (hwnd)
+ if (!SetWindowPos(hwnd, NULL,
+ 0, 0,
+ bounds.width, bounds.height,
+ SWP_NOZORDER | SWP_NOMOVE))
+ throw win32_error("SetWindowPos failed");
+}
+
+void CWindow::SetBounds(int left, int top, int width, int height)
+{
+ bounds = CBoundary(left, top, width, height);
+ if (hwnd)
+ if (!SetWindowPos(hwnd, NULL,
+ bounds.left, bounds.top,
+ bounds.width, bounds.height,
+ SWP_NOZORDER))
+ throw win32_error("SetWindowPos failed");
+}
+
+void CWindow::SetBounds(const RECT &rect)
+{
+ bounds = rect;
+ if (hwnd)
+ if (!SetWindowPos(hwnd, NULL,
+ bounds.left, bounds.top,
+ bounds.width, bounds.height,
+ SWP_NOZORDER))
+ throw win32_error("SetWindowPos failed");
+}
+
+HWND CWindow::GetHandle()
+{
+ if (hwnd == NULL)
+ Create();
+ return hwnd;
+}
+
+void CWindow::SetParent(CWindow *window)
+{
+ parent = window->GetHandle();
+ if (hwnd != NULL)
+ if (::SetParent(hwnd, parent) == NULL)
+ throw win32_error("SetParent failed");
+
+}
+
+void CWindow::SetStyle(DWORD style)
+{
+ this->style = style;
+ SetLastError(0);
+ if (hwnd)
+ SetWindowLong(hwnd, GWL_STYLE, style);
+ int err = GetLastError();
+ if (err != 0)
+ throw win32_error("SetWindowLong failed", err);
+}
+
+void CWindow::SetExStyle(DWORD exstyle)
+{
+ this->exstyle = exstyle;
+ SetLastError(0);
+ if (hwnd)
+ SetWindowLong(hwnd, GWL_EXSTYLE, exstyle);
+ int err = GetLastError();
+ if (err != 0)
+ throw win32_error("SetWindowWLong failed", err);
+}