diff --git a/rainbow/SDL2GUI/Cursor.cpp b/rainbow/SDL2GUI/Cursor.cpp new file mode 100644 index 000000000..bc953b54a --- /dev/null +++ b/rainbow/SDL2GUI/Cursor.cpp @@ -0,0 +1,70 @@ +#include "SDL2GUI.h" + +namespace Upp { + +#define LLOG(x) LOG(x) +#define LDUMP(x) //DDUMP(x) + +struct RectSDL { + SDL_Rect sr; + + operator SDL_Rect *() { return &sr; } + + RectSDL(const Rect& r) + { + sr.x = r.left; + sr.y = r.top; + sr.w = r.GetWidth(); + sr.h = r.GetHeight(); + } +}; + +SDL_Texture *SDLTextureFromImage(SDL_Renderer *renderer, const Image& m) +{ + Size isz = m.GetSize(); + SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STATIC, isz.cx, isz.cy); + if(texture) { + SDL_UpdateTexture(texture, RectSDL(isz), ~m, isz.cx * sizeof(RGBA)); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + } + return texture; +} + + +void SDL2GUI::SetMouseCursor(const Image& image) +{ + GuiLock __; + static Image fbCursorImage; + static Point fbCursorPos; + static SDL_Cursor *sdl_cursor; + static SDL_Surface *sdl_cursor_surface; + static Buffer data; + if(image.GetSerialId() != fbCursorImage.GetSerialId()) { + fbCursorImage = image; + fbCursorPos = Null; + SDL_ShowCursor(trye); + if(sdl_cursor) + SDL_FreeCursor(sdl_cursor); + if(sdl_cursor_surface) + SDL_FreeSurface(sdl_cursor_surface); + int64 a = image.GetAuxData(); + if(a) + sdl_cursor = SDL_CreateSystemCursor(SDL_SystemCursor(a - 1)); + else { + sdl_cursor = NULL; + data.Alloc(image.GetLength()); + Copy(data, image, image.GetLength()); + sdl_cursor_surface = SDL_CreateRGBSurfaceFrom(~data, image.GetWidth(), image.GetHeight(), + 32, sizeof(RGBA) * image.GetWidth(), + 0xff0000, 0xff00, 0xff, 0xff000000); + Point h = image.GetHotSpot(); + if(sdl_cursor_surface) + sdl_cursor = SDL_CreateColorCursor(sdl_cursor_surface, h.x, h.y); + } + if(sdl_cursor) + SDL_SetCursor(sdl_cursor); + } +} + +} diff --git a/rainbow/SDL2GUI/Draw.cpp b/rainbow/SDL2GUI/Draw.cpp new file mode 100644 index 000000000..c712073fc --- /dev/null +++ b/rainbow/SDL2GUI/Draw.cpp @@ -0,0 +1,18 @@ +#include "SDL2GUI.h" + +namespace Upp { + +SystemDraw& SDL2GUI::BeginDraw() +{ + gldraw.Init(GetSize(), (uint64)glcontext); + sysdraw.SetTarget(&gldraw); + return sysdraw; +} + +void SDL2GUI::CommitDraw() +{ + gldraw.Finish(); + SDL_GL_SwapWindow(win); +} + +}; \ No newline at end of file diff --git a/rainbow/SDL2GUI/Event.cpp b/rainbow/SDL2GUI/Event.cpp new file mode 100644 index 000000000..bfa811491 --- /dev/null +++ b/rainbow/SDL2GUI/Event.cpp @@ -0,0 +1,249 @@ +#include "SDL2GUI.h" + +#define LLOG(x) + +namespace Upp { + +dword fbKEYtoK(dword chr) { + if(chr == SDLK_TAB) + chr = K_TAB; + else + if(chr == SDLK_SPACE) + chr = K_SPACE; + else + if(chr == SDLK_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; +} + +dword lastbdowntime[8] = {0}; +dword isdblclick[8] = {0}; + +dword mouseb; +dword modkeys; +bool sdlMouseIsIn; + +bool SDL2GUI::IsMouseIn() +{ + return sdlMouseIsIn; +} + +dword SDL2GUI::GetMouseButtons() +{ + return mouseb; +} + +dword SDL2GUI::GetModKeys() +{ + return modkeys; +} + +void HandleSDLEvent(SDL_Event* event) +{ + LLOG("HandleSDLEvent " << event->type); + SDL_Event next_event; + dword keycode; + switch(event->type) { +// case SDL_ACTIVEEVENT: //SDL_ActiveEvent +// break; + case SDL_TEXTINPUT: { + //send respective keyup things as char events as well + WString text = FromUtf8(event->text.text); + for(int i = 0; i < text.GetCount(); i++) { + int c = text[i]; + if(c != 127) + Ctrl::DoKeyFB(c, 1); + } + break; + } + case SDL_KEYDOWN: + switch(event->key.keysym.sym) { + case SDLK_LSHIFT: modkeys |= KM_LSHIFT; break; + case SDLK_RSHIFT: modkeys |= KM_RSHIFT; break; + case SDLK_LCTRL: modkeys |= KM_LCTRL; break; + case SDLK_RCTRL: modkeys |= KM_RCTRL; break; + case SDLK_LALT: modkeys |= KM_LALT; break; + case SDLK_RALT: modkeys |= KM_RALT; break; + } + + keycode = fbKEYtoK((dword)event->key.keysym.sym); + + if(keycode != K_SPACE) { //dont send space on keydown + static int repeat_count; + SDL_PumpEvents(); + if(SDL_PeepEvents(&next_event, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN) && + next_event.key.keysym.sym == event->key.keysym.sym) { + repeat_count++; // Keyboard repeat compression + break; + } + Ctrl::DoKeyFB(keycode, 1 + repeat_count); + repeat_count = 0; + } + break; + case SDL_KEYUP: //SDL_KeyboardEvent + switch(event->key.keysym.sym) { + case SDLK_LSHIFT: modkeys &= ~KM_LSHIFT; break; + case SDLK_RSHIFT: modkeys &= ~KM_RSHIFT; break; + case SDLK_LCTRL: modkeys &= ~KM_LCTRL; break; + case SDLK_RCTRL: modkeys &= ~KM_RCTRL; break; + case SDLK_LALT: modkeys &= ~KM_LALT; break; + case SDLK_RALT: modkeys &= ~KM_RALT; break; + } + + Ctrl::DoKeyFB(fbKEYtoK((dword)event->key.keysym.sym) | K_KEYUP, 1); + break; + case SDL_MOUSEMOTION: + SDL_PumpEvents(); + if(SDL_PeepEvents(&next_event, 1, SDL_PEEKEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) + break; // MouseMove compression + Ctrl::DoMouseFB(Ctrl::MOUSEMOVE, Point(event->motion.x, event->motion.y)); + break; + case SDL_MOUSEWHEEL: + Ctrl::DoMouseFB(Ctrl::MOUSEWHEEL, GetMousePos(), sgn(event->wheel.y) * 120); + break; + case SDL_MOUSEBUTTONDOWN: { + Point p(event->button.x, event->button.y); + int bi = event->button.button; + dword ct = SDL_GetTicks(); + if(isdblclick[bi] && (abs(int(ct) - int(lastbdowntime[bi])) < 400)) + { + switch(bi) + { + case SDL_BUTTON_LEFT: Ctrl::DoMouseFB(Ctrl::LEFTDOUBLE, p); break; + case SDL_BUTTON_RIGHT: Ctrl::DoMouseFB(Ctrl::RIGHTDOUBLE, p); break; + case SDL_BUTTON_MIDDLE: Ctrl::DoMouseFB(Ctrl::MIDDLEDOUBLE, p); break; + } + isdblclick[bi] = 0; //reset, to go ahead sending repeats + } + else + { + lastbdowntime[bi] = ct; + isdblclick[bi] = 0; //prepare for repeat + switch(bi) + { + case SDL_BUTTON_LEFT: mouseb |= (1<<0); Ctrl::DoMouseFB(Ctrl::LEFTDOWN, p); break; + case SDL_BUTTON_RIGHT: mouseb |= (1<<1); Ctrl::DoMouseFB(Ctrl::RIGHTDOWN, p); break; + case SDL_BUTTON_MIDDLE: mouseb |= (1<<2); Ctrl::DoMouseFB(Ctrl::MIDDLEDOWN, p); break; + } + } + } + break; + case SDL_MOUSEBUTTONUP: { + int bi = event->button.button; + isdblclick[bi] = 1; //indicate maybe a dblclick + + Point p(event->button.x, event->button.y); + switch(bi) + { + case SDL_BUTTON_LEFT: mouseb &= ~(1<<0); Ctrl::DoMouseFB(Ctrl::LEFTUP, p); break; + case SDL_BUTTON_RIGHT: mouseb &= ~(1<<1); Ctrl::DoMouseFB(Ctrl::RIGHTUP, p); break; + case SDL_BUTTON_MIDDLE: mouseb &= ~(1<<2); Ctrl::DoMouseFB(Ctrl::MIDDLEUP, p); break; + } + } + break; +/* case SDL_VIDEORESIZE: //SDL_ResizeEvent + { + width = event->resize.w; + height = event->resize.h; + + SDL_FreeSurface(screen); + screen = CreateScreen(width, height, bpp, videoflags); + ASSERT(screen); + Ctrl::SetFramebufferSize(Size(width, height)); + } + break; + case SDL_VIDEOEXPOSE: //SDL_ExposeEvent + break;*/ + case SDL_WINDOWEVENT: + switch (event->window.event) { + case SDL_WINDOWEVENT_SHOWN: + break; + case SDL_WINDOWEVENT_HIDDEN: + break; + case SDL_WINDOWEVENT_EXPOSED: + break; + case SDL_WINDOWEVENT_MOVED: + break; +// case SDL_WINDOWEVENT_SIZE_CHANGED: +// SDLwidth = event->window.data1; +// SDLheight = event->window.data2; +// break; + case SDL_WINDOWEVENT_RESIZED: + break; + case SDL_WINDOWEVENT_MINIMIZED: + break; + case SDL_WINDOWEVENT_MAXIMIZED: + break; + case SDL_WINDOWEVENT_RESTORED: + break; + case SDL_WINDOWEVENT_ENTER: + sdlMouseIsIn = true; + Ctrl::PaintAll(); + break; + case SDL_WINDOWEVENT_LEAVE: + sdlMouseIsIn = false; + Ctrl::PaintAll(); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + break; + case SDL_WINDOWEVENT_CLOSE: + break; + } + break; + case SDL_QUIT: //SDL_QuitEvent + Ctrl::EndSession(); + break; + } +} + +bool SDL2GUI::ProcessEvent(bool *quit) +{ + bool ret = false; + SDL_Event event; + if(SDL_PollEvent(&event)) { + if(event.type == SDL_QUIT && quit) + *quit = true; + HandleSDLEvent(&event); + ret = true; + } + return ret; +} + + +void SDL2GUI::WaitEvent(int ms) +{ + SDL_WaitEventTimeout(NULL, ms); +} + +bool SDL2GUI::IsWaitingEvent() +{ + SDL_PumpEvents(); + SDL_Event events; + return SDL_PeepEvents(&events, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) > 0; +} + +SDL_TimerID waketimer_id = 0; +Uint32 WakeCb(Uint32 interval, void *param) +{ + //wake up message que, FIXME maybe it can be done better? + SDL_Event event; + event.type=SDL_USEREVENT; + SDL_PushEvent(&event); + return 0; +} + +void SDL2GUI::WakeUpGuiThread() +{ + waketimer_id = SDL_AddTimer(20, WakeCb, NULL); +} + +} diff --git a/rainbow/SDL2GUI/SDL2GUI.h b/rainbow/SDL2GUI/SDL2GUI.h new file mode 100644 index 000000000..64e420510 --- /dev/null +++ b/rainbow/SDL2GUI/SDL2GUI.h @@ -0,0 +1,48 @@ +#ifndef _SDL2GUI_SDL2GUI_h +#define _SDL2GUI_SDL2GUI_h + +#include +#include + +#ifdef PLATFORM_POSIX +#include +#else +#include +#endif + +namespace Upp { + +struct SDL2GUI : VirtualGui { + virtual Size GetSize(); + virtual dword GetMouseButtons(); + virtual dword GetModKeys(); + virtual bool IsMouseIn(); + virtual bool ProcessEvent(bool *quit); + virtual void WaitEvent(int ms); + virtual bool IsWaitingEvent(); + virtual void WakeUpGuiThread(); + virtual void SetMouseCursor(const Image& image); + virtual SystemDraw& BeginDraw(); + virtual void CommitDraw(); + + virtual void Quit(); + + SDL_Window *win; + SDL_GLContext glcontext; + int64 serial; + GLDraw gldraw; + SystemDraw sysdraw; + + void Attach(SDL_Window *win, SDL_GLContext glcontext); + void Detach(); + + bool Create(const Rect& rect, const char *title); + void Destroy(); + + SDL2GUI(); + ~SDL2GUI(); +}; + +}; + +#endif diff --git a/rainbow/SDL2GUI/SDL2GUI.upp b/rainbow/SDL2GUI/SDL2GUI.upp new file mode 100644 index 000000000..85654326a --- /dev/null +++ b/rainbow/SDL2GUI/SDL2GUI.upp @@ -0,0 +1,7 @@ +file + SDL2GUI.h, + Window.cpp, + Draw.cpp, + Event.cpp, + Cursor.cpp; + diff --git a/rainbow/SDL2GUI/Window.cpp b/rainbow/SDL2GUI/Window.cpp new file mode 100644 index 000000000..bd467baab --- /dev/null +++ b/rainbow/SDL2GUI/Window.cpp @@ -0,0 +1,75 @@ +#include "SDL2GUI.h" + +namespace Upp { + +Size SDL2GUI::GetSize() +{ + int w, h; + SDL_GetWindowSize(win, &w, &h); + return Size(w, h); +} + +bool SDL2GUI::Create(const Rect& rect, const char *title) +{ + SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER); + + win = SDL_CreateWindow(title, rect.left, rect.top, rect.GetWidth(), rect.GetHeight(), + SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL|SDL_WINDOW_BORDERLESS); + if(!win) + return false; + MemoryIgnoreLeaksBegin(); + glcontext = SDL_GL_CreateContext(win); + MemoryIgnoreLeaksEnd(); + if(!glcontext) { + Destroy(); + return false; + } + return true; +} + +extern SDL_TimerID waketimer_id; + +void SDL2GUI::Destroy() +{ + if(glcontext) { + SDL_GL_DeleteContext(glcontext); + glcontext = NULL; + GLDraw::ResetCache(); + } + if(win) { + SDL_RemoveTimer(waketimer_id); + SDL_DestroyWindow(win); + win = NULL; + } +} + +void SDL2GUI::Attach(SDL_Window *win_, SDL_GLContext glcontext_) +{ + win = win_; + glcontext = glcontext_; +} + +void SDL2GUI::Detach() +{ + win = NULL; + glcontext = NULL; +} + +SDL2GUI::SDL2GUI() +{ + glcontext = NULL; + win = NULL; +} + +SDL2GUI::~SDL2GUI() +{ + Destroy(); + SDL_Quit(); +} + +void SDL2GUI::Quit() +{ +// SDL_Quit(); +} + +} \ No newline at end of file diff --git a/rainbow/SlaveGui/Cursor.cpp b/rainbow/SlaveGui/Cursor.cpp deleted file mode 100644 index ccd962b77..000000000 --- a/rainbow/SlaveGui/Cursor.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "Local.h" - -#ifdef GUI_SLAVE - -NAMESPACE_UPP - -#define LLOG(x) LOG(x) -#define LDUMP(x) //DDUMP(x) - -void Ctrl::SetMouseCursor(const Image& image) -{ - GuiLock __; - SlaveGuiPtr->SetMouseCursor(image); -} - -#if 0 -struct RectSDL { - SDL_Rect sr; - - operator SDL_Rect *() { return &sr; } - - RectSDL(const Rect& r) - { - sr.x = r.left; - sr.y = r.top; - sr.w = r.GetWidth(); - sr.h = r.GetHeight(); - } -}; - -SDL_Texture *SDLTextureFromImage(SDL_Renderer *renderer, const Image& m) -{ - Size isz = m.GetSize(); - SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STATIC, isz.cx, isz.cy); - if(texture) { - SDL_UpdateTexture(texture, RectSDL(isz), ~m, isz.cx * sizeof(RGBA)); - SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); - } - return texture; -} - -SDL_Cursor *sdl_cursor; -SDL_Surface *sdl_cursor_surface; -Buffer data; - - if(image.GetSerialId() != fbCursorImage.GetSerialId()) { - fbCursorImage = image; - fbCursorPos = Null; - SDL_ShowCursor(SystemCursor); - if(SystemCursor) { - if(sdl_cursor) - SDL_FreeCursor(sdl_cursor); - if(sdl_cursor_surface) - SDL_FreeSurface(sdl_cursor_surface); - - int64 a = image.GetAuxData(); - if(a) - sdl_cursor = SDL_CreateSystemCursor(SDL_SystemCursor(a - 1)); - else { - sdl_cursor = NULL; - data.Alloc(image.GetLength()); - Copy(data, image, image.GetLength()); - sdl_cursor_surface = SDL_CreateRGBSurfaceFrom(~data, image.GetWidth(), image.GetHeight(), - 32, sizeof(RGBA) * image.GetWidth(), - 0xff0000, 0xff00, 0xff, 0xff000000); - Point h = image.GetHotSpot(); - if(sdl_cursor_surface) - sdl_cursor = SDL_CreateColorCursor(sdl_cursor_surface, h.x, h.y); - } - if(sdl_cursor) - SDL_SetCursor(sdl_cursor); - } - } -} - -#endif - -END_UPP_NAMESPACE - -#endif \ No newline at end of file diff --git a/rainbow/SlaveGui/Event.cpp b/rainbow/SlaveGui/Event.cpp deleted file mode 100644 index ecc1a6b9a..000000000 --- a/rainbow/SlaveGui/Event.cpp +++ /dev/null @@ -1,424 +0,0 @@ -#include "Local.h" - -#ifdef GUI_SLAVE - -NAMESPACE_UPP - -#define LLOG(x) LOG(x) -#define LDUMP(x) //DDUMP(x) - -static Point fbmousepos; - -int SDLwidth; -int SDLheight; - -Point GetMousePos() { - return fbmousepos; -} - -dword mouseb = 0; -dword modkeys = 0; - -enum KM { - KM_NONE = 0x00, - - KM_LSHIFT= 0x01, - KM_RSHIFT= 0x02, - KM_LCTRL = 0x04, - KM_RCTRL = 0x08, - KM_LALT = 0x10, - KM_RALT = 0x20, - - KM_CAPS = 0x40, - KM_NUM = 0x80, - - KM_CTRL = KM_LCTRL | KM_RCTRL, - KM_SHIFT = KM_LSHIFT | KM_RSHIFT, - KM_ALT = KM_LALT | KM_RALT, -}; - -bool GetMouseLeft() { return mouseb & (1<<0); } -bool GetMouseRight() { return mouseb & (1<<1); } -bool GetMouseMiddle() { return mouseb & (1<<2); } -bool GetShift() { return modkeys & KM_SHIFT; } -bool GetCtrl() { return modkeys & KM_CTRL; } -bool GetAlt() { return modkeys & KM_ALT; } -bool GetCapsLock() { return modkeys & KM_CAPS; } - -#if 0 - -dword fbKEYtoK(dword chr) { - if(chr == SDLK_TAB) - chr = K_TAB; - else - if(chr == SDLK_SPACE) - chr = K_SPACE; - else - if(chr == SDLK_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; -} - -dword lastbdowntime[8] = {0}; -dword isdblclick[8] = {0}; - -void Ctrl::HandleSDLEvent(SDL_Event* event) -{ - LLOG("HandleSDLEvent " << event->type); - SDL_Event next_event; - dword keycode; - switch(event->type) { -// case SDL_ACTIVEEVENT: //SDL_ActiveEvent -// break; - case SDL_TEXTINPUT: { - //send respective keyup things as char events as well - WString text = FromUtf8(event->text.text); - for(int i = 0; i < text.GetCount(); i++) { - int c = text[i]; - if(c != 127) - Ctrl::DoKeyFB(c, 1); - } - break; - } - case SDL_KEYDOWN: - switch(event->key.keysym.sym) { - case SDLK_LSHIFT: modkeys |= KM_LSHIFT; break; - case SDLK_RSHIFT: modkeys |= KM_RSHIFT; break; - case SDLK_LCTRL: modkeys |= KM_LCTRL; break; - case SDLK_RCTRL: modkeys |= KM_RCTRL; break; - case SDLK_LALT: modkeys |= KM_LALT; break; - case SDLK_RALT: modkeys |= KM_RALT; break; - } - - keycode = fbKEYtoK((dword)event->key.keysym.sym); - - if(keycode != K_SPACE) { //dont send space on keydown - static int repeat_count; - SDL_PumpEvents(); - if(SDL_PeepEvents(&next_event, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN) && - next_event.key.keysym.sym == event->key.keysym.sym) { - repeat_count++; // Keyboard repeat compression - break; - } - Ctrl::DoKeyFB(keycode, 1 + repeat_count); - repeat_count = 0; - } - break; - case SDL_KEYUP: //SDL_KeyboardEvent - switch(event->key.keysym.sym) { - case SDLK_LSHIFT: modkeys &= ~KM_LSHIFT; break; - case SDLK_RSHIFT: modkeys &= ~KM_RSHIFT; break; - case SDLK_LCTRL: modkeys &= ~KM_LCTRL; break; - case SDLK_RCTRL: modkeys &= ~KM_RCTRL; break; - case SDLK_LALT: modkeys &= ~KM_LALT; break; - case SDLK_RALT: modkeys &= ~KM_RALT; break; - } - - Ctrl::DoKeyFB(fbKEYtoK((dword)event->key.keysym.sym) | K_KEYUP, 1); - break; - case SDL_MOUSEMOTION: - SDL_PumpEvents(); - if(SDL_PeepEvents(&next_event, 1, SDL_PEEKEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) - break; // MouseMove compression - Ctrl::DoMouseFB(Ctrl::MOUSEMOVE, Point(event->motion.x, event->motion.y)); - break; - case SDL_MOUSEWHEEL: - Ctrl::DoMouseFB(Ctrl::MOUSEWHEEL, GetMousePos(), sgn(event->wheel.y) * 120); - break; - case SDL_MOUSEBUTTONDOWN: { - Point p(event->button.x, event->button.y); - int bi = event->button.button; - dword ct = SDL_GetTicks(); - if(isdblclick[bi] && (abs(int(ct) - int(lastbdowntime[bi])) < 400)) - { - switch(bi) - { - case SDL_BUTTON_LEFT: Ctrl::DoMouseFB(Ctrl::LEFTDOUBLE, p); break; - case SDL_BUTTON_RIGHT: Ctrl::DoMouseFB(Ctrl::RIGHTDOUBLE, p); break; - case SDL_BUTTON_MIDDLE: Ctrl::DoMouseFB(Ctrl::MIDDLEDOUBLE, p); break; - } - isdblclick[bi] = 0; //reset, to go ahead sending repeats - } - else - { - lastbdowntime[bi] = ct; - isdblclick[bi] = 0; //prepare for repeat - switch(bi) - { - case SDL_BUTTON_LEFT: mouseb |= (1<<0); Ctrl::DoMouseFB(Ctrl::LEFTDOWN, p); break; - case SDL_BUTTON_RIGHT: mouseb |= (1<<1); Ctrl::DoMouseFB(Ctrl::RIGHTDOWN, p); break; - case SDL_BUTTON_MIDDLE: mouseb |= (1<<2); Ctrl::DoMouseFB(Ctrl::MIDDLEDOWN, p); break; - } - } - } - break; - case SDL_MOUSEBUTTONUP: { - int bi = event->button.button; - isdblclick[bi] = 1; //indicate maybe a dblclick - - Point p(event->button.x, event->button.y); - switch(bi) - { - case SDL_BUTTON_LEFT: mouseb &= ~(1<<0); Ctrl::DoMouseFB(Ctrl::LEFTUP, p); break; - case SDL_BUTTON_RIGHT: mouseb &= ~(1<<1); Ctrl::DoMouseFB(Ctrl::RIGHTUP, p); break; - case SDL_BUTTON_MIDDLE: mouseb &= ~(1<<2); Ctrl::DoMouseFB(Ctrl::MIDDLEUP, p); break; - } - } - break; -/* case SDL_VIDEORESIZE: //SDL_ResizeEvent - { - width = event->resize.w; - height = event->resize.h; - - SDL_FreeSurface(screen); - screen = CreateScreen(width, height, bpp, videoflags); - ASSERT(screen); - Ctrl::SetFramebufferSize(Size(width, height)); - } - break; - case SDL_VIDEOEXPOSE: //SDL_ExposeEvent - break;*/ - case SDL_WINDOWEVENT: - switch (event->window.event) { - case SDL_WINDOWEVENT_SHOWN: - break; - case SDL_WINDOWEVENT_HIDDEN: - break; - case SDL_WINDOWEVENT_EXPOSED: - break; - case SDL_WINDOWEVENT_MOVED: - break; - case SDL_WINDOWEVENT_SIZE_CHANGED: - SDLwidth = event->window.data1; - SDLheight = event->window.data2; - break; - case SDL_WINDOWEVENT_RESIZED: - break; - case SDL_WINDOWEVENT_MINIMIZED: - break; - case SDL_WINDOWEVENT_MAXIMIZED: - break; - case SDL_WINDOWEVENT_RESTORED: - break; - case SDL_WINDOWEVENT_ENTER: - sdlMouseIsIn = true; - Invalidate(); - break; - case SDL_WINDOWEVENT_LEAVE: - sdlMouseIsIn = false; - Invalidate(); - break; - case SDL_WINDOWEVENT_FOCUS_GAINED: - break; - case SDL_WINDOWEVENT_FOCUS_LOST: - break; - case SDL_WINDOWEVENT_CLOSE: - break; - } - break; - case SDL_QUIT: //SDL_QuitEvent - Ctrl::EndSession(); - break; - } -} -#endif - -void Ctrl::MouseEventFB(Ptr t, int event, Point p, int zdelta) -{ - if(!t->IsEnabled()) - return; - Rect rr = t->GetRect(); - if((event & Ctrl::ACTION) == DOWN) { - Ptr q = t; - TopWindowFrame *wf = dynamic_cast(~t); - if(wf) - q = wf->window; - if(q) q->ClickActivateWnd(); - if(q) q->SetForeground(); - if(ignoreclick) - return; - } - if(t) - t->DispatchMouse(event, p - rr.TopLeft(), zdelta); - if(t) - t->PostInput(); -} - -Ctrl *Ctrl::FindMouseTopCtrl() -{ - for(int i = topctrl.GetCount() - 1; i >= 0; i--) { - Ctrl *t = topctrl[i]; - if(t->GetRect().Contains(fbmousepos)) - return t->IsEnabled() ? t : NULL; - } - return desktop->IsEnabled() ? desktop : NULL; -} - -void Ctrl::DoMouseFB(int event, Point p, int zdelta) -{ - fbmousepos = p; - int a = event & Ctrl::ACTION; - if(a == Ctrl::UP && Ctrl::ignoreclick) { - EndIgnore(); - return; - } - else - if(a == Ctrl::DOWN && ignoreclick) - return; - LLOG("### Mouse event: " << event << " position " << p << " zdelta " << zdelta << ", capture " << Upp::Name(captureCtrl)); - if(captureCtrl) - MouseEventFB(captureCtrl->GetTopCtrl(), event, p, zdelta); - else - for(int i = topctrl.GetCount() - 1; i >= 0; i--) { - Ptr t = topctrl[i]; - Rect rr = t->GetRect(); - if(rr.Contains(p)) { - MouseEventFB(t, event, p, zdelta); - return; - } - } - Ctrl *desktop = GetDesktop(); - if(desktop) { - desktop->DispatchMouse(event, p, zdelta); - desktop->PostInput(); - } -} - -bool Ctrl::DoKeyFB(dword key, int cnt) -{ - LLOG("DoKeyFB " << GetKeyDesc(key) << ", " << cnt); - - bool b = DispatchKey(key, cnt); - SyncCaret(); - Ctrl *desktop = GetDesktop(); - if(desktop) - desktop->PostInput(); - return b; -} - -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() -{ - CursorSync(); -} - -void Ctrl::CursorSync() -{ - LLOG("@ 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()) & focusCtrl->GetScreenView(); - if(fbCursorPos != p && !SystemCursor || cr != fbCaretRect) { - fbCaretRect = cr; - fbCursorPos = p; - Invalidate(); - } -} - -bool Ctrl::ProcessEvent(bool *quit) -{ - LLOG("@ ProcessEvent"); - ASSERT(IsMainThread()); - if(!GetMouseLeft() && !GetMouseRight() && !GetMouseMiddle()) - ReleaseCtrlCapture(); - bool ret = SlaveGuiPtr->ProcessEvent(quit); -#if 0 - SDL_Event event; - if(SDL_PollEvent(&event)) { - if(event.type == SDL_QUIT && quit) - *quit = true; - HandleSDLEvent(&event); - ret = true; - } -#endif - DefferedFocusSync(); - SyncCaret(); - SyncTopWindows(); - return ret; -} - -bool Ctrl::ProcessEvents(bool *quit) -{ - //LOGBLOCK("@ ProcessEvents"); -// MemoryCheckDebug(); - bool ret = ProcessEvent(quit); - while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop())); - TimeStop tm; - LLOG("TimerProc invoked at " << msecs()); - TimerProc(GetTickCount()); - LLOG("TimerProc elapsed: " << tm); - SweepMkImageCache(); - DoPaint(); - return ret; -} - -void Ctrl::EventLoop(Ctrl *ctrl) -{ - GuiLock __; - ASSERT(IsMainThread()); - ASSERT(LoopLevel == 0 || ctrl); - LoopLevel++; - LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN); - Ptr ploop; - if(ctrl) { - ploop = LoopCtrl; - LoopCtrl = ctrl; - ctrl->inloop = true; - } - - bool quit = false; - int64 loopno = ++EventLoopNo; - ProcessEvents(&quit); - while(loopno > EndSessionLoopNo && !quit && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) - { -// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep"); - SyncCaret(); - GuiSleep(20); -// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents"); - ProcessEvents(&quit); -// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / after ProcessEvents"); - LDUMP(loopno); - LDUMP(fbEndSessionLoop); - } - - if(ctrl) - LoopCtrl = ploop; - LoopLevel--; - LLOG(LOG_END << "Leaving event loop "); -} - -void Ctrl::GuiSleep(int ms) -{ - GuiLock __; - ASSERT(IsMainThread()); - LLOG("GuiSleep"); - int level = LeaveGuiMutexAll(); - SlaveGuiPtr->WaitEvent(ms); -#if 0 - SDL_WaitEventTimeout(NULL, ms); -#endif - EnterGuiMutex(level); -} - -END_UPP_NAMESPACE - -#endif diff --git a/rainbow/SlaveGui/SDL.cpp b/rainbow/SlaveGui/SDL.cpp deleted file mode 100644 index 8d14c17b0..000000000 --- a/rainbow/SlaveGui/SDL.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "Local.h" - -#ifdef GUI_SLAVE - -NAMESPACE_UPP - -#define LLOG(x) //LOG(x) - -dword SDLsettings; - -void USDLSetup(dword flags) -{ - SDLsettings = flags; -} - -Size screen_size; -// SDLWindow screen; - -SDL_TimerID waketimer_id = 0; -Uint32 WakeCb(Uint32 interval, void *param) -{ - //wake up message que, FIXME maybe it can be done better? - SDL_Event event; - event.type=SDL_USEREVENT; - SDL_PushEvent(&event); - return 0; -} - -void WakeUpGuiThread() -{ - waketimer_id = SDL_AddTimer(20, WakeCb, NULL); -} - -void FBInit() -{ - GuiLock __; - - SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER); - - Ctrl::InitFB(); - -#if 0 - if(SDL_Init(SDL_INIT_VIDEO/* | SDL_INIT_TIMER*/) < 0) //timer not needed, we post to queue directly - { - Cout() << Format("Couldn't initialize SDL: %s\n", SDL_GetError()); - return; - } - -// TODO -// SDL_EnableUNICODE(1); //for unicode keycode availability -// SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL/2); -// SDL_ShowCursor(0); - - const SDL_VideoInfo* vi = SDL_GetVideoInfo(); - //ASSERT(vi->hw_available); - - width = vi->current_w; - height = vi->current_h; - bpp = vi->vfmt->BitsPerPixel; - ASSERT(bpp == 32); - - //FIXME adjustable - videoflags = SDL_HWSURFACE | SDL_HWACCEL | SDL_DOUBLEBUF | SDL_RESIZABLE;// | SDL_NOFRAME | SDL_FULLSCREEN; -#endif - screen_size = Size(1500, 900); - screen.Create(Rect(Point(20, 20), screen_size), "First test"); - - Ctrl::SetDesktopSize(screen_size); -} - -void FBDeInit() -{ - SDL_RemoveTimer(waketimer_id); - Ctrl::ExitFB(); - screen.Destroy(); - SDL_Quit(); -} - -END_UPP_NAMESPACE - -#endif \ No newline at end of file diff --git a/rainbow/SlaveGui/Window.cpp b/rainbow/SlaveGui/Window.cpp deleted file mode 100644 index 60382f4ed..000000000 --- a/rainbow/SlaveGui/Window.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "Local.h" - -#ifdef GUI_SLAVE - -NAMESPACE_UPP - -bool SDLWindow::Create(const Rect& rect, const char *title) -{ - win = SDL_CreateWindow(title, rect.left, rect.top, rect.GetWidth(), rect.GetHeight(), - SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL|SDL_WINDOW_BORDERLESS); - if(!win) - return false; - MemoryIgnoreLeaksBegin(); - glcontext = SDL_GL_CreateContext(win); - MemoryIgnoreLeaksEnd(); - if(!glcontext) { - Destroy(); - return false; - } - INTERLOCKED { - static int64 h; - serial = h++; - } - return true; -} - -void SDLWindow::Destroy() -{ - if(glcontext) { - SDL_GL_DeleteContext(glcontext); - glcontext = NULL; - GLDraw::ResetCache(); // TODO: Consider not reseting ALL cache data, only specific context - } - if(win) { - SDL_DestroyWindow(win); - win = NULL; - } -} - -SDLWindow::SDLWindow() -{ - glcontext = NULL; - win = NULL; -} - -SDLWindow::~SDLWindow() -{ - Destroy(); -} - -END_UPP_NAMESPACE - -#endif diff --git a/rainbow/SlaveGuiUword/SlaveGuiUword.upp b/rainbow/SlaveGuiUword/SlaveGuiUword.upp index 62d8da907..f4d968bf8 100644 --- a/rainbow/SlaveGuiUword/SlaveGuiUword.upp +++ b/rainbow/SlaveGuiUword/SlaveGuiUword.upp @@ -2,7 +2,8 @@ uses CtrlLib, RichEdit, plugin/DroidFonts, - SlaveGui; + VirtualGui, + SDL2GUI; file main.cpp, @@ -10,5 +11,5 @@ file help.txt; mainconfig - "" = "GUI SLAVEGUI"; + "" = "GUI VIRTUALGUI"; diff --git a/rainbow/SlaveGui/After.h b/rainbow/VirtualGui/After.h similarity index 91% rename from rainbow/SlaveGui/After.h rename to rainbow/VirtualGui/After.h index 8f241c17e..fa98f2302 100644 --- a/rainbow/SlaveGui/After.h +++ b/rainbow/VirtualGui/After.h @@ -14,8 +14,7 @@ public: */ class DHCtrl : Ctrl {}; -void FBInit(); -void FBDeInit(); +#if 0 #ifdef PLATFORM_WIN32 #define GUI_APP_MAIN \ @@ -49,3 +48,5 @@ extern "C" int main(int argc, const char **argv, const char **envptr) { \ \ void GuiMainFn_() #endif + +#endif \ No newline at end of file diff --git a/rainbow/SlaveGui/ChSysInit.cpp b/rainbow/VirtualGui/ChSysInit.cpp similarity index 81% rename from rainbow/SlaveGui/ChSysInit.cpp rename to rainbow/VirtualGui/ChSysInit.cpp index bae67d35e..841b6c753 100644 --- a/rainbow/SlaveGui/ChSysInit.cpp +++ b/rainbow/VirtualGui/ChSysInit.cpp @@ -1,6 +1,6 @@ #include "Local.h" -#ifdef GUI_SLAVE +#ifdef VIRTUALGUI NAMESPACE_UPP diff --git a/rainbow/SlaveGui/Clip.cpp b/rainbow/VirtualGui/Clip.cpp similarity index 94% rename from rainbow/SlaveGui/Clip.cpp rename to rainbow/VirtualGui/Clip.cpp index 9c70c4b0f..980e81e24 100644 --- a/rainbow/SlaveGui/Clip.cpp +++ b/rainbow/VirtualGui/Clip.cpp @@ -1,6 +1,6 @@ #include "Local.h" -#ifdef GUI_SLAVE +#ifdef VIRTUALGUI NAMESPACE_UPP diff --git a/rainbow/SlaveGui/Ctrl.cpp b/rainbow/VirtualGui/Ctrl.cpp similarity index 91% rename from rainbow/SlaveGui/Ctrl.cpp rename to rainbow/VirtualGui/Ctrl.cpp index 25020af61..1b56621ca 100644 --- a/rainbow/SlaveGui/Ctrl.cpp +++ b/rainbow/VirtualGui/Ctrl.cpp @@ -1,6 +1,6 @@ #include "Local.h" -#ifdef GUI_SLAVE +#ifdef VIRTUALGUI #define LLOG(x) // DLOG(x) diff --git a/rainbow/SlaveGui/Ctrl.h b/rainbow/VirtualGui/Ctrl.h similarity index 93% rename from rainbow/SlaveGui/Ctrl.h rename to rainbow/VirtualGui/Ctrl.h index 8de4ee9de..b7c5f2fa6 100644 --- a/rainbow/SlaveGui/Ctrl.h +++ b/rainbow/VirtualGui/Ctrl.h @@ -6,7 +6,6 @@ private: static Point fbCursorPos; static Image fbCursorImage; - static bool sdlMouseIsIn; static Rect fbCaretRect; static int fbCaretTm; @@ -35,7 +34,6 @@ private: static void DragRectDraw0(const Vector& clip, const Rect& rect, int n, const byte *pattern, int animation); - friend struct PaintProxy__; friend class TopWindowFrame; friend class SystemDraw; friend struct DnDLoop; @@ -52,6 +50,8 @@ public: static void InitFB(); static void ExitFB(); static void EndSession(); + + static void PaintAll() { DoPaint(); } static void SetDesktop(Ctrl& q); static Ctrl *GetDesktop() { return desktop; } diff --git a/rainbow/SlaveGui/DnD.cpp b/rainbow/VirtualGui/DnD.cpp similarity index 92% rename from rainbow/SlaveGui/DnD.cpp rename to rainbow/VirtualGui/DnD.cpp index 18ef912e6..c70d4ba16 100644 --- a/rainbow/SlaveGui/DnD.cpp +++ b/rainbow/VirtualGui/DnD.cpp @@ -1,6 +1,6 @@ #include "Local.h" -#ifdef GUI_SLAVE +#ifdef VIRTUALGUI NAMESPACE_UPP @@ -92,7 +92,7 @@ void DnDLoop::Sync() void DnDLoop::LeftUp(Point, dword) { - GuiLock __; + GuiLock __; LLOG("DnDLoop::LeftUp"); DnD(true); EndLoop(); @@ -100,14 +100,14 @@ void DnDLoop::LeftUp(Point, dword) void DnDLoop::MouseMove(Point p, dword) { - GuiLock __; + GuiLock __; LLOG("DnDLoop::MouseMove"); Sync(); } bool DnDLoop::Key(dword, int) { - GuiLock __; + GuiLock __; LLOG("DnDLoop::Key"); Sync(); return false; @@ -115,14 +115,14 @@ bool DnDLoop::Key(dword, int) Image DnDLoop::CursorImage(Point, dword) { - GuiLock __; + GuiLock __; return action == DND_MOVE ? move : action == DND_COPY ? copy : reject; } int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions, const VectorMap& data) { - GuiLock __; + GuiLock __; DnDLoop d; d.actions = (byte)actions; d.reject = actions & DND_EXACTIMAGE ? CtrlCoreImg::DndNone() : MakeDragImage(CtrlCoreImg::DndNone(), sample); diff --git a/rainbow/SlaveGui/DrawDragRect.cpp b/rainbow/VirtualGui/DrawDragRect.cpp similarity index 89% rename from rainbow/SlaveGui/DrawDragRect.cpp rename to rainbow/VirtualGui/DrawDragRect.cpp index a1ce72c25..067ea68dd 100644 --- a/rainbow/SlaveGui/DrawDragRect.cpp +++ b/rainbow/VirtualGui/DrawDragRect.cpp @@ -48,7 +48,7 @@ void DrawDragFrame(SystemDraw& w, const Rect& r, int n, const int *pattern, int void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f) { - SystemDraw w; + SystemDraw& w = VirtualGuiPtr->BeginDraw(); Ctrl::PaintScene(w); w.Clip(f.clip); static int dashes[3][3] = { @@ -61,7 +61,7 @@ void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f) DrawDragFrame(w, f.rect2, f.n, dash, f.animation); w.End(); Ctrl::PaintCaretCursor(w); - SDL_GL_SwapWindow(screen.win); + VirtualGuiPtr->CommitDraw(); } void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, @@ -83,10 +83,10 @@ void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& cli void FinishDragRect(Ctrl& q) { - SystemDraw w; + SystemDraw& w = VirtualGuiPtr->BeginDraw(); Ctrl::PaintScene(w); Ctrl::PaintCaretCursor(w); - SDL_GL_SwapWindow(screen.win); + VirtualGuiPtr->CommitDraw(); } END_UPP_NAMESPACE diff --git a/rainbow/VirtualGui/Event.cpp b/rainbow/VirtualGui/Event.cpp new file mode 100644 index 000000000..7e163b55e --- /dev/null +++ b/rainbow/VirtualGui/Event.cpp @@ -0,0 +1,210 @@ +#include "Local.h" + +#ifdef VIRTUALGUI + +NAMESPACE_UPP + +#define LLOG(x) LOG(x) +#define LDUMP(x) //DDUMP(x) + +static Point fbmousepos; +static dword mouseb = 0; +static dword modkeys = 0; + +Point GetMousePos() { + return fbmousepos; +} + +bool GetMouseLeft() { return VirtualGuiPtr->GetMouseButtons() & (1<<0); } +bool GetMouseRight() { return VirtualGuiPtr->GetMouseButtons() & (1<<1); } +bool GetMouseMiddle() { return VirtualGuiPtr->GetMouseButtons() & (1<<2); } +bool GetShift() { return VirtualGuiPtr->GetModKeys() & KM_SHIFT; } +bool GetCtrl() { return VirtualGuiPtr->GetModKeys() & KM_CTRL; } +bool GetAlt() { return VirtualGuiPtr->GetModKeys() & KM_ALT; } +bool GetCapsLock() { return VirtualGuiPtr->GetModKeys() & KM_CAPS; } + +void Ctrl::MouseEventFB(Ptr t, int event, Point p, int zdelta) +{ + if(!t->IsEnabled()) + return; + Rect rr = t->GetRect(); + if((event & Ctrl::ACTION) == DOWN) { + Ptr q = t; + TopWindowFrame *wf = dynamic_cast(~t); + if(wf) + q = wf->window; + if(q) q->ClickActivateWnd(); + if(q) q->SetForeground(); + if(ignoreclick) + return; + } + if(t) + t->DispatchMouse(event, p - rr.TopLeft(), zdelta); + if(t) + t->PostInput(); +} + +Ctrl *Ctrl::FindMouseTopCtrl() +{ + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Ctrl *t = topctrl[i]; + if(t->GetRect().Contains(fbmousepos)) + return t->IsEnabled() ? t : NULL; + } + return desktop->IsEnabled() ? desktop : NULL; +} + +void Ctrl::DoMouseFB(int event, Point p, int zdelta) +{ + fbmousepos = p; + int a = event & Ctrl::ACTION; + if(a == Ctrl::UP && Ctrl::ignoreclick) { + EndIgnore(); + return; + } + else + if(a == Ctrl::DOWN && ignoreclick) + return; + LLOG("### Mouse event: " << event << " position " << p << " zdelta " << zdelta << ", capture " << Upp::Name(captureCtrl)); + if(captureCtrl) + MouseEventFB(captureCtrl->GetTopCtrl(), event, p, zdelta); + else + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Ptr t = topctrl[i]; + Rect rr = t->GetRect(); + if(rr.Contains(p)) { + MouseEventFB(t, event, p, zdelta); + return; + } + } + Ctrl *desktop = GetDesktop(); + if(desktop) { + desktop->DispatchMouse(event, p, zdelta); + desktop->PostInput(); + } +} + +bool Ctrl::DoKeyFB(dword key, int cnt) +{ + LLOG("DoKeyFB " << GetKeyDesc(key) << ", " << cnt); + + bool b = DispatchKey(key, cnt); + SyncCaret(); + Ctrl *desktop = GetDesktop(); + if(desktop) + desktop->PostInput(); + return b; +} + +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() +{ + CursorSync(); +} + +void Ctrl::CursorSync() +{ + LLOG("@ 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()) & focusCtrl->GetScreenView(); + if(fbCursorPos != p && !SystemCursor || cr != fbCaretRect) { + fbCaretRect = cr; + fbCursorPos = p; + Invalidate(); + } +} + +bool Ctrl::ProcessEvent(bool *quit) +{ + LLOG("@ ProcessEvent"); + ASSERT(IsMainThread()); + if(!GetMouseLeft() && !GetMouseRight() && !GetMouseMiddle()) + ReleaseCtrlCapture(); + bool ret = VirtualGuiPtr->ProcessEvent(quit); + DefferedFocusSync(); + SyncCaret(); + SyncTopWindows(); + return ret; +} + +bool Ctrl::ProcessEvents(bool *quit) +{ + //LOGBLOCK("@ ProcessEvents"); +// MemoryCheckDebug(); + bool ret = ProcessEvent(quit); + while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop())); + TimeStop tm; + LLOG("TimerProc invoked at " << msecs()); + TimerProc(GetTickCount()); + LLOG("TimerProc elapsed: " << tm); + SweepMkImageCache(); + DoPaint(); + return ret; +} + +void Ctrl::EventLoop(Ctrl *ctrl) +{ + GuiLock __; + ASSERT(IsMainThread()); + ASSERT(LoopLevel == 0 || ctrl); + LoopLevel++; + LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN); + Ptr ploop; + if(ctrl) { + ploop = LoopCtrl; + LoopCtrl = ctrl; + ctrl->inloop = true; + } + + bool quit = false; + int64 loopno = ++EventLoopNo; + ProcessEvents(&quit); + while(loopno > EndSessionLoopNo && !quit && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) + { +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep"); + SyncCaret(); + GuiSleep(20); +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents"); + ProcessEvents(&quit); +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / after ProcessEvents"); + LDUMP(loopno); + LDUMP(fbEndSessionLoop); + } + + if(ctrl) + LoopCtrl = ploop; + LoopLevel--; + LLOG(LOG_END << "Leaving event loop "); +} + +void Ctrl::GuiSleep(int ms) +{ + GuiLock __; + ASSERT(IsMainThread()); + LLOG("GuiSleep"); + int level = LeaveGuiMutexAll(); + VirtualGuiPtr->WaitEvent(ms); + EnterGuiMutex(level); +} + +void WakeUpGuiThread() +{ + VirtualGuiPtr->WakeUpGuiThread(); +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/VirtualGui/FB.iml b/rainbow/VirtualGui/FB.iml new file mode 100644 index 000000000..c36090ae7 --- /dev/null +++ b/rainbow/VirtualGui/FB.iml @@ -0,0 +1,63 @@ +PREMULTIPLIED +IMAGE_ID(Arrow) +IMAGE_ID(IBeam) +IMAGE_ID(Wait) +IMAGE_ID(No) +IMAGE_ID(SizeAll) +IMAGE_ID(SizeHorz) +IMAGE_ID(SizeRight) +IMAGE_ID(SizeLeft) +IMAGE_ID(SizeVert) +IMAGE_ID(SizeTopLeft) +IMAGE_ID(SizeTop) +IMAGE_ID(SizeTopRight) +IMAGE_ID(SizeBottomLeft) +IMAGE_ID(SizeBottom) +IMAGE_ID(SizeBottomRight) +IMAGE_ID(overlap) +IMAGE_ID(maximize) +IMAGE_ID(close) +IMAGE_ID(bgtitle) +IMAGE_ID(title) +IMAGE_ID(border) +IMAGE_ID(Hand) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,90,61,104,20,65,20,30,77,162,9,92,144,248,135,160,133,117,42,177,18,21,4,171,84,65,76,22,4,149) +IMAGE_DATA(136,17,37,49,66,4,13,40,72,34,4,145,128,120,133,196,20,49,30,24,11,207,104,33,105,196,4,114,133,34,66,68) +IMAGE_DATA(52,129,67,20,65,4,145,52,218,217,61,103,214,157,117,118,110,126,222,91,247,240,135,157,229,177,55,51,223,247,230,205) +IMAGE_DATA(247,222,206,94,244,88,129,109,98,162,173,97,171,196,13,184,5,12,223,128,200,129,114,153,196,129,239,223,183,195,244,244) +IMAGE_DATA(22,44,7,190,125,219,13,95,191,238,131,169,169,29,24,14,172,172,28,128,47,95,186,225,243,231,195,48,62,190,223,199) +IMAGE_DATA(129,79,159,122,225,227,199,83,240,225,195,25,120,255,254,28,20,139,7,93,28,120,247,238,60,188,125,123,1,170,213,97) +IMAGE_DATA(88,90,186,2,175,95,95,131,177,177,99,54,14,44,47,143,194,155,55,87,225,213,171,235,240,242,229,4,188,120,113,7) +IMAGE_DATA(158,63,159,134,209,209,126,19,135,99,138,176,184,120,131,227,38,225,217,179,123,176,176,176,16,217,3,24,30,30,208,57) +IMAGE_DATA(220,215,4,199,77,194,211,167,119,160,82,121,24,98,75,165,146,196,169,22,226,43,149,91,220,74,48,63,127,23,230,230) +IMAGE_DATA(238,195,227,199,143,156,251,125,242,228,54,92,188,120,58,246,51,52,52,232,196,15,13,245,169,243,194,96,112,112,64,141) +IMAGE_DATA(33,129,55,105,208,223,127,210,170,167,97,44,92,163,183,247,152,109,13,83,131,158,158,35,148,186,13,215,8,130,110,210) +IMAGE_DATA(26,93,93,7,41,248,128,16,143,185,53,177,117,108,53,91,27,26,211,18,47,76,54,237,115,28,176,214,255,231,199,44) +IMAGE_DATA(251,173,209,133,21,184,112,77,92,180,166,164,112,88,11,51,183,245,222,184,211,20,44,147,248,109,101,179,41,248,120,83) +IMAGE_DATA(155,175,93,50,114,196,152,152,211,240,65,203,174,157,176,254,236,137,4,71,124,22,99,98,142,25,158,36,149,227,193,38) +IMAGE_DATA(56,98,125,97,30,108,204,209,180,115,98,9,254,41,241,83,245,161,234,79,201,47,181,126,104,245,217,198,175,230,232,178) +IMAGE_DATA(9,103,33,163,143,70,132,89,147,230,193,81,230,93,241,186,252,164,225,215,36,80,233,99,215,183,125,166,196,111,138,139) +IMAGE_DATA(194,151,205,231,195,199,247,249,192,240,77,62,108,251,196,232,100,251,236,203,117,205,97,237,136,203,23,131,105,140,194,255) +IMAGE_DATA(157,231,129,82,79,212,231,22,227,203,204,69,28,72,63,189,242,38,94,217,226,142,8,194,200,47,151,203,130,15,209,157) +IMAGE_DATA(228,71,229,243,110,42,63,81,252,9,97,162,109,185,14,139,68,12,160,180,200,101,220,92,177,168,92,137,83,125,216,48) +IMAGE_DATA(166,253,171,241,234,62,212,125,170,250,232,250,233,205,54,166,250,49,233,135,53,25,119,22,113,100,161,71,86,121,201,170) +IMAGE_DATA(62,212,102,210,153,82,167,186,62,204,160,95,26,63,105,248,170,31,148,6,109,252,107,127,51,107,8,77,39,251,4,176) +IMAGE_DATA(9,109,43,22,155,15,234,195,99,106,236,15,60,60,152,56,178,208,35,147,188,228,137,206,19,157,39,250,127,74,244,90) +IMAGE_DATA(158,234,134,40,213,186,67,87,2,93,137,241,9,174,196,155,16,72,235,199,65,203,57,211,134,254,230,57,215,254,92,186) +IMAGE_DATA(184,244,116,229,65,205,83,77,254,90,249,181,38,186,106,235,19,87,61,166,96,41,28,204,151,17,149,211,222,222,142,230) +IMAGE_DATA(72,49,132,117,118,118,122,121,74,18,2,41,40,134,167,182,44,121,152,167,88,231,97,79,15,201,19,122,178,72,91,44) +IMAGE_DATA(135,41,249,195,228,91,47,106,12,199,88,139,249,201,84,191,57,215,254,92,186,212,253,100,114,53,107,165,120,56,212,138) +IMAGE_DATA(76,83,249,212,39,140,250,36,83,79,12,204,201,164,36,27,125,2,74,61,169,39,173,212,132,114,162,51,150,254,205,193) +IMAGE_DATA(8,111,40,106,77,229,5,155,23,172,147,195,254,182,130,205,95,165,245,155,115,237,207,165,75,221,95,165,105,42,69,110) +IMAGE_DATA(66,15,150,194,201,191,228,219,121,174,19,208,198,251,175,191,228,23,248,149,81,3,143,153,240,46,95,105,241,152,56,116) +IMAGE_DATA(188,111,205,172,240,24,125,234,165,139,58,70,201,19,190,101,80,76,190,224,40,98,153,48,57,62,123,60,37,95,248,246) +IMAGE_DATA(187,197,180,177,177,49,216,219,218,10,226,142,153,19,253,61,220,244,113,137,149,115,182,113,209,55,141,153,214,13,231,11) +IMAGE_DATA(133,208,108,216,4,71,96,35,156,248,108,195,82,241,148,120,168,251,77,171,39,54,95,164,214,200,47,217,186,186,38,224) +IMAGE_DATA(80,223,12,28,189,60,3,199,111,206,0,181,31,59,107,8,255,111,102,4,90,218,203,176,33,88,134,109,195,226,37,76) +IMAGE_DATA(236,139,50,111,226,87,244,183,44,246,121,74,188,249,125,77,252,166,90,197,255,250,77,182,217,70,70,70,114,124,157,240) +IMAGE_DATA(178,239,179,52,181,16,22,147,227,31,70,228,175,156,212,187,11,7,197,98,49,113,183,112,226,249,106,181,154,184,91,56) +IMAGE_DATA(53,56,121,87,214,97,234,198,108,120,101,157,56,142,142,142,14,52,94,244,165,97,240,179,179,179,9,142,201,20,124,32) +IMAGE_DATA(98,17,49,33,241,94,142,88,95,195,199,28,19,94,140,219,114,230,139,229,7,18,241,124,50,0,0,0,0,0,0,0) +IMAGE_END_DATA(1184, 22) diff --git a/rainbow/SlaveGui/Gui.h b/rainbow/VirtualGui/Gui.h similarity index 96% rename from rainbow/SlaveGui/Gui.h rename to rainbow/VirtualGui/Gui.h index fb5f0bc4d..c09221f60 100644 --- a/rainbow/SlaveGui/Gui.h +++ b/rainbow/VirtualGui/Gui.h @@ -1,4 +1,4 @@ -#define GUI_SLAVE +#define VIRTUALGUI NAMESPACE_UPP diff --git a/rainbow/SlaveGui/Image.cpp b/rainbow/VirtualGui/Image.cpp similarity index 98% rename from rainbow/SlaveGui/Image.cpp rename to rainbow/VirtualGui/Image.cpp index a7376c0d3..e57cad43b 100644 --- a/rainbow/SlaveGui/Image.cpp +++ b/rainbow/VirtualGui/Image.cpp @@ -1,6 +1,6 @@ #include -#ifdef GUI_SLAVE +#ifdef VIRTUALGUI NAMESPACE_UPP diff --git a/rainbow/SlaveGui/Keys.h b/rainbow/VirtualGui/Keys.h similarity index 100% rename from rainbow/SlaveGui/Keys.h rename to rainbow/VirtualGui/Keys.h diff --git a/rainbow/SlaveGui/Local.h b/rainbow/VirtualGui/Local.h similarity index 93% rename from rainbow/SlaveGui/Local.h rename to rainbow/VirtualGui/Local.h index 2db2f30f7..58e9ed55f 100644 --- a/rainbow/SlaveGui/Local.h +++ b/rainbow/VirtualGui/Local.h @@ -1,6 +1,6 @@ #include -#ifdef GUI_SLAVE +#ifdef VIRTUALGUI NAMESPACE_UPP @@ -62,4 +62,4 @@ extern Size screen_size; END_UPP_NAMESPACE -#endif \ No newline at end of file +#endif diff --git a/rainbow/SlaveGui/Top.cpp b/rainbow/VirtualGui/Top.cpp similarity index 93% rename from rainbow/SlaveGui/Top.cpp rename to rainbow/VirtualGui/Top.cpp index bd14d5605..bd24f5823 100644 --- a/rainbow/SlaveGui/Top.cpp +++ b/rainbow/VirtualGui/Top.cpp @@ -1,6 +1,6 @@ #include "Local.h" -#ifdef GUI_SLAVE +#ifdef VIRTUALGUI NAMESPACE_UPP diff --git a/rainbow/SlaveGui/Top.h b/rainbow/VirtualGui/Top.h similarity index 100% rename from rainbow/SlaveGui/Top.h rename to rainbow/VirtualGui/Top.h diff --git a/rainbow/SlaveGui/TopFrame.cpp b/rainbow/VirtualGui/TopFrame.cpp similarity index 94% rename from rainbow/SlaveGui/TopFrame.cpp rename to rainbow/VirtualGui/TopFrame.cpp index 27c71c80e..94b48b92b 100644 --- a/rainbow/SlaveGui/TopFrame.cpp +++ b/rainbow/VirtualGui/TopFrame.cpp @@ -1,6 +1,6 @@ #include "Local.h" -#ifdef GUI_SLAVE +#ifdef VIRTUALGUI NAMESPACE_UPP diff --git a/rainbow/SlaveGui/SlaveGui.h b/rainbow/VirtualGui/VirtualGui.h similarity index 64% rename from rainbow/SlaveGui/SlaveGui.h rename to rainbow/VirtualGui/VirtualGui.h index c27d61001..ff3d2509f 100644 --- a/rainbow/SlaveGui/SlaveGui.h +++ b/rainbow/VirtualGui/VirtualGui.h @@ -1,37 +1,56 @@ -#define GUI_SLAVE +#define VIRTUALGUI #ifdef PLATFORM_POSIX #include #endif -NAMESPACE_UPP +namespace Upp { #define IMAGECLASS FBImg -#define IMAGEFILE +#define IMAGEFILE #include -/* -struct SDLWindow { - SDL_Window *win; - SDL_GLContext glcontext; - int64 serial; - - bool Create(const Rect& rect, const char *title); - void Destroy(); - - operator bool() const { return win; } - - SDLWindow(); - ~SDLWindow(); -}; -*/ - -class SystemDraw/* : public GLDraw*/ { +class SystemDraw : public DrawProxy { public: bool CanSetSurface() { return false; } static void Flush() {} }; +enum KM { + KM_NONE = 0x00, + + KM_LSHIFT= 0x01, + KM_RSHIFT= 0x02, + KM_LCTRL = 0x04, + KM_RCTRL = 0x08, + KM_LALT = 0x10, + KM_RALT = 0x20, + + KM_CAPS = 0x40, + KM_NUM = 0x80, + + KM_CTRL = KM_LCTRL | KM_RCTRL, + KM_SHIFT = KM_LSHIFT | KM_RSHIFT, + KM_ALT = KM_LALT | KM_RALT, +}; + +struct VirtualGui { + virtual Size GetSize() = 0; + virtual dword GetMouseButtons() = 0; + virtual dword GetModKeys() = 0; + virtual bool IsMouseIn() = 0; + virtual bool ProcessEvent(bool *quit) = 0; + virtual void WaitEvent(int ms) = 0; + virtual void WakeUpGuiThread() = 0; + virtual void SetMouseCursor(const Image& image) = 0; + virtual void Quit() = 0; + virtual bool IsWaitingEvent() = 0; + virtual SystemDraw& BeginDraw() = 0; + virtual void CommitDraw() = 0; +}; + +extern VirtualGui *VirtualGuiPtr; + struct BackDraw__ : public SystemDraw { BackDraw__() : SystemDraw() {} }; @@ -59,7 +78,7 @@ public: ~BackDraw(); }; -class ImageDraw : public SImageDraw { +class ImageDraw : public SImageDraw { // using software renderer public: ImageDraw(Size sz) : SImageDraw(sz) {} ImageDraw(int cx, int cy) : SImageDraw(cx, cy) {} @@ -72,13 +91,13 @@ class TopWindowFrame; #define GUIPLATFORM_CTRL_TOP_DECLS Ctrl *owner_window; -#define GUIPLATFORM_CTRL_DECLS_INCLUDE +#define GUIPLATFORM_CTRL_DECLS_INCLUDE #define GUIPLATFORM_PASTECLIP_DECLS \ bool dnd; \ friend struct DnDLoop; \ -#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE +#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE class PrinterJob { // Dummy only... NilDraw nil; @@ -103,16 +122,6 @@ public: ~PrinterJob() {} }; -struct SlaveGui { - bool ProcessEvent(bool *quit); - void WaitEvent(int ms); - void SetMouseCursor(const Image& image); - void Quit(); - bool IsWaitingEvent(); -}; +} -extern SlaveGui *SlaveGuiPtr; - -END_UPP_NAMESPACE - -#define GUIPLATFORM_INCLUDE_AFTER +#define GUIPLATFORM_INCLUDE_AFTER diff --git a/rainbow/SlaveGui/SlaveGui.upp b/rainbow/VirtualGui/VirtualGui.upp similarity index 84% rename from rainbow/SlaveGui/SlaveGui.upp rename to rainbow/VirtualGui/VirtualGui.upp index 2db7ecfa5..3e06b761e 100644 --- a/rainbow/SlaveGui/SlaveGui.upp +++ b/rainbow/VirtualGui/VirtualGui.upp @@ -11,24 +11,21 @@ library(POSIX) "SDL2 SDL2main GL"; library(WIN32) "SDL2.lib SDL2main.lib OpenGL32.lib"; file - SlaveGui.h, - Keys.h, Local.h, + VirtualGui.h, + Keys.h, After.h, - Window.cpp, Image.cpp, FB.iml, Ctrl.h, DrawDragRect.cpp, Ctrl.cpp, Wnd.cpp, - Cursor.cpp, Event.cpp, Top.h, TopFrame.cpp, Top.cpp, Clip.cpp, DnD.cpp, - ChSysInit.cpp, - SDL.cpp; + ChSysInit.cpp; diff --git a/rainbow/SlaveGui/Wnd.cpp b/rainbow/VirtualGui/Wnd.cpp similarity index 90% rename from rainbow/SlaveGui/Wnd.cpp rename to rainbow/VirtualGui/Wnd.cpp index 15253eca9..cfaa5818c 100644 --- a/rainbow/SlaveGui/Wnd.cpp +++ b/rainbow/VirtualGui/Wnd.cpp @@ -1,6 +1,6 @@ #include "Local.h" -#ifdef GUI_SLAVE +#ifdef VIRTUALGUI NAMESPACE_UPP @@ -14,8 +14,6 @@ Vector Ctrl::topctrl; bool Ctrl::invalid; -bool Ctrl::sdlMouseIsIn; - Point Ctrl::fbCursorPos = Null; Image Ctrl::fbCursorImage; Rect Ctrl::fbCaretRect; @@ -61,7 +59,7 @@ void Ctrl::ExitFB() TopWindow::ShutdownWindows(); Ctrl::CloseTopCtrls(); if(fbEndSession) { - SlaveGuiPtr->Quit(); + VirtualGuiPtr->Quit(); #if 0 SDL_Event event; event.type = SDL_QUIT; @@ -159,12 +157,7 @@ void Ctrl::UnregisterSystemHotKey(int id) bool Ctrl::IsWaitingEvent() { - return SlaveGuiPtr->IsWaitingEvent(); -#if 0 - SDL_PumpEvents(); - SDL_Event events; - return SDL_PeepEvents(&events, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) > 0; -#endif + return VirtualGuiPtr->IsWaitingEvent(); } void Ctrl::SyncTopWindows() @@ -218,7 +211,6 @@ void Ctrl::PaintScene(SystemDraw& draw) return; LLOG("@ DoPaint"); LTIMING("DoPaint paint"); - draw.Init(screen_size, (uint64)screen.glcontext); draw.Begin(); Vector invalid; invalid.Add(screen_size); @@ -243,7 +235,7 @@ void Ctrl::PaintCaretCursor(SystemDraw& draw) { if(!IsNull(fbCaretRect)) draw.DrawRect(fbCaretRect, InvertColor); - if(sdlMouseIsIn && !SystemCursor) + if(VirtualGuiPtr->IsMouseIn() && !SystemCursor) draw.DrawImage(fbCursorPos.x, fbCursorPos.y, fbCursorImage); } @@ -252,11 +244,10 @@ void Ctrl::DoPaint() if(!PaintLock) { if(invalid && desktop) { invalid = false; - SystemDraw draw; + SystemDraw& draw = VirtualGuiPtr->BeginDraw(); PaintScene(draw); PaintCaretCursor(draw); - draw.Finish(); - SDL_GL_SwapWindow(screen.win); + VirtualGuiPtr->CommitDraw(); } } } diff --git a/rainbow/guiplatform.h b/rainbow/guiplatform.h index 8f5e17533..6ffcf17df 100644 --- a/rainbow/guiplatform.h +++ b/rainbow/guiplatform.h @@ -47,10 +47,10 @@ #define GUIPLATFORM_INCLUDE #endif -#ifdef flagSLAVEGUI -#define GUIPLATFORM_KEYCODES_INCLUDE +#ifdef flagVIRTUALGUI +#define GUIPLATFORM_KEYCODES_INCLUDE //need to make SDL_keysym.h known before K_ enum -#define GUIPLATFORM_INCLUDE +#define GUIPLATFORM_INCLUDE #endif #ifdef flagTELPP