Mercurial > ecos
diff packages/services/gfx/mw/current/src/mwin/mwobjects/mwobjects.cc @ 208:e0c0827131d1 ecos
Merge from eCos master repository on 2002-05-20-20:11:54-BST
| author | jlarmour |
|---|---|
| date | Mon, 20 May 2002 22:19:26 +0000 |
| parents | |
| children |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/services/gfx/mw/current/src/mwin/mwobjects/mwobjects.cc @@ -0,0 +1,551 @@ +/* + Copyright (C) Chris Johns (ccj@acm.org) + + Microwindows C++ Wrappers. + + */ + +#include <algorithm> +#include <stdarg.h> +#include <stdio.h> +#include <mwobjects.h> + +namespace MicroWindowsObjects +{ + + static Application *the_application = 0; + + WindowClass::WindowClass () + { + wclass.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW; + wclass.lpfnWndProc = 0; + wclass.lpfnWndProc = 0; + wclass.cbClsExtra = 0; + wclass.cbWndExtra = 0; + wclass.hInstance = 0; + wclass.hIcon = 0; + wclass.hCursor = 0; + wclass.hbrBackground = 0; + wclass.lpszMenuName = 0; + wclass.lpszClassName = 0; + } + + WindowClass::WindowClass (LPCSTR lpszClassName, + UINT style, + int cbClsExtra, + int cbWndExtra, + HINSTANCE hInstance, + HICON hIcon, + HCURSOR hCursor, + HBRUSH hbrBackground, + LPCSTR lpszMenuName) + { + wclass.style = style; + wclass.lpfnWndProc = (WNDPROC) Window::WndProc; + wclass.cbClsExtra = cbClsExtra; + wclass.cbWndExtra = cbWndExtra + sizeof (Window *); + wclass.hInstance = hInstance; + wclass.hIcon = hIcon; + wclass.hCursor = hCursor; + wclass.hbrBackground = hbrBackground; + wclass.lpszMenuName = lpszMenuName; + wclass.lpszClassName = lpszClassName; + } + + ATOM WindowClass::register_class () + { + return RegisterClass (&wclass); + } + + Window::Window () + : hwnd (0) + { + } + + Window::Window (DWORD dwExStyle, + LPCSTR lpClassName, + LPCSTR lpWindowName, + DWORD dwStyle, + int x, + int y, + int nWidth, + int nHeight, + HWND hwndParent, + HMENU hMenu, + HINSTANCE hInstance, + LPVOID lpParam) + : hwnd (0) + { + create (dwExStyle, + lpClassName, + lpWindowName, + dwStyle, + x, y, nWidth, nHeight, + hwndParent, + hMenu, + hInstance, + lpParam); + } + + Window::~Window () + { + destory (); + } + + HWND + Window::create (DWORD dwExStyle, + LPCSTR lpClassName, + LPCSTR lpWindowName, + DWORD dwStyle, + int x, + int y, + int nWidth, + int nHeight, + HWND hwndParent, + HMENU hMenu, + HINSTANCE hInstance, + LPVOID lpParam) + { + lpCreateParams = lpParam; + + lpParam = (LPVOID) this; + + hwnd = ::CreateWindowEx (dwExStyle, + lpClassName, + lpWindowName, + dwStyle, + x, y, nWidth, nHeight, + hwndParent, + hMenu, + hInstance, + lpParam); + return hwnd; + } + + BOOL + Window::destory () + { + if (hwnd) + { + HWND old_hwnd = hwnd; + hwnd = 0; + return ::DestroyWindow (old_hwnd); + } + return 0; + } + + bool + Window::attach (const int fd, FileDescriptor& file_descriptor) + { + // + // The user must set the fd before being added to the set. + // + + if ((fd < 0) || (fd >= FD_SETSIZE) || (file_descriptor.file_desc != -1)) + return false; + + // + // If this fd is already taken do not add another. + // + + file_descriptor.file_desc = fd; + file_descriptor.window = this; + + if (file_descriptors.find (&file_descriptor) != file_descriptors.end ()) + { + file_descriptor.file_desc = -1; + file_descriptor.window = 0; + return false; + } + + file_descriptors.insert (&file_descriptor); + + return true; + } + + bool + Window::detach (FileDescriptor& file_descriptor) + { + // + // The user must set the fd before being added to the set. + // + + if ((file_descriptor.fd () < 0) || (file_descriptor.fd () >= FD_SETSIZE)) + return false; + + // + // If this fd is already taken do not add another. + // + + if (file_descriptors.find (&file_descriptor) == file_descriptors.end ()) + return false; + + file_descriptor.disable_read (); + file_descriptor.disable_write (); + file_descriptor.disable_except (); + + file_descriptors.erase (&file_descriptor); + + file_descriptor.file_desc = -1; + file_descriptor.window = 0; + + return true; + } + + struct eq_fd + { + const int fd; + eq_fd (const int fd) : fd (fd) {} + bool operator() (const FileDescriptor* f1) const + { return (f1->fd () == fd); } + }; + + LRESULT + Window::message_handler (UINT msg, + WPARAM wp, + LPARAM lp) + { + switch (msg) + { + case WM_FDINPUT: + case WM_FDOUTPUT: + case WM_FDEXCEPT: + + { + // + // The iterator provides a reference to the object pointer + // as the set contains pointers. + // + + set<FileDescriptor*>::iterator file_descriptor; + + file_descriptor = find_if (file_descriptors.begin (), + file_descriptors.end (), + eq_fd ((int) wp)); + + if (file_descriptor != file_descriptors.end ()) + { + switch (msg) + { + case WM_FDINPUT: + return (*file_descriptor)->read (); + + case WM_FDOUTPUT: + return (*file_descriptor)->write (); + + case WM_FDEXCEPT: + return (*file_descriptor)->except (); + } + } + } + break; + + default: + break; + } + + return ::DefWindowProc (hwnd, msg, wp, lp); + } + + bool + Window::ltint::operator () (const FileDescriptor* f1, + const FileDescriptor* f2) const + { + return f1->fd () < f2->fd (); + } + + LRESULT CALLBACK + Window::WndProc (HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) + { + int offset = GetClassLong (hwnd, GCL_CBWNDEXTRA) - sizeof (Window *); + Window *window = 0; + + if (msg == WM_CREATE) + { + LPCREATESTRUCT cs = (LPCREATESTRUCT) lp; + + window = dynamic_cast<Window*>((Window*) cs->lpCreateParams); + + if (window) + { + window->hwnd = hwnd; + SetWindowLong (hwnd, offset, (DWORD) window); + cs->lpCreateParams = window->lpCreateParams; + } + } + else + { + window = dynamic_cast<Window*>((Window*) GetWindowLong (hwnd, offset)); + } + + if (window) + return window->message_handler (msg, wp, lp); + + return ::DefWindowProc (hwnd, msg, wp, lp); + } + + Paint::Paint (HWND hwnd) + : hwnd (hwnd), + draw_3d (false), + drawing (false), + r (0, 0, 0, 0), + text_format (0) + { + } + + Paint::Paint (HWND hwnd, LPARAM lpParam) + : hwnd (hwnd), + draw_3d (false), + drawing (false), + r (0, 0, 0, 0), + text_format (0) + { + POINTSTOPOINT (pt, lpParam); + } + + Paint::~Paint () + { + end (); + } + + void + Paint::begin (bool init_3d, bool draw_3d_in_mem) + { + if (!drawing && hwnd) + { + hdc = ::BeginPaint (hwnd, &ps); + + r.get_client (hwnd); + + if (init_3d) + initialise_3d (draw_3d_in_mem); + + drawing = true; + } + } + + void + Paint::end () + { + if (drawing) + { + paint_3d (); + + ::EndPaint (hwnd, &ps); + + drawing = false; + } + } + + int + Paint::text_out (int x, int y, const char *format, ...) + { + Rect rect (x, y, x + 100, y + 100); + va_list arg; + + va_start (arg, format); + vsnprintf (format_buf, TEXT_BUF_SIZE, format, arg); + format_buf[TEXT_BUF_SIZE - 1] = '\0'; + + return ::DrawText (hdc, format_buf, -1, rect, text_format); + } + + FileDescriptor::FileDescriptor () + : file_desc (-1), + window (0) + { + } + + FileDescriptor::~FileDescriptor () + { + if (window) + window->detach (*this); + } + + bool + FileDescriptor::enable_read () + { + if (!read_is_enabled && window && (file_desc != -1)) + { + ::MwRegisterFdInput (*window, file_desc); + read_is_enabled = true; + return true; + } + return false; + } + + bool + FileDescriptor::disable_read () + { + if (read_is_enabled && window && (file_desc != -1)) + { + ::MwUnregisterFdInput (*window, file_desc); + read_is_enabled = false; + return true; + } + return false; + } + + + bool + FileDescriptor::enable_write () + { + if (!write_is_enabled && window && (file_desc != -1)) + { + ::MwRegisterFdOutput (*window, file_desc); + write_is_enabled = true; + return true; + } + return false; + } + + bool + FileDescriptor::disable_write () + { + if (write_is_enabled && window && (file_desc != -1)) + { + ::MwUnregisterFdOutput (*window, file_desc); + write_is_enabled = false; + return true; + } + return false; + } + + bool + FileDescriptor::enable_except () + { + if (!except_is_enabled && window && (file_desc != -1)) + { + ::MwRegisterFdExcept (*window, file_desc); + except_is_enabled = true; + return true; + } + return false; + } + + bool + FileDescriptor::disable_except () + { + if (except_is_enabled && window && (file_desc != -1)) + { + ::MwUnregisterFdExcept (*window, file_desc); + except_is_enabled = false; + return true; + } + return false; + } + + LRESULT + FileDescriptor::read () + { + return 0; + } + + LRESULT + FileDescriptor::write () + { + return 0; + } + + LRESULT + FileDescriptor::except () + { + return 0; + } + + Application::Application () + : background (0) + { + if (!the_application) + the_application = this; + } + + Application::Application (MWIMAGEHDR& background) + : background (&background) + { + if (!the_application) + the_application = this; + } + + Application::~Application () + { + } + + int + Application::initialise () + { + return 0; + } + + int + Application::shutdown () + { + return 0; + } + + int WINAPI + Application::WinMain (HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nShowCmd) + { + if (the_application) + { + int result; + + MwRegisterButtonControl (0); + + result = the_application->initialise (); + + if (result) + return result; + + // + // Set background wallpaper + // + + if (the_application->background) + MwSetDesktopWallpaper (the_application->background); + + MSG msg; + + // + // type ESC to quit... + // + + while (GetMessage (&msg, 0, 0, 0)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + result = the_application->shutdown (); + + if (result) + return result; + + return 0; + } + + return 1; + } + +}; + +// +// Global Microwindows WinMain () routine with "C" linkage +// + +extern "C" +{ + int WinMain (HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nShowCmd) + { + return MicroWindowsObjects::Application::WinMain (hInstance, + hPrevInstance, + lpCmdLine, + nShowCmd); + } +};
