--- /dev/null
- case WM_NCDESTROY:
+/*
+ * Copyright 2003, 2004, 2005 Martin Fuchs
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+ //
+ // Explorer clone
+ //
+ // window.cpp
+ //
+ // Martin Fuchs, 23.07.2003
+ //
+
+
+#include <precomp.h>
+
+#include "../resource.h" // for ID_GO_BACK, ...
+
+
+WindowClass::WindowClass(LPCTSTR classname, UINT style_, WNDPROC wndproc)
+{
+ memset(this, 0, sizeof(WNDCLASSEX));
+
+ cbSize = sizeof(WNDCLASSEX);
+ style = style_;
+ hInstance = g_Globals._hInstance;
+ hCursor = LoadCursor(0, IDC_ARROW);
+
+ lpszClassName = classname;
+ lpfnWndProc = wndproc;
+
+ _atomClass = 0;
+}
+
+
+IconWindowClass::IconWindowClass(LPCTSTR classname, UINT nid, UINT style, WNDPROC wndproc)
+ : WindowClass(classname, style, wndproc)
+{
+ hIcon = ResIcon(nid);
+ hIconSm = SmallIcon(nid);
+}
+
+
+Window::WindowMap Window::s_wnd_map;
+
+Window::CREATORFUNC Window::s_window_creator = NULL;
+const void* Window::s_new_info = NULL;
+
+HHOOK Window::s_hcbtHook = 0;
+
+
+Window::StaticWindowData& Window::GetStaticWindowData()
+{
+ static StaticWindowData s_initialized_data;
+
+ return s_initialized_data;
+}
+
+
+Window::Window(HWND hwnd)
+ : WindowHandle(hwnd)
+{
+ Lock lock(GetStaticWindowData()._map_crit_sect); // protect access to s_wnd_map
+
+ s_wnd_map[_hwnd] = this;
+}
+
+Window::~Window()
+{
+ Lock lock(GetStaticWindowData()._map_crit_sect); // protect access to s_wnd_map
+
+ s_wnd_map.erase(_hwnd);
+}
+
+
+HWND Window::Create(CREATORFUNC creator, DWORD dwExStyle,
+ LPCTSTR lpClassName, LPCTSTR lpWindowName,
+ DWORD dwStyle, int x, int y, int w, int h,
+ HWND hwndParent, HMENU hMenu/*, LPVOID lpParam*/)
+{
+ Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
+
+ s_window_creator = creator;
+ s_new_info = NULL;
+
+ return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle,
+ x, y, w, h,
+ hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/);
+}
+
+HWND Window::Create(CREATORFUNC_INFO creator, const void* info, DWORD dwExStyle,
+ LPCTSTR lpClassName, LPCTSTR lpWindowName,
+ DWORD dwStyle, int x, int y, int w, int h,
+ HWND hwndParent, HMENU hMenu/*, LPVOID lpParam*/)
+{
+ Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
+
+ s_window_creator = (CREATORFUNC) creator;
+ s_new_info = info;
+
+ return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle,
+ x, y, w, h,
+ hwndParent, hMenu, g_Globals._hInstance, 0/*lpParam*/);
+}
+
+
+Window* Window::create_mdi_child(const ChildWndInfo& info, const MDICREATESTRUCT& mcs, CREATORFUNC_INFO creator)
+{
+ Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
+
+ s_window_creator = (CREATORFUNC) creator;
+ s_new_info = &info;
+
+ s_hcbtHook = SetWindowsHookEx(WH_CBT, MDICBTHookProc, 0, GetCurrentThreadId());
+
+ HWND hwnd = (HWND) SendMessage(info._hmdiclient, WM_MDICREATE, 0, (LPARAM)&mcs);
+
+ // end hook in case it's not already done
+ if (s_hcbtHook)
+ UnhookWindowsHookEx(s_hcbtHook);
+
+ Window* child = get_window(hwnd);
+ s_new_info = NULL;
+
+ if (child && (!hwnd || !child->_hwnd))
+ child = NULL;
+
+ return child;
+}
+
+LRESULT CALLBACK Window::MDICBTHookProc(int code, WPARAM wparam, LPARAM lparam)
+{
+ if (code == HCBT_CREATEWND) {
+ UnhookWindowsHookEx(s_hcbtHook); // use the hook only for the first created window
+ s_hcbtHook = 0;
+
+ HWND hwnd = (HWND)wparam;
+
+ // create Window controller and associate it with the window handle
+ Window* child = get_window(hwnd);
+
+ if (!child)
+ child = create_controller(hwnd);
+ }
+
+ return CallNextHookEx(s_hcbtHook, code, wparam, lparam);
+}
+
+
+/*
+Window* Window::create_property_sheet(PropertySheetDialog* ppsd, CREATORFUNC creator, const void* info)
+{
+ Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
+
+ s_window_creator = creator;
+ s_new_info = info;
+
+ s_hcbtHook = SetWindowsHookEx(WH_CBT, PropSheetCBTHookProc, 0, GetCurrentThreadId());
+
+ HWND hwnd = (HWND) PropertySheet(ppsd);
+
+ UnhookWindowsHookEx(s_hcbtHook);
+
+ Window* child = get_window(hwnd);
+ s_new_info = NULL;
+
+ if (child && (!hwnd || !child->_hwnd))
+ child = NULL;
+
+ return child;
+}
+*/
+
+LRESULT CALLBACK Window::PropSheetCBTHookProc(int code, WPARAM wparam, LPARAM lparam)
+{
+ if (code == HCBT_CREATEWND) {
+ HWND hwnd = (HWND)wparam;
+
+ // create Window controller and associate it with the window handle
+ Window* child = get_window(hwnd);
+
+ if (!child)
+ child = create_controller(hwnd);
+ }
+
+ return CallNextHookEx(s_hcbtHook, code, wparam, lparam);
+}
+
+
+ /// get window controller from window handle
+
+Window* Window::get_window(HWND hwnd)
+{
+ {
+ Lock lock(GetStaticWindowData()._map_crit_sect); // protect access to s_wnd_map
+
+ WindowMap::const_iterator found = s_wnd_map.find(hwnd);
+
+ if (found!=s_wnd_map.end())
+ return found->second;
+ }
+
+ return NULL;
+}
+
+
+ /// create controller for a new window
+
+Window* Window::create_controller(HWND hwnd)
+{
+ if (s_window_creator) { // protect for recursion and create the window object only for the first window
+ Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
+
+ const void* info = s_new_info;
+ s_new_info = NULL;
+
+ CREATORFUNC window_creator = s_window_creator;
+ s_window_creator = NULL;
+
+ if (info)
+ return CREATORFUNC_INFO(window_creator)(hwnd, info);
+ else
+ return CREATORFUNC(window_creator)(hwnd);
+ }
+
+ return NULL;
+}
+
+
+LRESULT Window::Init(LPCREATESTRUCT pcs)
+{
+ return 0;
+}
+
+
+LRESULT CALLBACK Window::WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ Window* pThis = get_window(hwnd);
+
+ if (!pThis)
+ pThis = create_controller(hwnd);
+
+ if (pThis) {
+ switch(nmsg) {
+ case WM_COMMAND:
+ return pThis->Command(LOWORD(wparam), HIWORD(wparam));
+
+ case WM_NOTIFY:
+ return pThis->Notify(wparam, (NMHDR*)lparam);
+
+ case WM_NOTIFYFORMAT:
+ return NFR_CURRENT;
+
+ case WM_CREATE:
+ return pThis->Init((LPCREATESTRUCT)lparam);
+
++ case WM_NCDESTROY:
+ delete pThis;
+ return 0;
+
+ default:
+ return pThis->WndProc(nmsg, wparam, lparam);
+ }
+ }
+ else
+ return DefWindowProc(hwnd, nmsg, wparam, lparam);
+}
+
+LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ return DefWindowProc(_hwnd, nmsg, wparam, lparam);
+}
+
+int Window::Command(int id, int code)
+{
+ return 1; // no command handler found
+}
+
+int Window::Notify(int id, NMHDR* pnmh)
+{
+ return 0;
+}
+
+void Window::CancelModes()
+{
+ PostMessage(HWND_BROADCAST, WM_CANCELMODE, 0, 0);
+}
+
+
+SubclassedWindow::SubclassedWindow(HWND hwnd)
+ : super(hwnd)
+{
+ _orgWndProc = SubclassWindow(_hwnd, SubclassedWndProc);
+
+ if (!_orgWndProc)
+ delete this;
+}
+
+LRESULT CALLBACK SubclassedWindow::SubclassedWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ SubclassedWindow* pThis = GET_WINDOW(SubclassedWindow, hwnd);
+ assert(pThis);
+
+ if (pThis) {
+ switch(nmsg) {
+ case WM_COMMAND:
+ if (!pThis->Command(LOWORD(wparam), HIWORD(wparam)))
+ return 0;
+ break;
+
+ case WM_NOTIFY:
+ return pThis->Notify(wparam, (NMHDR*)lparam);
+
+ case WM_NOTIFYFORMAT:
+ return NFR_CURRENT;
+
+ case WM_CREATE:
+ return pThis->Init((LPCREATESTRUCT)lparam);
+
+ case WM_NCDESTROY:
+ delete pThis;
+ return 0;
+
+ default:
+ return pThis->WndProc(nmsg, wparam, lparam);
+ }
+ }
+
+ return CallWindowProc(pThis->_orgWndProc, hwnd, nmsg, wparam, lparam);
+}
+
+LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ return CallWindowProc(_orgWndProc, _hwnd, nmsg, wparam, lparam);
+}
+
+int SubclassedWindow::Command(int id, int code)
+{
+ return 1; // no command handler found
+}
+
+int SubclassedWindow::Notify(int id, NMHDR* pnmh)
+{
+ return CallWindowProc(_orgWndProc, _hwnd, WM_NOTIFY, id, (LPARAM)pnmh);
+}
+
+
+ChildWindow::ChildWindow(HWND hwnd, const ChildWndInfo& info)
+ : super(hwnd),
+ _hwndFrame(GetParent(info._hmdiclient))
+{
+ _focus_pane = 0;
+ _split_pos = DEFAULT_SPLIT_POS;
+ _last_split = DEFAULT_SPLIT_POS;
+}
+
+
+ChildWindow* ChildWindow::create(const ChildWndInfo& info, const RECT& rect, CREATORFUNC_INFO creator,
+ LPCTSTR classname, LPCTSTR title, DWORD style)
+{
+ MDICREATESTRUCT mcs;
+
+ mcs.szClass = classname;
+ mcs.szTitle = title;
+ mcs.hOwner = g_Globals._hInstance;
+ mcs.x = rect.left,
+ mcs.y = rect.top;
+ mcs.cx = rect.right - rect.left;
+ mcs.cy = rect.bottom - rect.top;
+ mcs.style = style;
+ mcs.lParam = 0;
+
+ return static_cast<ChildWindow*>(create_mdi_child(info, mcs, creator));
+}
+
+
+LRESULT ChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ switch(nmsg) {
+ case WM_PAINT: {
+ RECT rc;
+ PaintCanvas canvas(_hwnd);
+ ClientRect rt(_hwnd);
+ rt.left = _split_pos-SPLIT_WIDTH/2;
+ rt.right = _split_pos+SPLIT_WIDTH/2+1;
+ HBRUSH lastBrush = SelectBrush(canvas, GetStockBrush(COLOR_SPLITBAR));
+ Rectangle(canvas, rt.left, rt.top-1, rt.right, rt.bottom+1);
+ SetRect(&rc, rt.left, rt.top-1, rt.right, rt.bottom+1);
+ DrawEdge(canvas, &rc, EDGE_RAISED, BF_RECT);
+ SelectObject(canvas, lastBrush);
+ break;}
+
+ case WM_SETCURSOR:
+ if (LOWORD(lparam) == HTCLIENT) {
+ POINT pt;
+ GetCursorPos(&pt);
+ ScreenToClient(_hwnd, &pt);
+
+ if (pt.x>=_split_pos-SPLIT_WIDTH/2 && pt.x<_split_pos+SPLIT_WIDTH/2+1) {
+ SetCursor(LoadCursor(0, IDC_SIZEWE));
+ return TRUE;
+ }
+ }
+ goto def;
+
+ case WM_SIZE:
+ if (wparam != SIZE_MINIMIZED)
+ resize_children(LOWORD(lparam), HIWORD(lparam));
+ goto def;
+
+ case WM_GETMINMAXINFO:
+ DefMDIChildProc(_hwnd, nmsg, wparam, lparam);
+
+ {LPMINMAXINFO lpmmi = (LPMINMAXINFO)lparam;
+
+ lpmmi->ptMaxTrackSize.x <<= 1; // 2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN
+ lpmmi->ptMaxTrackSize.y <<= 1; // 2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN
+ break;}
+
+ case WM_LBUTTONDOWN: {
+ int x = GET_X_LPARAM(lparam);
+
+ ClientRect rt(_hwnd);
+
+ if (x>=_split_pos-SPLIT_WIDTH/2 && x<_split_pos+SPLIT_WIDTH/2+1) {
+ _last_split = _split_pos;
+ SetCapture(_hwnd);
+ }
+
+ break;}
+
+ case WM_LBUTTONUP:
+ if (GetCapture() == _hwnd)
+ ReleaseCapture();
+ break;
+
+ case WM_KEYDOWN:
+ if (wparam == VK_ESCAPE)
+ if (GetCapture() == _hwnd) {
+ _split_pos = _last_split;
+ ClientRect rt(_hwnd);
+ resize_children(rt.right, rt.bottom);
+ _last_split = -1;
+ ReleaseCapture();
+ SetCursor(LoadCursor(0, IDC_ARROW));
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ if (GetCapture() == _hwnd) {
+ int x = GET_X_LPARAM(lparam);
+
+ ClientRect rt(_hwnd);
+
+ if (x>=0 && x<rt.right) {
+ _split_pos = x;
+ resize_children(rt.right, rt.bottom);
+ rt.left = x-SPLIT_WIDTH/2;
+ rt.right = x+SPLIT_WIDTH/2+1;
+ InvalidateRect(_hwnd, &rt, FALSE);
+ UpdateWindow(_left_hwnd);
+ UpdateWindow(_hwnd);
+ UpdateWindow(_right_hwnd);
+ }
+ }
+ break;
+
+ case PM_DISPATCH_COMMAND:
+ switch(LOWORD(wparam)) {
+ case ID_GO_BACK:
+ if (!_url_history.empty()) {
+ const String& url = jump_to_int(_url_history.top());
+
+ if (jump_to_int(url))
+ set_url(url);
+
+ _url_history.pop();
+ }
+ break;
+
+ case ID_GO_FORWARD:
+ //@@
+ break;
+
+ case ID_GO_UP:
+ ///@todo
+ break;
+
+ case ID_GO_HOME:
+ //@@
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+
+ case WM_MDIACTIVATE:
+ if ((HWND)lparam == _hwnd) {
+ SendMessage(_hwndFrame, PM_SETSTATUSTEXT, 0, (LPARAM)_statusText.c_str());
+ SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)_url.c_str());
+ }
+ break;
+
+ case PM_JUMP_TO_URL:
+ return go_to((LPCTSTR)lparam)? TRUE: FALSE;
+
+ default: def:
+ return DefMDIChildProc(_hwnd, nmsg, wparam, lparam);
+ }
+
+ return 0;
+}
+
+
+void ChildWindow::resize_children(int cx, int cy)
+{
+ HDWP hdwp = BeginDeferWindowPos(2);
+ RECT rt;
+
+ rt.left = 0;
+ rt.top = 0;
+ rt.right = cx;
+ rt.bottom = cy;
+
+ if (_left_hwnd) {
+ cx = _split_pos + SPLIT_WIDTH/2;
+
+ hdwp = DeferWindowPos(hdwp, _left_hwnd, 0, rt.left, rt.top, _split_pos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
+ } else {
+ _split_pos = 0;
+ cx = 0;
+ }
+
+ if (_right_hwnd)
+ hdwp = DeferWindowPos(hdwp, _right_hwnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
+
+ EndDeferWindowPos(hdwp);
+}
+
+
+bool ChildWindow::go_to(LPCTSTR url)
+{
+ const String& url_str = jump_to_int(url);
+
+ if (!url_str.empty()) {
+ set_url(url_str);
+
+ _url_history.push(url_str);
+
+ return true;
+ } else
+ return false;
+}
+
+void ChildWindow::set_url(LPCTSTR url)
+{
+ if (_url != url) {
+ _url = url;
+
+ SendMessage(_hwndFrame, PM_URL_CHANGED, 0, (LPARAM)url);
+ }
+}
+
+
+WindowSet Window::s_pretranslate_windows;
+
+void Window::register_pretranslate(HWND hwnd)
+{
+ s_pretranslate_windows.insert(hwnd);
+}
+
+void Window::unregister_pretranslate(HWND hwnd)
+{
+ s_pretranslate_windows.erase(hwnd);
+}
+
+BOOL Window::pretranslate_msg(LPMSG pmsg)
+{
+ for(WindowSet::const_iterator it=Window::s_pretranslate_windows.begin(); it!=s_pretranslate_windows.end(); ++it)
+ if (SendMessage(*it, PM_TRANSLATE_MSG, 0, (LPARAM)pmsg))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+WindowSet Window::s_dialogs;
+
+void Window::register_dialog(HWND hwnd)
+{
+ s_dialogs.insert(hwnd);
+}
+
+void Window::unregister_dialog(HWND hwnd)
+{
+ s_dialogs.erase(hwnd);
+}
+
+BOOL Window::dispatch_dialog_msg(MSG* pmsg)
+{
+ for(WindowSet::const_iterator it=Window::s_dialogs.begin(); it!=s_dialogs.end(); ++it)
+ if (IsDialogMessage(*it, pmsg))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+int Window::MessageLoop()
+{
+ MSG msg;
+
+ while(GetMessage(&msg, 0, 0, 0)) {
+ try {
+ if (pretranslate_msg(&msg))
+ continue;
+
+ if (dispatch_dialog_msg(&msg))
+ continue;
+
+ TranslateMessage(&msg);
+
+ try {
+ DispatchMessage(&msg);
+ } catch(COMException& e) {
+ HandleException(e, 0);
+ }
+ } catch(COMException& e) {
+ HandleException(e, 0);
+ }
+ }
+
+ return msg.wParam;
+}
+
+
+LRESULT Window::SendParent(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ HWND parent = GetParent(_hwnd);
+
+ if (!parent)
+ return 0;
+
+ return SendMessage(parent, nmsg, wparam, lparam);
+}
+
+LRESULT Window::PostParent(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ HWND parent = GetParent(_hwnd);
+
+ if (!parent)
+ return 0;
+
+ return PostMessage(parent, nmsg, wparam, lparam);
+}
+
+
+PreTranslateWindow::PreTranslateWindow(HWND hwnd)
+ : super(hwnd)
+{
+ register_pretranslate(hwnd);
+}
+
+PreTranslateWindow::~PreTranslateWindow()
+{
+ unregister_pretranslate(_hwnd);
+}
+
+
+Dialog::Dialog(HWND hwnd)
+ : super(hwnd)
+{
+ register_dialog(hwnd);
+}
+
+Dialog::~Dialog()
+{
+ unregister_dialog(_hwnd);
+}
+
+int Dialog::DoModal(UINT nid, CREATORFUNC creator, HWND hwndParent)
+{
+ Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
+
+ s_window_creator = creator;
+ s_new_info = NULL;
+
+ ///@todo call Window::pretranslate_msg()
+
+ return DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(nid), hwndParent, DialogProc, 0/*lpParam*/);
+}
+
+int Dialog::DoModal(UINT nid, CREATORFUNC_INFO creator, const void* info, HWND hwndParent)
+{
+ Lock lock(GetStaticWindowData()._create_crit_sect); // protect access to s_window_creator and s_new_info
+
+ s_window_creator = (CREATORFUNC) creator;
+ s_new_info = NULL;
+
+ ///@todo call Window::pretranslate_msg()
+
+ return DialogBoxParam(g_Globals._hInstance, MAKEINTRESOURCE(nid), hwndParent, DialogProc, 0/*lpParam*/);
+}
+
+INT_PTR CALLBACK Window::DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ Window* pThis = get_window(hwnd);
+
+ if (pThis) {
+ switch(nmsg) {
+ case WM_COMMAND:
+ pThis->Command(LOWORD(wparam), HIWORD(wparam));
+ return TRUE; // message has been processed
+
+ case WM_NOTIFY:
+ pThis->Notify(wparam, (NMHDR*)lparam);
+ return TRUE; // message has been processed
+
+ case WM_NOTIFYFORMAT:
+ SetWindowLongPtr(hwnd, DWLP_MSGRESULT, NFR_CURRENT); // set return value NFR_CURRENT
+ return TRUE; // message has been processed
+
+ case WM_NCDESTROY:
+ delete pThis;
+ return TRUE; // message has been processed
+
+ default:
+ return pThis->WndProc(nmsg, wparam, lparam);
+ }
+ } else if (nmsg == WM_INITDIALOG) {
+ pThis = create_controller(hwnd);
+
+ if (pThis)
+ return pThis->Init(NULL);
+ }
+
+ return FALSE; // message has not been processed
+}
+
+LRESULT Dialog::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ return FALSE; // message has not been processed
+}
+
+int Dialog::Command(int id, int code)
+{
+ if (code == BN_CLICKED) {
+ EndDialog(_hwnd, id);
+ return 0; // message has been processed
+ }
+
+ return 1;
+}
+
+
+ResizeManager::ResizeManager(HWND hwnd)
+ : _hwnd(hwnd)
+{
+ ClientRect clnt(hwnd);
+ _last_size.cx = clnt.right;
+ _last_size.cy = clnt.bottom;
+
+ WindowRect rect(hwnd);
+ _min_wnd_size.cx = rect.right - rect.left;
+ _min_wnd_size.cy = rect.bottom - rect.top;
+}
+
+void ResizeManager::HandleSize(int cx, int cy)
+{
+ ClientRect clnt_rect(_hwnd);
+ SIZE new_size = {cx, cy};
+
+ int dx = new_size.cx - _last_size.cx;
+ int dy = new_size.cy - _last_size.cy;
+
+ if (!dx && !dy)
+ return;
+
+ _last_size = new_size;
+
+ HDWP hDWP = BeginDeferWindowPos(size());
+
+ for(ResizeManager::const_iterator it=begin(); it!=end(); ++it) {
+ const ResizeEntry& e = *it;
+ RECT move = {0};
+
+ if (e._flags & MOVE_LEFT)
+ move.left += dx;
+
+ if (e._flags & MOVE_RIGHT)
+ move.right += dx;
+
+ if (e._flags & MOVE_TOP)
+ move.top += dy;
+
+ if (e._flags & MOVE_BOTTOM)
+ move.bottom += dy;
+
+ UINT flags = 0;
+
+ if (!move.left && !move.top)
+ flags = SWP_NOMOVE;
+
+ if (move.right==move.left && move.bottom==move.top)
+ flags |= SWP_NOSIZE;
+
+ if (flags != (SWP_NOMOVE|SWP_NOSIZE)) {
+ HWND hwnd = GetDlgItem(_hwnd, e._id);
+
+ if (hwnd) {
+ WindowRect rect(hwnd);
+ ScreenToClient(_hwnd, rect);
+
+ rect.left += move.left;
+ rect.right += move.right;
+ rect.top += move.top;
+ rect.bottom += move.bottom;
+
+ hDWP = DeferWindowPos(hDWP, hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, flags|SWP_NOACTIVATE|SWP_NOZORDER);
+ }
+ }
+ }
+
+ EndDeferWindowPos(hDWP);
+}
+
+void ResizeManager::Resize(int dx, int dy)
+{
+ ::SetWindowPos(_hwnd, 0, 0, 0, _min_wnd_size.cx+dx, _min_wnd_size.cy+dy, SWP_NOMOVE|SWP_NOACTIVATE);
+ MoveVisible(_hwnd);
+
+ ClientRect clnt_rect(_hwnd);
+ HandleSize(clnt_rect.right, clnt_rect.bottom);
+}
+
+
+Button::Button(HWND parent, LPCTSTR title, int left, int top, int width, int height,
+ int id, DWORD flags, DWORD exStyle)
+ : WindowHandle(CreateWindowEx(exStyle, TEXT("BUTTON"), title, flags, left, top, width, height,
+ parent, (HMENU)id, g_Globals._hInstance, 0))
+{
+}
+
+
+LRESULT OwnerdrawnButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ if (nmsg == PM_DISPATCH_DRAWITEM) {
+ DrawItem((LPDRAWITEMSTRUCT)lparam);
+ return TRUE;
+ } else
+ return super::WndProc(nmsg, wparam, lparam);
+}
+
+
+Static::Static(HWND parent, LPCTSTR title, int left, int top, int width, int height,
+ int id, DWORD flags, DWORD exStyle)
+ : WindowHandle(CreateWindowEx(exStyle, TEXT("STATIC"), title, flags, left, top, width, height,
+ parent, (HMENU)id, g_Globals._hInstance, 0))
+{
+}
+
+
+static RECT s_MyDrawText_Rect = {0, 0, 0, 0};
+
+static BOOL CALLBACK MyDrawText(HDC hdc, LPARAM data, int cnt)
+{
+ ::DrawText(hdc, (LPCTSTR)data, cnt, &s_MyDrawText_Rect, DT_SINGLELINE);
+ return TRUE;
+}
+
+void DrawGrayText(HDC hdc, LPRECT pRect, LPCTSTR title, int dt_flags)
+{
+ COLORREF gray = GetSysColor(COLOR_GRAYTEXT);
+
+ if (gray) {
+ TextColor lcColor(hdc, GetSysColor(COLOR_BTNHIGHLIGHT));
+ RECT shadowRect = {pRect->left+1, pRect->top+1, pRect->right+1, pRect->bottom+1};
+ DrawText(hdc, title, -1, &shadowRect, dt_flags);
+
+ SetTextColor(hdc, gray);
+ DrawText(hdc, title, -1, pRect, dt_flags);
+ } else {
+ int old_r = pRect->right;
+ int old_b = pRect->bottom;
+
+ DrawText(hdc, title, -1, pRect, dt_flags|DT_CALCRECT);
+
+ int x = pRect->left + (old_r-pRect->right)/2;
+ int y = pRect->top + (old_b-pRect->bottom)/2;
+ int w = pRect->right-pRect->left;
+ int h = pRect->bottom-pRect->top;
+ s_MyDrawText_Rect.right = w;
+ s_MyDrawText_Rect.bottom = h;
+
+ GrayString(hdc, GetSysColorBrush(COLOR_GRAYTEXT), MyDrawText, (LPARAM)title, -1, x, y, w, h);
+ }
+}
+
+
+/* not yet used
+void ColorButton::DrawItem(LPDRAWITEMSTRUCT dis)
+{
+ UINT state = DFCS_BUTTONPUSH;
+
+ if (dis->itemState & ODS_DISABLED)
+ state |= DFCS_INACTIVE;
+
+ RECT textRect = {dis->rcItem.left+2, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4};
+
+ if (dis->itemState & ODS_SELECTED) {
+ state |= DFCS_PUSHED;
+ ++textRect.left; ++textRect.top;
+ ++textRect.right; ++textRect.bottom;
+ }
+
+ DrawFrameControl(dis->hDC, &dis->rcItem, DFC_BUTTON, state);
+
+ TCHAR title[BUFFER_LEN];
+ GetWindowText(_hwnd, title, BUFFER_LEN);
+
+ BkMode bk_mode(dis->hDC, TRANSPARENT);
+
+ if (dis->itemState & (ODS_DISABLED|ODS_GRAYED))
+ DrawGrayText(dis, &textRect, title, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
+ else {
+ TextColor lcColor(dis->hDC, _textColor);
+ DrawText(dis->hDC, title, -1, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
+ }
+
+ if (dis->itemState & ODS_FOCUS) {
+ RECT rect = {
+ dis->rcItem.left+3, dis->rcItem.top+3,
+ dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4
+ };
+ if (dis->itemState & ODS_SELECTED) {
+ ++rect.left; ++rect.top;
+ ++rect.right; ++rect.bottom;
+ }
+ DrawFocusRect(dis->hDC, &rect);
+ }
+}
+*/
+
+
+void PictureButton::DrawItem(LPDRAWITEMSTRUCT dis)
+{
+ UINT state = DFCS_BUTTONPUSH;
+ int style = GetWindowStyle(_hwnd);
+
+ if (dis->itemState & ODS_DISABLED)
+ state |= DFCS_INACTIVE;
+
+ POINT imagePos;
+ RECT textRect;
+ int dt_flags;
+
+ if (style & BS_BOTTOM) {
+ // align horizontal centered, vertical floating
+ imagePos.x = (dis->rcItem.left + dis->rcItem.right - _cx) / 2;
+ imagePos.y = dis->rcItem.top + 3;
+
+ textRect.left = dis->rcItem.left + 2;
+ textRect.top = dis->rcItem.top + _cy + 4;
+ textRect.right = dis->rcItem.right - 4;
+ textRect.bottom = dis->rcItem.bottom - 4;
+
+ dt_flags = DT_SINGLELINE|DT_CENTER|DT_VCENTER;
+ } else {
+ // horizontal floating, vertical centered
+ imagePos.x = dis->rcItem.left + 3;
+ imagePos.y = (dis->rcItem.top + dis->rcItem.bottom - _cy)/2;
+
+ textRect.left = dis->rcItem.left + _cx + 4;
+ textRect.top = dis->rcItem.top + 2;
+ textRect.right = dis->rcItem.right - 4;
+ textRect.bottom = dis->rcItem.bottom - 4;
+
+ dt_flags = DT_SINGLELINE|DT_VCENTER/*|DT_CENTER*/;
+ }
+
+ if (dis->itemState & ODS_SELECTED) {
+ state |= DFCS_PUSHED;
+ ++imagePos.x; ++imagePos.y;
+ ++textRect.left; ++textRect.top;
+ ++textRect.right; ++textRect.bottom;
+ }
+
+ if (_flat) {
+ FillRect(dis->hDC, &dis->rcItem, _hBrush);
+
+ if (style & BS_FLAT) // Only with BS_FLAT set, there will be drawn a frame without highlight.
+ DrawEdge(dis->hDC, &dis->rcItem, EDGE_RAISED, BF_RECT|BF_FLAT);
+ } else
+ DrawFrameControl(dis->hDC, &dis->rcItem, DFC_BUTTON, state);
+
+ if (_hIcon)
+ DrawIconEx(dis->hDC, imagePos.x, imagePos.y, _hIcon, _cx, _cy, 0, _hBrush, DI_NORMAL);
+ else {
+ MemCanvas mem_dc;
+ BitmapSelection sel(mem_dc, _hBmp);
+ BitBlt(dis->hDC, imagePos.x, imagePos.y, _cx, _cy, mem_dc, 0, 0, SRCCOPY);
+ }
+
+ TCHAR title[BUFFER_LEN];
+ GetWindowText(_hwnd, title, BUFFER_LEN);
+
+ BkMode bk_mode(dis->hDC, TRANSPARENT);
+
+ if (dis->itemState & (ODS_DISABLED|ODS_GRAYED))
+ DrawGrayText(dis->hDC, &textRect, title, dt_flags);
+ else {
+ TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNTEXT));
+ DrawText(dis->hDC, title, -1, &textRect, dt_flags);
+ }
+
+ if (dis->itemState & ODS_FOCUS) {
+ RECT rect = {
+ dis->rcItem.left+3, dis->rcItem.top+3,
+ dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4
+ };
+ if (dis->itemState & ODS_SELECTED) {
+ ++rect.left; ++rect.top;
+ ++rect.right; ++rect.bottom;
+ }
+ DrawFocusRect(dis->hDC, &rect);
+ }
+}
+
+
+void FlatButton::DrawItem(LPDRAWITEMSTRUCT dis)
+{
+ UINT style = DFCS_BUTTONPUSH;
+
+ if (dis->itemState & ODS_DISABLED)
+ style |= DFCS_INACTIVE;
+
+ RECT textRect = {dis->rcItem.left+2, dis->rcItem.top+2, dis->rcItem.right-4, dis->rcItem.bottom-4};
+
+ if (dis->itemState & ODS_SELECTED) {
+ style |= DFCS_PUSHED;
+ ++textRect.left; ++textRect.top;
+ ++textRect.right; ++textRect.bottom;
+ }
+
+ FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_BTNFACE));
+
+ // highlight the button?
+ if (_active)
+ DrawEdge(dis->hDC, &dis->rcItem, EDGE_ETCHED, BF_RECT);
+ else if (GetWindowStyle(_hwnd) & BS_FLAT) // Only with BS_FLAT there will be drawn a frame to show highlighting.
+ DrawEdge(dis->hDC, &dis->rcItem, EDGE_RAISED, BF_RECT|BF_FLAT);
+
+ TCHAR txt[BUFFER_LEN];
+ int txt_len = GetWindowText(_hwnd, txt, BUFFER_LEN);
+
+ if (dis->itemState & (ODS_DISABLED|ODS_GRAYED)) {
+ COLORREF gray = GetSysColor(COLOR_GRAYTEXT);
+
+ if (gray) {
+ {
+ TextColor lcColor(dis->hDC, GetSysColor(COLOR_BTNHIGHLIGHT));
+ RECT shadowRect = {textRect.left+1, textRect.top+1, textRect.right+1, textRect.bottom+1};
+ DrawText(dis->hDC, txt, txt_len, &shadowRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
+ }
+
+ BkMode mode(dis->hDC, TRANSPARENT);
+ TextColor lcColor(dis->hDC, gray);
+ DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
+ } else {
+ int old_r = textRect.right;
+ int old_b = textRect.bottom;
+ DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER|DT_CALCRECT);
+ int x = textRect.left + (old_r-textRect.right)/2;
+ int y = textRect.top + (old_b-textRect.bottom)/2;
+ int w = textRect.right-textRect.left;
+ int h = textRect.bottom-textRect.top;
+ s_MyDrawText_Rect.right = w;
+ s_MyDrawText_Rect.bottom = h;
+ GrayString(dis->hDC, GetSysColorBrush(COLOR_GRAYTEXT), MyDrawText, (LPARAM)txt, txt_len, x, y, w, h);
+ }
+ } else {
+ TextColor lcColor(dis->hDC, _active? _activeColor: _textColor);
+ DrawText(dis->hDC, txt, txt_len, &textRect, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
+ }
+
+ if (dis->itemState & ODS_FOCUS) {
+ RECT rect = {
+ dis->rcItem.left+3, dis->rcItem.top+3,
+ dis->rcItem.right-dis->rcItem.left-4, dis->rcItem.bottom-dis->rcItem.top-4
+ };
+ if (dis->itemState & ODS_SELECTED) {
+ ++rect.left; ++rect.top;
+ ++rect.right; ++rect.bottom;
+ }
+ DrawFocusRect(dis->hDC, &rect);
+ }
+}
+
+LRESULT FlatButton::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ switch(nmsg) {
+ case WM_MOUSEMOVE: {
+ bool active = false;
+
+ if (IsWindowEnabled(_hwnd)) {
+ DWORD pid_foreground;
+ HWND hwnd_foreground = GetForegroundWindow(); //@@ may be better look for WM_ACTIVATEAPP ?
+ GetWindowThreadProcessId(hwnd_foreground, &pid_foreground);
+
+ if (GetCurrentProcessId() == pid_foreground) {
+ POINT pt = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
+ ClientRect clntRect(_hwnd);
+
+ // highlight the button?
+ if (pt.x>=clntRect.left && pt.x<clntRect.right && pt.y>=clntRect.top && pt.y<clntRect.bottom)
+ active = true;
+ }
+ }
+
+ if (active != _active) {
+ _active = active;
+
+ if (active) {
+ TRACKMOUSEEVENT tme = {sizeof(tme), /*TME_HOVER|*/TME_LEAVE, _hwnd/*, HOVER_DEFAULT*/};
+ _TrackMouseEvent(&tme);
+ }
+
+ InvalidateRect(_hwnd, NULL, TRUE);
+ }
+
+ return 0;}
+
+ case WM_LBUTTONUP: {
+ POINT pt = {GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)};
+ ClientRect clntRect(_hwnd);
+
+ // no more in the active rectangle?
+ if (pt.x<clntRect.left || pt.x>=clntRect.right || pt.y<clntRect.top || pt.y>=clntRect.bottom)
+ goto cancel_press;
+
+ goto def;}
+
+ case WM_CANCELMODE:
+ cancel_press: {
+ TRACKMOUSEEVENT tme = {sizeof(tme), /*TME_HOVER|*/TME_LEAVE|TME_CANCEL, _hwnd/*, HOVER_DEFAULT*/};
+ _TrackMouseEvent(&tme);
+ _active = false;
+ ReleaseCapture();}
+ // fall through
+
+ case WM_MOUSELEAVE:
+ if (_active) {
+ _active = false;
+
+ InvalidateRect(_hwnd, NULL, TRUE);
+ }
+
+ return 0;
+
+ default: def:
+ return super::WndProc(nmsg, wparam, lparam);
+ }
+}
+
+
+HyperlinkCtrl::HyperlinkCtrl(HWND hwnd, COLORREF colorLink, COLORREF colorVisited)
+ : super(hwnd),
+ _cmd(ResString(GetDlgCtrlID(hwnd))),
+ _textColor(colorLink),
+ _colorVisited(colorVisited),
+ _hfont(0),
+ _crsr_link(0)
+{
+ init();
+}
+
+HyperlinkCtrl::HyperlinkCtrl(HWND owner, int id, COLORREF colorLink, COLORREF colorVisited)
+ : super(GetDlgItem(owner, id)),
+ _cmd(ResString(id)),
+ _textColor(colorLink),
+ _colorVisited(colorVisited),
+ _hfont(0),
+ _crsr_link(0)
+{
+ init();
+}
+
+void HyperlinkCtrl::init()
+{
+ if (_cmd.empty()) {
+ TCHAR txt[BUFFER_LEN];
+ _cmd.assign(txt, GetWindowText(_hwnd, txt, BUFFER_LEN));
+ }
+}
+
+HyperlinkCtrl::~HyperlinkCtrl()
+{
+ if (_hfont)
+ DeleteObject(_hfont);
+}
+
+LRESULT HyperlinkCtrl::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ switch(nmsg) {
+ case PM_DISPATCH_CTLCOLOR: {
+ if (!_hfont) {
+ HFONT hfont = (HFONT) SendMessage(_hwnd, WM_GETFONT, 0, 0);
+ LOGFONT lf; GetObject(hfont, sizeof(lf), &lf);
+ lf.lfUnderline = TRUE;
+ _hfont = CreateFontIndirect(&lf);
+ }
+
+ HDC hdc = (HDC) wparam;
+ SetTextColor(hdc, _textColor); //@@
+ SelectFont(hdc, _hfont);
+ SetBkMode(hdc, TRANSPARENT);
+ return (LRESULT)GetStockObject(HOLLOW_BRUSH);
+ }
+
+ case WM_SETCURSOR:
+ if (!_crsr_link)
+ _crsr_link = LoadCursor(0, IDC_HAND);
+
+ if (_crsr_link)
+ SetCursor(_crsr_link);
+ return 0;
+
+ case WM_NCHITTEST:
+ return HTCLIENT; // Aktivierung von Maus-Botschaften
+
+ case WM_LBUTTONDOWN:
+ if (LaunchLink()) {
+ _textColor = _colorVisited;
+ InvalidateRect(_hwnd, NULL, FALSE);
+ } else
+ MessageBeep(0);
+ return 0;
+
+ default:
+ return super::WndProc(nmsg, wparam, lparam);
+ }
+}
+
+
+ToolTip::ToolTip(HWND owner)
+ : super(CreateWindowEx(WS_EX_TOPMOST|WS_EX_NOPARENTNOTIFY, TOOLTIPS_CLASS, 0,
+ WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
+ owner, 0, g_Globals._hInstance, 0))
+{
+ activate();
+}
+
+
+ListSort::ListSort(HWND hwndListview, PFNLVCOMPARE compare_fct)
+ : WindowHandle(hwndListview),
+ _compare_fct(compare_fct)
+{
+ _sort_crit = 0;
+ _direction = false;
+}
+
+void ListSort::toggle_sort(int idx)
+{
+ if (_sort_crit == idx)
+ _direction = !_direction;
+ else {
+ _sort_crit = idx;
+ _direction = false;
+ }
+}
+
+void ListSort::sort()
+{
+ int idx = ListView_GetSelectionMark(_hwnd);
+ LPARAM param = ListView_GetItemData(_hwnd, idx);
+
+ ListView_SortItems(_hwnd, _compare_fct, (LPARAM)this);
+
+ if (idx >= 0) {
+ idx = ListView_FindItemPara(_hwnd, param);
+ ListView_EnsureVisible(_hwnd, idx, FALSE);
+ }
+}
+
+
+PropSheetPage::PropSheetPage(UINT nid, Window::CREATORFUNC dlg_creator)
+ : _dlg_creator(dlg_creator)
+{
+ PROPSHEETPAGE::dwSize = sizeof(PROPSHEETPAGE);
+ PROPSHEETPAGE::dwFlags = 0;
+ PROPSHEETPAGE::hInstance = g_Globals._hInstance;
+ PROPSHEETPAGE::pszTemplate = MAKEINTRESOURCE(nid);
+ PROPSHEETPAGE::pfnDlgProc = PropSheetPageDlg::DialogProc;
+ PROPSHEETPAGE::lParam = (LPARAM) this;
+}
+
+
+#ifndef PSM_GETRESULT // currently (as of 18.01.2004) missing in MinGW headers
+#define PSM_GETRESULT (WM_USER + 135)
+#define PropSheet_GetResult(hDlg) SNDMSG(hDlg, PSM_GETRESULT, 0, 0)
+#endif
+
+
+PropertySheetDialog::PropertySheetDialog(HWND owner)
+ : _hwnd(0)
+{
+ PROPSHEETHEADER::dwSize = sizeof(PROPSHEETHEADER);
+ PROPSHEETHEADER::dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS;
+ PROPSHEETHEADER::hwndParent = owner;
+ PROPSHEETHEADER::hInstance = g_Globals._hInstance;
+}
+
+void PropertySheetDialog::add(PropSheetPage& psp)
+{
+ _pages.push_back(psp);
+}
+
+int PropertySheetDialog::DoModal(int start_page)
+{
+ PROPSHEETHEADER::ppsp = (LPCPROPSHEETPAGE) &_pages[0];
+ PROPSHEETHEADER::nPages = _pages.size();
+ PROPSHEETHEADER::nStartPage = start_page;
+/*
+ Window* pwnd = Window::create_property_sheet(this, WINDOW_CREATOR(PropertySheetDlg), NULL);
+ if (!pwnd)
+ return -1;
+
+ HWND hwndPropSheet = *pwnd;
+*/
+ int ret = PropertySheet(this);
+ if (ret == -1)
+ return -1;
+
+ HWND hwndPropSheet = (HWND) ret;
+ HWND hwndparent = GetParent(hwndPropSheet);
+
+ if (hwndparent)
+ EnableWindow(hwndparent, FALSE);
+
+ ret = 0;
+ MSG msg;
+
+ while(GetMessage(&msg, 0, 0, 0)) {
+ try {
+ if (Window::pretranslate_msg(&msg))
+ continue;
+
+ if (PropSheet_IsDialogMessage(hwndPropSheet, &msg))
+ continue;
+
+ if (Window::dispatch_dialog_msg(&msg))
+ continue;
+
+ TranslateMessage(&msg);
+
+ try {
+ DispatchMessage(&msg);
+ } catch(COMException& e) {
+ HandleException(e, 0);
+ }
+
+ if (!PropSheet_GetCurrentPageHwnd(hwndPropSheet)) {
+ ret = PropSheet_GetResult(hwndPropSheet);
+ break;
+ }
+ } catch(COMException& e) {
+ HandleException(e, 0);
+ }
+ }
+
+ if (hwndparent)
+ EnableWindow(hwndparent, TRUE);
+
+ DestroyWindow(hwndPropSheet);
+
+ return ret;
+}
+
+HWND PropertySheetDialog::GetCurrentPage()
+{
+ HWND hdlg = PropSheet_GetCurrentPageHwnd(_hwnd);
+ return hdlg;
+}
+
+
+PropSheetPageDlg::PropSheetPageDlg(HWND hwnd)
+ : super(hwnd)
+{
+}
+
+INT_PTR CALLBACK PropSheetPageDlg::DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam)
+{
+ PropSheetPageDlg* pThis = GET_WINDOW(PropSheetPageDlg, hwnd);
+
+ if (pThis) {
+ switch(nmsg) {
+ case WM_COMMAND:
+ pThis->Command(LOWORD(wparam), HIWORD(wparam));
+ return TRUE; // message has been processed
+
+ case WM_NOTIFY:
+ pThis->Notify(wparam, (NMHDR*)lparam);
+ return TRUE; // message has been processed
+
+ case WM_NOTIFYFORMAT:
+ SetWindowLongPtr(hwnd, DWLP_MSGRESULT, NFR_CURRENT); // set return value NFR_CURRENT
+ return TRUE; // message has been processed
+
+ case WM_NCDESTROY:
+ delete pThis;
+ return TRUE; // message has been processed
+
+ default:
+ return pThis->WndProc(nmsg, wparam, lparam);
+ }
+ } else if (nmsg == WM_INITDIALOG) {
+ PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lparam;
+ PropSheetPage* ppsp = (PropSheetPage*) psp->lParam;
+
+ if (ppsp->_dlg_creator) {
+ pThis = static_cast<PropSheetPageDlg*>(ppsp->_dlg_creator(hwnd));
+
+ if (pThis)
+ return pThis->Init(NULL);
+ }
+ }
+
+ return FALSE; // message has not been processed
+}
+
+int PropSheetPageDlg::Command(int id, int code)
+{
+ // override call to EndDialog in Dialog::Command();
+
+ return FALSE;
+}
--- /dev/null
- drivers\battery\cmbatt\cmbatt.sys 2
+; Main ReactOS package
+
+.Set DiskLabelTemplate="ReactOS" ; Label of disk
+.Set CabinetNameTemplate="reactos.cab" ; reactos.cab
+.Set InfFileName="reactos.inf" ; reactos.inf
+
+
+;.Set Cabinet=on
+;.Set Compress=on
+
+.InfBegin
+[Version]
+Signature = "$ReactOS$"
+
+[Directories]
+1 = system32
+2 = system32\drivers
+3 = Fonts
+4 =
+5 = system32\drivers\etc
+6 = inf
+7 = bin
+8 = media
+
+.InfEnd
+
+; Contents of disk
+.InfBegin
+[SourceFiles]
+.InfEnd
+
+
+; Base files
+base\applications\cacls\cacls.exe 1
+base\applications\calc\calc.exe 1
+base\applications\charmap\charmap.exe 1
+base\applications\cmdutils\dbgprint\dbgprint.exe 1
+base\applications\cmdutils\doskey\doskey.exe 1
+base\applications\cmdutils\find\find.exe 1
+base\applications\cmdutils\hostname\hostname.exe 1
+base\applications\cmdutils\lodctr\lodctr.exe 1
+base\applications\cmdutils\more\more.exe 1
+base\applications\cmdutils\reg\reg.exe 1
+base\applications\cmdutils\xcopy\xcopy.exe 1
+base\applications\control\control.exe 1
+base\applications\dxdiag\dxdiag.exe 1
+base\applications\fontview\fontview.exe 1
+base\applications\mscutils\devmgmt\devmgmt.exe 1
+base\applications\mscutils\eventvwr\eventvwr.exe 1
+base\applications\games\solitaire\sol.exe 1
+base\applications\games\spider\spider.exe 1
+base\applications\games\winemine\winemine.exe 1
+base\applications\hh\hh.exe 4
+base\applications\kbswitch\kbswitch.exe 1
+base\applications\kbswitch\kbsdll\kbsdll.dll 1
+base\applications\logoff\logoff.exe 1
+base\applications\magnify\magnify.exe 1
+base\applications\mplay32\mplay32.exe 1
+base\applications\msconfig\msconfig.exe 1
+base\applications\mstsc\mstsc.exe 1
+base\applications\network\arp\arp.exe 1
+base\applications\network\dwnl\dwnl.exe 1
+base\applications\network\route\route.exe 1
+base\applications\network\finger\finger.exe 1
+base\applications\network\ftp\ftp.exe 1
+base\applications\network\ipconfig\ipconfig.exe 1
+base\applications\network\netstat\netstat.exe 1
+base\applications\network\nslookup\nslookup.exe 1
+base\applications\network\ping\ping.exe 1
+base\applications\network\telnet\telnet.exe 1
+base\applications\network\tracert\tracert.exe 1
+base\applications\network\whois\whois.exe 1
+base\applications\notepad\notepad.exe 1
+base\applications\paint\paint.exe 1
+base\applications\rapps\rapps.exe 1
+base\applications\regedit\regedit.exe 4
+base\applications\regedit\clb\clb.dll 1
+base\applications\regedt32\regedt32.exe 1
+base\applications\sc\sc.exe 1
+base\applications\screensavers\3dtext\3dtext.scr 1
+base\applications\screensavers\logon\logon.scr 1
+base\applications\mscutils\servman\servman.exe 1
+base\applications\shutdown\shutdown.exe 1
+base\applications\sndrec32\sndrec32.exe 1
+base\applications\sndvol32\sndvol32.exe 1
+base\applications\taskmgr\taskmgr.exe 1
+base\applications\winhlp32\winhlp32.exe 4
+base\applications\winver\winver.exe 1
+base\applications\wordpad\wordpad.exe 1
+base\applications\write\write.exe 1
+
+base\services\audiosrv\audiosrv.exe 1
+base\services\dhcp\dhcp.exe 1
+base\services\eventlog\eventlog.exe 1
+base\services\rpcss\rpcss.exe 1
+base\services\spoolsv\spoolsv.exe 1
+base\services\tcpsvcs\tcpsvcs.exe 1
+base\services\telnetd\telnetd.exe 1
+base\services\tcpsvcs\quotes 5
+base\services\umpnpmgr\umpnpmgr.exe 1
+base\services\wlansvc\wlansvc.exe 1
+base\services\svchost\svchost.exe 1
+
+base\setup\setup\setup.exe 1
+base\setup\vmwinst\vmwinst.exe 1
+
+base\shell\cmd\cmd.exe 1
+base\shell\explorer\explorer.exe 4
+base\shell\explorer\explorer-cfg-template.xml 4
+base\shell\explorer\notifyhook\notifyhook.dll 1
+base\shell\explorer-new\explorer_new.exe 4 optional
+
+base\system\autochk\autochk.exe 1
+base\system\bootok\bootok.exe 1
+base\system\format\format.exe 1
+base\system\lsass\lsass.exe 1
+base\system\msiexec\msiexec.exe 1
+base\system\regsvr32\regsvr32.exe 1
+base\system\rundll32\rundll32.exe 1
+base\system\runonce\runonce.exe 1
+base\system\services\services.exe 1
+base\system\userinit\userinit.exe 1
+base\system\winlogon\winlogon.exe 1
+base\system\expand\expand.exe 1
+base\system\smss\smss.exe 1
+
+
+; Dynamic Link Libraries
+dll\3rdparty\mesa32\mesa32.dll 1
+dll\3rdparty\libjpeg\libjpeg.dll 1
+dll\3rdparty\libxslt\libxslt.dll 1
+dll\3rdparty\dxtn\dxtn.dll 1 optional
+
+dll\cpl\access\access.cpl 1
+dll\cpl\appwiz\appwiz.cpl 1
+dll\cpl\console\console.dll 1
+dll\cpl\desk\desk.cpl 1
+dll\cpl\hdwwiz\hdwwiz.cpl 1
+dll\cpl\input\input.dll 1
+dll\cpl\intl\intl.cpl 1
+dll\cpl\joy\joy.cpl 1
+;dll\cpl\liccpa\liccpa.cpl 1
+dll\cpl\main\main.cpl 1
+dll\cpl\mmsys\mmsys.cpl 1
+dll\cpl\ncpa\ncpa.cpl 1
+;dll\cpl\odbccp32\odbccp32.cpl 1
+dll\cpl\powercfg\powercfg.cpl 1
+dll\cpl\sysdm\sysdm.cpl 1
+;dll\cpl\telephon\telephon.cpl 1
+dll\cpl\timedate\timedate.cpl 1
+;dll\cpl\usrmgr\usrmgr.cpl 1
+
+dll\directx\amstream\amstream.dll 1
+dll\directx\bdaplgin\bdaplgin.ax 1
+dll\directx\dinput\dinput.dll 1
+dll\directx\dinput8\dinput8.dll 1
+dll\directx\dmusic\dmusic.dll 1
+dll\directx\dplay\dplay.dll 1
+dll\directx\dplayx\dplayx.dll 1
+dll\directx\dsound\dsound.dll 1
+dll\directx\dxdiagn\dxdiagn.dll 1
+dll\directx\wine\ddraw\ddraw.dll 1
+dll\directx\d3d8thk\d3d8thk.dll 1
+dll\directx\devenum\devenum.dll 1
+dll\directx\ksproxy\ksproxy.ax 1
+dll\directx\ksuser\ksuser.dll 1
+dll\directx\msdmo\msdmo.dll 1
+dll\directx\msdvbnp\msdvbnp.ax 1
+dll\directx\msvidctl\msvidctl.dll 1
+dll\directx\quartz\quartz.dll 1
+dll\directx\qedit\qedit.dll 1
+dll\directx\wine\d3d8\d3d8.dll 1
+dll\directx\wine\wined3d\wined3d.dll 1
+dll\directx\wine\d3d9\d3d9.dll 1
+
+dll\keyboard\kbda1\kbda1.dll 1
+dll\keyboard\kbda2\kbda2.dll 1
+dll\keyboard\kbda3\kbda3.dll 1
+dll\keyboard\kbdal\kbdal.dll 1
+dll\keyboard\kbdarme\kbdarme.dll 1
+dll\keyboard\kbdarmw\kbdarmw.dll 1
+dll\keyboard\kbdaze\kbdaze.dll 1
+dll\keyboard\kbdazel\kbdazel.dll 1
+dll\keyboard\kbdbgm\kbdbgm.dll 1
+dll\keyboard\kbdbgt\kbdbgt.dll 1
+dll\keyboard\kbdblr\kbdblr.dll 1
+dll\keyboard\kbdbr\kbdbr.dll 1
+dll\keyboard\kbdbga\kbdbga.dll 1
+dll\keyboard\kbdbe\kbdbe.dll 1
+dll\keyboard\kbdbur\kbdbur.dll 1
+dll\keyboard\kbdcan\kbdcan.dll 1
+dll\keyboard\kbdcr\kbdcr.dll 1
+dll\keyboard\kbdcz\kbdcz.dll 1
+dll\keyboard\kbdcz1\kbdcz1.dll 1
+dll\keyboard\kbdda\kbdda.dll 1
+dll\keyboard\kbddv\kbddv.dll 1
+dll\keyboard\kbdes\kbdes.dll 1
+dll\keyboard\kbdest\kbdest.dll 1
+dll\keyboard\kbdfc\kbdfc.dll 1
+dll\keyboard\kbdfi\kbdfi.dll 1
+dll\keyboard\kbdfr\kbdfr.dll 1
+dll\keyboard\kbdgeo\kbdgeo.dll 1
+dll\keyboard\kbdgerg\kbdgerg.dll 1
+dll\keyboard\kbdgneo\kbdgneo.dll 1
+dll\keyboard\kbdgrist\kbdgrist.dll 1
+dll\keyboard\kbdgr\kbdgr.dll 1
+dll\keyboard\kbdhe\kbdhe.dll 1
+dll\keyboard\kbdheb\kbdheb.dll 1
+dll\keyboard\kbdhu\kbdhu.dll 1
+dll\keyboard\kbdic\kbdic.dll 1
+dll\keyboard\kbdinasa\kbdinasa.dll 1
+dll\keyboard\kbdinben\kbdinben.dll 1
+dll\keyboard\kbdindev\kbdindev.dll 1
+dll\keyboard\kbdinguj\kbdinguj.dll 1
+dll\keyboard\kbdinmal\kbdinmal.dll 1
+dll\keyboard\kbdir\kbdir.dll 1
+dll\keyboard\kbdit\kbdit.dll 1
+dll\keyboard\kbdja\kbdja.dll 1
+dll\keyboard\kbdkaz\kbdkaz.dll 1
+dll\keyboard\kbdla\kbdla.dll 1
+dll\keyboard\kbdlt1\kbdlt1.dll 1
+dll\keyboard\kbdlv\kbdlv.dll 1
+dll\keyboard\kbdmac\kbdmac.dll 1
+dll\keyboard\kbdne\kbdne.dll 1
+dll\keyboard\kbdno\kbdno.dll 1
+dll\keyboard\kbdpl1\kbdpl1.dll 1
+dll\keyboard\kbdpo\kbdpo.dll 1
+dll\keyboard\kbdro\kbdro.dll 1
+dll\keyboard\kbdru\kbdru.dll 1
+dll\keyboard\kbdru1\kbdru1.dll 1
+dll\keyboard\kbdsg\kbdsg.dll 1
+dll\keyboard\kbdsk\kbdsk.dll 1
+dll\keyboard\kbdsk1\kbdsk1.dll 1
+dll\keyboard\kbdsw\kbdsw.dll 1
+dll\keyboard\kbdtat\kbdtat.dll 1
+dll\keyboard\kbdth0\kbdth0.dll 1
+dll\keyboard\kbdth1\kbdth1.dll 1
+dll\keyboard\kbdth2\kbdth2.dll 1
+dll\keyboard\kbdth3\kbdth3.dll 1
+dll\keyboard\kbdtuf\kbdtuf.dll 1
+dll\keyboard\kbdtuq\kbdtuq.dll 1
+dll\keyboard\kbduk\kbduk.dll 1
+dll\keyboard\kbdur\kbdur.dll 1
+dll\keyboard\kbdurs\kbdurs.dll 1
+dll\keyboard\kbdus\kbdus.dll 1
+dll\keyboard\kbdusa\kbdusa.dll 1
+dll\keyboard\kbdusl\kbdusl.dll 1
+dll\keyboard\kbdusr\kbdusr.dll 1
+dll\keyboard\kbdusx\kbdusx.dll 1
+dll\keyboard\kbduzb\kbduzb.dll 1
+dll\keyboard\kbdvntc\kbdvntc.dll 1
+dll\keyboard\kbdycc\kbdycc.dll 1
+dll\keyboard\kbdycl\kbdycl.dll 1
+dll\keyboard\kbdko\kbdko.dll 1
+
+dll\ntdll\ntdll.dll 1
+
+dll\win32\acledit\acledit.dll 1
+dll\win32\aclui\aclui.dll 1
+dll\win32\activeds\activeds.dll 1
+dll\win32\advapi32\advapi32.dll 1
+dll\win32\advpack\advpack.dll 1
+dll\win32\actxprxy\actxprxy.dll 1
+dll\win32\atl\atl.dll 1
+dll\win32\authz\authz.dll 1
+dll\win32\avicap32\avicap32.dll 1
+dll\win32\avifil32\avifil32.dll 1
+dll\win32\batt\batt.dll 1
+dll\win32\bcrypt\bcrypt.dll 1
+dll\win32\beepmidi\beepmidi.dll 1
+dll\win32\browseui\browseui.dll 1
+dll\win32\cabinet\cabinet.dll 1
+dll\win32\cards\cards.dll 1
+dll\win32\cfgmgr32\cfgmgr32.dll 1
+dll\win32\clusapi\clusapi.dll 1
+dll\win32\comcat\comcat.dll 1
+dll\win32\comctl32\comctl32.dll 1
+dll\win32\comdlg32\comdlg32.dll 1
+dll\win32\compstui\compstui.dll 1
+dll\win32\credui\credui.dll 1
+dll\win32\crtdll\crtdll.dll 1
+dll\win32\crypt32\crypt32.dll 1
+dll\win32\cryptdlg\cryptdlg.dll 1
+dll\win32\cryptdll\cryptdll.dll 1
+dll\win32\cryptnet\cryptnet.dll 1
+dll\win32\cryptui\cryptui.dll 1
+dll\win32\dbghelp\dbghelp.dll 1
+dll\win32\dciman32\dciman32.dll 1
+dll\win32\dwmapi\dwmapi.dll 1
+dll\win32\devmgr\devmgr.dll 1
+dll\win32\dhcpcsvc\dhcpcsvc.dll 1
+dll\win32\dnsapi\dnsapi.dll 1
+dll\win32\faultrep\faultrep.dll 1
+dll\win32\fmifs\fmifs.dll 1
+dll\win32\fusion\fusion.dll 1
+dll\win32\gdi32\gdi32.dll 1
+dll\win32\gdiplus\gdiplus.dll 1
+dll\win32\getuname\getuname.dll 1
+dll\win32\glu32\glu32.dll 1
+dll\win32\hhctrl.ocx\hhctrl.ocx 1
+dll\win32\hid\hid.dll 1
+dll\win32\hlink\hlink.dll 1
+dll\win32\hnetcfg\hnetcfg.dll 1
+dll\win32\httpapi\httpapi.dll 1
+dll\win32\iccvid\iccvid.dll 1
+dll\win32\icmp\icmp.dll 1
+dll\win32\imaadp32.acm\imaadp32.acm 1
+dll\win32\imagehlp\imagehlp.dll 1
+dll\win32\imm32\imm32.dll 1
+dll\win32\inetcomm\inetcomm.dll 1
+dll\win32\inetmib1\inetmib1.dll 1
+dll\win32\initpki\initpki.dll 1
+dll\win32\inseng\inseng.dll 1
+dll\win32\iphlpapi\iphlpapi.dll 1
+dll\win32\itircl\itircl.dll 1
+dll\win32\itss\itss.dll 1
+dll\win32\jscript\jscript.dll 1
+dll\win32\kernel32\kernel32.dll 1
+dll\win32\loadperf\loadperf.dll 1
+dll\win32\localspl\localspl.dll 1
+dll\win32\localui\localui.dll 1
+dll\win32\lsasrv\lsasrv.dll 1
+dll\win32\lz32\lz32.dll 1
+dll\win32\mapi32\mapi32.dll 1
+dll\win32\mciavi32\mciavi32.dll 1
+dll\win32\mcicda\mcicda.dll 1
+dll\win32\mciqtz32\mciqtz32.dll 1
+dll\win32\mciseq\mciseq.dll 1
+dll\win32\mciwave\mciwave.dll 1
+dll\win32\mlang\mlang.dll 1
+dll\win32\mmdrv\mmdrv.dll 1
+dll\win32\modemui\modemui.dll 1
+dll\win32\mpr\mpr.dll 1
+dll\win32\mprapi\mprapi.dll 1
+dll\win32\msacm32\msacm32.dll 1
+dll\win32\msacm32\msacm32.drv\msacm32.drv 1
+dll\win32\msadp32.acm\msadp32.acm 1
+dll\win32\msafd\msafd.dll 1
+dll\win32\mscat32\mscat32.dll 1
+dll\win32\mscms\mscms.dll 1
+dll\win32\mscoree\mscoree.dll 1
+dll\win32\msctf\msctf.dll 1
+dll\win32\msftedit\msftedit.dll 1
+dll\win32\msg711.acm\msg711.acm 1
+dll\win32\msgina\msgina.dll 1
+dll\win32\msgsm32.acm\msgsm32.acm 1
+dll\win32\mshtml\mshtml.dll 1
+dll\win32\mshtml.tlb\mshtml.tlb 1
+dll\win32\msi\msi.dll 1
+dll\win32\msimg32\msimg32.dll 1
+dll\win32\msimtf\msimtf.dll 1
+dll\win32\msisip\msisip.dll 1
+dll\win32\msisys.ocx\msisys.ocx 1
+dll\win32\msnet32\msnet32.dll 1
+dll\win32\msrle32\msrle32.dll 1
+dll\win32\mssign32\mssign32.dll 1
+dll\win32\mssip32\mssip32.dll 1
+dll\win32\mstask\mstask.dll 1
+dll\win32\msvcrt\msvcrt.dll 1
+dll\win32\msvcrt20\msvcrt20.dll 1
+dll\win32\msvcrt40\msvcrt40.dll 1
+dll\win32\msvfw32\msvfw32.dll 1
+dll\win32\msvidc32\msvidc32.dll 1
+dll\win32\mswsock\mswsock.dll 1
+dll\win32\msxml3\msxml3.dll 1
+dll\win32\nddeapi\nddeapi.dll 1
+dll\win32\netapi32\netapi32.dll 1
+dll\win32\netcfgx\netcfgx.dll 1
+dll\win32\netid\netid.dll 1
+dll\win32\netshell\netshell.dll 1
+dll\win32\newdev\newdev.dll 1
+dll\win32\ntdsapi\ntdsapi.dll 1
+dll\win32\ntlanman\ntlanman.dll 1
+dll\win32\ntmarta\ntmarta.dll 1
+dll\win32\ntprint\ntprint.dll 1
+dll\win32\objsel\objsel.dll 1
+dll\win32\odbc32\odbc32.dll 1
+dll\win32\odbccp32\odbccp32.dll 1
+dll\win32\ole32\ole32.dll 1
+dll\win32\oleacc\oleacc.dll 1
+dll\win32\oleaut32\oleaut32.dll 1
+dll\win32\olecli32\olecli32.dll 1
+dll\win32\oledlg\oledlg.dll 1
+dll\win32\olepro32\olepro32.dll 1
+dll\win32\olesvr32\olesvr32.dll 1
+dll\win32\olethk32\olethk32.dll 1
+dll\win32\opengl32\opengl32.dll 1
+dll\win32\pdh\pdh.dll 1
+dll\win32\pidgen\pidgen.dll 1
+dll\win32\powrprof\powrprof.dll 1
+dll\win32\printui\printui.dll 1
+dll\win32\psapi\psapi.dll 1
+dll\win32\pstorec\pstorec.dll 1
+dll\win32\qmgr\qmgr.dll 1
+dll\win32\qmgrprxy\qmgrprxy.dll 1
+dll\win32\query\query.dll 1
+dll\win32\rasadhlp\rasadhlp.dll 1
+dll\win32\rasapi32\rasapi32.dll 1
+dll\win32\rasdlg\rasdlg.dll 1
+dll\win32\resutils\resutils.dll 1
+dll\win32\rasman\rasman.dll 1
+dll\win32\riched20\riched20.dll 1
+dll\win32\riched32\riched32.dll 1
+dll\win32\rpcrt4\rpcrt4.dll 1
+dll\win32\rsabase\rsabase.dll 1
+dll\win32\rsaenh\rsaenh.dll 1
+dll\win32\samlib\samlib.dll 1
+dll\win32\samsrv\samsrv.dll 1
+dll\win32\sccbase\sccbase.dll 1
+dll\win32\schannel\schannel.dll 1
+dll\win32\secur32\secur32.dll 1
+dll\win32\security\security.dll 1
+dll\win32\sensapi\sensapi.dll 1
+dll\win32\serialui\serialui.dll 1
+dll\win32\setupapi\setupapi.dll 1
+dll\win32\sfc\sfc.dll 1
+dll\win32\sfc_os\sfc_os.dll 1
+dll\win32\shdoclc\shdoclc.dll 1
+dll\win32\shdocvw\shdocvw.dll 1
+dll\win32\shell32\shell32.dll 1
+dll\win32\shfolder\shfolder.dll 1
+dll\win32\shimgvw\shimgvw.dll 1
+dll\win32\shlwapi\shlwapi.dll 1
+dll\win32\slbcsp\slbcsp.dll 1
+dll\win32\smdll\smdll.dll 1
+dll\win32\snmpapi\snmpapi.dll 1
+dll\win32\softpub\softpub.dll 1
+dll\win32\spoolss\spoolss.dll 1
+dll\win32\srclient\srclient.dll 1
+dll\win32\stdole2.tlb\stdole2.tlb 1
+dll\win32\stdole32.tlb\stdole32.tlb 1
+dll\win32\sti\sti.dll 1
+dll\win32\sxs\sxs.dll 1
+dll\win32\syssetup\syssetup.dll 1
+dll\win32\t2embed\t2embed.dll 1
+dll\win32\tapi32\tapi32.dll 1
+dll\win32\tapiui\tapiui.dll 1
+dll\win32\traffic\traffic.dll 1
+dll\win32\twain_32\twain_32.dll 1
+dll\win32\uext2\uext2.dll 1
+dll\win32\ufat\ufat.dll 1
+dll\win32\ufatx\ufatx.dll 1 optional
+dll\win32\untfs\untfs.dll 1
+dll\win32\updspapi\updspapi.dll 1
+dll\win32\url\url.dll 1
+dll\win32\urlmon\urlmon.dll 1
+dll\win32\user32\user32.dll 1
+dll\win32\userenv\userenv.dll 1
+dll\win32\usp10\usp10.dll 1
+dll\win32\uxtheme\uxtheme.dll 1
+dll\win32\vdmdbg\vdmdbg.dll 1
+dll\win32\version\version.dll 1
+dll\win32\windowscodecs\windowscodecs.dll 1
+dll\win32\winemp3.acm\winemp3.acm 1
+dll\win32\winfax\winfax.dll 1
+dll\win32\winhttp\winhttp.dll 1
+dll\win32\wininet\wininet.dll 1
+dll\win32\winmm\winmm.dll 1
+dll\win32\winspool\winspool.drv 1
+dll\win32\winsta\winsta.dll 1
+dll\win32\wlanapi\wlanapi.dll 1
+dll\win32\wintrust\wintrust.dll 1
+dll\win32\wldap32\wldap32.dll 1
+dll\win32\wmi\wmi.dll 1
+dll\win32\ws2_32\ws2_32.dll 1
+dll\win32\ws2help\ws2help.dll 1
+dll\win32\wshirda\wshirda.dll 1
+dll\win32\wshtcpip\wshtcpip.dll 1
+dll\win32\wsock32\wsock32.dll 1
+dll\win32\wtsapi32\wtsapi32.dll 1
+dll\win32\wuapi\wuapi.dll 1
+dll\win32\xinput1_1\xinput1_1.dll 1
+dll\win32\xinput1_2\xinput1_2.dll 1
+dll\win32\xinput1_3\xinput1_3.dll 1
+dll\win32\xinput9_1_0\xinput9_1_0.dll 1
+dll\win32\xmllite\xmllite.dll 1
+dll\win32\winmm\midimap\midimap.dll 1
+dll\win32\wdmaud.drv\wdmaud.drv 1
+
+; Shell Extensions
+dll\shellext\deskadp\deskadp.dll 1
+dll\shellext\deskmon\deskmon.dll 1
+
+; Drivers
+drivers\base\bootvid\bootvid.dll 1
+drivers\base\beep\beep.sys 2
+drivers\base\null\null.sys 2
+drivers\base\nmidebug\nmidebug.sys 2
+
+drivers\battery\battc\battc.sys 2
+
+drivers\bus\isapnp\isapnp.sys 2
+
++drivers\bus\acpi\cmbatt\cmbatt.sys 2
++drivers\bus\acpi\compbatt\compbatt.sys 2
++
+drivers\directx\dxapi\dxapi.sys 2
+drivers\directx\dxg\dxg.sys 2
+drivers\directx\dxgthk\dxgthk.sys 2
+
+drivers\filesystems\fs_rec\fs_rec.sys 2
+drivers\filesystems\msfs\msfs.sys 2
+drivers\filesystems\mup\mup.sys 2
+drivers\filesystems\npfs\npfs.sys 2
+
+drivers\input\mouclass\mouclass.sys 2
+drivers\input\sermouse\sermouse.sys 2
+
+drivers\ksfilter\ks\ks.sys 2
+drivers\multimedia\bdasup\bdasup.sys 2
+
+drivers\network\afd\afd.sys 2
+drivers\network\ndis\ndis.sys 2
+drivers\network\tcpip\tcpip.sys 2
+drivers\network\tdi\tdi.sys 2
+drivers\network\dd\ne2000\ne2000.sys 2
+drivers\network\dd\pcnet\pcnet.sys 2
+
+drivers\serial\serenum\serenum.sys 2
+drivers\serial\serial\serial.sys 2
+
+drivers\storage\ide\pciide\pciide.sys 2
+drivers\storage\ide\pciidex\pciidex.sys 2
+
+;drivers\usb\miniport\usbohci\usbohci.sys 2
+;drivers\usb\miniport\usbuhci\usbuhci.sys 2
+;drivers\usb\usbhub\usbhub.sys 2
+;drivers\usb\usbport\usbport.sys 2
+drivers\usb\nt4compat\usbdriver\usbdriver.sys 2
+
+drivers\video\displays\vga\vgaddi.dll 1
+drivers\video\displays\framebuf\framebuf.dll 1
+drivers\video\miniport\vga\vgamp.sys 2
+drivers\video\miniport\vbe\vbemp.sys 2
+drivers\video\videoprt\videoprt.sys 2
+drivers\video\font\ftfd\ftfd.dll 1
+
+drivers\wdm\audio\filters\kmixer\kmixer.sys 2
+drivers\wdm\audio\sysaudio\sysaudio.sys 2
+drivers\wdm\audio\legacy\wdmaud\wdmaud.sys 2
+drivers\wdm\audio\backpln\portcls\portcls.sys 2
+drivers\wdm\audio\drm\drmk\drmk.sys 2
+drivers\wmi\wmilib.sys 2
+
+; Media
+media\fonts\DejaVuSans.ttf 3
+media\fonts\DejaVuSans-Bold.ttf 3
+media\fonts\DejaVuSans-BoldOblique.ttf 3
+media\fonts\DejaVuSansMono.ttf 3
+media\fonts\DejaVuSansMono-Bold.ttf 3
+media\fonts\DejaVuSansMono-BoldOblique.ttf 3
+media\fonts\DejaVuSansMono-Oblique.ttf 3
+media\fonts\DejaVuSans-Oblique.ttf 3
+media\fonts\DejaVuSerif.ttf 3
+media\fonts\DejaVuSerif-Bold.ttf 3
+media\fonts\DejaVuSerif-BoldItalic.ttf 3
+media\fonts\DejaVuSerif-Italic.ttf 3
+
+media\fonts\FreeMono.ttf 3
+media\fonts\FreeMonoBold.ttf 3
+media\fonts\FreeMonoBoldOblique.ttf 3
+media\fonts\FreeMonoOblique.ttf 3
+
+media\fonts\LiberationMono-Bold.ttf 3
+media\fonts\LiberationMono-BoldItalic.ttf 3
+media\fonts\LiberationMono-Italic.ttf 3
+media\fonts\LiberationMono-Regular.ttf 3
+media\fonts\LiberationSans-Bold.ttf 3
+media\fonts\LiberationSans-BoldItalic.ttf 3
+media\fonts\LiberationSans-Italic.ttf 3
+media\fonts\LiberationSans-Regular.ttf 3
+media\fonts\LiberationSerif-Bold.ttf 3
+media\fonts\LiberationSerif-BoldItalic.ttf 3
+media\fonts\LiberationSerif-Italic.ttf 3
+media\fonts\LiberationSerif-Regular.ttf 3
+
+media\fonts\Marlett.ttf 3
+media\fonts\symbol.ttf 3
+media\fonts\tahoma.ttf 3
+media\fonts\tahomabd.ttf 3
+
+media\vgafonts\vgafonts.cab 4
+
+media\nls\c_037.nls 1
+media\nls\c_424.nls 1
+media\nls\c_500.nls 1
+media\nls\c_737.nls 1
+media\nls\c_775.nls 1
+media\nls\c_850.nls 1
+media\nls\c_852.nls 1
+media\nls\c_855.nls 1
+media\nls\c_856.nls 1
+media\nls\c_857.nls 1
+media\nls\c_860.nls 1
+media\nls\c_861.nls 1
+media\nls\c_862.nls 1
+media\nls\c_863.nls 1
+media\nls\c_864.nls 1
+media\nls\c_865.nls 1
+media\nls\c_866.nls 1
+media\nls\c_869.nls 1
+media\nls\c_874.nls 1
+media\nls\c_875.nls 1
+media\nls\c_878.nls 1
+media\nls\c_932.nls 1
+media\nls\c_936.nls 1
+media\nls\c_949.nls 1
+media\nls\c_950.nls 1
+media\nls\c_1006.nls 1
+media\nls\c_1026.nls 1
+media\nls\c_1250.nls 1
+media\nls\c_1251.nls 1
+media\nls\c_1253.nls 1
+media\nls\c_1254.nls 1
+media\nls\c_1255.nls 1
+media\nls\c_1256.nls 1
+media\nls\c_1257.nls 1
+media\nls\c_1258.nls 1
+media\nls\c_10000.nls 1
+media\nls\c_10006.nls 1
+media\nls\c_10007.nls 1
+media\nls\c_10029.nls 1
+media\nls\c_10079.nls 1
+media\nls\c_10081.nls 1
+media\nls\c_20866.nls 1
+media\nls\c_21866.nls 1
+media\nls\c_28591.nls 1
+media\nls\c_28592.nls 1
+media\nls\c_28593.nls 1
+media\nls\c_28594.nls 1
+media\nls\c_28595.nls 1
+media\nls\c_28596.nls 1
+media\nls\c_28597.nls 1
+media\nls\c_28598.nls 1
+media\nls\c_28599.nls 1
+media\nls\c_28600.nls 1
+media\nls\c_28603.nls 1
+media\nls\c_28604.nls 1
+media\nls\c_28605.nls 1
+media\nls\c_28606.nls 1
+media\drivers\etc\services 5
+media\inf\audio.inf 6
+media\inf\acpi.inf 6
+media\inf\battery.inf 6
+media\inf\cdrom.inf 6
+media\inf\cpu.inf 6
+media\inf\display.inf 6
+media\inf\font.inf 6
+media\inf\fdc.inf 6
+media\inf\hdc.inf 6
+media\inf\intl.inf 6
+media\inf\layout.inf 6
+media\inf\machine.inf 6
+media\inf\msmouse.inf 6
+media\inf\keyboard.inf 6
+media\inf\ks.inf 6
+media\inf\NET_NIC.inf 6
+media\inf\netamd.inf 6
+media\inf\netisa.inf 6
+media\inf\netrtpnt.inf 6
+media\inf\nettcpip.inf 6
+media\inf\ports.inf 6
+media\inf\scsi.inf 6
+media\inf\syssetup.inf 6
+media\inf\usbport.inf 6
+media\inf\usb.inf 6
+media\inf\usbstor.inf 6
+media\inf\xboxdisp.inf 6
+
+
+; Media Files
+media\sounds\ReactOS_LogOn.wav 8
+
+; Ini Files
+boot\bootdata\system.ini 4
+
+; Regression Testing
+boot\bootdata\bootcdregtest\regtest.cmd 7 optional
+
+; Subsystems
+subsystems\win32\csrss\csrss.exe 1
+subsystems\win32\csrss\win32csr\win32csr.dll 1
+subsystems\win32\csrss\csrsrv\csrsrv.dll 1
+subsystems\ntvdm\ntvdm.exe 1
+subsystems\win32\win32k\win32k.sys 1
+
+; Optional/proprietary files
+modules\optional\DroidSansFallback.ttf 3 optional
+modules\optional\NOTICE_for_Droid_Font.txt 4 optional
+modules\optional\netkvm2k.inf 6 optional
+modules\optional\netkvm2k.cat 6 optional
+modules\optional\netkvm.sys 2 optional
+modules\optional\alcxwdm.inf 6 optional
+modules\optional\alcxwdm.sys 2 optional
+modules\optional\mfc42.dll 1 optional
+modules\optional\mfc42u.dll 1 optional
+modules\optional\mfc71.dll 1 optional
+modules\optional\mfc71u.dll 1 optional
+modules\optional\msvbvm50.dll 1 optional
+modules\optional\msvbvm60.dll 1 optional
+modules\optional\msvcirt.dll 1 optional
+modules\optional\msvcp71.dll 1 optional
+modules\optional\msvcr71.dll 1 optional
+modules\optional\vmx_fb.dll 1 optional
+modules\optional\vmx_mode.dll 1 optional
+modules\optional\vmx_svga.inf 6 optional
+modules\optional\vmx_svga.sys 2 optional
+modules\optional\wine_gecko-1.0.0-x86.cab 4 optional
+
+; Rosapps
+modules\rosapps\applications\screensavers\cylfrac\cylfrac.scr 1 optional
+modules\rosapps\applications\screensavers\matrix\matrix.scr 1 optional
+modules\rosapps\applications\screensavers\blankscr\scrnsave.scr 1 optional
+modules\rosapps\applications\screensavers\starfield\starfield.scr 1 optional
+modules\rosapps\applications\screensavers\mazescr\mazescr.scr 1 optional
+modules\rosapps\applications\screensavers\butterflies\butterflies.scr 1 optional
+modules\rosapps\applications\cmdutils\comp\comp.exe 1 optional
+modules\rosapps\applications\cmdutils\mode\mode.exe 1 optional
+modules\rosapps\applications\cmdutils\sort\sort.exe 1 optional
+modules\rosapps\applications\cmdutils\tee\tee.exe 1 optional
+modules\rosapps\applications\cmdutils\touch\touch.exe 1 optional
+modules\rosapps\applications\cmdutils\uptime\uptime.exe 1 optional
+modules\rosapps\applications\cmdutils\y\y.exe 1 optional
+modules\rosapps\applications\devutils\gdb2\gdb2.exe 1 optional
+modules\rosapps\applications\devutils\gdihv\gdihv.exe 1 optional
+modules\rosapps\applications\devutils\genguid\genguid.exe 1 optional
+modules\rosapps\applications\sysutils\gettype\gettype.exe 1 optional
+modules\rosapps\applications\net\ncftp\ncftp.exe 1 optional
+modules\rosapps\applications\net\netreg\netreg.exe 1 optional
+modules\rosapps\applications\net\niclist\niclist.exe 1 optional
+modules\rosapps\applications\net\roshttpd\roshttpd.exe 1 optional
+modules\rosapps\applications\notevil\notevil.exe 1 optional
+modules\rosapps\applications\sysutils\chkdsk\chkdsk.exe 1 optional
+modules\rosapps\applications\sysutils\systeminfo\systeminfo.exe 1 optional
+modules\rosapps\applications\sysutils\chklib\chklib.exe 1 optional
+modules\rosapps\applications\sysutils\ctm\ctm.exe 1 optional
+modules\rosapps\applications\sysutils\kill\kill.exe 1 optional
+modules\rosapps\applications\sysutils\lsdd\lsdd.exe 1 optional
+modules\rosapps\applications\sysutils\man\man.exe 1 optional
+modules\rosapps\applications\sysutils\pedump\pedump.exe 1 optional
+modules\rosapps\applications\sysutils\regexpl\regexpl.exe 1 optional
+modules\rosapps\applications\sysutils\tcat\tcat.exe 1 optional
+modules\rosapps\applications\sysutils\tlist\tlist.exe 1 optional
+modules\rosapps\applications\sysutils\screenshot\screenshot.exe 1 optional
+modules\rosapps\applications\sysutils\utils\binpatch\binpatch.exe 1 optional
+modules\rosapps\applications\sysutils\utils\cat\cat.exe 1 optional
+modules\rosapps\applications\sysutils\utils\driver\load\load.exe 1 optional
+modules\rosapps\applications\sysutils\utils\driver\unload\unload.exe 1 optional
+modules\rosapps\applications\sysutils\utils\infinst\infinst.exe 1 optional
+modules\rosapps\applications\sysutils\utils\nts2w32err\nts2w32err.exe 1 optional
+modules\rosapps\applications\sysutils\utils\objdir\objdir.exe 1 optional
+modules\rosapps\applications\sysutils\utils\partinfo\partinfo.exe 1 optional
+modules\rosapps\applications\sysutils\utils\ps\ps.exe 1 optional
+modules\rosapps\applications\sysutils\utils\rosperf\rosperf.exe 1 optional
+modules\rosapps\applications\sysutils\utils\stats\stats.exe 1 optional
+modules\rosapps\applications\sysutils\utils\tickcount\tickcount.exe 1 optional
+modules\rosapps\applications\winfile\winfile.exe 1 optional
+modules\rosapps\demos\maze\maze.exe 1 optional
+modules\rosapps\drivers\green\green.sys 2 optional
+
+; Rostests
+modules\rostests\rosautotest\rosautotest.exe 1 optional
+modules\rostests\tests\pseh2\pseh2_test.exe 7 optional
+modules\rostests\winetests\advapi32\advapi32_winetest.exe 7 optional
+modules\rostests\winetests\advpack\advpack_winetest.exe 7 optional
+modules\rostests\winetests\browseui\browseui_winetest.exe 7 optional
+modules\rostests\winetests\cabinet\cabinet_winetest.exe 7 optional
+modules\rostests\winetests\comcat\comcat_winetest.exe 7 optional
+modules\rostests\winetests\comctl32\comctl32_winetest.exe 7 optional
+modules\rostests\winetests\comdlg32\comdlg32_winetest.exe 7 optional
+modules\rostests\winetests\crypt32\crypt32_winetest.exe 7 optional
+modules\rostests\winetests\cryptnet\cryptnet_winetest.exe 7 optional
+modules\rostests\winetests\dsound\dsound_winetest.exe 7 optional
+modules\rostests\winetests\gdi32\gdi32_winetest.exe 7 optional
+modules\rostests\winetests\gdiplus\gdiplus_winetest.exe 7 optional
+modules\rostests\winetests\hlink\hlink_winetest.exe 7 optional
+modules\rostests\winetests\icmp\icmp_winetest.exe 7 optional
+modules\rostests\winetests\iphlpapi\iphlpapi_winetest.exe 7 optional
+modules\rostests\winetests\jscript\jscript_winetest.exe 7 optional
+modules\rostests\winetests\kernel32\kernel32_winetest.exe 7 optional
+modules\rostests\winetests\lz32\lz32_winetest.exe 7 optional
+modules\rostests\winetests\mapi32\mapi32_winetest.exe 7 optional
+modules\rostests\winetests\mlang\mlang_winetest.exe 7 optional
+modules\rostests\winetests\mshtml\mshtml_winetest.exe 7 optional
+modules\rostests\winetests\msi\msi_winetest.exe 7 optional
+modules\rostests\winetests\mstask\mstask_winetest.exe 7 optional
+modules\rostests\winetests\msvcrt\msvcrt_winetest.exe 7 optional
+modules\rostests\winetests\msxml3\msxml3_winetest.exe 7 optional
+modules\rostests\winetests\netapi32\netapi32_winetest.exe 7 optional
+modules\rostests\winetests\ntdll\ntdll_winetest.exe 7 optional
+modules\rostests\winetests\odbccp32\odbccp32_winetest.exe 7 optional
+modules\rostests\winetests\ole32\ole32_winetest.exe 7 optional
+modules\rostests\winetests\oleaut32\oleaut32_winetest.exe 7 optional
+modules\rostests\winetests\powrprof\powrprof_winetest.exe 7 optional
+modules\rostests\winetests\psapi\psapi_winetest.exe 7 optional
+modules\rostests\winetests\riched20\riched20_winetest.exe 7 optional
+modules\rostests\winetests\rpcrt4\rpcrt4_winetest.exe 7 optional
+modules\rostests\winetests\rsabase\rsabase_winetest.exe 7 optional
+modules\rostests\winetests\rsaenh\rsaenh_winetest.exe 7 optional
+modules\rostests\winetests\schannel\schannel_winetest.exe 7 optional
+modules\rostests\winetests\secur32\secur32_winetest.exe 7 optional
+modules\rostests\winetests\setupapi\setupapi_winetest.exe 7 optional
+modules\rostests\winetests\shdocvw\shdocvw_winetest.exe 7 optional
+modules\rostests\winetests\shell32\shell32_winetest.exe 7 optional
+modules\rostests\winetests\shlwapi\shlwapi_winetest.exe 7 optional
+modules\rostests\winetests\urlmon\urlmon_winetest.exe 7 optional
+modules\rostests\winetests\user32\user32_winetest.exe 7 optional
+modules\rostests\winetests\usp10\usp10_winetest.exe 7 optional
+modules\rostests\winetests\uxtheme\uxtheme_winetest.exe 7 optional
+modules\rostests\winetests\version\version_winetest.exe 7 optional
+modules\rostests\winetests\winhttp\winhttp_winetest.exe 7 optional
+modules\rostests\winetests\wininet\wininet_winetest.exe 7 optional
+modules\rostests\winetests\winmm\winmm_winetest.exe 7 optional
+modules\rostests\winetests\wintrust\wintrust_winetest.exe 7 optional
+modules\rostests\winetests\wlanapi\wlanapi_winetest.exe 7 optional
+modules\rostests\winetests\ws2_32\ws2_32_winetest.exe 7 optional
+modules\rostests\winetests\xmllite\xmllite_winetest.exe 7 optional
+
+
+modules\wallpaper\Angelus_02_ROSWP.bmp 4 optional
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Support for physical devices
+ * FILE: subsystems/win32/win32k/eng/pdevobj.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#include <w32k.h>
+
+#include <intrin.h>
+
+#define NDEBUG
+#include <debug.h>
+
+static PPDEVOBJ gppdevList = NULL;
+PPDEVOBJ gppdevPrimary = NULL;
+static HSEMAPHORE ghsemPDEV;
+
+BOOL
+NTAPI
+InitPDEVImpl()
+{
+ ghsemPDEV = EngCreateSemaphore();
+ return TRUE;
+}
+
+
+PPDEVOBJ
+PDEVOBJ_AllocPDEV()
+{
+ PPDEVOBJ ppdev;
+
+ ppdev = ExAllocatePoolWithTag(PagedPool, sizeof(PDEVOBJ), GDITAG_PDEV);
+ if (!ppdev)
+ return NULL;
+
+ RtlZeroMemory(ppdev, sizeof(PDEVOBJ));
+
+ ppdev->cPdevRefs = 1;
+
+ return ppdev;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vRelease(PPDEVOBJ ppdev)
+{
+ /* Lock loader */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ /* Decrease reference count */
+ --ppdev->cPdevRefs;
+
+ ASSERT(ppdev->cPdevRefs >= 0) ;
+
+ /* Check if references are left */
+ if (ppdev->cPdevRefs == 0)
+ {
+ /* Do we have a surface? */
+ if(ppdev->pSurface)
+ {
+ /* Release the surface and let the driver free it */
+ SURFACE_ShareUnlockSurface(ppdev->pSurface);
+ ppdev->pfn.DisableSurface(ppdev->dhpdev);
+ }
+
+ /* Disable PDEV */
+ ppdev->pfn.DisablePDEV(ppdev->dhpdev);
+
+ /* Remove it from list */
+ if( ppdev == gppdevList )
+ gppdevList = ppdev->ppdevNext ;
+ else
+ {
+ PPDEVOBJ ppdevCurrent = gppdevList;
+ BOOL found = FALSE ;
+ while (!found && ppdevCurrent->ppdevNext)
+ {
+ if (ppdevCurrent->ppdevNext == ppdev)
+ found = TRUE;
+ else
+ ppdevCurrent = ppdevCurrent->ppdevNext ;
+ }
+ if(found)
+ ppdevCurrent->ppdevNext = ppdev->ppdevNext;
+ }
+
+ /* Is this the primary one ? */
+ if (ppdev == gppdevPrimary)
+ gppdevPrimary = NULL;
+
+ /* Free it */
+ ExFreePoolWithTag(ppdev, GDITAG_PDEV );
+ }
+
+ /* Unlock loader */
+ EngReleaseSemaphore(ghsemPDEV);
+
+}
+
+BOOL
+NTAPI
+PDEVOBJ_bEnablePDEV(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdevmode,
+ PWSTR pwszLogAddress)
+{
+ PFN_DrvEnablePDEV pfnEnablePDEV;
+
+ DPRINT1("PDEVOBJ_bEnablePDEV()\n");
+
+ /* Get the DrvEnablePDEV function */
+ pfnEnablePDEV = ppdev->pldev->pfn.EnablePDEV;
+
+ /* Call the drivers DrvEnablePDEV function */
+ ppdev->dhpdev = pfnEnablePDEV(pdevmode,
+ pwszLogAddress,
+ HS_DDI_MAX,
+ ppdev->ahsurf,
+ sizeof(GDIINFO),
+ &ppdev->gdiinfo,
+ sizeof(DEVINFO),
+ &ppdev->devinfo,
+ (HDEV)ppdev,
+ ppdev->pGraphicsDevice->pwszDescription,
+ ppdev->pGraphicsDevice->DeviceObject);
+
+ DPRINT1("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev);
+
+ return TRUE;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vCompletePDEV(
+ PPDEVOBJ ppdev)
+{
+ /* Call the drivers DrvCompletePDEV function */
+ ppdev->pldev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
+}
+
+PSURFACE
+NTAPI
+PDEVOBJ_pSurface(
+ PPDEVOBJ ppdev)
+{
+ HSURF hsurf;
+
+ DPRINT1("PDEVOBJ_pSurface()\n");
+
+ /* Check if we already have a surface */
+ if (ppdev->pSurface)
+ {
+ /* Increment reference count */
+ GDIOBJ_IncrementShareCount(&ppdev->pSurface->BaseObject);
+ }
+ else
+ {
+ /* Call the drivers DrvEnableSurface */
+ hsurf = ppdev->pldev->pfn.EnableSurface(ppdev->dhpdev);
+
+ /* Lock the surface */
+ ppdev->pSurface = SURFACE_ShareLockSurface(hsurf);
+ }
+
+ DPRINT1("PDEVOBJ_pSurface() returning %p\n", ppdev->pSurface);
+ return ppdev->pSurface;
+}
+
+PDEVMODEW
+NTAPI
+PDEVOBJ_pdmMatchDevMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PDEVMODEW pdmCurrent;
+ INT i;
+
+ pGraphicsDevice = ppdev->pGraphicsDevice;
+
+ for (i = 0; i < pGraphicsDevice->cDevModes; i++)
+ {
+ pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
+
+ /* Compare DEVMODE fields */
+ if (pdmCurrent->dmBitsPerPel == pdm->dmBitsPerPel &&
+ pdmCurrent->dmPelsWidth == pdm->dmPelsWidth &&
+ pdmCurrent->dmPelsHeight == pdm->dmPelsHeight &&
+ pdmCurrent->dmDisplayFrequency == pdm->dmDisplayFrequency)
+ {
+ /* Match! Return the DEVMODE */
+ return pdmCurrent;
+ }
+ }
+
+ /* Nothing found */
+ return NULL;
+}
+
+
+static
+PPDEVOBJ
+EngpCreatePDEV(
+ PUNICODE_STRING pustrDeviceName,
+ PDEVMODEW pdm)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PPDEVOBJ ppdev;
+
+ /* Try to find the GRAPHICS_DEVICE */
+ pGraphicsDevice = EngpFindGraphicsDevice(pustrDeviceName, 0, 0);
+ if (!pGraphicsDevice)
+ {
+ DPRINT1("No GRAPHICS_DEVICE found for %ls!\n",
+ pustrDeviceName ? pustrDeviceName->Buffer : 0);
+ return NULL;
+ }
+
+ /* Allocate a new PDEVOBJ */
+ ppdev = PDEVOBJ_AllocPDEV();
+ if (!ppdev)
+ {
+ DPRINT1("failed to allocate a PDEV\n");
+ return NULL;
+ }
+
+ /* If no DEVMODEW is given, ... */
+ if (!pdm)
+ {
+ /* ... use the device's default one */
+ pdm = pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm;
+ DPRINT1("Using iDefaultMode = %ld\n", pGraphicsDevice->iDefaultMode);
+ }
+
+ /* Try to get a diplay driver */
+ ppdev->pldev = EngLoadDriver(pdm->dmDeviceName, LDEV_DEVICE_DISPLAY);
+ if (!ppdev->pldev)
+ {
+ DPRINT1("Could not load diplsay driver '%ls'\n", pGraphicsDevice->pDiplayDrivers);
+ ExFreePoolWithTag(ppdev, GDITAG_PDEV);
+ return NULL;
+ }
+
+ /* Copy the function table */
+ ppdev->pfn = ppdev->pldev->pfn;
+
+ /* Set MovePointer function */
+ ppdev->pfnMovePointer = ppdev->pfn.MovePointer;
+ if (!ppdev->pfnMovePointer)
+ ppdev->pfnMovePointer = EngMovePointer;
+
+ ppdev->pGraphicsDevice = pGraphicsDevice;
+ ppdev->hsemDevLock = EngCreateSemaphore();
+ ppdev->pdmwDev = pGraphicsDevice->pDevModeList[pGraphicsDevice->iCurrentMode].pdm;
+
+ /* FIXME! */
+ ppdev->flFlags = PDEV_DISPLAY;
+
+ /* HACK: Don't use the pointer */
+ ppdev->Pointer.Exclude.right = -1;
+
+ /* Call the driver to enable the PDEV */
+ if (!PDEVOBJ_bEnablePDEV(ppdev, pdm, NULL))
+ {
+ DPRINT1("Failed to enable PDEV!\n");
+ ASSERT(FALSE);
+ }
+
+ /* Fix up some values */
+ if (ppdev->gdiinfo.ulLogPixelsX == 0)
+ ppdev->gdiinfo.ulLogPixelsX = 96;
+
+ if (ppdev->gdiinfo.ulLogPixelsY == 0)
+ ppdev->gdiinfo.ulLogPixelsY = 96;
+
+ /* FIXME: this must be done in a better way */
+ pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
+
+ /* Tell the driver that the PDEV is ready */
+ PDEVOBJ_vCompletePDEV(ppdev);
+
+ /* Return the PDEV */
+ return ppdev;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vSwitchPdev(
+ PPDEVOBJ ppdev,
+ PPDEVOBJ ppdev2)
+{
+ PDEVOBJ pdevTmp;
+ HDEV hdev;
+
+ /* Exchange data */
+ pdevTmp = *ppdev;
+
+ /* Exchange driver functions */
+ ppdev->pfn = ppdev2->pfn;
+ ppdev2->pfn = pdevTmp.pfn;
+
+ /* Exchange LDEVs */
+ ppdev->pldev = ppdev2->pldev;
+ ppdev2->pldev = pdevTmp.pldev;
+
+ /* Exchange DHPDEV */
+ ppdev->dhpdev = ppdev2->dhpdev;
+ ppdev2->dhpdev = pdevTmp.dhpdev;
+
+ /* Exchange surface */
+ ppdev->pSurface = ppdev2->pSurface;
+ ppdev2->pSurface = pdevTmp.pSurface;
+ hdev = ppdev->pSurface->SurfObj.hdev;
+ ppdev->pSurface->SurfObj.hdev = ppdev2->pSurface->SurfObj.hdev;
+ ppdev2->pSurface->SurfObj.hdev = hdev;
+
+ /* Exchange devinfo */
+ ppdev->devinfo = ppdev2->devinfo;
+ ppdev2->devinfo = pdevTmp.devinfo;
+
+ /* Exchange gdiinfo */
+ ppdev->gdiinfo = ppdev2->gdiinfo;
+ ppdev2->gdiinfo = pdevTmp.gdiinfo;
+
+ /* Notify each driver instance of its new HDEV association */
+ ppdev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
+ ppdev2->pfn.CompletePDEV(ppdev2->dhpdev, (HDEV)ppdev2);
+}
+
+
+BOOL
+NTAPI
+PDEVOBJ_bSwitchMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm)
+{
+ UNICODE_STRING ustrDevice;
+ PPDEVOBJ ppdevTmp;
+ PSURFACE pSurface;
+ BOOL retval = FALSE;
+
+ /* Lock the PDEV */
+ EngAcquireSemaphore(ppdev->hsemDevLock);
+ /* And everything else */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
+
+ // Lookup the GraphicsDevice + select DEVMODE
+ // pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
+
+ /* 1. Temporarily disable the current PDEV */
+ if (!ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE))
+ {
+ DPRINT1("DrvAssertMode failed\n");
+ goto leave;
+ }
+
+ /* 2. Create new PDEV */
+ RtlInitUnicodeString(&ustrDevice, ppdev->pGraphicsDevice->szWinDeviceName);
+ ppdevTmp = EngpCreatePDEV(&ustrDevice, pdm);
+ if (!ppdevTmp)
+ {
+ DPRINT1("Failed to create a new PDEV\n");
+ goto leave;
+ }
+
+ /* 3. Create a new surface */
+ pSurface = PDEVOBJ_pSurface(ppdevTmp);
+ if (!pSurface)
+ {
+ DPRINT1("DrvEnableSurface failed\n");
+ goto leave;
+ }
+
+ ASSERT(pSurface->BitsLock);
+
+ /* 4. Get DirectDraw information */
+ /* 5. Enable DirectDraw Not traced */
+ /* 6. Copy old PDEV state to new PDEV instance */
+
+ /* 7. Switch the PDEVs */
+ PDEVOBJ_vSwitchPdev(ppdev, ppdevTmp);
+ ASSERT(ppdev->pSurface->BitsLock);
+
+ /* 8. Disable DirectDraw */
+
+ PDEVOBJ_vRelease(ppdevTmp);
+
+ /* Success! */
+ retval = TRUE;
+leave:
+ /* Unlock PDEV */
+ EngReleaseSemaphore(ppdev->hsemDevLock);
+ EngReleaseSemaphore(ghsemPDEV);
+
+ DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
+ ASSERT(ppdev->pSurface->BitsLock);
+
+ return retval;
+}
+
+
+PPDEVOBJ
+NTAPI
+EngpGetPDEV(
+ PUNICODE_STRING pustrDeviceName)
+{
+ UNICODE_STRING ustrCurrent;
+ PPDEVOBJ ppdev;
+ PGRAPHICS_DEVICE pGraphicsDevice;
+
+ /* Acquire PDEV lock */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ /* If no device name is given, ... */
+ if (!pustrDeviceName && gppdevPrimary)
+ {
+ /* ... use the primary PDEV */
+ ppdev = gppdevPrimary;
+
+ /* Reference the pdev */
+ InterlockedIncrement(&ppdev->cPdevRefs);
+ goto leave;
+ }
+
+ /* Loop all present PDEVs */
+ for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
+ {
+ /* Get a pointer to the GRAPHICS_DEVICE */
+ pGraphicsDevice = ppdev->pGraphicsDevice;
+
+ /* Compare the name */
+ RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
+ if (RtlEqualUnicodeString(pustrDeviceName, &ustrCurrent, FALSE))
+ {
+ /* Found! Reference the PDEV */
+ InterlockedIncrement(&ppdev->cPdevRefs);
+ break;
+ }
+ }
+
+ /* Did we find one? */
+ if (!ppdev)
+ {
+ /* No, create a new PDEV */
+ ppdev = EngpCreatePDEV(pustrDeviceName, NULL);
+ if (ppdev)
+ {
+ /* Insert the PDEV into the list */
+ ppdev->ppdevNext = gppdevList;
+ gppdevList = ppdev;
+
+ /* Set as primary PDEV, if we don't have one yet */
+ if (!gppdevPrimary)
+ {
+ gppdevPrimary = ppdev;
+ }
+ }
+ }
+
+leave:
+ /* Release PDEV lock */
+ EngReleaseSemaphore(ghsemPDEV);
+
+ return ppdev;
+}
+
+INT
+NTAPI
+PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev)
+{
+ INT ret = CM_NONE;
+
+ if (ppdev->flFlags & PDEV_DISPLAY)
+ {
+ if (ppdev->devinfo.iDitherFormat == BMF_8BPP ||
+ ppdev->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP)
+ ret = CM_GAMMA_RAMP;
+ }
+
+ if (ppdev->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR)
+ ret |= CM_CMYK_COLOR;
+ if (ppdev->devinfo.flGraphicsCaps & GCAPS_ICM)
+ ret |= CM_DEVICE_ICM;
+
+ return ret;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vGetDeviceCaps(
+ IN PPDEVOBJ ppdev,
+ OUT PDEVCAPS pDevCaps)
+{
+ PGDIINFO pGdiInfo = &ppdev->gdiinfo;
+
+ pDevCaps->ulVersion = pGdiInfo->ulVersion;
+ pDevCaps->ulTechnology = pGdiInfo->ulTechnology;
+ pDevCaps->ulHorzSizeM = (pGdiInfo->ulHorzSize + 500) / 1000;
+ pDevCaps->ulVertSizeM = (pGdiInfo->ulVertSize + 500) / 1000;
+ pDevCaps->ulHorzSize = pGdiInfo->ulHorzSize;
+ pDevCaps->ulVertSize = pGdiInfo->ulVertSize;
+ pDevCaps->ulHorzRes = pGdiInfo->ulHorzRes;
+ pDevCaps->ulVertRes = pGdiInfo->ulVertRes;
+ pDevCaps->ulBitsPixel = pGdiInfo->cBitsPixel;
+ if (pDevCaps->ulBitsPixel == 15) pDevCaps->ulBitsPixel = 16;
+ pDevCaps->ulPlanes = pGdiInfo->cPlanes;
+ pDevCaps->ulNumPens = pGdiInfo->ulNumColors;
+ if (pDevCaps->ulNumPens != -1) pDevCaps->ulNumPens *= 5;
+ pDevCaps->ulNumFonts = 0; // PDEVOBJ_cFonts(ppdev);
+ pDevCaps->ulNumColors = pGdiInfo->ulNumColors;
+ pDevCaps->ulRasterCaps = pGdiInfo->flRaster;
+ pDevCaps->ulAspectX = pGdiInfo->ulAspectX;
+ pDevCaps->ulAspectY = pGdiInfo->ulAspectY;
+ pDevCaps->ulAspectXY = pGdiInfo->ulAspectXY;
+ pDevCaps->ulLogPixelsX = pGdiInfo->ulLogPixelsX;
+ pDevCaps->ulLogPixelsY = pGdiInfo->ulLogPixelsY;
+ pDevCaps->ulSizePalette = pGdiInfo->ulNumPalReg;
+ pDevCaps->ulColorRes = pGdiInfo->ulDACRed +
+ pGdiInfo->ulDACGreen +
+ pGdiInfo->ulDACBlue;
+ pDevCaps->ulPhysicalWidth = pGdiInfo->szlPhysSize.cx;
+ pDevCaps->ulPhysicalHeight = pGdiInfo->szlPhysSize.cy;
+ pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x;
+ pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y;
+ pDevCaps->ulTextCaps = pGdiInfo->flTextCaps;
+ pDevCaps->ulTextCaps |= (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
+ if (pGdiInfo->ulTechnology != DT_PLOTTER)
+ pDevCaps->ulTextCaps |= TC_VA_ABLE;
+ pDevCaps->ulVRefresh = pGdiInfo->ulVRefresh;
+ pDevCaps->ulDesktopHorzRes = pGdiInfo->ulHorzRes;
+ pDevCaps->ulDesktopVertRes = pGdiInfo->ulVertRes;
+ pDevCaps->ulBltAlignment = pGdiInfo->ulBltAlignment;
+ pDevCaps->ulPanningHorzRes = pGdiInfo->ulPanningHorzRes;
+ pDevCaps->ulPanningVertRes = pGdiInfo->ulPanningVertRes;
+ pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment;
+ pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment;
+ pDevCaps->ulShadeBlend = pGdiInfo->flShadeBlend;
+ pDevCaps->ulColorMgmtCaps = PDEVOBJ_iGetColorManagementCaps(ppdev);
+}
+
+
+/** Exported functions ********************************************************/
+
+LPWSTR
+APIENTRY
+EngGetDriverName(IN HDEV hdev)
+{
+ PPDEVOBJ ppdev = (PPDEVOBJ)hdev;
+ PLDEVOBJ pldev;
+
+ if (!hdev)
+ return NULL;
+
+ pldev = ppdev->pldev;
+ ASSERT(pldev);
+
+ if (!pldev->pGdiDriverInfo)
+ return NULL;
+
+ return pldev->pGdiDriverInfo->DriverName.Buffer;
+}
+
+
+INT
+APIENTRY
+NtGdiGetDeviceCaps(
+ HDC hdc,
+ INT Index)
+{
+ PDC pdc;
+ DEVCAPS devcaps;
+
+ /* Lock the given DC */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ /* Get the data */
+ PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+
+ /* Return capability */
+ switch (Index)
+ {
+ case DRIVERVERSION:
+ return devcaps.ulVersion;
+
+ case TECHNOLOGY:
+ return devcaps.ulTechnology;
+
+ case HORZSIZE:
+ return devcaps.ulHorzSize;
+
+ case VERTSIZE:
+ return devcaps.ulVertSize;
+
+ case HORZRES:
+ return devcaps.ulHorzRes;
+
+ case VERTRES:
+ return devcaps.ulVertRes;
+
+ case LOGPIXELSX:
+ return devcaps.ulLogPixelsX;
+
+ case LOGPIXELSY:
+ return devcaps.ulLogPixelsY;
+
+ case BITSPIXEL:
+ return devcaps.ulBitsPixel;
+
+ case PLANES:
+ return devcaps.ulPlanes;
+
+ case NUMBRUSHES:
+ return -1;
+
+ case NUMPENS:
+ return devcaps.ulNumPens;
+
+ case NUMFONTS:
+ return devcaps.ulNumFonts;
+
+ case NUMCOLORS:
+ return devcaps.ulNumColors;
+
+ case ASPECTX:
+ return devcaps.ulAspectX;
+
+ case ASPECTY:
+ return devcaps.ulAspectY;
+
+ case ASPECTXY:
+ return devcaps.ulAspectXY;
+
+ case CLIPCAPS:
+ return CP_RECTANGLE;
+
+ case SIZEPALETTE:
+ return devcaps.ulSizePalette;
+
+ case NUMRESERVED:
+ return 20;
+
+ case COLORRES:
+ return devcaps.ulColorRes;
+
+ case DESKTOPVERTRES:
+ return devcaps.ulVertRes;
+
+ case DESKTOPHORZRES:
+ return devcaps.ulHorzRes;
+
+ case BLTALIGNMENT:
+ return devcaps.ulBltAlignment;
+
+ case SHADEBLENDCAPS:
+ return devcaps.ulShadeBlend;
+
+ case COLORMGMTCAPS:
+ return devcaps.ulColorMgmtCaps;
+
+ case PHYSICALWIDTH:
+ return devcaps.ulPhysicalWidth;
+
+ case PHYSICALHEIGHT:
+ return devcaps.ulPhysicalHeight;
+
+ case PHYSICALOFFSETX:
+ return devcaps.ulPhysicalOffsetX;
+
+ case PHYSICALOFFSETY:
+ return devcaps.ulPhysicalOffsetY;
+
+ case VREFRESH:
+ return devcaps.ulVRefresh;
+
+ case RASTERCAPS:
+ return devcaps.ulRasterCaps;
+
+ case CURVECAPS:
+ return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
+ CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
+
+ case LINECAPS:
+ return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+ LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
+
+ case POLYGONALCAPS:
+ return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
+ PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
+
+ case TEXTCAPS:
+ return devcaps.ulTextCaps;
+
+ case CAPS1:
+ case PDEVICESIZE:
+ case SCALINGFACTORX:
+ case SCALINGFACTORY:
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+
+BOOL
+APIENTRY
+NtGdiGetDeviceCapsAll(
+ IN HDC hDC,
+ OUT PDEVCAPS pDevCaps)
+{
+ PDC pdc;
+ DEVCAPS devcaps;
+ BOOL bResult = TRUE;
+
+ /* Lock the given DC */
+ pdc = DC_LockDc(hDC);
+ if (!pdc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ /* Get the data */
+ PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+
+ /* Copy data to caller */
+ _SEH2_TRY
+ {
+ ProbeForWrite(pDevCaps, sizeof(DEVCAPS), 1);
+ RtlCopyMemory(pDevCaps, &devcaps, sizeof(DEVCAPS));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ bResult = FALSE;
+ }
+ _SEH2_END;
+
+ return bResult;
+}
+
+DHPDEV
+APIENTRY
+NtGdiGetDhpdev(
+ IN HDEV hdev)
+{
+ PPDEVOBJ ppdev;
+ DHPDEV dhpdev = NULL;
+
+ /* Check parameter */
+ if (!hdev || (PCHAR)hdev < (PCHAR)MmSystemRangeStart)
+ return NULL;
+
+ /* Lock PDEV list */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ /* Walk through the list of PDEVs */
+ for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
+ {
+ /* Compare with the given HDEV */
+ if (ppdev == hdev)
+ {
+ /* Found the PDEV! Get it's dhpdev and break */
+ dhpdev = ppdev->dhpdev;
+ break;
+ }
+ }
+
+ /* Unlock PDEV list */
+ EngReleaseSemaphore(ghsemPDEV);
+
+ return dhpdev;
+}
++
++PSIZEL
++FASTCALL
++PDEVOBJ_sizl(PPDEVOBJ ppdev, PSIZEL psizl)
++{
++ if (ppdev->flFlags & PDEV_META_DEVICE)
++ {
++ psizl->cx = ppdev->ulHorzRes;
++ psizl->cy = ppdev->ulVertRes;
++ }
++ else
++ {
++ psizl->cx = ppdev->gdiinfo.ulHorzRes;
++ psizl->cy = ppdev->gdiinfo.ulVertRes;
++ }
++ return psizl;
++}
--- /dev/null
+#ifndef __WIN32K_DC_H
+#define __WIN32K_DC_H
+
+typedef struct _DC *PDC;
+
+#include "engobjects.h"
+#include "brush.h"
+#include "bitmaps.h"
+#include "pdevobj.h"
+#include "palette.h"
+#include "region.h"
+
+/* Constants ******************************************************************/
+
+/* Get/SetBounds/Rect support. */
+#define DCB_WINDOWMGR 0x8000 /* Queries the Windows bounding rectangle instead of the application's */
+
+/* flFontState */
+#define DC_DIRTYFONT_XFORM 1
+#define DC_DIRTYFONT_LFONT 2
+#define DC_UFI_MAPPING 4
+
+/* fl */
+#define DC_FL_PAL_BACK 1
+
+#define DC_DISPLAY 1
+#define DC_DIRECT 2
+#define DC_CANCELED 4
+#define DC_PERMANANT 0x08
+#define DC_DIRTY_RAO 0x10
+#define DC_ACCUM_WMGR 0x20
+#define DC_ACCUM_APP 0x40
+#define DC_RESET 0x80
+#define DC_SYNCHRONIZEACCESS 0x100
+#define DC_EPSPRINTINGESCAPE 0x200
+#define DC_TEMPINFODC 0x400
+#define DC_FULLSCREEN 0x800
+#define DC_IN_CLONEPDEV 0x1000
+#define DC_REDIRECTION 0x2000
+#define DC_SHAREACCESS 0x4000
+
+typedef enum
+{
+ DCTYPE_DIRECT = 0,
+ DCTYPE_MEMORY = 1,
+ DCTYPE_INFO = 2,
+} DCTYPE;
+
+
+/* Type definitions ***********************************************************/
+
+typedef struct _ROS_DC_INFO
+{
+ HRGN hClipRgn; /* Clip region (may be 0) */
+ HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */
+
+ BYTE bitsPerPixel;
+
+ CLIPOBJ *CombinedClip;
+
+ UNICODE_STRING DriverName;
+
+} ROS_DC_INFO;
+
+typedef struct _DCLEVEL
+{
+ HPALETTE hpal;
+ struct _PALETTE * ppal;
+ PVOID pColorSpace; /* COLORSPACE* */
+ LONG lIcmMode;
+ LONG lSaveDepth;
+ DWORD unk1_00000000;
+ HGDIOBJ hdcSave;
+ POINTL ptlBrushOrigin;
+ PBRUSH pbrFill;
+ PBRUSH pbrLine;
+ PVOID plfnt; /* LFONTOBJ* (TEXTOBJ*) */
+ HGDIOBJ hPath; /* HPATH */
+ FLONG flPath;
+ LINEATTRS laPath; /* 0x20 bytes */
+ PVOID prgnClip; /* PROSRGNDATA */
+ PVOID prgnMeta;
+ COLORADJUSTMENT ca;
+ FLONG flFontState;
+ UNIVERSAL_FONT_ID ufi;
+ UNIVERSAL_FONT_ID ufiLoc[4]; /* Local List. */
+ UNIVERSAL_FONT_ID *pUFI;
+ ULONG uNumUFIs;
+ BOOL ufiSet;
+ FLONG fl;
+ FLONG flBrush;
+ MATRIX mxWorldToDevice;
+ MATRIX mxDeviceToWorld;
+ MATRIX mxWorldToPage;
+ FLOATOBJ efM11PtoD;
+ FLOATOBJ efM22PtoD;
+ FLOATOBJ efDxPtoD;
+ FLOATOBJ efDyPtoD;
+ FLOATOBJ efM11_TWIPS;
+ FLOATOBJ efM22_TWIPS;
+ FLOATOBJ efPr11;
+ FLOATOBJ efPr22;
+ PSURFACE pSurface;
+ SIZE sizl;
+} DCLEVEL, *PDCLEVEL;
+
+/* The DC object structure */
+typedef struct _DC
+{
+ /* Header for all gdi objects in the handle table.
+ Do not (re)move this. */
+ BASEOBJECT BaseObject;
+
+ DHPDEV dhpdev; /* <- PDEVOBJ.hPDev DHPDEV for device. */
+ INT dctype;
+ INT fs;
+ PPDEVOBJ ppdev;
+ PVOID hsem; /* PERESOURCE aka HSEMAPHORE */
+ FLONG flGraphicsCaps;
+ FLONG flGraphicsCaps2;
+ PDC_ATTR pdcattr;
+ DCLEVEL dclevel;
+ DC_ATTR dcattr;
+ HDC hdcNext;
+ HDC hdcPrev;
+ RECTL erclClip;
+ POINTL ptlDCOrig;
+ RECTL erclWindow;
+ RECTL erclBounds;
+ RECTL erclBoundsApp;
+ PREGION prgnAPI; /* PROSRGNDATA */
+ PREGION prgnVis; /* Visible region (must never be 0) */
+ PREGION prgnRao;
+ POINTL ptlFillOrigin;
+ EBRUSHOBJ eboFill;
+ EBRUSHOBJ eboLine;
+ EBRUSHOBJ eboText;
+ EBRUSHOBJ eboBackground;
+ HFONT hlfntCur;
+ FLONG flSimulationFlags;
+ LONG lEscapement;
+ PVOID prfnt; /* RFONT* */
+ XCLIPOBJ co; /* CLIPOBJ */
+ PVOID pPFFList; /* PPFF* */
+ PVOID pClrxFormLnk;
+ INT ipfdDevMax;
+ ULONG ulCopyCount;
+ PVOID pSurfInfo;
+ POINTL ptlDoBanding;
+
+ /* Reactos specific members */
+ ROS_DC_INFO rosdc;
+} DC;
+
+/* Internal functions *********************************************************/
+
+#if 0
+#define DC_LockDc(hDC) \
+ ((PDC) GDIOBJ_LockObj ((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC))
+#define DC_UnlockDc(pDC) \
+ GDIOBJ_UnlockObjByPtr ((POBJ)pDC)
+#endif
+
+VOID NTAPI EngAcquireSemaphoreShared(IN HSEMAPHORE hsem);
+
+PDC
+FORCEINLINE
+DC_LockDc(HDC hdc)
+{
+ PDC pdc;
+ pdc = GDIOBJ_LockObj(hdc, GDILoObjType_LO_DC_TYPE);
+
+ /* Direct DC's need PDEV locking */
+ if(pdc && pdc->dctype == DCTYPE_DIRECT)
+ {
+ /* Acquire shared PDEV lock */
+ EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
+
+ /* Update Surface if needed */
+ if(pdc->dclevel.pSurface != pdc->ppdev->pSurface)
+ {
+ if(pdc->dclevel.pSurface) SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
+ pdc->dclevel.pSurface = PDEVOBJ_pSurface(pdc->ppdev);
+ }
+ }
+ return pdc;
+}
+
+void
+FORCEINLINE
+DC_UnlockDc(PDC pdc)
+{
+ if(pdc->dctype == DCTYPE_DIRECT)
+ {
+ /* Release PDEV lock */
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+ }
+
+ GDIOBJ_UnlockObjByPtr(&pdc->BaseObject);
+}
+
+
+extern PDC defaultDCstate;
+
+NTSTATUS FASTCALL InitDcImpl(VOID);
+PPDEVOBJ FASTCALL IntEnumHDev(VOID);
+PDC NTAPI DC_AllocDcWithHandle();
+VOID FASTCALL DC_InitDC(HDC DCToInit);
+VOID FASTCALL DC_AllocateDcAttr(HDC);
+VOID FASTCALL DC_FreeDcAttr(HDC);
+BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody);
+BOOL FASTCALL DC_SetOwnership(HDC hDC, PEPROCESS Owner);
+VOID FASTCALL DC_LockDisplay(HDC);
+VOID FASTCALL DC_UnlockDisplay(HDC);
+BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
+
+VOID FASTCALL DC_UpdateXforms(PDC dc);
+BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest);
+VOID FASTCALL DC_vUpdateViewportExt(PDC pdc);
+VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL to);
+VOID FASTCALL DC_vUpdateFillBrush(PDC pdc);
+VOID FASTCALL DC_vUpdateLineBrush(PDC pdc);
+VOID FASTCALL DC_vUpdateTextBrush(PDC pdc);
+VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc);
+
+VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel);
+
+BOOL FASTCALL DCU_SyncDcAttrtoUser(PDC);
+BOOL FASTCALL DCU_SynchDcAttrtoUser(HDC);
+VOID FASTCALL DCU_SetDcUndeletable(HDC);
+VOID NTAPI DC_vFreeDcAttr(PDC pdc);
+VOID NTAPI DC_vInitDc(PDC pdc, DCTYPE dctype, PPDEVOBJ ppdev);
+
+COLORREF FASTCALL IntGdiSetBkColor (HDC hDC, COLORREF Color);
+INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode);
+COLORREF APIENTRY IntGdiGetBkColor(HDC hDC);
+INT APIENTRY IntGdiGetBkMode(HDC hDC);
+COLORREF FASTCALL IntGdiSetTextColor(HDC hDC, COLORREF color);
+UINT FASTCALL IntGdiSetTextAlign(HDC hDC, UINT Mode);
+UINT APIENTRY IntGdiGetTextAlign(HDC hDC);
+COLORREF APIENTRY IntGdiGetTextColor(HDC hDC);
+INT APIENTRY IntGdiSetStretchBltMode(HDC hDC, INT stretchBltMode);
+VOID FASTCALL IntGdiReferencePdev(PPDEVOBJ pPDev);
+VOID FASTCALL IntGdiUnreferencePdev(PPDEVOBJ pPDev, DWORD CleanUpType);
+HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC);
+BOOL FASTCALL IntGdiCleanDC(HDC hDC);
+VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS);
++BOOL FASTCALL MakeInfoDC(PDC,BOOL);
++BOOL FASTCALL IntSetDefaultRegion(PDC);
+
+VOID
+FORCEINLINE
+DC_vSelectSurface(PDC pdc, PSURFACE psurfNew)
+{
+ PSURFACE psurfOld = pdc->dclevel.pSurface;
+ if (psurfOld)
+ SURFACE_ShareUnlockSurface(psurfOld);
+ if (psurfNew)
+ GDIOBJ_IncrementShareCount((POBJ)psurfNew);
+ pdc->dclevel.pSurface = psurfNew;
+}
+
+VOID
+FORCEINLINE
+DC_vSelectFillBrush(PDC pdc, PBRUSH pbrFill)
+{
+ PBRUSH pbrFillOld = pdc->dclevel.pbrFill;
+ if (pbrFillOld)
+ BRUSH_ShareUnlockBrush(pbrFillOld);
+ if (pbrFill)
+ GDIOBJ_IncrementShareCount((POBJ)pbrFill);
+ pdc->dclevel.pbrFill = pbrFill;
+}
+
+VOID
+FORCEINLINE
+DC_vSelectLineBrush(PDC pdc, PBRUSH pbrLine)
+{
+ PBRUSH pbrLineOld = pdc->dclevel.pbrLine;
+ if (pbrLineOld)
+ BRUSH_ShareUnlockBrush(pbrLineOld);
+ if (pbrLine)
+ GDIOBJ_IncrementShareCount((POBJ)pbrLine);
+ pdc->dclevel.pbrLine = pbrLine;
+}
+
+VOID
+FORCEINLINE
+DC_vSelectPalette(PDC pdc, PPALETTE ppal)
+{
+ PPALETTE ppalOld = pdc->dclevel.ppal;
+ if (ppalOld)
+ PALETTE_ShareUnlockPalette(ppalOld);
+ if (ppal)
+ GDIOBJ_IncrementShareCount((POBJ)ppal);
+ pdc->dclevel.ppal = ppal;
+}
+
+#endif /* not __WIN32K_DC_H */
--- /dev/null
-
+#ifndef __WIN32K_PDEVOBJ_H
+#define __WIN32K_PDEVOBJ_H
+
+/* PDEVOBJ flags */
+#define PDEV_DISPLAY 0x00000001 /* Display device */
+#define PDEV_HARDWARE_POINTER 0x00000002 /* Supports hardware cursor */
+#define PDEV_SOFTWARE_POINTER 0x00000004
+#define PDEV_GOTFONTS 0x00000040 /* Has font driver */
+#define PDEV_PRINTER 0x00000080
+#define PDEV_ALLOCATEDBRUSHES 0x00000100
+#define PDEV_HTPAL_IS_DEVPAL 0x00000200
+#define PDEV_DISABLED 0x00000400
+#define PDEV_SYNCHRONIZE_ENABLED 0x00000800
+#define PDEV_FONTDRIVER 0x00002000 /* Font device */
+#define PDEV_GAMMARAMP_TABLE 0x00004000
+#define PDEV_UMPD 0x00008000
+#define PDEV_SHARED_DEVLOCK 0x00010000
+#define PDEV_META_DEVICE 0x00020000
+#define PDEV_DRIVER_PUNTED_CALL 0x00040000 /* Driver calls back to GDI engine */
+#define PDEV_CLONE_DEVICE 0x00080000
+
+/* Type definitions ***********************************************************/
+
+typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ aka HDEV aka PDEV. */
+{
+ /* private GDI pointer handling information, required for software emulation */
+ BOOL Enabled;
+ SIZEL Size;
+ POINTL HotSpot;
+ XLATEOBJ *XlateObject;
+ SURFACE *psurfColor;
+ SURFACE *psurfMask;
+ SURFACE *psurfSave;
+
+ /* public pointer information */
+ RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */
+} GDIPOINTER, *PGDIPOINTER;
+
+typedef struct _DEVMODEINFO
+{
+ struct _DEVMODEINFO *pdmiNext;
+ struct _LDEVOBJ *pldev;
+ ULONG cbdevmode;
+ DEVMODEW adevmode[1];
+} DEVMODEINFO, *PDEVMODEINFO;
+
+typedef struct
+{
+ DWORD dwFlags;
+ PDEVMODEW pdm;
- // ULONG ulHorzRes;
- // ULONG ulVertRes;
++
+} DEVMODEENTRY, *PDEVMODEENTRY;
+
+typedef struct _GRAPHICS_DEVICE
+{
+ WCHAR szNtDeviceName[CCHDEVICENAME/2];
+ WCHAR szWinDeviceName[CCHDEVICENAME/2];
+ struct _GRAPHICS_DEVICE * pNextGraphicsDevice;
+ struct _GRAPHICS_DEVICE * pVgaDevice;
+ PDEVICE_OBJECT DeviceObject;
+ PVOID pDeviceHandle;
+ DWORD hkClassDriverConfig;
+ DWORD StateFlags; /* See DISPLAY_DEVICE_* */
+ ULONG cbdevmodeInfo;
+ PDEVMODEINFO pdevmodeInfo;
+ ULONG cDevModes;
+ PDEVMODEENTRY pDevModeList;
+ LPWSTR pDiplayDrivers;
+ LPWSTR pwszDescription;
+ DWORD dwUnknown;
+ PVOID pUnknown;
+ PFILE_OBJECT FileObject;
+ DWORD ProtocolType;
+ ULONG iDefaultMode;
+ ULONG iCurrentMode;
+} GRAPHICS_DEVICE, *PGRAPHICS_DEVICE;
+
+typedef struct _PDEVOBJ
+{
+ BASEOBJECT BaseObject;
+
+ struct _PDEVOBJ * ppdevNext;
+ LONG cPdevRefs;
+ LONG cPdevOpenRefs;
+ struct _PDEVOBJ * ppdevParent;
+ FLONG flFlags; // flags
+// FLONG flAccelerated;
+ HSEMAPHORE hsemDevLock; /* Device lock. */
+// HSEMAPHORE hsemPointer;
+ POINTL ptlPointer;
+// SIZEL szlPointer;
+// SPRITESTATE SpriteState;
+// HFONT hlfntDefault;
+// HFONT hlfntAnsiVariable;
+// HFONT hlfntAnsiFixed;
+ HSURF ahsurf[HS_DDI_MAX];
+// PUNICODE_STRING pusPrtDataFileName;
+// PVOID pDevHTInfo;
+// RFONT * prfntActive;
+// RFONT * prfntInactive;
+// ULONG cInactive;
+// BYTE ajbo[0x5C];
+// ULONG cDirectDrawDisableLocks;
+// PVOID TypeOneInfo;
+ PVOID pvGammaRamp; /* Gamma ramp pointer. */
+// PVOID RemoteTypeOne;
- // POINTL ptlOrigion;
++ ULONG ulHorzRes;
++ ULONG ulVertRes;
+// PFN_DrvSetPointerShape pfnDrvSetPointerShape;
+// PFN_DrvMovePointer pfnDrvMovePointer;
+ PFN_DrvMovePointer pfnMovePointer;
+// PFN_DrvSynchronize pfnDrvSynchronize;
+// PFN_DrvSynchronizeSurface pfnDrvSynchronizeSurface;
+// PFN_DrvSetPalette pfnDrvSetPalette;
+// PFN_DrvNotify pfnDrvNotify;
+// ULONG TagSig;
+ struct _LDEVOBJ * pldev;
+ DHPDEV dhpdev; /* DHPDEV for device. */
+ PVOID ppalSurf; /* PEPALOBJ/PPALETTE for this device. */
+ DEVINFO devinfo;
+ GDIINFO gdiinfo;
+ PSURFACE pSurface; /* SURFACE for this device. */
+// HANDLE hSpooler; /* Handle to spooler, if spooler dev driver. */
+// PVOID pDesktopId;
+ PGRAPHICS_DEVICE pGraphicsDevice;
++ POINTL ptlOrigion;
+ PDEVMODEW pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
+// DWORD Unknown3;
+ FLONG DxDd_Flags; /* DxDD active status flags. */
+// LONG devAttr;
+// PVOID WatchDogContext;
+// ULONG WatchDogs;
+ union
+ {
+ DRIVER_FUNCTIONS DriverFunctions;
+ DRIVER_FUNCTIONS pfn;
+ PVOID apfn[INDEX_LAST]; // B8C 0x0598
+ };
+
+ /* ros specific */
+ ULONG DxDd_nCount;
+ GDIPOINTER Pointer;
+ /* Stuff to keep track of software cursors; win32k gdi part */
+ UINT SafetyRemoveLevel; /* at what level was the cursor removed?
+ 0 for not removed */
+ UINT SafetyRemoveCount;
+ struct _EDD_DIRECTDRAW_GLOBAL * pEDDgpl;
+} PDEVOBJ, *PPDEVOBJ;
+
+/* Globals ********************************************************************/
+
+extern PPDEVOBJ gppdevPrimary;
+#define pPrimarySurface gppdevPrimary
+
+
+/* Function prototypes ********************************************************/
+
+PPDEVOBJ
+NTAPI
+EngpGetPDEV(PUNICODE_STRING pustrDevice);
+
+VOID
+NTAPI
+PDEVOBJ_vRelease(PPDEVOBJ ppdev);
+
+PSURFACE
+NTAPI
+PDEVOBJ_pSurface(
+ PPDEVOBJ ppdev);
+
+VOID
+NTAPI
+PDEVOBJ_vGetDeviceCaps(
+ PPDEVOBJ ppdev,
+ PDEVCAPS pDevCaps);
+
+BOOL
+NTAPI
+InitPDEVImpl();
+
+BOOL
+NTAPI
+InitLDEVImpl();
+
+BOOL
+NTAPI
+InitDeviceImpl();
+
++PSIZEL
++FASTCALL
++PDEVOBJ_sizl(PPDEVOBJ, PSIZEL);
++
+#endif /* !__WIN32K_PDEVOBJ_H */
--- /dev/null
- co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes);
-
- UserRedrawDesktop();
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Video initialization and display settings
+ * FILE: subsystems/win32/win32k/ntuser/display.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#include <w32k.h>
+
+#include <intrin.h>
+
+#define NDEBUG
+#include <debug.h>
+
+PDEVOBJ *gpdevPrimary;
+
+const PWCHAR KEY_ROOT = L"";
+const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
+
+NTSTATUS
+NTAPI
+UserEnumDisplayDevices(
+ PUNICODE_STRING pustrDevice,
+ DWORD iDevNum,
+ PDISPLAY_DEVICEW pdispdev,
+ DWORD dwFlags);
+
+VOID
+RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData)
+{
+ UNICODE_STRING ustrValue;
+ UNICODE_STRING ustrData;
+
+ RtlInitUnicodeString(&ustrValue, pwszValue);
+ RtlInitUnicodeString(&ustrData, pwszData);
+ ZwSetValueKey(hkey, &ustrValue, 0, REG_SZ, &ustrData, ustrData.Length + sizeof(WCHAR));
+}
+
+VOID
+RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData)
+{
+ UNICODE_STRING ustrValue;
+
+ RtlInitUnicodeString(&ustrValue, pwszValue);
+ ZwSetValueKey(hkey, &ustrValue, 0, REG_DWORD, &dwData, sizeof(DWORD));
+}
+
+
+BOOL
+RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData)
+{
+ NTSTATUS Status;
+ ULONG cbSize = sizeof(DWORD);
+ Status = RegQueryValue(hkey, pwszValue, REG_DWORD, pdwData, &cbSize);
+ return NT_SUCCESS(Status);
+}
+
+VOID
+RegWriteDisplaySettings(HKEY hkey, PDEVMODEW pdm)
+{
+ RegWriteDWORD(hkey, L"DefaultSettings.BitsPerPel", pdm->dmBitsPerPel);
+ RegWriteDWORD(hkey, L"DefaultSettings.XResolution", pdm->dmPelsWidth);
+ RegWriteDWORD(hkey, L"DefaultSettings.YResolution", pdm->dmPelsHeight);
+ RegWriteDWORD(hkey, L"DefaultSettings.Flags", pdm->dmDisplayFlags);
+ RegWriteDWORD(hkey, L"DefaultSettings.VRefresh", pdm->dmDisplayFrequency);
+ RegWriteDWORD(hkey, L"DefaultSettings.XPanning", pdm->dmPanningWidth);
+ RegWriteDWORD(hkey, L"DefaultSettings.YPanning", pdm->dmPanningHeight);
+ RegWriteDWORD(hkey, L"DefaultSettings.Orientation", pdm->dmDisplayOrientation);
+ RegWriteDWORD(hkey, L"DefaultSettings.FixedOutput", pdm->dmDisplayFixedOutput);
+ RegWriteDWORD(hkey, L"Attach.RelativeX", pdm->dmPosition.x);
+ RegWriteDWORD(hkey, L"Attach.RelativeY", pdm->dmPosition.y);
+// RegWriteDWORD(hkey, L"Attach.ToDesktop, pdm->dmBitsPerPel", pdm->);
+}
+
+VOID
+RegReadDisplaySettings(HKEY hkey, PDEVMODEW pdm)
+{
+ DWORD dwValue;
+
+ /* Zero out the structure */
+ RtlZeroMemory(pdm, sizeof(DEVMODEW));
+
+/* Helper macro */
+#define READ(field, str, flag) \
+ if (RegReadDWORD(hkey, L##str, &dwValue)) \
+ { \
+ pdm->field = dwValue; \
+ pdm->dmFields |= flag; \
+ }
+
+ /* Read all present settings */
+ READ(dmBitsPerPel, "DefaultSettings.BitsPerPel", DM_BITSPERPEL);
+ READ(dmPelsWidth, "DefaultSettings.XResolution", DM_YRESOLUTION); // DM_XRESOLUTION?
+ READ(dmPelsHeight, "DefaultSettings.YResolution", DM_YRESOLUTION);
+ READ(dmDisplayFlags, "DefaultSettings.Flags", DM_DISPLAYFLAGS);
+ READ(dmDisplayFrequency, "DefaultSettings.VRefresh", DM_DISPLAYFREQUENCY);
+ READ(dmPanningWidth, "DefaultSettings.XPanning", DM_PANNINGWIDTH);
+ READ(dmPanningHeight, "DefaultSettings.YPanning", DM_PANNINGHEIGHT);
+ READ(dmDisplayOrientation, "DefaultSettings.Orientation", DM_DISPLAYORIENTATION);
+ READ(dmDisplayFixedOutput, "DefaultSettings.FixedOutput", DM_DISPLAYFIXEDOUTPUT);
+ READ(dmPosition.x, "Attach.RelativeX", DM_POSITION);
+ READ(dmPosition.y, "Attach.RelativeY", DM_POSITION);
+}
+
+
+enum
+{
+ VF_USEVGA = 0x1,
+};
+
+BOOL
+InitDisplayDriver(
+ PUNICODE_STRING pustrRegPath,
+ FLONG flags)
+{
+// PWSTR pwszDriverName;
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ NTSTATUS Status;
+
+ /* Setup QueryTable for direct registry query */
+ RtlZeroMemory(QueryTable, sizeof(QueryTable));
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED|RTL_QUERY_REGISTRY_DIRECT;
+
+
+ /* Check if vga mode is requested */
+ if (flags & VF_USEVGA)
+ {
+ DWORD dwVgaCompatible;
+
+ /* */
+ QueryTable[0].Name = L"VgaCompatible";
+ QueryTable[0].EntryContext = &dwVgaCompatible;
+
+ /* Check if the driver is vga */
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ pustrRegPath->Buffer,
+ QueryTable,
+ NULL,
+ NULL);
+
+ if (!dwVgaCompatible)
+ {
+ /* This driver is not a vga driver */
+ return FALSE;
+ }
+ }
+
+#if 0
+
+ /* Query the adapter's registry path */
+ swprintf(awcBuffer, L"\\Device\\Video%lu", iDevNum);
+ QueryTable[0].Name = pGraphicsDevice->szNtDeviceName;
+
+ /* Set string for the registry key */
+ ustrRegistryPath.Buffer = pdispdev->DeviceKey;
+ ustrRegistryPath.Length = 128;
+ ustrRegistryPath.MaximumLength = 128;
+ QueryTable[0].EntryContext = &ustrRegistryPath;
+
+ /* Query the registry */
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
+ L"VIDEO",
+ QueryTable,
+ NULL,
+ NULL);
+
+ RegQueryValue(KEY_VIDEO, awcBuffer, REG_SZ, pdispdev->DeviceKey, 256);
+
+ {
+ HANDLE hmod;
+
+ hmod = EngLoadImage(pwszDriverName);
+
+ /* Jump to next name */
+ pwszDriverName += wcslen(pwszDriverName) + 1;
+ }
+ while (pwszDriverName < 0);
+#endif
+
+ return 0;
+}
+
+
+NTSTATUS
+NTAPI
+DisplayDriverQueryRoutine(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext)
+{
+ PWSTR pwszRegKey = ValueData;
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ UNICODE_STRING ustrDeviceName, ustrDisplayDrivers, ustrDescription;
+ NTSTATUS Status;
+ WCHAR awcBuffer[128];
+ ULONG cbSize;
+ HKEY hkey;
+ DEVMODEW dmDefault;
+
+ UNREFERENCED_PARAMETER(ValueLength);
+ UNREFERENCED_PARAMETER(Context);
+ UNREFERENCED_PARAMETER(EntryContext);
+
+ DPRINT1("DisplayDriverQueryRoutine(%S, %S);\n",
+ ValueName, pwszRegKey);
+
+ /* Check if we have a correct entry */
+ if (ValueType != REG_SZ || ValueName[0] != '\\')
+ {
+ /* Something else, just skip it */
+ return STATUS_SUCCESS;
+ }
+
+ /* Open the driver's registry key */
+ Status = RegOpenKey(pwszRegKey, &hkey);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open registry key\n");
+ return STATUS_SUCCESS;
+ }
+
+// HACK: only use 1st adapter
+//if (ValueName[13] != '0')
+// return STATUS_SUCCESS;
+
+ /* Query the diplay drivers */
+ cbSize = sizeof(awcBuffer) - 10;
+ Status = RegQueryValue(hkey,
+ L"InstalledDisplayDrivers",
+ REG_MULTI_SZ,
+ awcBuffer,
+ &cbSize);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Didn't find 'InstalledDisplayDrivers', status = 0x%lx\n", Status);
+ ZwClose(hkey);
+ return STATUS_SUCCESS;
+ }
+
+ /* Initialize the UNICODE_STRING */
+ ustrDisplayDrivers.Buffer = awcBuffer;
+ ustrDisplayDrivers.MaximumLength = cbSize;
+ ustrDisplayDrivers.Length = cbSize;
+
+ /* Set Buffer for description and size of remaining buffer */
+ ustrDescription.Buffer = awcBuffer + (cbSize / sizeof(WCHAR));
+ cbSize = sizeof(awcBuffer) - cbSize;
+
+ /* Query the device string */
+ Status = RegQueryValue(hkey,
+ L"Device Description",
+ REG_SZ,
+ ustrDescription.Buffer,
+ &cbSize);
+ if (NT_SUCCESS(Status))
+ {
+ ustrDescription.MaximumLength = cbSize;
+ ustrDescription.Length = cbSize;
+ }
+ else
+ {
+ RtlInitUnicodeString(&ustrDescription, L"<unknown>");
+ }
+
+ /* Query the default settings */
+ RegReadDisplaySettings(hkey, &dmDefault);
+
+ /* Close the registry key */
+ ZwClose(hkey);
+
+ /* Register the device with GDI */
+ RtlInitUnicodeString(&ustrDeviceName, ValueName);
+ pGraphicsDevice = EngpRegisterGraphicsDevice(&ustrDeviceName,
+ &ustrDisplayDrivers,
+ &ustrDescription,
+ &dmDefault);
+
+ // FIXME: what to do with pGraphicsDevice?
+
+ return STATUS_SUCCESS;
+}
+
+BOOL InitSysParams();
+
+BOOL
+InitVideo(FLONG flags)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ NTSTATUS Status;
+
+ DPRINT1("----------------------------- InitVideo() -------------------------------\n");
+
+ /* Setup QueryTable for registry query */
+ RtlZeroMemory(QueryTable, sizeof(QueryTable));
+ QueryTable[0].QueryRoutine = DisplayDriverQueryRoutine;
+
+ /* Query the registry */
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
+ L"VIDEO",
+ QueryTable,
+ NULL,
+ NULL);
+
+ InitSysParams();
+
+ return 0;
+}
+
+
+NTSTATUS
+NTAPI
+UserEnumDisplayDevices(
+ PUNICODE_STRING pustrDevice,
+ DWORD iDevNum,
+ PDISPLAY_DEVICEW pdispdev,
+ DWORD dwFlags)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ ULONG cbSize;
+ HKEY hkey;
+ NTSTATUS Status;
+
+ /* Ask gdi for the GRAPHICS_DEVICE */
+ pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, iDevNum, 0);
+ if (!pGraphicsDevice)
+ {
+ /* No device found */
+ DPRINT1("No GRAPHICS_DEVICE found\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Open thhe device map registry key */
+ Status = RegOpenKey(KEY_VIDEO, &hkey);
+ if (!NT_SUCCESS(Status))
+ {
+ /* No device found */
+ DPRINT1("Could not open reg key\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Query the registry path */
+ cbSize = sizeof(pdispdev->DeviceKey);
+ RegQueryValue(hkey,
+ pGraphicsDevice->szNtDeviceName,
+ REG_SZ,
+ pdispdev->DeviceKey,
+ &cbSize);
+
+ /* Close registry key */
+ ZwClose(hkey);
+
+ /* Copy device name, device string and StateFlags */
+ wcsncpy(pdispdev->DeviceName, pGraphicsDevice->szWinDeviceName, 32);
+ wcsncpy(pdispdev->DeviceString, pGraphicsDevice->pwszDescription, 128);
+ pdispdev->StateFlags = pGraphicsDevice->StateFlags;
+
+ // FIXME: fill in DEVICE ID
+
+ return STATUS_SUCCESS;
+}
+
+//NTSTATUS
+BOOL
+NTAPI
+NtUserEnumDisplayDevices(
+ PUNICODE_STRING pustrDevice,
+ DWORD iDevNum,
+ PDISPLAY_DEVICEW pDisplayDevice,
+ DWORD dwFlags)
+{
+ UNICODE_STRING ustrDevice;
+ WCHAR awcDevice[CCHDEVICENAME];
+ DISPLAY_DEVICEW dispdev;
+ NTSTATUS Status;
+
+ DPRINT1("Enter NtUserEnumDisplayDevices(%p, %ls, %ld)\n",
+ pustrDevice, pustrDevice ? pustrDevice->Buffer : 0, iDevNum);
+
+ // FIXME: HACK, desk.cpl passes broken crap
+ if (pustrDevice && iDevNum != 0)
+ return FALSE;
+
+ dispdev.cb = sizeof(DISPLAY_DEVICEW);
+
+ if (pustrDevice)
+ {
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
+ _SEH2_TRY
+ {
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+// _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ _SEH2_YIELD(return NT_SUCCESS(_SEH2_GetExceptionCode()));
+ }
+ _SEH2_END
+
+ if (ustrDevice.Length > 0)
+ pustrDevice = &ustrDevice;
+ else
+ pustrDevice = NULL;
+ }
+
+ /* Acquire global USER lock */
+ UserEnterExclusive();
+
+ /* Call the internal function */
+ Status = UserEnumDisplayDevices(pustrDevice, iDevNum, &dispdev, dwFlags);
+
+ /* Release lock */
+ UserLeave();
+
+ /* On success copy data to caller */
+ if (NT_SUCCESS(Status))
+ {
+ /* Enter SEH */
+ _SEH2_TRY
+ {
+ /* First probe the cb field */
+ ProbeForWrite(&pDisplayDevice->cb, sizeof(DWORD), 1);
+
+ /* Check the buffer size */
+ if (pDisplayDevice->cb)
+ {
+ /* Probe the output buffer */
+ pDisplayDevice->cb = min(pDisplayDevice->cb, sizeof(dispdev));
+ ProbeForWrite(pDisplayDevice, pDisplayDevice->cb, 1);
+
+ /* Copy as much as the given buffer allows */
+ RtlCopyMemory(pDisplayDevice, &dispdev, pDisplayDevice->cb);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+ }
+
+ DPRINT1("Leave NtUserEnumDisplayDevices, Status = 0x%lx\n", Status);
+ /* Return the result */
+// return Status;
+ return NT_SUCCESS(Status); // FIXME
+}
+
+NTSTATUS
+NTAPI
+UserEnumCurrentDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ PDEVMODEW *ppdm)
+{
+ PPDEVOBJ ppdev;
+
+ /* Get the PDEV for the device */
+ ppdev = EngpGetPDEV(pustrDevice);
+ if (!ppdev)
+ {
+ /* No device found */
+ DPRINT1("No PDEV found!\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ *ppdm = ppdev->pdmwDev;
+ PDEVOBJ_vRelease(ppdev);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+UserEnumDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ DWORD iModeNum,
+ LPDEVMODEW *ppdm,
+ DWORD dwFlags)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PDEVMODEENTRY pdmentry;
+ ULONG i, iFoundMode;
+
+ DPRINT1("Enter UserEnumDisplaySettings('%ls', %ld)\n",
+ pustrDevice ? pustrDevice->Buffer : NULL, iModeNum);
+
+ /* Ask gdi for the GRAPHICS_DEVICE */
+ pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, 0, 0);
+ if (!pGraphicsDevice)
+ {
+ /* No device found */
+ DPRINT1("No device found!\n");
+ return FALSE;
+ }
+
+ if (iModeNum == 0)
+ {
+ DPRINT1("Should initialize modes somehow\n");
+ // Update DISPLAY_DEVICEs?
+ }
+
+ iFoundMode = 0;
+ for (i = 0; i < pGraphicsDevice->cDevModes; i++)
+ {
+ pdmentry = &pGraphicsDevice->pDevModeList[i];
+
+// if ((!(dwFlags & EDS_RAWMODE) && (pdmentry->dwFlags & 1)) || // FIXME!
+// (dwFlags & EDS_RAWMODE))
+ {
+ /* Is this the one we want? */
+ if (iFoundMode == iModeNum)
+ {
+ *ppdm = pdmentry->pdm;
+ return STATUS_SUCCESS;
+ }
+
+ /* Increment number of found modes */
+ iFoundMode++;
+ }
+ }
+
+ /* Nothing was found */
+ return STATUS_INVALID_PARAMETER;
+}
+
+NTSTATUS
+NTAPI
+UserOpenDisplaySettingsKey(
+ OUT PHKEY phkey,
+ IN PUNICODE_STRING pustrDevice,
+ IN BOOL bGlobal)
+{
+ HKEY hkey;
+ DISPLAY_DEVICEW dispdev;
+ NTSTATUS Status;
+
+ /* Get device info */
+ Status = UserEnumDisplayDevices(pustrDevice, 0, &dispdev, 0);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ if (bGlobal)
+ {
+ // FIXME: need to fix the registry key somehow
+ }
+
+ /* Open the registry key */
+ Status = RegOpenKey(dispdev.DeviceKey, &hkey);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ *phkey = hkey;
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+UserEnumRegistryDisplaySettings(
+ IN PUNICODE_STRING pustrDevice,
+ OUT LPDEVMODEW pdm)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS
+APIENTRY
+NtUserEnumDisplaySettings(
+ IN PUNICODE_STRING pustrDevice,
+ IN DWORD iModeNum,
+ OUT LPDEVMODEW lpDevMode,
+ IN DWORD dwFlags)
+{
+ UNICODE_STRING ustrDevice;
+ WCHAR awcDevice[CCHDEVICENAME];
+ NTSTATUS Status;
+ ULONG cbSize, cbExtra;
+ DEVMODEW dmReg, *pdm;
+
+ DPRINT1("Enter NtUserEnumDisplaySettings(%ls, %ld)\n",
+ pustrDevice ? pustrDevice->Buffer:0, iModeNum);
+
+ if (pustrDevice)
+ {
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
+ _SEH2_TRY
+ {
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END
+
+ pustrDevice = &ustrDevice;
+ }
+
+ /* Acquire global USER lock */
+ UserEnterExclusive();
+
+ if (iModeNum == ENUM_REGISTRY_SETTINGS)
+ {
+ /* Get the registry settings */
+ Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg);
+ pdm = &dmReg;
+ }
+ else if (iModeNum == ENUM_CURRENT_SETTINGS)
+ {
+ /* Get the current settings */
+ Status = UserEnumCurrentDisplaySettings(pustrDevice, &pdm);
+ }
+ else
+ {
+ /* Get specified settings */
+ Status = UserEnumDisplaySettings(pustrDevice, iModeNum, &pdm, dwFlags);
+ }
+
+ /* Release lock */
+ UserLeave();
+
+ /* Did we succeed? */
+ if (NT_SUCCESS(Status))
+ {
+ /* Copy some information back */
+ _SEH2_TRY
+ {
+ ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
+ cbSize = lpDevMode->dmSize;
+ cbExtra = lpDevMode->dmDriverExtra;
+
+ ProbeForWrite(lpDevMode, cbSize + cbExtra, 1);
+ lpDevMode->dmPelsWidth = pdm->dmPelsWidth;
+ lpDevMode->dmPelsHeight = pdm->dmPelsHeight;
+ lpDevMode->dmBitsPerPel = pdm->dmBitsPerPel;
+ lpDevMode->dmDisplayFrequency = pdm->dmDisplayFrequency;
+ lpDevMode->dmDisplayFlags = pdm->dmDisplayFlags;
+
+ /* output private/extra driver data */
+ if (cbExtra > 0 && pdm->dmDriverExtra > 0)
+ {
+ RtlCopyMemory((PCHAR)lpDevMode + cbSize,
+ (PCHAR)pdm + pdm->dmSize,
+ min(cbExtra, pdm->dmDriverExtra));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+
+ return Status;
+}
+
+BOOL APIENTRY UserClipCursor(RECTL *prcl);
+VOID APIENTRY UserRedrawDesktop();
+
+LONG
+APIENTRY
+UserChangeDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ LPDEVMODEW pdm,
+ HWND hwnd,
+ DWORD flags,
+ LPVOID lParam)
+{
+ DEVMODEW dmReg;
+ LONG lResult = DISP_CHANGE_SUCCESSFUL;
+ HKEY hkey;
+ NTSTATUS Status;
+ PPDEVOBJ ppdev;
+ PDESKTOP pdesk;
+
+ /* If no DEVMODE is given, use registry settings */
+ if (!pdm)
+ {
+ /* Get the registry settings */
+ Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not load registry settings\n");
+ return DISP_CHANGE_BADPARAM;
+ }
+ pdm = &dmReg;
+ }
+
+ /* Get the PDEV */
+ ppdev = EngpGetPDEV(pustrDevice);
+ if (!ppdev)
+ {
+ DPRINT1("failed to get PDEV\n");
+ return DISP_CHANGE_BADPARAM;
+ }
+
+ /* Look for the requested DEVMODE */
+ pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
+ if (!pdm)
+ {
+ DPRINT1("Could not find a matching DEVMODE\n");
+ lResult = DISP_CHANGE_BADMODE;
+ goto leave;
+ }
+
+ /* Shall we update the registry? */
+ if (flags & CDS_UPDATEREGISTRY)
+ {
+ /* Open the local or global settings key */
+ Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, flags & CDS_GLOBAL);
+ if (NT_SUCCESS(Status))
+ {
+ /* Store the settings */
+ RegWriteDisplaySettings(hkey, pdm);
+
+ /* Close the registry key */
+ ZwClose(hkey);
+ }
+ else
+ {
+ DPRINT1("Could not open registry key\n");
+ lResult = DISP_CHANGE_NOTUPDATED;
+ }
+ }
+
+ /* Check if DEVMODE matches the current mode */
+ if (pdm == ppdev->pdmwDev && !(flags & CDS_RESET))
+ {
+ DPRINT1("DEVMODE matches, nothing to do\n");
+ goto leave;
+ }
+
+ /* Shall we apply the settings? */
+ if (!(flags & CDS_NORESET))
+ {
+ ULONG ulResult;
+
+ if (!PDEVOBJ_bSwitchMode(ppdev, pdm))
+ {
+ DPRINT1("failed to set mode\n");
+ lResult = (lResult == DISP_CHANGE_NOTUPDATED) ?
+ DISP_CHANGE_FAILED : DISP_CHANGE_RESTART;
+
+ goto leave;
+ }
+
+ /* Update the system metrics */
+ InitMetrics();
+
+ /* Remove all cursor clipping */
+ UserClipCursor(NULL);
+
+ //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps);
+
+ pdesk = IntGetActiveDesktop();
+ IntHideDesktop(pdesk);
+
+ /* Send WM_DISPLAYCHANGE to all toplevel windows */
+ co_IntSendMessageTimeout(HWND_BROADCAST,
+ WM_DISPLAYCHANGE,
+ (WPARAM)ppdev->gdiinfo.cBitsPixel,
+ (LPARAM)(ppdev->gdiinfo.ulHorzRes + (ppdev->gdiinfo.ulHorzRes << 16)),
+ SMTO_NORMAL,
+ 100,
+ &ulResult);
++
++ co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes);
++
++ UserRedrawDesktop();
+ }
+
+leave:
+ /* Release the PDEV */
+ PDEVOBJ_vRelease(ppdev);
+
+ return lResult;
+}
+
+LONG
+APIENTRY
+NtUserChangeDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ LPDEVMODEW lpDevMode,
+ HWND hwnd,
+ DWORD dwflags,
+ LPVOID lParam)
+{
+ WCHAR awcDevice[CCHDEVICENAME];
+ UNICODE_STRING ustrDevice;
+ DEVMODEW dmLocal;
+ LONG lRet;
+
+ /* Check arguments */
+ if ((dwflags != CDS_VIDEOPARAMETERS && lParam != NULL) ||
+ (hwnd != NULL))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return DISP_CHANGE_BADPARAM;
+ }
+
+ /* Check flags */
+ if ((dwflags & (CDS_GLOBAL|CDS_NORESET)) && !(dwflags & CDS_UPDATEREGISTRY))
+ {
+ return DISP_CHANGE_BADFLAGS;
+ }
+
+ /* Copy the device name */
+ if (pustrDevice)
+ {
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
+ _SEH2_TRY
+ {
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Set and return error */
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
+ }
+ _SEH2_END
+
+ pustrDevice = &ustrDevice;
+ }
+
+ /* Copy devmode */
+ if (lpDevMode)
+ {
+ _SEH2_TRY
+ {
+ /* Probe the size field of the structure */
+ ProbeForRead(lpDevMode, sizeof(dmLocal.dmSize), 1);
+
+ /* Calculate usable size */
+ dmLocal.dmSize = min(sizeof(dmLocal), lpDevMode->dmSize);
+
+ /* Probe and copy the full DEVMODE */
+ ProbeForRead(lpDevMode, dmLocal.dmSize, 1);
+ RtlCopyMemory(&dmLocal, lpDevMode, dmLocal.dmSize);
+ dmLocal.dmSize = sizeof(dmLocal);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Set and return error */
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
+ }
+ _SEH2_END
+
+ /* Check for extra parameters */
+ if (dmLocal.dmDriverExtra > 0)
+ {
+ /* FIXME: TODO */
+ DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n");
+ dmLocal.dmDriverExtra = 0;
+ }
+
+ /* Use the local structure */
+ lpDevMode = &dmLocal;
+ }
+
+ // FIXME: Copy videoparameters
+
+ /* Acquire global USER lock */
+ UserEnterExclusive();
+
+ /* Call internal function */
+ lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, hwnd, dwflags, NULL);
+
+ /* Release lock */
+ UserLeave();
+
+ return lRet;
+}
+
--- /dev/null
- UNIMPLEMENTED;
- ASSERT(FALSE);
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Functions for creation and destruction of DCs
+ * FILE: subsystem/win32/win32k/objects/dclife.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
+ */
+
+#include <w32k.h>
+#include <bugcodes.h>
+
+#define NDEBUG
+#include <debug.h>
+
+//FIXME: windows uses 0x0012009f
+#define DIRTY_DEFAULT DIRTY_CHARSET|DIRTY_BACKGROUND|DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL
+
+PSURFACE psurfDefaultBitmap = NULL;
+PBRUSH pbrDefaultBrush = NULL;
+
+// FIXME: these should go to floatobj.h or something
+#define FLOATOBJ_0 {0x00000000, 0x00000000}
+#define FLOATOBJ_1 {0x40000000, 0x00000002}
+#define FLOATOBJ_16 {0x40000000, 0x00000006}
+#define FLOATOBJ_1_16 {0x40000000, 0xfffffffe}
+
+static const FLOATOBJ gef0 = FLOATOBJ_0;
+static const FLOATOBJ gef1 = FLOATOBJ_1;
+static const FLOATOBJ gef16 = FLOATOBJ_16;
+
+static const MATRIX gmxWorldToDeviceDefault =
+{
+ FLOATOBJ_16, FLOATOBJ_0,
+ FLOATOBJ_0, FLOATOBJ_16,
+ FLOATOBJ_0, FLOATOBJ_0,
+ 0, 0, 0x4b
+};
+
+static const MATRIX gmxDeviceToWorldDefault =
+{
+ FLOATOBJ_1_16, FLOATOBJ_0,
+ FLOATOBJ_0, FLOATOBJ_1_16,
+ FLOATOBJ_0, FLOATOBJ_0,
+ 0, 0, 0x53
+};
+
+static const MATRIX gmxWorldToPageDefault =
+{
+ FLOATOBJ_1, FLOATOBJ_0,
+ FLOATOBJ_0, FLOATOBJ_1,
+ FLOATOBJ_0, FLOATOBJ_0,
+ 0, 0, 0x63
+};
+
+// HACK!! Fix XFORMOBJ then use 1:16 / 16:1
+#define gmxWorldToDeviceDefault gmxWorldToPageDefault
+#define gmxDeviceToWorldDefault gmxWorldToPageDefault
+
+/** Internal functions ********************************************************/
+
+NTSTATUS
+InitDcImpl()
+{
+ psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
+ if (!psurfDefaultBitmap)
+ return STATUS_UNSUCCESSFUL;
+
+ pbrDefaultBrush = BRUSH_ShareLockBrush(StockObjects[BLACK_BRUSH]);
+ if (!pbrDefaultBrush)
+ return STATUS_UNSUCCESSFUL;
+
+ return STATUS_SUCCESS;
+}
+
+
+PDC
+NTAPI
+DC_AllocDcWithHandle()
+{
+ PDC pdc;
+ pdc = (PDC)GDIOBJ_AllocObjWithHandle(GDILoObjType_LO_DC_TYPE);
+
+ pdc->pdcattr = &pdc->dcattr;
+
+ return pdc;
+}
+
+
+void
+DC_InitHack(PDC pdc)
+{
+ HRGN hVisRgn;
+
+ TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
+ pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
+
+ /* This should never fail */
+ ASSERT(pdc->dclevel.ppal);
+
+ /* Select regions */
+ // FIXME: too complicated, broken error handling
+ pdc->rosdc.hClipRgn = NULL;
+ pdc->rosdc.hGCClipRgn = NULL;
+ hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
+ ASSERT(hVisRgn);
+ GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
+ GreDeleteObject(hVisRgn);
+ ASSERT(pdc->prgnVis);
+ pdc->rosdc.bitsPerPixel = pdc->ppdev->gdiinfo.cBitsPixel *
+ pdc->ppdev->gdiinfo.cPlanes;
+}
+
+VOID
+NTAPI
+DC_vInitDc(
+ PDC pdc,
+ DCTYPE dctype,
+ PPDEVOBJ ppdev)
+{
+ if (dctype == DCTYPE_DIRECT)
+ {
+ /* Lock ppdev */
+ EngAcquireSemaphoreShared(ppdev->hsemDevLock);
+ }
+
+ /* Setup some basic fields */
+ pdc->dctype = dctype;
+ pdc->ppdev = ppdev;
+ pdc->dhpdev = ppdev->dhpdev;
+ pdc->hsem = ppdev->hsemDevLock;
+ pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
+ pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
+ pdc->fs = DC_DIRTY_RAO;
+
+ /* Setup dc attribute */
+ pdc->pdcattr = &pdc->dcattr;
+ pdc->dcattr.pvLDC = NULL;
+ pdc->dcattr.ulDirty_ = DIRTY_DEFAULT;
+ if (ppdev == gppdevPrimary)
+ pdc->dcattr.ulDirty_ |= DC_PRIMARY_DISPLAY;
+
+ /* Setup the DC size */
+ if (dctype == DCTYPE_MEMORY)
+ {
+ /* Memory DCs have a 1 x 1 bitmap by default */
+ pdc->dclevel.sizl.cx = 1;
+ pdc->dclevel.sizl.cy = 1;
+ }
+ else
+ {
+ /* Other DC's are as big as the related PDEV */
+ pdc->dclevel.sizl.cx = ppdev->gdiinfo.ulHorzRes;
+ pdc->dclevel.sizl.cy = ppdev->gdiinfo.ulVertRes;
+ }
+
+ /* Setup Window rect based on DC size */
+ pdc->erclWindow.left = 0;
+ pdc->erclWindow.top = 0;
+ pdc->erclWindow.right = pdc->dclevel.sizl.cx;
+ pdc->erclWindow.bottom = pdc->dclevel.sizl.cy;
+
+ if (dctype == DCTYPE_DIRECT)
+ {
+ /* Direct DCs get the surface from the PDEV */
+ pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
+
+ pdc->erclBounds.left = 0x7fffffff;
+ pdc->erclBounds.top = 0x7fffffff;
+ pdc->erclBounds.right = 0x80000000;
+ pdc->erclBounds.bottom = 0x80000000;
+ pdc->erclBoundsApp.left = 0xffffffff;
+ pdc->erclBoundsApp.top = 0xfffffffc;
+ pdc->erclBoundsApp.right = 0x00007ffc; // FIXME
+ pdc->erclBoundsApp.bottom = 0x00000333; // FIXME
+ pdc->erclClip = pdc->erclBounds;
+// pdc->co
+
+ pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY;
+ }
+ else
+ {
+ /* Non-direct DCs don't have a surface by default */
+ pdc->dclevel.pSurface = NULL;
+
+ // FIXME: HACK, because our code expects a surface
+ pdc->dclevel.pSurface = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
+
+ pdc->erclBounds.left = 0;
+ pdc->erclBounds.top = 0;
+ pdc->erclBounds.right = 0;
+ pdc->erclBounds.bottom = 0;
+ pdc->erclBoundsApp = pdc->erclBounds;
+ pdc->erclClip = pdc->erclWindow;
+// pdc->co = NULL
+ }
+
+// pdc->dcattr.VisRectRegion:
+
+ /* Setup coordinate transformation data */
+ pdc->dclevel.mxWorldToDevice = gmxWorldToDeviceDefault;
+ pdc->dclevel.mxDeviceToWorld = gmxDeviceToWorldDefault;
+ pdc->dclevel.mxWorldToPage = gmxWorldToPageDefault;
+ pdc->dclevel.efM11PtoD = gef16;
+ pdc->dclevel.efM22PtoD = gef16;
+ pdc->dclevel.efDxPtoD = gef0;
+ pdc->dclevel.efDyPtoD = gef0;
+ pdc->dclevel.efM11_TWIPS = gef0;
+ pdc->dclevel.efM22_TWIPS = gef0;
+ pdc->dclevel.efPr11 = gef0;
+ pdc->dclevel.efPr22 = gef0;
+ pdc->dcattr.mxWorldToDevice = pdc->dclevel.mxWorldToDevice;
+ pdc->dcattr.mxDeviceToWorld = pdc->dclevel.mxDeviceToWorld;
+ pdc->dcattr.mxWorldToPage = pdc->dclevel.mxWorldToPage;
+ pdc->dcattr.efM11PtoD = pdc->dclevel.efM11PtoD;
+ pdc->dcattr.efM22PtoD = pdc->dclevel.efM22PtoD;
+ pdc->dcattr.efDxPtoD = pdc->dclevel.efDxPtoD;
+ pdc->dcattr.efDyPtoD = pdc->dclevel.efDyPtoD;
+ pdc->dcattr.iMapMode = MM_TEXT;
+ pdc->dcattr.dwLayout = 0;
+ pdc->dcattr.flXform = PAGE_TO_DEVICE_SCALE_IDENTITY |
+ PAGE_TO_DEVICE_IDENTITY |
+ WORLD_TO_PAGE_IDENTITY;
+
+ /* Setup more coordinates */
+ pdc->ptlDCOrig.x = 0;
+ pdc->ptlDCOrig.y = 0;
+ pdc->dcattr.lWindowOrgx = 0;
+ pdc->dcattr.ptlWindowOrg.x = 0;
+ pdc->dcattr.ptlWindowOrg.y = 0;
+ pdc->dcattr.szlWindowExt.cx = 1;
+ pdc->dcattr.szlWindowExt.cy = 1;
+ pdc->dcattr.ptlViewportOrg.x = 0;
+ pdc->dcattr.ptlViewportOrg.y = 0;
+ pdc->dcattr.szlViewportExt.cx = 1;
+ pdc->dcattr.szlViewportExt.cy = 1;
+ pdc->dcattr.szlVirtualDevicePixel.cx = 0;
+ pdc->dcattr.szlVirtualDevicePixel.cy = 0;
+ pdc->dcattr.szlVirtualDeviceMm.cx = 0;
+ pdc->dcattr.szlVirtualDeviceMm.cy = 0;
+ pdc->dcattr.szlVirtualDeviceSize.cx = 0;
+ pdc->dcattr.szlVirtualDeviceSize.cy = 0;
+
+ /* Setup regions */
+ pdc->prgnAPI = NULL;
+ pdc->prgnVis = NULL; // FIXME
+ pdc->prgnRao = NULL;
+
+ /* Setup palette */
+ pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE];
+ pdc->dclevel.ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal);
+
+ /* Setup path */
+ pdc->dclevel.hPath = NULL;
+ pdc->dclevel.flPath = 0;
+// pdc->dclevel.lapath:
+
+ /* Setup colors */
+ pdc->dcattr.crBackgroundClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.ulBackgroundClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.crForegroundClr = RGB(0, 0, 0);
+ pdc->dcattr.ulForegroundClr = RGB(0, 0, 0);
+ pdc->dcattr.crBrushClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.ulBrushClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.crPenClr = RGB(0, 0, 0);
+ pdc->dcattr.ulPenClr = RGB(0, 0, 0);
+
+ /* Select the default fill and line brush */
+ pdc->dcattr.hbrush = StockObjects[WHITE_BRUSH];
+ pdc->dcattr.hpen = StockObjects[BLACK_PEN];
+ pdc->dclevel.pbrFill = BRUSH_ShareLockBrush(pdc->pdcattr->hbrush);
+ pdc->dclevel.pbrLine = PEN_ShareLockPen(pdc->pdcattr->hpen);
+ pdc->dclevel.ptlBrushOrigin.x = 0;
+ pdc->dclevel.ptlBrushOrigin.y = 0;
+ pdc->dcattr.ptlBrushOrigin = pdc->dclevel.ptlBrushOrigin;
+
+ /* Initialize EBRUSHOBJs */
+ EBRUSHOBJ_vInit(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
+ EBRUSHOBJ_vInit(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
+ EBRUSHOBJ_vInit(&pdc->eboText, pbrDefaultBrush, pdc);
+ EBRUSHOBJ_vInit(&pdc->eboBackground, pbrDefaultBrush, pdc);
+
+ /* Setup fill data */
+ pdc->dcattr.jROP2 = R2_COPYPEN;
+ pdc->dcattr.jBkMode = 2;
+ pdc->dcattr.lBkMode = 2;
+ pdc->dcattr.jFillMode = ALTERNATE;
+ pdc->dcattr.lFillMode = 1;
+ pdc->dcattr.jStretchBltMode = 1;
+ pdc->dcattr.lStretchBltMode = 1;
+ pdc->ptlFillOrigin.x = 0;
+ pdc->ptlFillOrigin.y = 0;
+
+ /* Setup drawing position */
+ pdc->dcattr.ptlCurrent.x = 0;
+ pdc->dcattr.ptlCurrent.y = 0;
+ pdc->dcattr.ptfxCurrent.x = 0;
+ pdc->dcattr.ptfxCurrent.y = 0;
+
+ /* Setup ICM data */
+ pdc->dclevel.lIcmMode = 0;
+ pdc->dcattr.lIcmMode = 0;
+ pdc->dcattr.hcmXform = NULL;
+ pdc->dcattr.flIcmFlags = 0;
+ pdc->dcattr.IcmBrushColor = CLR_INVALID;
+ pdc->dcattr.IcmPenColor = CLR_INVALID;
+ pdc->dcattr.pvLIcm = NULL;
+ pdc->dcattr.hColorSpace = NULL; // FIXME: 0189001f
+ pdc->dclevel.pColorSpace = NULL; // FIXME
+ pdc->pClrxFormLnk = NULL;
+// pdc->dclevel.ca =
+
+ /* Setup font data */
+ pdc->hlfntCur = NULL; // FIXME: 2f0a0cf8
+ pdc->pPFFList = NULL;
+ pdc->flSimulationFlags = 0;
+ pdc->lEscapement = 0;
+ pdc->prfnt = NULL;
+ pdc->dcattr.flFontMapper = 0;
+ pdc->dcattr.flTextAlign = 0;
+ pdc->dcattr.lTextAlign = 0;
+ pdc->dcattr.lTextExtra = 0;
+ pdc->dcattr.lRelAbs = 1;
+ pdc->dcattr.lBreakExtra = 0;
+ pdc->dcattr.cBreak = 0;
+ pdc->dcattr.hlfntNew = StockObjects[SYSTEM_FONT];
+// pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew);
+
+ /* Other stuff */
+ pdc->hdcNext = NULL;
+ pdc->hdcPrev = NULL;
+ pdc->ipfdDevMax = 0x0000ffff;
+ pdc->ulCopyCount = -1;
+ pdc->ptlDoBanding.x = 0;
+ pdc->ptlDoBanding.y = 0;
+ pdc->dclevel.lSaveDepth = 1;
+ pdc->dclevel.hdcSave = NULL;
+ pdc->dcattr.iGraphicsMode = GM_COMPATIBLE;
+ pdc->dcattr.iCS_CP = 0;
+ pdc->pSurfInfo = NULL;
+
+}
+
+BOOL
+INTERNAL_CALL
+DC_Cleanup(PVOID ObjectBody)
+{
+ PDC pdc = (PDC)ObjectBody;
+
+ /* Free DC_ATTR */
+ DC_vFreeDcAttr(pdc);
+
+ /* Delete saved DCs */
+ DC_vRestoreDC(pdc, 1);
+
+ /* Deselect dc objects */
+ DC_vSelectSurface(pdc, NULL);
+ DC_vSelectFillBrush(pdc, NULL);
+ DC_vSelectLineBrush(pdc, NULL);
+ DC_vSelectPalette(pdc, NULL);
+
+ /* Cleanup the dc brushes */
+ EBRUSHOBJ_vCleanup(&pdc->eboFill);
+ EBRUSHOBJ_vCleanup(&pdc->eboLine);
+ EBRUSHOBJ_vCleanup(&pdc->eboText);
+ EBRUSHOBJ_vCleanup(&pdc->eboBackground);
+
+ /* Free regions */
+ if (pdc->rosdc.hClipRgn)
+ GreDeleteObject(pdc->rosdc.hClipRgn);
+ if (pdc->prgnVis)
+ REGION_FreeRgnByHandle(pdc->prgnVis->BaseObject.hHmgr);
+ASSERT(pdc->rosdc.hGCClipRgn);
+ if (pdc->rosdc.hGCClipRgn)
+ GreDeleteObject(pdc->rosdc.hGCClipRgn);
+ if (NULL != pdc->rosdc.CombinedClip)
+ IntEngDeleteClipRegion(pdc->rosdc.CombinedClip);
+
+ PATH_Delete(pdc->dclevel.hPath);
+
+ if(pdc->dclevel.pSurface)
+ SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
+
+ PDEVOBJ_vRelease(pdc->ppdev) ;
+
+ return TRUE;
+}
+
+BOOL
+FASTCALL
+DC_SetOwnership(HDC hDC, PEPROCESS Owner)
+{
+ INT Index;
+ PGDI_TABLE_ENTRY Entry;
+ PDC pDC;
+ BOOL ret = FALSE;
+
+ /* FIXME: This function has broken error handling */
+
+ if (!GDIOBJ_SetOwnership(hDC, Owner))
+ {
+ DPRINT1("GDIOBJ_SetOwnership failed\n");
+ return FALSE;
+ }
+
+ pDC = DC_LockDc(hDC);
+ if (!pDC)
+ {
+ DPRINT1("Could not lock DC\n");
+ return FALSE;
+ }
+
+ /*
+ System Regions:
+ These regions do not use attribute sections and when allocated, use
+ gdiobj level functions.
+ */
+ if (pDC->rosdc.hClipRgn)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) goto leave;
+ }
+ if (pDC->prgnVis)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->prgnVis->BaseObject.hHmgr);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->prgnVis->BaseObject.hHmgr, Owner)) goto leave;
+ }
+ if (pDC->rosdc.hGCClipRgn)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) goto leave;
+ }
+ if (pDC->dclevel.hPath)
+ {
+ if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) goto leave;
+ }
+ ret = TRUE;
+
+leave:
+ DC_UnlockDc(pDC);
+
+ return ret;
+}
+
+HDC
+NTAPI
+GreOpenDCW(
+ PUNICODE_STRING pustrDevice,
+ DEVMODEW *pdmInit,
+ PUNICODE_STRING pustrLogAddr,
+ ULONG iType,
+ BOOL bDisplay,
+ HANDLE hspool,
+ VOID *pDriverInfo2,
+ VOID *pUMdhpdev)
+{
+ PPDEVOBJ ppdev;
+ PDC pdc;
+ HDC hdc;
+
+ DPRINT("GreOpenDCW(%S, iType=%ld)\n",
+ pustrDevice ? pustrDevice->Buffer : NULL, iType);
+
+ /* Get a PDEVOBJ for the device */
+ ppdev = EngpGetPDEV(pustrDevice);
+ if (!ppdev)
+ {
+ DPRINT1("Didn't find a suitable PDEV\n");
+ return NULL;
+ }
+
+ DPRINT("GreOpenDCW - ppdev = %p\n", ppdev);
+
+ pdc = DC_AllocDcWithHandle();
+ if (!pdc)
+ {
+ DPRINT1("Could not Allocate a DC\n");
+ PDEVOBJ_vRelease(ppdev);
+ return NULL;
+ }
+ hdc = pdc->BaseObject.hHmgr;
+
+ /* Lock ppdev and initialize the new DC */
+ DC_vInitDc(pdc, iType, ppdev);
+ /* FIXME: HACK! */
+ DC_InitHack(pdc);
+
+ DC_AllocDcAttr(pdc);
+
+ DC_UnlockDc(pdc);
+
+ DPRINT("returning hdc = %p\n", hdc);
+
+ return hdc;
+}
+
+HDC
+APIENTRY
+NtGdiOpenDCW(
+ PUNICODE_STRING pustrDevice,
+ DEVMODEW *pdmInit,
+ PUNICODE_STRING pustrLogAddr,
+ ULONG iType,
+ BOOL bDisplay,
+ HANDLE hspool,
+ VOID *pDriverInfo2,
+ VOID *pUMdhpdev)
+{
+ UNICODE_STRING ustrDevice;
+ WCHAR awcDevice[CCHDEVICENAME];
+ DEVMODEW dmInit;
+ PVOID dhpdev;
+ HDC hdc;
+
+ /* Only if a devicename is given, we need any data */
+ if (pustrDevice)
+ {
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
+ _SEH2_TRY
+ {
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+
+ if (pdmInit)
+ {
+ /* FIXME: could be larger */
+ ProbeForRead(pdmInit, sizeof(DEVMODEW), 1);
+ RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW));
+ }
+
+ if (pUMdhpdev)
+ {
+ ProbeForWrite(pUMdhpdev, sizeof(HANDLE), 1);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return NULL);
+ }
+ _SEH2_END
+ }
+ else
+ {
+ pdmInit = NULL;
+ pUMdhpdev = NULL;
+ }
+
+ /* FIXME: HACK! */
+ if (pustrDevice)
+ {
+ UNICODE_STRING ustrDISPLAY = RTL_CONSTANT_STRING(L"DISPLAY");
+ if (RtlEqualUnicodeString(&ustrDevice, &ustrDISPLAY, TRUE))
+ {
+ pustrDevice = NULL;
+ }
+ }
+
+ /* Call the internal function */
+ hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL,
+ pdmInit ? &dmInit : NULL,
+ NULL, // fixme pwszLogAddress
+ iType,
+ bDisplay,
+ hspool,
+ NULL, //FIXME: pDriverInfo2
+ pUMdhpdev ? &dhpdev : NULL);
+
+ /* If we got a HDC and a UM dhpdev is requested,... */
+ if (hdc && pUMdhpdev)
+ {
+ /* Copy dhpdev to caller (FIXME: use dhpdev?? */
+ _SEH2_TRY
+ {
+ /* Pointer was already probed */
+ *(HANDLE*)pUMdhpdev = dhpdev;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Ignore error */
+ }
+ _SEH2_END
+ }
+
+ return hdc;
+}
+
+
+HDC
+APIENTRY
+NtGdiCreateCompatibleDC(HDC hdc)
+{
+ HDC hdcNew;
+ PPDEVOBJ ppdev;
+ PDC pdc, pdcNew;
+
+ DPRINT("NtGdiCreateCompatibleDC(0x%p)\n", hdc);
+
+ /* Did the caller provide a DC? */
+ if (hdc)
+ {
+ /* Yes, try to lock it */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ DPRINT1("Could not lock source DC %p\n", hdc);
+ return NULL;
+ }
+
+ /* Get the pdev from the DC */
+ ppdev = pdc->ppdev;
+ InterlockedIncrement(&ppdev->cPdevRefs);
+
+ /* Unlock the source DC */
+ DC_UnlockDc(pdc);
+ }
+ else
+ {
+ /* No DC given, get default device */
+ ppdev = EngpGetPDEV(NULL);
+ }
+
+ if (!ppdev)
+ {
+ DPRINT1("Didn't find a suitable PDEV\n");
+ return NULL;
+ }
+
+ /* Allocate a new DC */
+ pdcNew = DC_AllocDcWithHandle();
+ if (!pdcNew)
+ {
+ DPRINT1("Could not allocate a new DC\n");
+ PDEVOBJ_vRelease(ppdev);
+ return NULL;
+ }
+ hdcNew = pdcNew->BaseObject.hHmgr;
+
+ /* Lock ppdev and initialize the new DC */
+ DC_vInitDc(pdcNew, DCTYPE_MEMORY, ppdev);
+ /* FIXME: HACK! */
+ DC_InitHack(pdcNew);
+
+ /* Allocate a dc attribute */
+ DC_AllocDcAttr(pdcNew);
+
+ // HACK!
+ DC_vSelectSurface(pdcNew, psurfDefaultBitmap);
+
+ DC_UnlockDc(pdcNew);
+
+ DPRINT("Leave NtGdiCreateCompatibleDC hdcNew = %p\n", hdcNew);
+
+ return hdcNew;
+}
+
+BOOL
+FASTCALL
+IntGdiDeleteDC(HDC hDC, BOOL Force)
+{
+ PDC DCToDelete = DC_LockDc(hDC);
+
+ if (DCToDelete == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (!Force)
+ {
+ if (DCToDelete->fs & DC_FLAG_PERMANENT)
+ {
+ DPRINT1("No! You Naughty Application!\n");
+ DC_UnlockDc(DCToDelete);
+ return UserReleaseDC(NULL, hDC, FALSE);
+ }
+ }
+
+ DC_UnlockDc(DCToDelete);
+
+ if (!IsObjectDead(hDC))
+ {
+ if (!GDIOBJ_FreeObjByHandle(hDC, GDI_OBJECT_TYPE_DC))
+ {
+ DPRINT1("DC_FreeDC failed\n");
+ }
+ }
+ else
+ {
+ DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC);
+ }
+
+ return TRUE;
+}
+
+BOOL
+APIENTRY
+NtGdiDeleteObjectApp(HANDLE DCHandle)
+{
+ /* Complete all pending operations */
+ NtGdiFlushUserBatch();
+
+ if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
+
+ if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC)
+ return GreDeleteObject((HGDIOBJ) DCHandle);
+
+ if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
+
+ if (!GDIOBJ_OwnedByCurrentProcess(DCHandle))
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ return IntGdiDeleteDC(DCHandle, FALSE);
+}
+
++BOOL
++FASTCALL
++MakeInfoDC(PDC pdc, BOOL bSet)
++{
++ PSURFACE pSurface;
++ SIZEL sizl;
++
++ /* Can not be a display DC. */
++ if (pdc->fs & DC_FLAG_DISPLAY) return FALSE;
++ if (bSet)
++ {
++ if (pdc->fs & DC_FLAG_TEMPINFODC || pdc->dctype == DC_TYPE_DIRECT)
++ return FALSE;
++
++ pSurface = pdc->dclevel.pSurface;
++ pdc->fs |= DC_FLAG_TEMPINFODC;
++ pdc->pSurfInfo = pSurface;
++ pdc->dctype = DC_TYPE_INFO;
++ pdc->dclevel.pSurface = NULL;
++
++ PDEVOBJ_sizl(pdc->ppdev, &sizl);
++
++ if ( sizl.cx == pdc->dclevel.sizl.cx &&
++ sizl.cy == pdc->dclevel.sizl.cy )
++ return TRUE;
++
++ pdc->dclevel.sizl.cx = sizl.cx;
++ pdc->dclevel.sizl.cy = sizl.cy;
++ }
++ else
++ {
++ if (!(pdc->fs & DC_FLAG_TEMPINFODC) || pdc->dctype != DC_TYPE_INFO)
++ return FALSE;
++
++ pSurface = pdc->pSurfInfo;
++ pdc->fs &= ~DC_FLAG_TEMPINFODC;
++ pdc->dclevel.pSurface = pSurface;
++ pdc->dctype = DC_TYPE_DIRECT;
++ pdc->pSurfInfo = NULL;
++
++ if ( !pSurface ||
++ (pSurface->SurfObj.sizlBitmap.cx == pdc->dclevel.sizl.cx &&
++ pSurface->SurfObj.sizlBitmap.cy == pdc->dclevel.sizl.cy) )
++ return TRUE;
++
++ pdc->dclevel.sizl.cx = pSurface->SurfObj.sizlBitmap.cx;
++ pdc->dclevel.sizl.cy = pSurface->SurfObj.sizlBitmap.cy;
++ }
++ return IntSetDefaultRegion(pdc);
++}
++
++/*
++* @implemented
++*/
+BOOL
+APIENTRY
+NtGdiMakeInfoDC(
+ IN HDC hdc,
+ IN BOOL bSet)
+{
++ BOOL Ret;
++ PDC pdc = DC_LockDc(hdc);
++ if (pdc)
++ {
++ Ret = MakeInfoDC(pdc, bSet);
++ DC_UnlockDc(pdc);
++ return Ret;
++ }
+ return FALSE;
+}
+
+
+HDC FASTCALL
+IntGdiCreateDC(
+ PUNICODE_STRING Driver,
+ PUNICODE_STRING pustrDevice,
+ PVOID pUMdhpdev,
+ CONST PDEVMODEW pdmInit,
+ BOOL CreateAsIC)
+{
+ HDC hdc;
+
+ hdc = GreOpenDCW(pustrDevice,
+ pdmInit,
+ NULL,
+ CreateAsIC ? DCTYPE_INFO :
+ (Driver ? DC_TYPE_DIRECT : DC_TYPE_DIRECT),
+ TRUE,
+ NULL,
+ NULL,
+ pUMdhpdev);
+
+ return hdc;
+}
+
+HDC FASTCALL
+IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
+{
+ HDC hDC;
+ UNIMPLEMENTED;
+ ASSERT(FALSE);
+
+ if (DcType == DC_TYPE_MEMORY)
+ hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth!
+ else
+ hDC = IntGdiCreateDC(NULL, NULL, NULL, NULL, (DcType == DC_TYPE_INFO));
+
+ return hDC;
+}
+