From eb343f8ebfce64ab8be0d0d79da7fdca19267d16 Mon Sep 17 00:00:00 2001 From: unodgs Date: Fri, 1 Jul 2011 21:15:25 +0000 Subject: [PATCH] Rainbow: started WinGL (wip..) git-svn-id: svn://ultimatepp.org/upp/trunk@3584 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- rainbow/WinGl/After.h | 42 ++++++ rainbow/WinGl/Draw.cpp | 235 +++++++++++++++++++++++++++++++++ rainbow/WinGl/Event.cpp | 152 +++++++++++++++++++++ rainbow/WinGl/Keys.h | 114 ++++++++++++++++ rainbow/WinGl/Proc.cpp | 170 ++++++++++++++++++++++++ rainbow/WinGl/Win.cpp | 114 ++++++++++++++++ rainbow/WinGl/WinGl.h | 283 ++++++++++++++++++++++++++++++++++++++++ rainbow/WinGl/WinGl.upp | 10 ++ rainbow/WinGl/init | 3 + rainbow/guiplatform.h | 4 + 10 files changed, 1127 insertions(+) create mode 100644 rainbow/WinGl/After.h create mode 100644 rainbow/WinGl/Draw.cpp create mode 100644 rainbow/WinGl/Event.cpp create mode 100644 rainbow/WinGl/Keys.h create mode 100644 rainbow/WinGl/Proc.cpp create mode 100644 rainbow/WinGl/Win.cpp create mode 100644 rainbow/WinGl/WinGl.h create mode 100644 rainbow/WinGl/WinGl.upp create mode 100644 rainbow/WinGl/init diff --git a/rainbow/WinGl/After.h b/rainbow/WinGl/After.h new file mode 100644 index 000000000..799e0a943 --- /dev/null +++ b/rainbow/WinGl/After.h @@ -0,0 +1,42 @@ +#ifndef _WinGl_After_h_ +#define _WinGl_After_h_ + +class ViewDraw : public SystemDraw { + ImageBuffer ib; + + Vector dummy_invalid; + +public: + ViewDraw(Ctrl *ctrl) : SystemDraw(ib, dummy_invalid) { _DBG_ } + ~ViewDraw() {} +}; + +void InitGl(); + +Vector& coreCmdLine__(); +Vector SplitCmdLine__(const char *cmd); + +void FBInit(HINSTANCE hInstance); + +#define GUI_APP_MAIN \ +void GuiMainFn_();\ +\ +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow) \ +{ \ + UPP::coreCmdLine__() = UPP::SplitCmdLine__(UPP::FromSystemCharset(lpCmdLine)); \ + UPP::AppInitEnvironment__(); \ + UPP::GlInit(hInstance); \ + GuiMainFn_(); \ + UPP::Ctrl::CloseTopCtrls(); \ + UPP::UsrLog("---------- About to delete this log of WinGL..."); \ + UPP::DeleteUsrLog(); \ + return UPP::GetExitCode(); \ +} \ +\ +void GuiMainFn_() + + +void SetDesktop(Ctrl& desktop); +Ctrl *GetDesktop(); + +#endif diff --git a/rainbow/WinGl/Draw.cpp b/rainbow/WinGl/Draw.cpp new file mode 100644 index 000000000..f3bd67ab4 --- /dev/null +++ b/rainbow/WinGl/Draw.cpp @@ -0,0 +1,235 @@ +#include + +#ifdef GUI_WINGL + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) +#define LTIMING(x) // RTIMING(x) + +ArrayMap Resources::textures; +VectorMap Resources::fonts; + +float GetFps() +{ + static float fps = 0.0f; + static dword updateInterval = 1000; + static dword timeSinceLastUpdate = 0; + static dword frameCount = 0; + static dword currentTick; + static dword lastTick; + static bool isFirst = true; + + if(isFirst) + { + currentTick = GetTickCount(); + lastTick = currentTick; + isFirst = false; + } + + frameCount++; + currentTick = GetTickCount(); + + dword elapsed = currentTick - lastTick; + + lastTick = currentTick; + timeSinceLastUpdate += elapsed; + + if (timeSinceLastUpdate > updateInterval) + { + if (timeSinceLastUpdate) + { + fps = (frameCount / float(timeSinceLastUpdate)) * 1000.f; + frameCount = 0; + timeSinceLastUpdate -= updateInterval; + } + } + + return fps; +} + +void Texture::AddPart(int64 serialId, const Image& img) +{ +} + +int64 Resources::Bind(const Image& img, bool linear) +{ + int64 serialId = img.GetSerialId(); + + if(!Bind(serialId)) + return serialId; + + int textureNumber = textures.Find(serialId); + + if(textureNumber < 0) + { + textures.Add(serialId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.GetWidth(), img.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, img); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST); + } + + return serialId; +} + +bool Resources::Bind(int64 serialId, bool force) +{ + if(!force && serialId == currentSerialId) + return false; + + currentSerialId = serialId; + glBindTexture(GL_TEXTURE_2D, (GLuint) serialId); + return true; +} + +OpenGLFont& Resources::GetFont(const char* fontName) +{ + int n = fonts.Find(fontName); + if(n >= 0) + return fonts[n]; + else + { + OpenGLFont& font = fonts.Add(fontName); + font.Load(fontName); + return font; + } +} + +OpenGLFont& Resources::StdFont(bool bold) +{ +// return GetFont(bold ? "tahoma14b.fnt" : "tahoma14.fnt"); +// return GetFont(bold ? "tahoma.fnt" : "tahoma.fnt"); + return GetFont(bold ? "arial.fnt" : "arial.fnt"); +} + +dword SystemDraw::GetInfo() const +{ + return 0; +} + +Size SystemDraw::GetPageSize() const +{ + return Size(0, 0); +} + +Size SystemDraw::GetNativeDpi() const +{ + return Size(96, 96); +} + +void SystemDraw::BeginNative() +{ +} + +void SystemDraw::EndNative() +{ +} + +int SystemDraw::GetCloffLevel() const +{ + return ci; +} + +void SystemDraw::InitClip(const Rect& clip) +{ + drawing_clip = clip; +} + +void SystemDraw::Reset() { + cloff.SetCount(20); + ci = 0; + cn = 0; + cd = 0; + drawing_offset = Point(0, 0); + alpha = 255; + angle = 0.f; +} + +SystemDraw::OpenGLDraw() { + Reset(); +} + +SystemDraw::OpenGLDraw(HDC hdc, Size sz) { + Reset(); + drawing_clip = sz; + drawing_size = sz; + clip = sz; + Init(); +} + +void SystemDraw::Init() +{ + //glVertexPointer(2, GL_FLOAT, 0, vtx); + //glTexCoordPointer(2, GL_FLOAT, 0, crd); + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glShadeModel(GL_SMOOTH); + glDisable(GL_ALPHA_TEST); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); +#if CLIP_MODE == 0 + glEnable(GL_SCISSOR_TEST); +#elif CLIP_MODE == 1 + glEnable(GL_CLIP_PLANE0); + glEnable(GL_CLIP_PLANE1); + glEnable(GL_CLIP_PLANE2); + glEnable(GL_CLIP_PLANE3); +#elif CLIP_MODE == 2 + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 0, ~0); + glStencilFunc(GL_KEEP, GL_KEEP, GL_KEEP); + glClearStencil(0); +#endif + glEnable(GL_LINE_SMOOTH); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glClearColor(0.f, 0.f, 0.f, 1.f); + glClearDepth(1.0f); + glEnableClientState(GL_VERTEX_ARRAY); + //glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glColor4f(1.f, 1.f, 1.f, 1.f); +} + +void SystemDraw::Clear() +{ +#if CLIP_MODE == 0 + glDisable(GL_SCISSOR_TEST); +#endif + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +#if CLIP_MODE == 0 + glEnable(GL_SCISSOR_TEST); +#endif +} + +void SystemDraw::FlatView() +{ + glViewport(0, 0, (GLsizei) drawing_size.cx, (GLsizei) drawing_size.cy); + float aspect = drawing_size.cx / (float) drawing_size.cy; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, drawing_size.cx, drawing_size.cy, 0, -100, 100); + //glFrustum(0, drawing_size.cx, drawing_size.cy, 0, -100, 100); + //gluPerspective(45, 1, -100, 100); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + float dx = (float) drawing_size.cx / 2; + float dy = (float) drawing_size.cy / 2; + glTranslatef(dx, dy, 0.f); + glRotatef(angle, 0, 0, 1); + glTranslatef(-dx, -dy, 0.f); +} + +void SystemDraw::PushContext() +{ +} + +void SystemDraw::PopContext() +{ + FlatView(); +} + + +SystemDraw::~OpenGLDraw() { +} + +END_UPP_NAMESPACE \ No newline at end of file diff --git a/rainbow/WinGl/Event.cpp b/rainbow/WinGl/Event.cpp new file mode 100644 index 000000000..8c8f7ca85 --- /dev/null +++ b/rainbow/WinGl/Event.cpp @@ -0,0 +1,152 @@ +#include + +NAMESPACE_UPP + +#define LLOG(x) LOG(x) + +static Point fbmousepos; + +Point GetMousePos() { + return fbmousepos; +} + +void Ctrl::DoMouseFB(int event, Point p, int zdelta) +{ + fbmousepos = p; + int a = event & Ctrl::ACTION; +// if(a == DOWN) +// ClickActivateWnd(); + if(a == Ctrl::UP && Ctrl::ignoreclick) { + EndIgnore(); + return; + } + else + if(a == Ctrl::DOWN && ignoreclick) + return; + LLOG("Mouse event: " << event << " position " << p << " zdelta " << zdelta); + Ctrl *desktop = GetDesktop(); + if(desktop) { + desktop->DispatchMouse(event, p, zdelta); + desktop->PostInput(); + } +// if(a == Ctrl::MOUSEMOVE) +// DoCursorShape(); +} + +bool Ctrl::DoKeyFB(dword key, int cnt) +{ + bool b = DispatchKey(key, cnt); + SyncCaret(); + Ctrl *desktop = GetDesktop(); + if(desktop) + desktop->PostInput(); + return b; +} + +Point fbCursorPos = Null; +Image fbCursorImage; + +Point fbCursorBakPos = Null; +Image fbCursorBak; + +Rect fbCaretRect; +Image fbCaretBak; +int fbCaretTm; + +Image Ctrl::GetBak(Rect& tr) +{ + Image bak; + tr.Intersect(framebuffer.GetSize()); + if(!tr.IsEmpty()) { + Image h = framebuffer; + bak = CreateImage(tr.GetSize(), Black); + Copy(bak, Point(0, 0), h, tr); + framebuffer = h; + } + return bak; +} + +void Ctrl::RemoveCursor() +{ + if(!IsNull(fbCursorBakPos)) { + Copy(framebuffer, fbCursorBakPos, fbCursorBak, fbCursorBak.GetSize()); + FBUpdate(Rect(fbCursorBakPos, fbCursorBak.GetSize())); + } + fbCursorPos = fbCursorBakPos = Null; + fbCursorBak = Null; +} + +void Ctrl::RemoveCaret() +{ + if(!IsNull(fbCaretRect)) { + Copy(framebuffer, fbCaretRect.TopLeft(), fbCaretBak, fbCaretBak.GetSize()); + FBUpdate(fbCaretRect); + } + fbCaretRect = Null; + fbCaretBak = Null; +} + +void Ctrl::SetCaret(int x, int y, int cx, int cy) +{ + GuiLock __; + caretx = x; + carety = y; + caretcx = cx; + caretcy = cy; + fbCaretTm = GetTickCount(); + SyncCaret(); +} + +void Ctrl::SyncCaret() { + GuiLock __; +} + +void Ctrl::CursorSync() +{ + Point p = GetMousePos() - fbCursorImage.GetHotSpot(); + Rect cr = Null; + if(focusCtrl && (((GetTickCount() - fbCaretTm) / 500) & 1) == 0) + cr = RectC(focusCtrl->caretx, focusCtrl->carety, focusCtrl->caretcx, focusCtrl->caretcy) + + focusCtrl->GetScreenView().TopLeft(); + if(fbCursorPos != p || cr != fbCaretRect) { + RemoveCursor(); + RemoveCaret(); + + fbCursorPos = p; + Size sz = fbCursorImage.GetSize(); + Rect tr(p, sz); + fbCursorBak = GetBak(tr); + fbCursorBakPos = tr.TopLeft(); + + if(!cr.IsEmpty()) { + fbCaretBak = GetBak(cr); + fbCaretRect = cr; + for(int y = cr.top; y < cr.bottom; y++) { + RGBA *s = framebuffer[y] + cr.left; + const RGBA *e = framebuffer[y] + cr.right; + while(s < e) { + s->r = ~s->r; + s->g = ~s->g; + s->b = ~s->b; + s++; + } + } + FBUpdate(fbCaretRect); + } + + Over(framebuffer, p, fbCursorImage, sz); + FBUpdate(tr); + FBSync(); + } +} + +void Ctrl::SetMouseCursor(const Image& image) +{ + GuiLock __; + if(image.GetSerialId() != fbCursorImage.GetSerialId()) { + fbCursorImage = image; + fbCursorPos = Null; + } +} + +END_UPP_NAMESPACE diff --git a/rainbow/WinGl/Keys.h b/rainbow/WinGl/Keys.h new file mode 100644 index 000000000..9fe3f13dc --- /dev/null +++ b/rainbow/WinGl/Keys.h @@ -0,0 +1,114 @@ +#ifndef _WinGl_Keys_h_ +#define _WinGl_Keys_h_ + +K_BACK = VK_BACK + K_DELTA, +K_BACKSPACE = VK_BACK + K_DELTA, + +K_TAB = 9, + +K_SPACE = 32, + +K_RETURN = 13, +K_ENTER = K_RETURN, + +K_SHIFT_KEY = VK_SHIFT + K_DELTA, +K_CTRL_KEY = VK_CONTROL + K_DELTA, +K_ALT_KEY = VK_MENU + K_DELTA, +K_CAPSLOCK = VK_CAPITAL + K_DELTA, +K_ESCAPE = VK_ESCAPE + K_DELTA, +K_PRIOR = VK_PRIOR + K_DELTA, +K_PAGEUP = VK_PRIOR + K_DELTA, +K_NEXT = VK_NEXT + K_DELTA, +K_PAGEDOWN = VK_NEXT + K_DELTA, +K_END = VK_END + K_DELTA, +K_HOME = VK_HOME + K_DELTA, +K_LEFT = VK_LEFT + K_DELTA, +K_UP = VK_UP + K_DELTA, +K_RIGHT = VK_RIGHT + K_DELTA, +K_DOWN = VK_DOWN + K_DELTA, +K_INSERT = VK_INSERT + K_DELTA, +K_DELETE = VK_DELETE + K_DELTA, + +K_NUMPAD0 = VK_NUMPAD0 + K_DELTA, +K_NUMPAD1 = VK_NUMPAD1 + K_DELTA, +K_NUMPAD2 = VK_NUMPAD2 + K_DELTA, +K_NUMPAD3 = VK_NUMPAD3 + K_DELTA, +K_NUMPAD4 = VK_NUMPAD4 + K_DELTA, +K_NUMPAD5 = VK_NUMPAD5 + K_DELTA, +K_NUMPAD6 = VK_NUMPAD6 + K_DELTA, +K_NUMPAD7 = VK_NUMPAD7 + K_DELTA, +K_NUMPAD8 = VK_NUMPAD8 + K_DELTA, +K_NUMPAD9 = VK_NUMPAD9 + K_DELTA, +K_MULTIPLY = VK_MULTIPLY + K_DELTA, +K_ADD = VK_ADD + K_DELTA, +K_SEPARATOR = VK_SEPARATOR + K_DELTA, +K_SUBTRACT = VK_SUBTRACT + K_DELTA, +K_DECIMAL = VK_DECIMAL + K_DELTA, +K_DIVIDE = VK_DIVIDE + K_DELTA, +K_SCROLL = VK_SCROLL + K_DELTA, + +K_F1 = VK_F1 + K_DELTA, +K_F2 = VK_F2 + K_DELTA, +K_F3 = VK_F3 + K_DELTA, +K_F4 = VK_F4 + K_DELTA, +K_F5 = VK_F5 + K_DELTA, +K_F6 = VK_F6 + K_DELTA, +K_F7 = VK_F7 + K_DELTA, +K_F8 = VK_F8 + K_DELTA, +K_F9 = VK_F9 + K_DELTA, +K_F10 = VK_F10 + K_DELTA, +K_F11 = VK_F11 + K_DELTA, +K_F12 = VK_F12 + K_DELTA, + +K_A = 'A' + K_DELTA, +K_B = 'B' + K_DELTA, +K_C = 'C' + K_DELTA, +K_D = 'D' + K_DELTA, +K_E = 'E' + K_DELTA, +K_F = 'F' + K_DELTA, +K_G = 'G' + K_DELTA, +K_H = 'H' + K_DELTA, +K_I = 'I' + K_DELTA, +K_J = 'J' + K_DELTA, +K_K = 'K' + K_DELTA, +K_L = 'L' + K_DELTA, +K_M = 'M' + K_DELTA, +K_N = 'N' + K_DELTA, +K_O = 'O' + K_DELTA, +K_P = 'P' + K_DELTA, +K_Q = 'Q' + K_DELTA, +K_R = 'R' + K_DELTA, +K_S = 'S' + K_DELTA, +K_T = 'T' + K_DELTA, +K_U = 'U' + K_DELTA, +K_V = 'V' + K_DELTA, +K_W = 'W' + K_DELTA, +K_X = 'X' + K_DELTA, +K_Y = 'Y' + K_DELTA, +K_Z = 'Z' + K_DELTA, +K_0 = '0' + K_DELTA, +K_1 = '1' + K_DELTA, +K_2 = '2' + K_DELTA, +K_3 = '3' + K_DELTA, +K_4 = '4' + K_DELTA, +K_5 = '5' + K_DELTA, +K_6 = '6' + K_DELTA, +K_7 = '7' + K_DELTA, +K_8 = '8' + K_DELTA, +K_9 = '9' + K_DELTA, + +K_CTRL_LBRACKET = K_CTRL|219|K_DELTA, +K_CTRL_RBRACKET = K_CTRL|221|K_DELTA, +K_CTRL_MINUS = K_CTRL|0xbd|K_DELTA, +K_CTRL_GRAVE = K_CTRL|0xc0|K_DELTA, +K_CTRL_SLASH = K_CTRL|0xbf|K_DELTA, +K_CTRL_BACKSLASH = K_CTRL|0xdc|K_DELTA, +K_CTRL_COMMA = K_CTRL|0xbc|K_DELTA, +K_CTRL_PERIOD = K_CTRL|0xbe|K_DELTA, +K_CTRL_SEMICOLON = K_CTRL|0xbe|K_DELTA, +K_CTRL_EQUAL = K_CTRL|0xbb|K_DELTA, +K_CTRL_APOSTROPHE= K_CTRL|0xde|K_DELTA, + +K_BREAK = VK_CANCEL + K_DELTA, + +#endif diff --git a/rainbow/WinGl/Proc.cpp b/rainbow/WinGl/Proc.cpp new file mode 100644 index 000000000..037b53b81 --- /dev/null +++ b/rainbow/WinGl/Proc.cpp @@ -0,0 +1,170 @@ +#include "WinGl.h" + +NAMESPACE_UPP + +#define LLOG(x) LOG(x) + +bool GetShift() { return !!(GetKeyState(VK_SHIFT) & 0x8000); } +bool GetCtrl() { return !!(GetKeyState(VK_CONTROL) & 0x8000); } +bool GetAlt() { return !!(GetKeyState(VK_MENU) & 0x8000); } +bool GetCapsLock() { return !!(GetKeyState(VK_CAPITAL) & 1); } +bool GetMouseLeft() { return !!(GetKeyState(VK_LBUTTON) & 0x8000); } +bool GetMouseRight() { return !!(GetKeyState(VK_RBUTTON) & 0x8000); } +bool GetMouseMiddle() { return !!(GetKeyState(VK_MBUTTON) & 0x8000); } + +dword fbKEYtoK(dword chr) { + if(chr == VK_TAB) + chr = K_TAB; + else + if(chr == VK_SPACE) + chr = K_SPACE; + else + if(chr == VK_RETURN) + chr = K_RETURN; + else + chr = chr + K_DELTA; + if(chr == K_ALT_KEY || chr == K_CTRL_KEY || chr == K_SHIFT_KEY) + return chr; + if(GetCtrl()) chr |= K_CTRL; + if(GetAlt()) chr |= K_ALT; + if(GetShift()) chr |= K_SHIFT; + return chr; +} + +#ifdef _DEBUG + +#define x_MSG(x) { x, #x }, + +Tuple2 sWinMsg[] = { +#include + {0, NULL} +}; + +#endif + +LRESULT CALLBACK glWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + GuiLock __; +#ifdef _DEBUG + Tuple2 *x = FindTuple(sWinMsg, __countof(sWinMsg), message); + if(x) + LLOG(x->b << ", wParam: " << wParam << ", lParam: " << lParam); +#endif + // LLOG("Ctrl::WindowProc(" << message << ") in " << ::Name(this) << ", focus " << (void *)::GetFocus()); + switch(message) { + case WM_PAINT: + ASSERT(hwnd); + if(hwnd) { + PAINTSTRUCT ps; + HDC dc = BeginPaint(hwnd, &ps); + EndPaint(hwnd, &ps); + } + return 0L; + case WM_LBUTTONDOWN: + Ctrl::DoMouseFB(Ctrl::LEFTDOWN, Point((dword)lParam)); + return 0L; + case WM_LBUTTONUP: + Ctrl::DoMouseFB(Ctrl::LEFTUP, Point((dword)lParam)); + return 0L; + case WM_LBUTTONDBLCLK: + Ctrl::DoMouseFB(Ctrl::LEFTDOUBLE, Point((dword)lParam)); + return 0L; + case WM_RBUTTONDOWN: + Ctrl::DoMouseFB(Ctrl::RIGHTDOWN, Point((dword)lParam)); + return 0L; + case WM_RBUTTONUP: + Ctrl::DoMouseFB(Ctrl::RIGHTUP, Point((dword)lParam)); + return 0L; + case WM_RBUTTONDBLCLK: + Ctrl::DoMouseFB(Ctrl::RIGHTDOUBLE, Point((dword)lParam)); + return 0L; + case WM_MBUTTONDOWN: + Ctrl::DoMouseFB(Ctrl::MIDDLEDOWN, Point((dword)lParam)); + return 0L; + case WM_MBUTTONUP: + Ctrl::DoMouseFB(Ctrl::MIDDLEUP, Point((dword)lParam)); + return 0L; + case WM_MBUTTONDBLCLK: + Ctrl::DoMouseFB(Ctrl::MIDDLEDOUBLE, Point((dword)lParam)); + return 0L; + case WM_MOUSEMOVE: + Ctrl::DoMouseFB(Ctrl::MOUSEMOVE, Point((dword)lParam)); + return 0L; + case 0x20a: // WM_MOUSEWHEEL: + { + Point p(0, 0); + ::ClientToScreen(hwnd, p); + Ctrl::DoMouseFB(Ctrl::MOUSEWHEEL, Point((dword)lParam) - p, (short)HIWORD(wParam)); + } + return 0L; + case WM_SETCURSOR: + if(LOWORD((dword)lParam) == HTCLIENT) { + SetCursor(NULL); + return TRUE; + } + break; +// case WM_MENUCHAR: +// return MAKELONG(0, MNC_SELECT); + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_CHAR: +// ignorekeyup = false; + case WM_KEYUP: + case WM_SYSKEYUP: + { + String msgdump; + switch(message) + { + case WM_KEYDOWN: msgdump << "WM_KEYDOWN"; break; + case WM_KEYUP: msgdump << "WM_KEYUP"; break; + case WM_SYSKEYDOWN: msgdump << "WM_SYSKEYDOWN"; break; + case WM_SYSKEYUP: msgdump << "WM_SYSKEYUP"; break; + case WM_CHAR: msgdump << "WM_CHAR"; break; + } + msgdump << " wParam = 0x" << FormatIntHex(wParam, 8) + << ", lParam = 0x" << FormatIntHex(lParam, 8); + LLOG(msgdump); + dword keycode = 0; + if(message == WM_KEYDOWN) { + keycode = fbKEYtoK((dword)wParam); + if(keycode == K_SPACE) + keycode = 0; + } + else + if(message == WM_KEYUP) + keycode = fbKEYtoK((dword)wParam) | K_KEYUP; + else + if(message == WM_SYSKEYDOWN /*&& ((lParam & 0x20000000) || wParam == VK_F10)*/) + keycode = fbKEYtoK((dword)wParam); + else + if(message == WM_SYSKEYUP /*&& ((lParam & 0x20000000) || wParam == VK_F10)*/) + keycode = fbKEYtoK((dword)wParam) | K_KEYUP; + else + if(message == WM_CHAR && wParam != 127 && wParam > 32 || wParam == 32 && fbKEYtoK(VK_SPACE) == K_SPACE) + keycode = (dword)wParam; + bool b = false; + if(keycode) + b = Ctrl::DoKeyFB(keycode, LOWORD(lParam)); +// LOG("key processed = " << b); +// if(b || (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP) +// && wParam != VK_F4 && !PassWindowsKey((dword)wParam)) // 17.11.2003 Mirek -> invoke system menu +// return 0L; + break; + } + break; +// case WM_GETDLGCODE: +// return wantfocus ? 0 : DLGC_STATIC; + case WM_ERASEBKGND: + return 1L; + case WM_SIZE: + case WM_MOVE: + return 0L; + case WM_HELP: + return TRUE; + case WM_CLOSE: + fbEndSession = true; + } + return DefWindowProc(hwnd, message, wParam, lParam); +} + +END_UPP_NAMESPACE diff --git a/rainbow/WinGl/Win.cpp b/rainbow/WinGl/Win.cpp new file mode 100644 index 000000000..5cb118c63 --- /dev/null +++ b/rainbow/WinGl/Win.cpp @@ -0,0 +1,114 @@ +#include "WinFb.h" + +NAMESPACE_UPP + +HWND glHWND; + +bool glEndSession; + +bool GlEndSession() +{ + return fbEndSession; +} + +bool GlIsWaitingEvent() +{ + MSG msg; + return PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); +} + +bool GlProcessEvent(bool *quit) +{ + MSG msg; + if(PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { + if(msg.message == WM_QUIT && quit) + *quit = true; + TranslateMessage(&msg); + DispatchMessageW(&msg); + return true; + } + return false; +} + +void GlSleep(int ms) +{ + MsgWaitForMultipleObjects(0, NULL, FALSE, ms, QS_ALLINPUT); +} + +void GlInit(HINSTANCE hInstance) +{ + GuiLock __; + + Ctrl::InitGl(); + + WNDCLASSW wc; + Zero(wc); + wc.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW|CS_OWNDC; + wc.lpfnWndProc = (WNDPROC)fbWindowProc; + wc.hInstance = hInstance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)NULL; + wc.lpszClassName = L"UPP-FB-CLASS"; + RegisterClassW(&wc); + fbHWND = CreateWindowW(L"UPP-FB-CLASS", L"", WS_OVERLAPPED|WS_VISIBLE|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, hInstance, NULL); + + + hDC = ::GetDC(GetHWND()); + if(!hDC) + return; + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_SUPPORT_COMPOSITION; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; + pfd.iLayerType = PFD_MAIN_PLANE; + int pf = ChoosePixelFormat(hDC, &pfd); + if(!pf) { + + RLOG("OpenGL: ChoosePixelFormat error"); + DestroyGL(); + return; + } + if(!SetPixelFormat(hDC, pf, &pfd)) { + RLOG("OpenGL: SetPixelFormat error"); + DestroyGL(); + return; + } + DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + hRC = wglCreateContext(hDC); + if(!hRC) + { + RLOG("OpenGL: wglCreateContext error"); + DestroyGL(); + return; + } + if(!wglMakeCurrent(hDC, hRC)) + { + RLOG("OpenGL: wglMakeCurrent error"); + DestroyGL(); + return; + } + //ActivateGLContext(); + GLenum err = glewInit(); + if(err != GLEW_OK) + { + RLOG("OpenGL: Glew library initialization error: " + String((const char*) glewGetErrorString(err))); + DestroyGL(); + return; + } + + //InitializeShaders(); + //wglSwapIntervalEXT(0); + //SetTimeCallback(-10, THISBACK(Repaint), 1); + + //SetTimer(fbHWND, 1, 10, NULL); + +} + +END_UPP_NAMESPACE diff --git a/rainbow/WinGl/WinGl.h b/rainbow/WinGl/WinGl.h new file mode 100644 index 000000000..7040658e6 --- /dev/null +++ b/rainbow/WinGl/WinGl.h @@ -0,0 +1,283 @@ +#ifndef _WinGl_WinGl_h_ +#define _WinGl_WinGl_h_ + +#include + +NAMESPACE_UPP + +extern bool glEndSession; + +LRESULT CALLBACK glWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +#define GUI_FB + +float GetFps(); + +#define CLIP_MODE 2 +/* +0 - Scissor clip +1 - Plane clip +2 - Stencil clip +3 - Manual clip +*/ + +struct OpenGLFont : Moveable +{ + float scaleW; + float scaleH; + float lineHeight; + float base; + + bool texturesUpdated; + + float vtx[1024 * 4 * 2]; + float crd[1024 * 4 * 2]; + + struct CharInfo : Moveable + { + int id; + float x; + float y; + float width; + float height; + float xoffset; + float yoffset; + float xadvance; + int page; + }; + + Vector chars; + VectorMap> kerns; + Vector files; + Vector pages; + + OpenGLFont() : texturesUpdated(false) + {} + + ~OpenGLFont() + {} + + void Load(const String& fileName); + void UpdateTextures(); + void BuildVertices(); + +}; + +struct Texture : Moveable +{ + Size sz; + Point curpos; + VectorMap parts; + void AddPart(int64 serialId, const Image& img); +}; + +struct Resources +{ + static int64 currentSerialId; + static ArrayMap textures; + static VectorMap fonts; + static int64 Bind(const Image& img, bool linear = false); + static bool Bind(int64 serialId, bool force = false); + static OpenGLFont& GetFont(const char* fontName); + static OpenGLFont& StdFont(bool bold = false); +}; + +class SystemDraw : public Draw { +public: + virtual dword GetInfo() const; + virtual Size GetPageSize() const; + + void PlaneEquation(double eq[4], float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3); + void SetClipRect(const Rect& r); + void ScissorClip(const Rect& r); + void PlaneClip(const Rect& r); + void StencilClip(const Rect& r, int mode = 0); + void SetClip(const Rect& r, int mode = 0); + + virtual void BeginOp(); + virtual void EndOp(); + virtual void OffsetOp(Point p); + virtual bool ClipOp(const Rect& r); + virtual bool ClipoffOp(const Rect& r); + virtual bool ExcludeClipOp(const Rect& r); + virtual bool IntersectClipOp(const Rect& r); + virtual bool IsPaintingOp(const Rect& r) const; + virtual Rect GetPaintRect() const; + + virtual void DrawRectOp(int x, int y, int cx, int cy, Color color); + virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); + virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color); + + virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, + const int *counts, int count_count, + int width, Color color, Color doxor); + virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, + const int *subpolygon_counts, int scc, + const int *disjunct_polygon_counts, int dpcc, + Color color, int width, Color outline, + uint64 pattern, Color doxor); + virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color); + + virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor); + virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, + Color ink, int n, const int *dx); + + virtual Size GetNativeDpi() const; + virtual void BeginNative(); + virtual void EndNative(); + + virtual int GetCloffLevel() const; + +private: + + friend class FontInfo; + friend class Font; + + OpenGLFont fi; + + struct Cloff : Moveable { + bool clipping; + Point org; + Rect drawing_clip; + }; + + float current_color[4]; + float vtx[8]; + float crd[8]; + void SetVec(float* v, float sx, float sy, float dx, float dy); + void SetVec(float* v, int sx, int sy, int dx, int dy); + + void SaveCurrentColor(); + void RestoreLastColor(); + +public: + Rect drawing_clip; + Size drawing_size; + Point drawing_offset; + Rect clip; + float alpha; + float angle; + +private: + Array cloff; + int ci; + int cn; + int cd; + + void Reset(); + +protected: + + SystemDraw(); + void InitClip(const Rect& clip); + void Init(); + +public: + + static void Flush() { /*glFlush();*/ } + Point GetOffset() const { return drawing_offset; } + SystemDraw(HDC hdc, Size sz = Size(0, 0)); + virtual ~SystemDraw(); + void FlatView(); + void Clear(); + void PushContext(); + void PopContext(); +}; + +struct BackDraw__ : public SystemDraw { + BackDraw__() {} +}; + +class BackDraw : public BackDraw__ { // Dummy only, as we are running in GlobalBackBuffer mode + Size size; + Draw *painting; + Point painting_offset; + ImageBuffer ib; + +public: + virtual bool IsPaintingOp(const Rect& r) const; + +public: + void Put(SystemDraw& w, int x, int y) {} + void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); } + + void Create(SystemDraw& w, int cx, int cy) {} + void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); } + void Destroy() {} + + void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; } + + BackDraw(); + ~BackDraw(); +}; + +struct ImageDraw__ { + ImageBuffer image; + ImageBuffer alpha; + + ImageDraw__(int cx, int cy) : image(cx, cy), alpha(cx, cy) {} +}; + +class ImageDraw : private ImageDraw__ { + bool has_alpha; + + Image Get(bool pm) const; + +public: + Draw& Alpha(); + + operator Image() const { return Get(true); } + + Image GetStraight() const { return Get(false); } + + ImageDraw(Size sz); + ImageDraw(int cx, int cy); +}; + +void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, uint64 pattern); + +#define GUIPLATFORM_CTRL_TOP_DECLS +#define GUIPLATFORM_CTRL_DECLS_INCLUDE +#define GUIPLATFORM_PASTECLIP_DECLS +#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE + + +bool GlIsWaitingEvent(); +bool GlProcessEvent(bool *quit); +void GlSleep(int ms); +bool GlEndSession(); + +class PrinterJob { // Dummy only... + NilDraw nil; + Vector pages; + +public: + Draw& GetDraw() { return nil; } + operator Draw&() { return GetDraw(); } + const Vector& GetPages() const { return pages; } + int operator[](int i) const { return 0; } + int GetPageCount() const { return 0; } + + bool Execute() { return false; } + + PrinterJob& Landscape(bool b = true) { return *this; } + PrinterJob& MinMaxPage(int minpage, int maxpage) { return *this; } + PrinterJob& PageCount(int n) { return *this; } + PrinterJob& CurrentPage(int currentpage) { return *this; } + PrinterJob& Name(const char *_name) { return *this; } + + PrinterJob(const char *name = NULL) {} + ~PrinterJob() {} +}; + +END_UPP_NAMESPACE + +#include +#include "vkcodes.h" //FIXME + +#define GUIPLATFORM_INCLUDE_AFTER + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/WinGl/WinGl.upp b/rainbow/WinGl/WinGl.upp new file mode 100644 index 000000000..08034cca3 --- /dev/null +++ b/rainbow/WinGl/WinGl.upp @@ -0,0 +1,10 @@ +file + WinGl.h, + Keys.h, + Draw.cpp, + Win.cpp, + Proc.cpp, + After.h, + Event.cpp, + Top.h; + diff --git a/rainbow/WinGl/init b/rainbow/WinGl/init new file mode 100644 index 000000000..3359257e3 --- /dev/null +++ b/rainbow/WinGl/init @@ -0,0 +1,3 @@ +#ifndef _WinGl_icpp_init_stub +#define _WinGl_icpp_init_stub +#endif diff --git a/rainbow/guiplatform.h b/rainbow/guiplatform.h index b5d859ea6..3a272cb32 100644 --- a/rainbow/guiplatform.h +++ b/rainbow/guiplatform.h @@ -15,3 +15,7 @@ #define GUIPLATFORM_KEYCODES_INCLUDE #define GUIPLATFORM_INCLUDE #endif + +#ifdef flagWINGL +#define GUIPLATFORM_INCLUDE +#endif