From 8beda45e4d14d16a9d34aec623d5287d68484955 Mon Sep 17 00:00:00 2001 From: cxl Date: Wed, 16 Nov 2011 09:44:09 +0000 Subject: [PATCH] .reference: Rainbow example (RM #158) git-svn-id: svn://ultimatepp.org/upp/trunk@4176 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- reference/Framebuffer/After.h | 17 + reference/Framebuffer/ChSysInit.cpp | 21 + reference/Framebuffer/Clip.cpp | 238 ++++++++ reference/Framebuffer/Ctrl.cpp | 81 +++ reference/Framebuffer/Ctrl.h | 86 +++ reference/Framebuffer/DnD.cpp | 150 +++++ reference/Framebuffer/Draw.cpp | 105 ++++ reference/Framebuffer/Event.cpp | 189 +++++++ reference/Framebuffer/FB.iml | 59 ++ reference/Framebuffer/Fb.h | 64 +++ reference/Framebuffer/Framebuffer.h | 141 +++++ reference/Framebuffer/Framebuffer.upp | 25 + reference/Framebuffer/Gui.h | 358 ++++++++++++ reference/Framebuffer/Image.cpp | 121 ++++ reference/Framebuffer/Top.cpp | 150 +++++ reference/Framebuffer/Top.h | 16 + reference/Framebuffer/TopFrame.cpp | 259 +++++++++ reference/Framebuffer/Util.cpp | 71 +++ reference/Framebuffer/Wnd.cpp | 764 ++++++++++++++++++++++++++ reference/Framebuffer/init | 5 + reference/LinuxFb/Keys.h | 118 ++++ reference/LinuxFb/LinuxFb.h | 12 + reference/LinuxFb/LinuxFb.upp | 13 + reference/LinuxFb/LinuxFbLocal.h | 56 ++ reference/LinuxFb/Local.h | 23 + reference/LinuxFb/Proc.cpp | 235 ++++++++ reference/LinuxFb/Win.cpp | 396 +++++++++++++ reference/LinuxFb/init | 4 + reference/LinuxFb/keymap.cpp | 162 ++++++ reference/LinuxFb/vgakeyboard.h | 198 +++++++ reference/UWord_FB/UWord.cpp | 278 ++++++++++ reference/UWord_FB/UWord.iml | 10 + reference/UWord_FB/UWord_FB.upp | 29 + reference/UWord_FB/icon.ico | Bin 0 -> 6 bytes reference/UWord_FB/init | 13 + reference/WinFb/Keys.h | 113 ++++ reference/WinFb/Local.h | 21 + reference/WinFb/Proc.cpp | 182 ++++++ reference/WinFb/Win.cpp | 120 ++++ reference/WinFb/WinFb.h | 13 + reference/WinFb/WinFb.upp | 10 + reference/WinFb/init | 4 + reference/guiplatform.h | 31 ++ 43 files changed, 4961 insertions(+) create mode 100644 reference/Framebuffer/After.h create mode 100644 reference/Framebuffer/ChSysInit.cpp create mode 100644 reference/Framebuffer/Clip.cpp create mode 100644 reference/Framebuffer/Ctrl.cpp create mode 100644 reference/Framebuffer/Ctrl.h create mode 100644 reference/Framebuffer/DnD.cpp create mode 100644 reference/Framebuffer/Draw.cpp create mode 100644 reference/Framebuffer/Event.cpp create mode 100644 reference/Framebuffer/FB.iml create mode 100644 reference/Framebuffer/Fb.h create mode 100644 reference/Framebuffer/Framebuffer.h create mode 100644 reference/Framebuffer/Framebuffer.upp create mode 100644 reference/Framebuffer/Gui.h create mode 100644 reference/Framebuffer/Image.cpp create mode 100644 reference/Framebuffer/Top.cpp create mode 100644 reference/Framebuffer/Top.h create mode 100644 reference/Framebuffer/TopFrame.cpp create mode 100644 reference/Framebuffer/Util.cpp create mode 100644 reference/Framebuffer/Wnd.cpp create mode 100644 reference/Framebuffer/init create mode 100644 reference/LinuxFb/Keys.h create mode 100644 reference/LinuxFb/LinuxFb.h create mode 100644 reference/LinuxFb/LinuxFb.upp create mode 100644 reference/LinuxFb/LinuxFbLocal.h create mode 100644 reference/LinuxFb/Local.h create mode 100644 reference/LinuxFb/Proc.cpp create mode 100644 reference/LinuxFb/Win.cpp create mode 100644 reference/LinuxFb/init create mode 100644 reference/LinuxFb/keymap.cpp create mode 100644 reference/LinuxFb/vgakeyboard.h create mode 100644 reference/UWord_FB/UWord.cpp create mode 100644 reference/UWord_FB/UWord.iml create mode 100644 reference/UWord_FB/UWord_FB.upp create mode 100644 reference/UWord_FB/icon.ico create mode 100644 reference/UWord_FB/init create mode 100644 reference/WinFb/Keys.h create mode 100644 reference/WinFb/Local.h create mode 100644 reference/WinFb/Proc.cpp create mode 100644 reference/WinFb/Win.cpp create mode 100644 reference/WinFb/WinFb.h create mode 100644 reference/WinFb/WinFb.upp create mode 100644 reference/WinFb/init create mode 100644 reference/guiplatform.h diff --git a/reference/Framebuffer/After.h b/reference/Framebuffer/After.h new file mode 100644 index 000000000..11cd4fcc4 --- /dev/null +++ b/reference/Framebuffer/After.h @@ -0,0 +1,17 @@ +class ViewDraw : public SystemDraw { +public: + ViewDraw(Ctrl *ctrl); + ~ViewDraw(); +}; + + +/* +class ViewDraw : public SystemDraw { + Vector dummy; +public: + ViewDraw(Ctrl *) : SystemDraw(Ctrl::framebuffer, dummy) { dummy.Add(Rect(10, 10, 100, 100)); } +}; +*/ +class DHCtrl : Ctrl {}; + +#include FRAMEBUFFER_INCLUDE diff --git a/reference/Framebuffer/ChSysInit.cpp b/reference/Framebuffer/ChSysInit.cpp new file mode 100644 index 000000000..e27a7685d --- /dev/null +++ b/reference/Framebuffer/ChSysInit.cpp @@ -0,0 +1,21 @@ +#include + +#ifdef GUI_FB + +NAMESPACE_UPP + +void ChSysInit() +{ + CtrlImg::Reset(); + CtrlsImg::Reset(); + ChReset(); +} + +void ChHostSkin() +{ + ChSysInit(); +} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Clip.cpp b/reference/Framebuffer/Clip.cpp new file mode 100644 index 000000000..c588b5c64 --- /dev/null +++ b/reference/Framebuffer/Clip.cpp @@ -0,0 +1,238 @@ +#include "Fb.h" + +#ifdef GUI_FB + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) + +static VectorMap fbClipboard; + +void ClearClipboard() +{ + GuiLock __; + fbClipboard.Clear(); +} + +void AppendClipboard(const char *format, const Value& data, String (*render)(const Value&)) +{ + GuiLock __; + ClipData& cd = fbClipboard.GetAdd(format); + cd.data = data; + cd.render = render; +} + +static String sRawRender(const Value& v) +{ + return v; +} + +void AppendClipboard(const char *format, const String& data) +{ + GuiLock __; + AppendClipboard(format, data, sRawRender); +} + +void AppendClipboard(const char *format, const byte *data, int length) +{ + GuiLock __; + AppendClipboard(format, String(data, length)); +} + +String ReadClipboard(const char *format) +{ + GuiLock __; + int q = fbClipboard.Find(format); + return q >= 0 ? (*fbClipboard[q].render)(fbClipboard[q].data) : String(); +} + +void AppendClipboardText(const String& s) +{ + AppendClipboard("text", ToSystemCharset(s)); +} + +void AppendClipboardUnicodeText(const WString& s) +{ + AppendClipboard("wtext", (byte *)~s, 2 * s.GetLength()); +} + +const char *ClipFmtsText() +{ + return "wtext;text"; +} + +String GetString(PasteClip& clip) +{ + GuiLock __; + if(clip.Accept("wtext")) { + String s = ~clip; + return WString((const wchar *)~s, wstrlen((const wchar *)~s)).ToString(); + } + if(clip.IsAvailable("text")) + return ~clip; + return Null; +} + +WString GetWString(PasteClip& clip) +{ + GuiLock __; + if(clip.Accept("wtext")) { + String s = ~clip; + return WString((const wchar *)~s, wstrlen((const wchar *)~s)); + } + if(clip.IsAvailable("text")) + return (~clip).ToWString(); + return Null; +} + + +bool AcceptText(PasteClip& clip) +{ + return clip.Accept(ClipFmtsText()); +} + +static String sText(const Value& data) +{ + return data; +} + +static String sWText(const Value& data) +{ + return Unicode__(WString(data)); +} + +void Append(VectorMap& data, const String& text) +{ + data.GetAdd("text", ClipData(text, sText)); + data.GetAdd("wtext", ClipData(text, sWText)); +} + +void Append(VectorMap& data, const WString& text) +{ + data.GetAdd("text", ClipData(text, sText)); + data.GetAdd("wtext", ClipData(text, sWText)); +} + +String GetTextClip(const WString& text, const String& fmt) +{ + if(fmt == "text") + return text.ToString(); + if(fmt == "wtext") + return Unicode__(text); + return Null; +} + +String GetTextClip(const String& text, const String& fmt) +{ + if(fmt == "text") + return text; + if(fmt == "wtext") + return Unicode__(text.ToWString()); + return Null; +} + +String ReadClipboardText() +{ + String w = ReadClipboard("text"); + return w.GetCount() ? w : ReadClipboardUnicodeText().ToString(); +} + +WString ReadClipboardUnicodeText() +{ + String w = ReadClipboard("wtext"); + if(w.GetCount()) + return WString((const wchar *)~w, w.GetLength() / 2); + return ReadClipboard("text").ToWString(); +} + +bool IsClipboardAvailable(const char *id) +{ + return fbClipboard.Find(id) >= 0; +} + +bool IsClipboardAvailableText() +{ + return IsClipboardAvailable("text") || IsClipboardAvailable("wtext"); +} + +const char *ClipFmtsImage() +{ + static const char *q; + ONCELOCK { + static String s = "dib;" + ClipFmt(); + q = s; + } + return q; +} + +bool AcceptImage(PasteClip& clip) +{ + GuiLock __; + return clip.Accept(ClipFmtsImage()); +} + +Image GetImage(PasteClip& clip) +{ + GuiLock __; + Image m; + if(Accept(clip)) { + LoadFromString(m, ~clip); + if(!m.IsEmpty()) + return m; + } + return Null; +} + +Image ReadClipboardImage() +{ + GuiLock __; + PasteClip d = Ctrl::Clipboard(); + return GetImage(d); +} + +String sImage(const Value& image) +{ + Image img = image; + return StoreAsString(const_cast(img)); +} + +String GetImageClip(const Image& img, const String& fmt) +{ + GuiLock __; + if(img.IsEmpty()) return Null; + if(fmt == ClipFmt()) + return sImage(img); + return Null; +} + +void AppendClipboardImage(const Image& img) +{ + GuiLock __; + if(img.IsEmpty()) return; + AppendClipboard(ClipFmt(), img, sImage); +} + +bool AcceptFiles(PasteClip& clip) +{ + if(clip.Accept("files")) { + clip.SetAction(DND_COPY); + return true; + } + return false; +} + +bool IsAvailableFiles(PasteClip& clip) +{ + return clip.IsAvailable("files"); +} + +Vector GetFiles(PasteClip& clip) +{ + GuiLock __; + Vector f; + return f; +} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Ctrl.cpp b/reference/Framebuffer/Ctrl.cpp new file mode 100644 index 000000000..a0d4ef73c --- /dev/null +++ b/reference/Framebuffer/Ctrl.cpp @@ -0,0 +1,81 @@ +#include "Fb.h" + +#ifdef GUI_FB + +#define LLOG(x) // DLOG(x) + +NAMESPACE_UPP + +void Ctrl::GuiPlatformConstruct() +{ +} + +void Ctrl::GuiPlatformRemove() +{ +} + +void Ctrl::GuiPlatformGetTopRect(Rect& r) const +{ +} + +bool Ctrl::GuiPlatformRefreshFrameSpecial(const Rect& r) +{ + return false; +} + +bool Ctrl::GuiPlatformSetFullRefreshSpecial() +{ + return false; +} + +void Ctrl::PaintCaret(SystemDraw& w) +{ +} + +String GuiPlatformGetKeyDesc(dword key) +{ + return Null; +} + +void Ctrl::GuiPlatformSelection(PasteClip&) +{ +} + +void GuiPlatformAdjustDragImage(ImageBuffer&) +{ +} + +bool GuiPlatformHasSizeGrip() +{ + return true; +} + +void GuiPlatformGripResize(TopWindow *q) +{ + q->GripResize(); +} + +Color GuiPlatformGetScreenPixel(int x, int y) +{ + return Ctrl::GetFrameBuffer()[y][x]; +} + +void GuiPlatformAfterMenuPopUp() +{ +} + +String Ctrl::Name() const { + GuiLock __; +#ifdef CPU_64 + String s = String(typeid(*this).name()) + " : 0x" + FormatIntHex(this); +#else + String s = String(typeid(*this).name()) + " : " + Format("0x%x", (int) this); +#endif + if(IsChild()) + s << "(parent " << String(typeid(*parent).name()) << ")"; + return s; +} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Ctrl.h b/reference/Framebuffer/Ctrl.h new file mode 100644 index 000000000..ac2f22117 --- /dev/null +++ b/reference/Framebuffer/Ctrl.h @@ -0,0 +1,86 @@ +//$ class Ctrl { +private: + static Ptr desktop; + static Vector topctrl; + static ImageBuffer framebuffer; + static Vector invalid, update; + + static Point fbCursorPos; + static Image fbCursorImage; + + static Point fbCursorBakPos; + static Image fbCursorBak; + + static Rect fbCaretRect; + static Image fbCaretBak; + static int fbCaretTm; + + static int renderingMode; + + static bool fbEndSession; + static int64 fbEventLoop; + static int64 fbEndSessionLoop; + + static Image GetBak(Rect& tr); + static void RemoveCursor(); + static void RemoveCaret(); + static void CursorSync(); + + int FindTopCtrl() const; + static Rect GetClipBound(const Vector& inv, const Rect& r); + static void DoPaint(); + static void DoUpdate(); + static void SyncTopWindows(); + + static void AddInvalid(const Rect& rect); + + void DestroyWnd(); + + void NewTop() { top = new Top; top->owner_window = NULL; } + void PutForeground(); + static void MouseEventFB(Ptr t, int event, Point p, int zdelta); + Vector GetPaintRects(); + + static void DrawLine(const Vector& clip, int x, int y, int cx, int cy, bool horz, + const byte *pattern, int animation); + 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; + + void SetOpen(bool b) { isopen = b; } + +protected: + static int PaintLock; + +public: + static void DoMouseFB(int event, Point p, int zdelta = 0); + static bool DoKeyFB(dword key, int cnt); + + static void InitFB(); + static void ExitFB(); + static void EndSession(); + + static void SetDesktop(Ctrl& q); + static Ctrl *GetDesktop() { return desktop; } + static void SetFramebufferSize(Size sz); + + static const ImageBuffer& GetFrameBuffer() { return framebuffer; } + + static void SetRenderingMode(int mode); + + static void AddUpdate(const Rect& rect); + + void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, int type, int animation); + + static Ctrl *FindMouseTopCtrl(); + + static bool FullWindowDrag; + + enum { DRAWDRAGRECT_SCREEN = 0x8000 }; + +//$ }; diff --git a/reference/Framebuffer/DnD.cpp b/reference/Framebuffer/DnD.cpp new file mode 100644 index 000000000..945de0fd7 --- /dev/null +++ b/reference/Framebuffer/DnD.cpp @@ -0,0 +1,150 @@ +#include "Fb.h" + +#ifdef GUI_FB + +NAMESPACE_UPP + +#define LLOG(x) // DLOG(x) + +// -------------------------------------------------------------------------------------------- + +Ptr sDnDSource; + +Ctrl * Ctrl::GetDragAndDropSource() +{ + return sDnDSource; +} + +struct DnDLoop : LocalLoop { + const VectorMap *data; + Vector fmts; + + Image move, copy, reject; + Ptr target; + int action; + byte actions; + + void Sync(); + String GetData(const String& f); + void DnD(bool paste); + + virtual void LeftUp(Point, dword); + virtual bool Key(dword, int); + virtual void MouseMove(Point p, dword); + virtual Image CursorImage(Point, dword); +}; + +Ptr dndloop; + +bool PasteClip::IsAvailable(const char *fmt) const +{ + GuiLock __; + return dnd ? dndloop && FindIndex(dndloop->fmts, fmt) >= 0 + : IsClipboardAvailable(fmt); +} + +String DnDLoop::GetData(const String& f) +{ + GuiLock __; + int i = data->Find(f); + String d; + if(i >= 0) + d = (*data)[i].Render(); + else + if(sDnDSource) + d = sDnDSource->GetDropData(f); + return d; +} + +String PasteClip::Get(const char *fmt) const +{ + return dnd ? dndloop ? dndloop->GetData(fmt) : String() : ReadClipboard(fmt); +} + +void PasteClip::GuiPlatformConstruct() +{ + dnd = false; +} + +void DnDLoop::DnD(bool paste) +{ + PasteClip d; + d.paste = paste; + d.accepted = false; + d.allowed = (byte)actions; + d.action = GetCtrl() ? DND_COPY : DND_MOVE; + d.dnd = true; + if(target) + target->DnD(GetMousePos(), d); + action = d.IsAccepted() ? d.GetAction() : DND_NONE; +} + +void DnDLoop::Sync() +{ + GuiLock __; + Ptr t = FindMouseTopCtrl(); + if(t != target) + if(target) + target->DnDLeave(); + target = t; + DnD(false); +} + +void DnDLoop::LeftUp(Point, dword) +{ + GuiLock __; + LLOG("DnDLoop::LeftUp"); + DnD(true); + EndLoop(); +} + +void DnDLoop::MouseMove(Point p, dword) +{ + GuiLock __; + LLOG("DnDLoop::MouseMove"); + Sync(); +} + +bool DnDLoop::Key(dword, int) +{ + GuiLock __; + LLOG("DnDLoop::Key"); + Sync(); + return false; +} + +Image DnDLoop::CursorImage(Point, dword) +{ + 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 __; + DnDLoop d; + d.actions = (byte)actions; + d.reject = actions & DND_EXACTIMAGE ? CtrlCoreImg::DndNone() : MakeDragImage(CtrlCoreImg::DndNone(), sample); + if(actions & DND_COPY) + d.copy = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndCopy(), sample); + if(actions & DND_MOVE) + d.move = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndMoveX11(), sample); + d.SetMaster(*this); + d.data = &data; + d.action = DND_NONE; + d.fmts = Split(fmts, ';'); + dndloop = &d; + sDnDSource = this; + d.Run(); + sDnDSource = NULL; + SyncCaret(); + LLOG("DoDragAndDrop finished"); + return d.action; +} + +void Ctrl::SetSelectionSource(const char *fmts) {} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Draw.cpp b/reference/Framebuffer/Draw.cpp new file mode 100644 index 000000000..bca6767da --- /dev/null +++ b/reference/Framebuffer/Draw.cpp @@ -0,0 +1,105 @@ +#include + +#ifdef GUI_FB + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) +#define LTIMING(x) // RTIMING(x) + +SystemDraw::SystemDraw() +: BufferPainter(Ctrl::framebuffer, Ctrl::renderingMode) +{ +} + +SystemDraw::~SystemDraw() +{ +} + + +void SystemDraw::Push() +{ + Point p = GetOffset(); + offset.Add(p); + BufferPainter::BeginOp(); +} + +void SystemDraw::Pop() +{ + if(offset.GetCount()) + offset.Drop(); + BufferPainter::EndOp(); +} + +Point SystemDraw::GetOffset() const +{ + return offset.GetCount() ? offset.Top() : Point(0, 0); +} + +void SystemDraw::BeginOp() +{ + Push(); +} + +void SystemDraw::EndOp() +{ + Pop(); +} + +void SystemDraw::OffsetOp(Point p) +{ + Push(); + offset.Top() += p; + Translate(p.x, p.y); +} + +bool SystemDraw::ClipOp(const Rect& r) +{ + Push(); + RectPath(r); + Painter::Clip(); + return true; +} + +bool SystemDraw::ClipoffOp(const Rect& r) +{ + Push(); + offset.Top() += r.TopLeft(); + RectPath(r); + Painter::Clip(); + Translate(r.left, r.top); + return true; +} + +bool SystemDraw::IsPaintingOp(const Rect& r) const +{ + Rect rr = r + GetOffset(); + for(int i = 0; i < Ctrl::invalid.GetCount(); i++) + if(Ctrl::invalid[i].Intersects(rr)) + return true; + return true; +} + +/*Rect SystemDraw::GetVirtualScreenArea() +{ + GuiLock __; +}*/ + +/* +void BackDraw::Destroy() +{ + GuiLock __; +} + +void BackDraw::Create(SystemDraw& w, int cx, int cy) { + GuiLock __; +} + +void BackDraw::Put(SystemDraw& w, int x, int y) { + GuiLock __; +} +*/ + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Event.cpp b/reference/Framebuffer/Event.cpp new file mode 100644 index 000000000..64ad722ef --- /dev/null +++ b/reference/Framebuffer/Event.cpp @@ -0,0 +1,189 @@ +#include "Fb.h" + +#ifdef GUI_FB + +NAMESPACE_UPP + +#define LLOG(x) //DLOG(x) +#define LDUMP(x) //DDUMP(x) + +static Point fbmousepos; + +Point GetMousePos() { + return fbmousepos; +} + +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) +{ + bool b = DispatchKey(key, cnt); + SyncCaret(); + Ctrl *desktop = GetDesktop(); + if(desktop) + desktop->PostInput(); + return b; +} + +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()); + AddUpdate(Rect(fbCursorBakPos, fbCursorBak.GetSize())); + } + fbCursorPos = fbCursorBakPos = Null; + fbCursorBak = Null; +} + +void Ctrl::RemoveCaret() +{ + if(!IsNull(fbCaretRect)) { + Copy(framebuffer, fbCaretRect.TopLeft(), fbCaretBak, fbCaretBak.GetSize()); + AddUpdate(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() +{ + 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(); + LDUMP(GetTickCount()); + if(fbCursorPos != p || cr != fbCaretRect) { + LDUMP(fbCaretRect); + RemoveCursor(); + RemoveCaret(); + + fbCursorPos = p; + Size sz = fbCursorImage.GetSize(); + Rect tr(p, sz); + fbCursorBak = GetBak(tr); + fbCursorBakPos = tr.TopLeft(); + + fbCaretRect = cr; + if(!cr.IsEmpty()) { + fbCaretBak = GetBak(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++; + } + } + AddUpdate(fbCaretRect); + } + + Over(framebuffer, p, fbCursorImage, sz); + LLOG("Cursor: " << p << ", rect " << tr); + AddUpdate(tr); + } +} + +void Ctrl::SetMouseCursor(const Image& image) +{ + GuiLock __; + if(image.GetSerialId() != fbCursorImage.GetSerialId()) { + fbCursorImage = image; + fbCursorPos = Null; + } +} + +END_UPP_NAMESPACE + +#endif \ No newline at end of file diff --git a/reference/Framebuffer/FB.iml b/reference/Framebuffer/FB.iml new file mode 100644 index 000000000..08f565033 --- /dev/null +++ b/reference/Framebuffer/FB.iml @@ -0,0 +1,59 @@ +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,205,75,84,81,20,191,101,163,6,74,72,180,115,209,166,77,127,66,4,109,91,6,22,4,209,38,23,209) +IMAGE_DATA(162,93,45,162,204,9,34,130,8,13,178,36,44,45,11,212,172,197,108,68,84,212,133,31,8,126,224,7,12,162,8,34) +IMAGE_DATA(136,136,160,43,221,157,238,140,51,227,245,188,251,206,61,231,206,27,43,120,231,113,208,247,238,239,119,238,57,191,115,222) +IMAGE_DATA(123,227,135,170,82,23,84,198,202,213,169,204,23,80,50,3,33,7,0,68,28,56,56,184,8,251,251,151,184,28,216,219) +IMAGE_DATA(187,2,187,187,215,96,103,231,58,135,3,219,219,55,96,107,235,38,108,110,222,129,245,245,122,23,7,54,54,234,53,238) +IMAGE_DATA(62,172,173,61,132,213,213,71,144,78,63,165,56,176,178,242,24,150,151,159,104,92,35,44,46,190,130,249,249,183,48,59) +IMAGE_DATA(219,28,198,129,165,165,151,176,176,240,26,230,230,154,96,102,166,21,166,166,58,97,114,242,59,76,76,180,219,56,26,211) +IMAGE_DATA(12,211,211,239,53,174,13,198,199,187,97,100,100,36,231,191,96,120,184,19,115,116,172,86,141,107,131,177,177,78,24,29) +IMAGE_DATA(253,93,192,171,163,94,154,28,141,249,172,189,3,134,134,126,192,224,224,79,232,239,79,145,245,14,12,180,67,95,223,215) +IMAGE_DATA(66,156,84,170,155,196,167,82,95,2,57,118,117,125,11,213,199,166,65,71,199,39,10,111,221,183,165,229,157,104,14,155) +IMAGE_DATA(154,222,136,103,61,153,124,46,218,163,161,225,153,120,15,1,54,104,9,117,78,157,86,21,89,87,168,241,42,123,179,30) +IMAGE_DATA(26,250,190,176,57,58,255,239,175,133,212,27,208,69,85,105,225,18,90,180,196,113,225,184,158,229,212,246,124,32,221,192) +IMAGE_DATA(158,4,158,228,88,176,161,28,2,27,224,48,176,5,142,4,235,147,139,79,173,62,90,254,133,254,202,230,179,70,31,149) +IMAGE_DATA(185,131,18,206,226,92,227,222,36,28,126,49,235,146,60,139,229,7,26,200,136,97,127,250,248,243,195,242,146,242,185,49) +IMAGE_DATA(36,235,174,61,56,57,82,117,82,230,210,88,194,183,229,36,153,21,219,53,95,62,55,142,207,125,231,115,223,186,98,217) +IMAGE_DATA(141,249,64,58,140,26,124,189,139,204,124,253,23,195,207,187,52,14,230,251,196,1,195,208,169,51,6,198,217,244,160,98) +IMAGE_DATA(133,225,57,215,204,235,56,111,91,45,24,139,249,62,110,139,227,147,71,84,122,68,213,23,91,44,91,45,46,46,222,31) +IMAGE_DATA(187,36,134,45,142,148,143,227,248,242,81,28,218,106,244,199,254,74,85,150,117,76,118,5,160,48,220,34,194,112,212,208) +IMAGE_DATA(218,76,169,147,191,121,56,121,68,165,135,185,238,213,151,184,209,113,163,253,2,50,19,118,225,138,21,216,188,230,227,182) +IMAGE_DATA(56,62,121,68,165,135,185,238,213,151,10,221,234,178,92,171,45,27,178,19,193,194,186,4,183,9,132,206,157,133,255,235) +IMAGE_DATA(107,84,125,148,46,148,158,156,92,140,245,35,171,214,71,121,238,8,100,130,68,39,2,146,73,185,56,46,124,177,28,44) +IMAGE_DATA(182,139,131,155,197,221,47,108,239,98,121,146,62,72,106,53,121,170,132,189,240,157,17,235,44,198,79,166,210,173,81,245) +IMAGE_DATA(81,186,80,122,114,114,49,214,143,204,124,50,81,22,200,18,53,132,216,236,68,159,66,92,14,22,223,197,161,26,201,197) +IMAGE_DATA(227,117,28,75,146,3,7,111,114,212,9,235,207,205,77,58,83,241,192,198,3,91,18,14,55,55,241,192,198,175,210,210) +IMAGE_DATA(173,81,245,81,186,80,122,114,114,49,214,143,44,254,144,31,228,224,102,113,247,11,219,187,88,158,164,15,146,90,77,158) +IMAGE_DATA(42,97,47,124,103,196,58,139,85,250,136,200,172,119,154,225,54,60,21,203,23,207,201,3,227,93,123,70,133,231,232,83) +IMAGE_DATA(42,93,204,107,146,62,241,45,130,97,114,37,39,17,203,134,137,241,209,227,37,253,226,91,20,79,166,171,213,213,161,155) +IMAGE_DATA(227,181,204,121,222,109,88,219,154,237,58,21,7,175,187,176,97,28,10,43,197,75,242,145,212,235,171,39,149,39,85,7) +IMAGE_DATA(105,103,244,145,183,186,186,86,184,253,160,23,238,190,232,133,123,31,123,65,122,94,8,86,150,253,219,76,18,206,94,238) +IMAGE_DATA(129,243,183,150,160,182,49,243,18,22,158,103,198,60,161,143,220,207,178,220,251,233,216,155,223,101,230,255,83,231,207,41) +IMAGE_DATA(79,38,147,49,190,68,248,252,185,203,125,102,33,59,76,142,95,140,80,159,94,48,14,210,233,244,177,175,97,88,140,51) +IMAGE_DATA(240,214,79,32,97,120,180,79,33,6,23,239,194,217,240,121,151,226,195,28,213,44,197,59,57,148,166,76,44,11,255,7) +IMAGE_DATA(113,204,146,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(1056, 22) diff --git a/reference/Framebuffer/Fb.h b/reference/Framebuffer/Fb.h new file mode 100644 index 000000000..fbcba1d77 --- /dev/null +++ b/reference/Framebuffer/Fb.h @@ -0,0 +1,64 @@ +#ifndef _Framebuffer_Fb_h_ +#define _Framebuffer_Fb_h_ + +#include + +NAMESPACE_UPP + +class TopWindowFrame : public Ctrl { +public: + virtual void Layout(); + virtual void Paint(Draw& w); + virtual Image CursorImage(Point p, dword keyflags); + virtual void LeftDown(Point p, dword keyflags); + virtual void LeftHold(Point p, dword keyflags); + virtual void LeftDouble(Point p, dword keyflags); + virtual void MouseMove(Point p, dword keyflags); + virtual void CancelMode(); + virtual void LeftUp(Point p, dword keyflags); + +private: + Point dir; + Point startpos; + Rect startrect; + + bool maximized; + Rect overlapped; + + bool holding; + TimeCallback hold; + + Point GetDragMode(Point p); + Image GetDragImage(Point dragmode); + void StartDrag(); + Rect Margins() const; + Rect ComputeClient(Rect r); + void Hold(); + + typedef TopWindowFrame CLASSNAME; + +public: + String title; + Button close, maximize; + Image icon; + Size minsize; + bool sizeable; + TopWindow *window; + + void SetTitle(const String& s) { title = s; Refresh(); } + Rect GetClient() const; + void SetClient(Rect r); + void GripResize(); + + void Maximize(); + void Overlap(); + void ToggleMaximize(); + bool IsMaximized() const { return maximized; } + void SyncRect(); + + TopWindowFrame(); +}; + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Framebuffer.h b/reference/Framebuffer/Framebuffer.h new file mode 100644 index 000000000..4372e4470 --- /dev/null +++ b/reference/Framebuffer/Framebuffer.h @@ -0,0 +1,141 @@ +#define GUI_FB + +#include + +NAMESPACE_UPP + +#define IMAGECLASS FBImg +#define IMAGEFILE +#include + +class SystemDraw : public BufferPainter { +public: + 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 IsPaintingOp(const Rect& r) const; + +private: + Vector offset; + + void Push(); + void Pop(); + +public: + Point GetOffset() const; + bool CanSetSurface() { return false; } + bool Clip(const Rect& r) { return Draw::Clip(r); } + bool Clip(int x, int y, int cx, int cy) { return Draw::Clip(x, y, cx, cy); } + + static void Flush() {} + + SystemDraw(); + ~SystemDraw(); +}; + +struct BackDraw__ : public SystemDraw { + BackDraw__() : SystemDraw() {} +}; + +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__, public BufferPainter { + BufferPainter alpha_painter; + 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); + +class TopWindowFrame; + +#define GUIPLATFORM_CTRL_TOP_DECLS Ctrl *owner_window; + +#define GUIPLATFORM_CTRL_DECLS_INCLUDE + +#define GUIPLATFORM_PASTECLIP_DECLS \ + bool dnd; \ + friend struct DnDLoop; \ + +#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE + +// to be implemented by final FB { + +bool FBIsWaitingEvent(); +bool FBProcessEvent(bool *quit); +void FBSleep(int ms); +void FBInitUpdate(); +void FBUpdate(const Rect& area); +void FBFlush(); +void FBQuitSession(); + +// } + +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 + +#define GUIPLATFORM_INCLUDE_AFTER diff --git a/reference/Framebuffer/Framebuffer.upp b/reference/Framebuffer/Framebuffer.upp new file mode 100644 index 000000000..6df6c1a8e --- /dev/null +++ b/reference/Framebuffer/Framebuffer.upp @@ -0,0 +1,25 @@ +description "Generic framebuffer GUI rainbow\377"; + +uses + Painter, + CtrlLib; + +file + Framebuffer.h, + After.h, + Fb.h, + Draw.cpp, + Image.cpp, + Util.cpp, + FB.iml, + Ctrl.h, + Ctrl.cpp, + Wnd.cpp, + Event.cpp, + Top.h, + TopFrame.cpp, + Top.cpp, + Clip.cpp, + DnD.cpp, + ChSysInit.cpp; + diff --git a/reference/Framebuffer/Gui.h b/reference/Framebuffer/Gui.h new file mode 100644 index 000000000..b99463c69 --- /dev/null +++ b/reference/Framebuffer/Gui.h @@ -0,0 +1,358 @@ +#define GUI_FB + +NAMESPACE_UPP + +class SystemDraw : public Draw { +public: + virtual dword GetInfo() const; + virtual Size GetPageSize() const; + + 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: + Size pageSize; + Size nativeSize; + Size nativeDpi; + bool palette:1; + bool color16:1; + bool is_mono:1; + int native; + + friend class ImageDraw; + friend class FontInfo; + friend class Font; + + friend void StaticExitDraw_(); + + Point actual_offset_bak; + + struct Cloff : Moveable { + Point org; + HRGN hrgn; + Rect drawingclip; + }; + + Array cloff; + Rect drawingclip; + + COLORREF lastTextColor; + Color lastColor; + HBRUSH orgBrush; + HBRUSH actBrush; + HPEN orgPen; + HPEN actPen; + int lastPen; + Color lastPenColor; + + void Unselect0(); + void Cinit(); + + void LoadCaps(); + void SetPrinterMode(); + void Reset(); + void SetOrg(); + friend HPALETTE GetQlibPalette(); + void DotsMode(); + + static void InitColors(); + + friend class BackDraw; + friend class ScreenDraw; + friend class PrintDraw; + +protected: + dword style; + HDC handle; + Point actual_offset; + + SystemDraw(); + void Init(); + void InitClip(const Rect& clip); + +public: + static Rect GetVirtualScreenArea(); + + static void SetAutoPalette(bool ap); + static bool AutoPalette(); + bool PaletteMode() { return palette; } + + static void Flush() { GdiFlush(); } + + COLORREF GetColor(Color color) const; + + Point GetOffset() const { return actual_offset; } + +#ifndef PLATFORM_WINCE + Point LPtoDP(Point p) const; + Point DPtoLP(Point p) const; + Rect LPtoDP(const Rect& r) const; + Rect DPtoLP(const Rect& r) const; +#endif + + void SetColor(Color color); + void SetDrawPen(int width, Color color); + + Size GetSizeCaps(int i, int j) const; + HDC BeginGdi(); + void EndGdi(); + HDC GetHandle() { return handle; } + operator HDC() const { return handle; } + void Unselect(); + void Attach(HDC ahandle) { handle = ahandle; Init(); } + HDC Detach() { Unselect(); HDC h = handle; handle = NULL; return h; } + + SystemDraw(HDC hdc); + virtual ~SystemDraw(); + + bool CanSetSurface() { return IsGui() && IsWinNT(); } +}; + +#ifndef PLATFORM_WINCE +class WinMetaFile { + Size size; + HENHMETAFILE hemf; + + void Init(); + +public: + void Attach(HENHMETAFILE emf); + HENHMETAFILE Detach(); + + void Set(const void *data, dword len); + void Set(const String& data) { Set(~data, data.GetCount()); } + + String Get() const; + + operator bool() const { return hemf; } + void SetSize(const Size& sz) { size = sz; } + Size GetSize() const { return hemf ? size : Size(0, 0); } + + void Clear(); + + void Paint(Draw& w, const Rect& r) const; + void Paint(Draw& w, int x, int y, int cx, int cy) const; + + void Serialize(Stream& s); + + void ReadClipboard(); + void WriteClipboard() const; + void Load(const char *file) { Set(LoadFile(file)); } + + WinMetaFile() { Init(); } + WinMetaFile(HENHMETAFILE hemf); + WinMetaFile(HENHMETAFILE hemf, Size sz); + WinMetaFile(const char *file); + WinMetaFile(void *data, int len); + WinMetaFile(const String& data); + + ~WinMetaFile() { Clear(); } + + HENHMETAFILE GetHEMF() const { return hemf; } +}; + +class WinMetaFileDraw : public SystemDraw { + Size size; + +public: + bool Create(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + bool Create(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + WinMetaFile Close(); + + WinMetaFileDraw() {} + WinMetaFileDraw(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + WinMetaFileDraw(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + ~WinMetaFileDraw(); +}; + +void DrawWMF(Draw& w, int x, int y, int cx, int cy, const String& wmf); +void DrawWMF(Draw& w, int x, int y, const String& wmf); +Drawing LoadWMF(const char *path, int cx, int cy); +Drawing LoadWMF(const char *path); + +String AsWMF(const Drawing& iw); + +#endif + +class ScreenDraw : public SystemDraw { +public: + ScreenDraw(bool ic = false); + ~ScreenDraw(); +}; + +#ifndef PLATFORM_WINCE +class PrintDraw : public SystemDraw { +public: + virtual void StartPage(); + virtual void EndPage(); + +private: + bool aborted; + + void InitPrinter(); +public: + PrintDraw(HDC hdc, const char *jobname); + ~PrintDraw(); +}; +#endif + +inline bool BitBlt(HDC ddc, Point d, HDC sdc, const Rect& s, dword rop = SRCCOPY) +{ return BitBlt(ddc, d.x, d.y, s.Width(), s.Height(), sdc, s.left, s.top, rop); } + +inline bool StretchBlt(HDC ddc, const Rect& r, HDC sdc, const Rect& s, dword rop = SRCCOPY) +{ return StretchBlt(ddc, r.left, r.top, r.Width(), r.Height(), sdc, s.left, s.top, s.Width(), s.Height(), rop); } + +inline bool PatBlt(HDC dc, const Rect& r, dword rop = PATCOPY) +{ return PatBlt(dc, r.left, r.top, r.Width(), r.Height(), rop); } + +inline void MoveTo(HDC hdc, Point pt) { MoveToEx(hdc, pt.x, pt.y, 0); } +inline void LineTo(HDC hdc, Point pt) { LineTo(hdc, pt.x, pt.y); } + +inline void DrawLine(HDC hdc, Point p, Point q) { MoveTo(hdc, p); LineTo(hdc, q); } +inline void DrawLine(HDC hdc, int px, int py, int qx, int qy) { MoveToEx(hdc, px, py, 0); LineTo(hdc, qx, qy); } + +#ifndef PLATFORM_WINCE +inline void DrawArc(HDC hdc, const Rect& rc, Point p, Point q){ Arc(hdc, rc.left, rc.top, rc.right, rc.bottom, p.x, p.y, q.x, q.y); } +#endif +inline void DrawCircle(HDC hdc, int x, int y, int radius) { Ellipse(hdc, x - radius, y - radius, x + radius + 1, y + radius + 1); } +inline void DrawCircle(HDC hdc, Point centre, int radius) { DrawCircle(hdc, centre.x, centre.y, radius); } +inline void DrawEllipse(HDC hdc, const Rect& rc) { Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); } + +inline void DrawRect(HDC hdc, const Rect& rc) { Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); } + +HDC ScreenHDC(); +HPALETTE GetQlibPalette(); + +Image Win32Icon(LPCSTR id, int iconsize = 0); +Image Win32Icon(int id, int iconsize = 0); +Image Win32Cursor(LPCSTR id); +Image Win32Cursor(int id); +HICON IconWin32(const Image& img, bool cursor = false); +Image Win32DllIcon(const char *dll, int ii, bool large); + +class BackDraw : public SystemDraw { +public: + virtual bool IsPaintingOp(const Rect& r) const; + +protected: + HBITMAP hbmpold; + HBITMAP hbmp; + + Size size; + Draw *painting; + Point painting_offset; + +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(); +}; + +class ImageDraw : public SystemDraw { + Size size; + + struct Section { + HDC dc; + HBITMAP hbmp, hbmpOld; + RGBA *pixels; + + void Init(int cx, int cy); + ~Section(); + }; + + Section rgb; + Section a; + SystemDraw alpha; + + + bool has_alpha; + + void Init(); + Image Get(bool pm) const; + +public: + Draw& Alpha(); + + operator Image() const; + + Image GetStraight() const; + + ImageDraw(Size sz); + ImageDraw(int cx, int cy); + ~ImageDraw(); +}; + +END_UPP_NAMESPACE + +#define GUIPLATFORM_KEYCODES_INCLUDE "Win32Keys.h" + + +#define GUIPLATFORM_CTRL_TOP_DECLS \ + HWND hwnd; \ + UDropTarget *dndtgt; \ + + +#define GUIPLATFORM_CTRL_DECLS_INCLUDE "Win32Ctrl.h" + + +#define GUIPLATFORM_PASTECLIP_DECLS \ + UDropTarget *dt; \ + +#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE "Win32Top.h" + +NAMESPACE_UPP + +inline unsigned GetHashValue(const HWND& hwnd) +{ + return (unsigned)(intptr_t)hwnd; +} +END_UPP_NAMESPACE + +#ifdef PLATFORM_WIN32 +#ifndef PLATFORM_WINCE + +#include + +#endif +#endif + +#define GUIPLATFORM_INCLUDE_AFTER "Win32GuiA.h" diff --git a/reference/Framebuffer/Image.cpp b/reference/Framebuffer/Image.cpp new file mode 100644 index 000000000..ec97c7b31 --- /dev/null +++ b/reference/Framebuffer/Image.cpp @@ -0,0 +1,121 @@ +#include + +#ifdef GUI_FB + +NAMESPACE_UPP + +#define LTIMING(x) // RTIMING(x) + +void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels) +{ + GuiLock __; +} + +void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size psz, Point poff) +{ + GuiLock __; +} + +struct Image::Data::SystemData { +}; + +void Image::Data::SysInitImp() +{ + SystemData& sd = Sys(); +} + +void Image::Data::SysReleaseImp() +{ + SystemData& sd = Sys(); +} + +Image::Data::SystemData& Image::Data::Sys() const +{ + ASSERT(sizeof(system_buffer) >= sizeof(SystemData)); + return *(SystemData *)system_buffer; +} + +int Image::Data::GetResCountImp() const +{ + SystemData& sd = Sys(); + return 0; +} + +void Image::Data::PaintImp(SystemDraw& w, int x, int y, const Rect& src, Color c) +{ + GuiLock __; + SystemData& sd = Sys(); +} + +Image ImageDraw::Get(bool pm) const +{ + ImageBuffer result(image.GetSize()); + const RGBA *e = image.End(); + const RGBA *p = ~image; + RGBA *t = ~result; + if(has_alpha) { + const RGBA *a = ~alpha; + while(p < e) { + *t = *p++; + (t++)->a = (a++)->r; + } + if(pm) + Premultiply(result); + result.SetKind(IMAGE_ALPHA); + } + else { + while(p < e) { + *t = *p++; + (t++)->a = 255; + } + } + return result; +} + +Draw& ImageDraw::Alpha() +{ + has_alpha = true; + return alpha_painter; +} + + +ImageDraw::ImageDraw(Size sz) +: ImageDraw__(sz.cx, sz.cy), + BufferPainter(image), + alpha_painter(alpha) +{ + has_alpha = false; +} + +ImageDraw::ImageDraw(int cx, int cy) +: ImageDraw__(cx, cy), + BufferPainter(image), + alpha_painter(alpha) +{ + has_alpha = false; +} + +#define IMAGECLASS FBImg +#define IMAGEFILE +#include + +Image Image::Arrow() { return FBImg::arrow(); } +Image Image::Wait() { return FBImg::wait(); } +Image Image::IBeam() { return FBImg::ibeam(); } +Image Image::No() { return FBImg::no(); } +Image Image::SizeAll() { return FBImg::sizeall(); } +Image Image::SizeHorz() { return FBImg::sizehorz(); } +Image Image::SizeVert() { return FBImg::sizevert(); } +Image Image::SizeTopLeft() { return FBImg::sizetopleft(); } +Image Image::SizeTop() { return FBImg::sizetop(); } +Image Image::SizeTopRight() { return FBImg::sizetopright(); } +Image Image::SizeLeft() { return FBImg::sizeleft(); } +Image Image::SizeRight() { return FBImg::sizeright(); } +Image Image::SizeBottomLeft() { return FBImg::sizebottomleft(); } +Image Image::SizeBottom() { return FBImg::sizebottom(); } +Image Image::SizeBottomRight() { return FBImg::sizebottomright(); } +Image Image::Hand() { return FBImg::hand(); } + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Top.cpp b/reference/Framebuffer/Top.cpp new file mode 100644 index 000000000..988950a7c --- /dev/null +++ b/reference/Framebuffer/Top.cpp @@ -0,0 +1,150 @@ +#include "Fb.h" + +#ifdef GUI_FB + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) + +void TopWindow::SyncFrameRect(const Rect& r) +{ + frame->SetClient(r); +} + +void TopWindow::DestroyFrame() +{ + if(frame->IsOpen()) + frame->DestroyWnd(); +} + +void TopWindow::GripResize() +{ + frame->GripResize(); +} + +void TopWindow::SyncSizeHints() +{ + SyncCaption0(); +} + +void TopWindow::SyncTitle0() +{ + SyncCaption0(); +} + +void TopWindow::SyncCaption0() +{ + GuiLock __; + frame->title = title.ToString(); + frame->minsize = minsize; + frame->close.Show(!noclosebox); + frame->maximize.Show(maximizebox); + frame->sizeable = sizeable; + frame->RefreshLayout(); + frame->Refresh(); + frame->close <<= Proxy(WhenClose); + frame->icon = icon; + frame->Enable(IsEnabled()); +} + +void TopWindow::State(int reason) +{ + SyncCaption0(); +} + +void TopWindow::SyncRect() +{ + frame->SyncRect(); + Rect r = frame->GetClient(); + if(r != GetRect()) { + SetRect(r); + } +} + +void TopWindow::Open(Ctrl *owner) +{ + GuiLock __; + LLOG("Open " << Upp::Name(owner)); + Rect r = GetRect(); + if(r.IsEmpty()) + SetRect(GetDefaultWindowRect()); + else + if(r.left == 0 && r.top == 0) + if(owner && center == 1) + SetRect(owner->GetRect().CenterRect(r.GetSize())); + else + if(center) + SetRect(GetWorkArea().CenterRect(r.GetSize())); + frame->SetClient(GetRect()); + frame->window = this; + frame->PopUp(owner, false, true); + PopUp(frame, false, true); + popup = false; + SetRect(frame->GetClient()); + SyncCaption0(); + if(state == MAXIMIZED) + frame->Maximize(); +} + +void TopWindow::Open() +{ + Open(GetActiveCtrl()); +} + +void TopWindow::OpenMain() +{ + Open(NULL); +} + +void TopWindow::Minimize(bool effect) +{ +// state = MINIMIZED; +} + +TopWindow& TopWindow::FullScreen(bool b) +{ + return *this; +} + +void TopWindow::Maximize(bool effect) +{ + state = MAXIMIZED; + frame->Maximize(); +} + +void TopWindow::Overlap(bool effect) +{ + GuiLock __; + state = OVERLAPPED; + frame->Overlap(); +} + +TopWindow& TopWindow::TopMost(bool b, bool stay_top) +{ + GuiLock __; + return *this; +} + +bool TopWindow::IsTopMost() const +{ + return true; +} + +void TopWindow::GuiPlatformConstruct() +{ + frame = new TopWindowFrame; +} + +void TopWindow::GuiPlatformDestruct() +{ + delete frame; +} + +void TopWindow::SerializePlacement(Stream& s, bool reminimize) +{ + GuiLock __; +} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Top.h b/reference/Framebuffer/Top.h new file mode 100644 index 000000000..2e9b12c16 --- /dev/null +++ b/reference/Framebuffer/Top.h @@ -0,0 +1,16 @@ +//$ class TopWindow { +public: + virtual void State(int reason); + +private: + TopWindowFrame *frame; + + void SyncRect(); + void SyncFrameRect(const Rect& r); + void DestroyFrame(); + + friend class Ctrl; + +public: + void GripResize(); +//$ }; diff --git a/reference/Framebuffer/TopFrame.cpp b/reference/Framebuffer/TopFrame.cpp new file mode 100644 index 000000000..36bba5dac --- /dev/null +++ b/reference/Framebuffer/TopFrame.cpp @@ -0,0 +1,259 @@ +#include "Fb.h" + +#ifdef GUI_FB + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) +#define LDUMP(x) //DDUMP(x) + +TopWindowFrame::TopWindowFrame() +{ + close.SetImage(FBImg::close()); + close.EdgeStyle(); + Add(close); + maximize.SetImage(FBImg::maximize()); + maximize.EdgeStyle(); + Add(maximize); + maximize <<= THISBACK(ToggleMaximize); + maximized = false; + sizeable = false; + holding = false; +} + +void TopWindowFrame::SyncRect() +{ + if(maximized) { + Size sz = framebuffer.GetSize(); + if(GetRect().GetSize() != sz) + SetRect(sz); + } +} + +void TopWindowFrame::Maximize() +{ + if(!maximized && maximize.IsShown()) { + maximized = true; + overlapped = GetRect(); + SetRect(framebuffer.GetSize()); + maximize.SetImage(FBImg::overlap()); + } +} + +void TopWindowFrame::Overlap() +{ + if(maximized && maximize.IsShown()) { + maximized = false; + SetRect(overlapped); + maximize.SetImage(FBImg::maximize()); + } +} + +void TopWindowFrame::ToggleMaximize() +{ + if(maximized) + Overlap(); + else + Maximize(); +} + +Rect TopWindowFrame::Margins() const +{ + return maximized ? Rect(0, 0, 0, 0) : ChMargins(FBImg::border()); +} + +void TopWindowFrame::Paint(Draw& w) +{ + Size sz = GetSize(); + Rect m = Margins(); + int c = GetStdFontCy() + 4; + ChPaintEdge(w, sz, FBImg::border()); + ChPaint(w, m.left, m.top, sz.cx - m.left - m.right, GetStdFontCy() + 4, + window->IsForeground() ? FBImg::title() : FBImg::bgtitle()); + int tx = m.left + 2; + int tcx = sz.cx - m.left - m.right - 4 - c * (close.IsShown() + maximize.IsShown()); + if(!IsNull(icon)) { + Image h = icon; + if(h.GetWidth() > c || h.GetHeight() > c) + h = Rescale(h, GetFitSize(h.GetSize(), Size(c))); + w.DrawImage(tx, m.top + 2, h); + tx += c; + tcx -= c; + } + DrawTextEllipsis(w, tx, m.top + 2, tcx, title, "..", StdFont(), SColorHighlightText()); +} + +void TopWindowFrame::Layout() +{ + Size sz = GetSize(); + Rect m = Margins(); + int c = GetStdFontCy() + 4; + int x = sz.cx - m.right; + if(close.IsShown()) + close.SetRect(x -= c, m.top, c, c); + if(maximize.IsShown()) + maximize.SetRect(x -= c, m.top, c, c); +} + +Rect TopWindowFrame::GetClient() const +{ + Rect r = GetRect(); + Rect m = Margins(); + r.left += m.left; + r.right -= m.right; + r.top += m.top; + r.bottom -= m.bottom; + r.top += GetStdFontCy() + 4; + return r; +} + +Rect TopWindowFrame::ComputeClient(Rect r) +{ + Rect m = Margins(); + r.left -= m.left; + r.right += m.right; + r.top -= m.top; + r.bottom += m.bottom; + r.top -= GetStdFontCy() + 4; + return r; +} + +void TopWindowFrame::SetClient(Rect r) +{ + SetRect(ComputeClient(r)); +} + +Point TopWindowFrame::GetDragMode(Point p) +{ + Size sz = GetSize(); + Rect m = ChMargins(FBImg::border()); + Point dir; + dir.y = p.y < m.top ? -1 : p.y > sz.cy - m.top ? 1 : 0; + dir.x = p.x < m.left ? -1 : p.x > sz.cx - m.right ? 1 : 0; + return dir; +} + +void TopWindowFrame::StartDrag() +{ + if(maximized) + return; + if(!sizeable && (dir.x || dir.y)) + return; + if(FullWindowDrag) { + SetCapture(); + startrect = GetRect(); + startpos = GetMousePos(); + } + else { + Rect r = GetScreenRect(); + RectTracker tr(*this); + tr.SetCursorImage(GetDragImage(dir)) + .MaxRect(framebuffer.GetSize()) + .MinSize(ComputeClient(minsize).GetSize()) + .Pattern(DRAWDRAGRECT_DASHED | DRAWDRAGRECT_SCREEN) + .Width(2) + .Animation(); + PaintLock++; + r = tr.Track(r, dir.x < 0 ? ALIGN_LEFT : dir.x > 0 ? ALIGN_RIGHT : ALIGN_CENTER, + dir.y < 0 ? ALIGN_TOP : dir.y > 0 ? ALIGN_BOTTOM : ALIGN_CENTER); + PaintLock--; + SetRect(r); + } + LLOG("START DRAG ---------------"); +} + +void TopWindowFrame::GripResize() +{ + dir = Point(1, 1); + StartDrag(); +} + +void TopWindowFrame::LeftDown(Point p, dword keyflags) +{ + dir = GetDragMode(p); + if(dir.x || dir.y || FullWindowDrag) + StartDrag(); + else { + SetCapture(); + holding = true; + hold.Set(GetKbdDelay() / 3, THISBACK(Hold)); + } +} + +void TopWindowFrame::CancelMode() +{ + holding = false; +} + +void TopWindowFrame::LeftUp(Point p, dword keyflags) +{ + holding = false; +} + +void TopWindowFrame::Hold() +{ + if(HasCapture()) { + if(HasMouse() && GetMouseLeft() && holding) + StartDrag(); + ReleaseCapture(); + holding = false; + } +} + +void TopWindowFrame::LeftHold(Point p, dword keyflags) +{ + if(HasCapture() || FullWindowDrag) + return; + dir = GetDragMode(p); + if(!dir.x && !dir.y) + StartDrag(); +} + +void TopWindowFrame::LeftDouble(Point p, dword keyflags) +{ + ToggleMaximize(); + IgnoreMouseUp(); +} + +void TopWindowFrame::MouseMove(Point, dword) +{ + LDUMP(HasWndCapture()); + LDUMP(HasCapture()); + if(!HasCapture() || holding) + return; + Size msz = ComputeClient(minsize).GetSize(); + Point p = GetMousePos() - startpos; + Rect r = startrect; + if(dir.x == -1) + r.left = min(r.left + p.x, startrect.right - msz.cx); + if(dir.x == 1) + r.right = max(r.right + p.x, startrect.left + msz.cx); + if(dir.y == -1) + r.top = min(r.top + p.y, startrect.bottom - msz.cy); + if(dir.y == 1) + r.bottom = max(r.bottom + p.y, startrect.top + msz.cy); + if(dir.y == 0 && dir.x == 0) + r.Offset(p); + SetRect(r); +} + +Image TopWindowFrame::GetDragImage(Point dir) +{ + static Image (*im[9])() = { + Image::SizeTopLeft, Image::SizeLeft, Image::SizeBottomLeft, + Image::SizeTop, Image::Arrow, Image::SizeBottom, + Image::SizeTopRight, Image::SizeRight, Image::SizeBottomRight, + }; + return (*im[(dir.x + 1) * 3 + (dir.y + 1)])(); +} + +Image TopWindowFrame::CursorImage(Point p, dword) +{ + if(!sizeable) + return Image::Arrow(); + return GetDragImage(HasCapture() ? dir : GetDragMode(p)); +} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Util.cpp b/reference/Framebuffer/Util.cpp new file mode 100644 index 000000000..fa47b449b --- /dev/null +++ b/reference/Framebuffer/Util.cpp @@ -0,0 +1,71 @@ +#include + +#ifdef GUI_FB + +NAMESPACE_UPP + +/* +static void sRenderLine(SystemDraw& w, int x, int y, int dx, int dy, int cx, int cy, int len, byte pattern) +{ + DLOG(len); + for(int i = 0; i < len; i++) + if((128 >> (i & 7)) & pattern) + w.DrawRect(x + dx * i, y + dy * i, cx, cy, Black); + DDUMP("~sRenderLine"); +} + +static void sRenderRect(SystemDraw& w, const Rect& r, int n, byte pattern) +{ + sRenderLine(w, r.left, r.top, 1, 0, 1, n, r.GetWidth(), pattern); + sRenderLine(w, r.left, r.bottom - 1, 1, 0, 1, n, r.GetWidth(), pattern); + sRenderLine(w, r.left, r.top, 0, 1, n, 1, r.GetHeight(), pattern); + sRenderLine(w, r.right - 1, r.top, 0, 1, n, 1, r.GetHeight(), pattern); +} + +void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, + const Rect& clip, int n, Color color, uint64 pattern) +{ + DLOG("@ DrawDragRect " << rect1 << " " << rect2 << ", clip: " << clip << ", pattern: " << pattern); + TIMING("DrawDrawRect"); + w.Clip(clip); + w.Invert(); + sRenderRect(w, rect1, n, (byte)pattern); + sRenderRect(w, rect2, n, (byte)pattern); + Ctrl::AddUpdate((rect1 | rect2).Offseted(w.GetOffset())); +// MemoryProfile mem; +// DDUMP(mem); + w.End(); +} + + + + +static uint64 sGetAniPat(uint64 src, int pos) +{ + uint64 out = 0; + pos &= 7; + for(int i = 8; --i >= 0;) { + byte sr = (byte)(src >> (8 * ((7 - i - pos) & 7))); + out = (out << 8) | (byte)((sr | (sr << 8)) >> pos); + } + return out; +} +*/ + + +/* +Size GetScreenSize() +{ + return ScreenInfo().GetPageSize(); +} +*/ + +void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, int type, int animation) +{ + q.DragRectDraw(rect1, rect2, clip, n, color, type, animation); +} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/Wnd.cpp b/reference/Framebuffer/Wnd.cpp new file mode 100644 index 000000000..3c93454c1 --- /dev/null +++ b/reference/Framebuffer/Wnd.cpp @@ -0,0 +1,764 @@ +#include "Fb.h" + +#ifdef GUI_FB + +NAMESPACE_UPP + +#define LLOG(x) //DLOG(x) +#define LDUMP(x) //DDUMP(x) +#define LDUMPC(x) //DDUMPC(x) + +ImageBuffer Ctrl::framebuffer; +Vector Ctrl::invalid; +Vector Ctrl::update; + +Ptr Ctrl::desktop; +Vector Ctrl::topctrl; + +Point Ctrl::fbCursorPos = Null; +Image Ctrl::fbCursorImage; +Point Ctrl::fbCursorBakPos = Null; +Image Ctrl::fbCursorBak; +Rect Ctrl::fbCaretRect; +Image Ctrl::fbCaretBak; +int Ctrl::fbCaretTm; +int Ctrl::renderingMode = MODE_ANTIALIASED; +bool Ctrl::fbEndSession; +bool Ctrl::FullWindowDrag; +int Ctrl::PaintLock; + +void Ctrl::SetDesktop(Ctrl& q) +{ + desktop = &q; + desktop->SetRect(framebuffer.GetSize()); + desktop->SetOpen(true); + desktop->NewTop(); + invalid.Add(framebuffer.GetSize()); +} + +void Ctrl::SetRenderingMode(int mode) +{ + renderingMode = mode; + invalid.Add(framebuffer.GetSize()); +} + +void Ctrl::InitFB() +{ + Ctrl::GlobalBackBuffer(); + Ctrl::InitTimer(); + framebuffer.Create(1, 1); + +#ifdef PLATFORM_POSIX + SetStdFont(ScreenSans(12)); //FIXME general handling +#endif + ChStdSkin(); + + static StaticRect x; + x.Color(Cyan()); + SetDesktop(x); +} + +void Ctrl::EndSession() +{ + GuiLock __; + LLOG("Ctrl::EndSession"); + fbEndSession = true; + EndSessionLoopNo = EventLoopNo; +} + +void Ctrl::ExitFB() +{ + TopWindow::ShutdownWindows(); + Ctrl::CloseTopCtrls(); + if(fbEndSession) + FBQuitSession(); +} + +void Ctrl::SetFramebufferSize(Size sz) +{ + framebuffer.Create(sz); + if(desktop) + desktop->SetRect(sz); + invalid.Add(sz); + SyncTopWindows(); +} + +int Ctrl::FindTopCtrl() const +{ + for(int i = 0; i < topctrl.GetCount(); i++) + if(this == topctrl[i]) + return i; + return -1; +} + +bool Ctrl::IsAlphaSupported() +{ + return false; +} + +bool Ctrl::IsCompositedGui() +{ + return false; +} + +Vector Ctrl::GetTopCtrls() +{ + Vector ctrl; + if(desktop) + ctrl.Add(desktop); + for(int i = 0; i < topctrl.GetCount(); i++) + if(!dynamic_cast(topctrl[i])) + ctrl.Add(topctrl[i]); + return ctrl; +} + +Ctrl *Ctrl::GetOwner() +{ + GuiLock __; + int q = FindTopCtrl(); + if(q > 0 && topctrl[q]->top) { + Ctrl *x = topctrl[q]->top->owner_window; + LDUMP(Upp::Name(x)); + return dynamic_cast(x) ? x->GetOwner() : x; + } + return NULL; +} + +Ctrl *Ctrl::GetActiveCtrl() +{ + GuiLock __; + return focusCtrl ? focusCtrl->GetTopCtrl() : NULL; +} + +// Vector Ctrl::hotkey; + +int Ctrl::RegisterSystemHotKey(dword key, Callback cb) +{ +/* ASSERT(key >= K_DELTA); + int q = hotkey.GetCount(); + for(int i = 0; i < hotkey.GetCount(); i++) + if(!hotkey[i]) { + q = i; + break; + } + hotkey.At(q) = cb; + dword mod = 0; + if(key & K_ALT) + mod |= MOD_ALT; + if(key & K_SHIFT) + mod |= MOD_SHIFT; + if(key & K_CTRL) + mod |= MOD_CONTROL; + + return RegisterHotKey(NULL, q, mod, key & 0xffff) ? q : -1;*/ + return -1; +} + +void Ctrl::UnregisterSystemHotKey(int id) +{ +/* if(id >= 0 && id < hotkey.GetCount()) { + UnregisterHotKey(NULL, id); + hotkey[id].Clear(); + }*/ +} + +bool Ctrl::IsWaitingEvent() +{ + return FBIsWaitingEvent(); +} + +void Ctrl::AddUpdate(const Rect& rect) +{ + LLOG("@AddUpdate " << rect); + AddRefreshRect(update, rect); +} + +void Ctrl::AddInvalid(const Rect& rect) +{ + LLOG("@AddInvalid " << rect); + AddRefreshRect(invalid, rect); +} + +void Ctrl::SyncTopWindows() +{ + for(int i = 0; i < topctrl.GetCount(); i++) { + TopWindow *w = dynamic_cast(topctrl[i]); + if(w) + w->SyncRect(); + } +} + +bool Ctrl::ProcessEvent(bool *quit) +{ + LLOG("@ ProcessEvent"); + ASSERT(IsMainThread()); + if(DoCall()) { + SyncTopWindows(); + return false; + } + if(!GetMouseLeft() && !GetMouseRight() && !GetMouseMiddle()) + ReleaseCtrlCapture(); + if(FBProcessEvent(quit)) { + LLOG("FBProcesEvent returned true"); + SyncTopWindows(); + DefferedFocusSync(); + SyncCaret(); + return true; + } + return false; +} + +Rect Ctrl::GetClipBound(const Vector& inv, const Rect& r) +{ + Rect ri = Null; + for(int j = 0; j < inv.GetCount(); j++) { + Rect rr = inv[j] & r; + if(!rr.IsEmpty()) + ri = IsNull(ri) ? rr : rr | ri; + } + return ri; +} + + +ViewDraw::ViewDraw(Ctrl *ctrl) +{ + if(Ctrl::invalid.GetCount()) + Ctrl::DoPaint(); + Ctrl::invalid.Clear(); + Ctrl::RemoveCursor(); + Ctrl::RemoveCaret(); + Rect r = ctrl->GetScreenView(); + Ctrl::invalid.Add(r); + Ctrl::AddUpdate(r); + for(int i = max(ctrl->GetTopCtrl()->FindTopCtrl() + 1, 0); i < Ctrl::topctrl.GetCount(); i++) { + Rect rr = Ctrl::topctrl[i]->GetScreenRect(); + ExcludeClip(rr); + Subtract(Ctrl::invalid, rr); + } + Offset(r.TopLeft()); +} + +ViewDraw::~ViewDraw() +{ + FBInitUpdate(); + Ctrl::DoUpdate(); + FBFlush(); +// Ctrl::invalid.Clear(); +} + +void Ctrl::DoUpdate() +{ + LLOG("DoUpdate"); + invalid.Clear(); + CursorSync(); + LDUMPC(update); +#if 0 + FBUpdate(framebuffer.GetSize()); +#else + for(int i = 0; i < update.GetCount(); i++) { + LDUMP(update[i]); + FBUpdate(update[i]); + } +#endif + update.Clear(); +// Sleep(1000); +} + +Vector Ctrl::GetPaintRects() +{ + Vector r; + int q = FindTopCtrl(); + r.Add(GetScreenRect()); + for(int i = max(FindTopCtrl() + 1, 0); i < topctrl.GetCount(); i++) + Subtract(r, topctrl[i]->GetScreenRect()); + return r; +} + + +void DDRect(RGBA *t, int dir, const byte *pattern, int pos, int count) +{ + while(count-- > 0) { + byte p = pattern[7 & pos++]; + t->r ^= p; + t->g ^= p; + t->b ^= p; + t += dir; + } +} + +void Ctrl::DrawLine(const Vector& clip, int x, int y, int cx, int cy, bool horz, const byte *pattern, int animation) +{ + if(cx <= 0 || cy <= 0) + return; + Vector rr = Intersection(clip, RectC(x, y, cx, cy)); + for(int i = 0; i < rr.GetCount(); i++) { + Rect r = rr[i]; + AddUpdate(r); + if(horz) + for(int y = r.top; y < r.bottom; y++) + DDRect(framebuffer[y] + r.left, 1, pattern, r.left + animation, r.GetWidth()); + else + for(int x = r.left; x < r.right; x++) + DDRect(framebuffer[r.top] + x, framebuffer.GetWidth(), pattern, r.top + animation, r.GetHeight()); + } +} + +void Ctrl::DragRectDraw0(const Vector& clip, const Rect& rect, int n, const byte *pattern, int animation) +{ + int hn = min(rect.GetHeight(), n); + int vn = min(rect.GetWidth(), n); + DrawLine(clip, rect.left, rect.top, rect.GetWidth(), hn, true, pattern, animation); + DrawLine(clip, rect.left, rect.top + hn, vn, rect.GetHeight() - hn, false, pattern, animation); + DrawLine(clip, rect.right - vn, rect.top + hn, vn, rect.GetHeight() - hn, false, pattern, animation); + DrawLine(clip, rect.left + vn, rect.bottom - hn, rect.GetWidth() - 2 * vn, hn, true, pattern, animation); +} + +void Ctrl::DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, int type, int animation) +{ + static byte solid[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + static byte normal[] = { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00 }; + static byte dashed[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; + Point p = GetScreenView().TopLeft(); + Vector pr; + if(type & DRAWDRAGRECT_SCREEN) { + pr.Add(Rect(framebuffer.GetSize())); + type &= ~DRAWDRAGRECT_SCREEN; + p = Point(0, 0); + } + else + pr = Intersection(GetPaintRects(), clip.Offseted(p)); + const byte *pattern = type == DRAWDRAGRECT_DASHED ? dashed : + type == DRAWDRAGRECT_NORMAL ? normal : solid; + RemoveCursor(); + RemoveCaret(); + DragRectDraw0(pr, rect1.Offseted(p), n, pattern, animation); + DragRectDraw0(pr, rect2.Offseted(p), n, pattern, animation); +} + +void Ctrl::DoPaint() +{ + LLOG("@ DoPaint"); + if(!PaintLock) { + bool scroll = false; + if(desktop) + desktop->SyncScroll(); + for(int i = 0; i < topctrl.GetCount(); i++) + topctrl[i]->SyncScroll(); + if((invalid.GetCount() || scroll) && desktop) { + RemoveCursor(); + RemoveCaret(); + for(int phase = 0; phase < 2; phase++) { + LLOG("DoPaint invalid phase " << phase); + LDUMPC(invalid); + SystemDraw painter; + painter.Begin(); + for(int i = 0; i < invalid.GetCount(); i++) { + painter.RectPath(invalid[i]); + AddUpdate(invalid[i]); + } + painter.Painter::Clip(); + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Rect r = topctrl[i]->GetRect(); + Rect ri = GetClipBound(invalid, r); + if(!IsNull(ri)) { + painter.Clipoff(r); + topctrl[i]->UpdateArea(painter, ri - r.TopLeft()); + painter.End(); + Subtract(invalid, r); + painter.ExcludeClip(r); + } + } + Rect ri = GetClipBound(invalid, framebuffer.GetSize()); + if(!IsNull(ri)) + desktop->UpdateArea(painter, ri); + } + } + } + DoUpdate(); +} + +void Ctrl::WndUpdate0r(const Rect& r) +{ + GuiLock __; + Rect rr = r + GetRect().TopLeft(); + bool dummy; + Vector h; + h <<= invalid; + invalid = Intersect(invalid, rr, dummy); + FBInitUpdate(); + DoPaint(); + invalid <<= h; + Subtract(invalid, rr); + FBFlush(); +} + +bool Ctrl::ProcessEvents(bool *quit) +{ + //LOGBLOCK("@ ProcessEvents"); +// MemoryCheckDebug(); + if(!ProcessEvent(quit)) + return false; + while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop())); + TimeStop tm; + TimerProc(GetTickCount()); + LLOG("TimerProc elapsed: " << tm); + SweepMkImageCache(); + FBInitUpdate(); + DoPaint(); + FBFlush(); + return true; +} + +void Ctrl::EventLoop0(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::GuiSleep0(int ms) +{ + GuiLock __; + ASSERT(IsMainThread()); + LLOG("GuiSleep"); + int level = LeaveGMutexAll(); + FBSleep(ms); + EnterGMutex(level); +} + +Rect Ctrl::GetWndScreenRect() const +{ + GuiLock __; + return GetRect(); +} + +void Ctrl::WndShow0(bool b) +{ + GuiLock __; +} + +void Ctrl::WndUpdate0() +{ + GuiLock __; +} + +bool Ctrl::IsWndOpen() const { + GuiLock __; + return FindTopCtrl() >= 0 || this == desktop; +} + +void Ctrl::SetAlpha(byte alpha) +{ + GuiLock __; +} + +Rect Ctrl::GetWorkArea() const +{ + GuiLock __; + return framebuffer.GetSize(); +} + +void Ctrl::GetWorkArea(Array& rc) +{ + GuiLock __; + Array r; + r.Add(framebuffer.GetSize()); +} + +Rect Ctrl::GetVirtualWorkArea() +{ + return framebuffer.GetSize(); +} + +Rect Ctrl::GetWorkArea(Point pt) +{ + return framebuffer.GetSize(); +} + +Rect Ctrl::GetVirtualScreenArea() +{ + GuiLock __; + return framebuffer.GetSize(); +} + +Rect Ctrl::GetPrimaryWorkArea() +{ + Rect r; + return framebuffer.GetSize(); +} + +Rect Ctrl::GetPrimaryScreenArea() +{ + return framebuffer.GetSize(); +} + +int Ctrl::GetKbdDelay() +{ + GuiLock __; + return 500; +} + +int Ctrl::GetKbdSpeed() +{ + GuiLock __; + return 1000 / 32; +} + +void Ctrl::DestroyWnd() +{ + for(int i = 0; i < topctrl.GetCount(); i++) + if(topctrl[i]->top && topctrl[i]->top->owner_window == this) + topctrl[i]->WndDestroy0(); + int q = FindTopCtrl(); + if(q >= 0) { + AddInvalid(GetRect()); + topctrl.Remove(q); + } + if(top) { + delete top; + top = NULL; + } + isopen = false; + TopWindow *win = dynamic_cast(this); + if(win) + win->DestroyFrame(); +} + +void Ctrl::WndDestroy0() +{ + DestroyWnd(); + if(topctrl.GetCount()) + topctrl.Top()->ActivateWnd(); +} + +void Ctrl::PutForeground() +{ + int q = FindTopCtrl(); + if(q >= 0) { + AddInvalid(GetRect()); + topctrl.Remove(q); + topctrl.Add(this); + } + Vector< Ptr > fw; + for(int i = 0; i < topctrl.GetCount(); i++) + if(topctrl[i] && topctrl[i]->top && topctrl[i]->top->owner_window == this && topctrl[i] != this) + fw.Add(topctrl[i]); + for(int i = 0; i < fw.GetCount(); i++) + if(fw[i]) + fw[i]->PutForeground(); +} + +void Ctrl::SetWndForeground0() +{ + GuiLock __; + ASSERT(IsOpen()); + if(IsWndForeground()) + return; + Ctrl *to = this; + while(to->top && to->top->owner_window) + to = to->top->owner_window; + to->PutForeground(); + if(this != focusCtrl) + ActivateWnd(); +} + +bool Ctrl::IsWndForeground() const +{ + GuiLock __; + bool b = false; + for(int i = 0; i < topctrl.GetCount(); i++) { + const TopWindow *tw = dynamic_cast(topctrl[i]); + if(tw) + b = tw == this; + } + return b; +} + +void Ctrl::WndEnable0(bool *b) +{ + GuiLock __; + *b = true; +} + +void Ctrl::SetWndFocus0(bool *b) +{ + GuiLock __; + *b = true; +} + +bool Ctrl::HasWndFocus() const +{ + GuiLock __; + return focusCtrl && focusCtrl->GetTopCtrl() == this; +} + +bool Ctrl::SetWndCapture() +{ + GuiLock __; + ASSERT(IsMainThread()); + return true; +} + +bool Ctrl::ReleaseWndCapture() +{ + GuiLock __; + ASSERT(IsMainThread()); + return true; +} + +bool Ctrl::HasWndCapture() const +{ + GuiLock __; + return captureCtrl && captureCtrl->GetTopCtrl() == this; +} + +void Ctrl::WndInvalidateRect0(const Rect& r) +{ + GuiLock __; + int q = FindTopCtrl(); + if(q >= 0) + AddInvalid(r + topctrl[q]->GetRect().TopLeft()); + else + AddInvalid(r); +} + +void Ctrl::WndSetPos0(const Rect& rect) +{ + GuiLock __; + TopWindow *w = dynamic_cast(this); + if(w) + w->SyncFrameRect(rect); + invalid.Add(GetRect()); + SetWndRect(rect); + invalid.Add(rect); +} + +void Ctrl::WndScrollView0(const Rect& r, int dx, int dy) +{ + GuiLock __; + if(dx == 0 && dy == 0) + return; + if(dx && dy) { + Refresh(r); + return; + } + RemoveCursor(); + RemoveCaret(); + Rect sr = r.Offseted(GetScreenRect().TopLeft()); + Vector pr = Intersection(GetPaintRects(), sr); + for(int i = 0; i < pr.GetCount(); i++) { + Rect r = pr[i]; + if(dx) { + int n = r.GetWidth() - abs(dx); + if(n > 0) { + int to = r.left + dx * (dx > 0); + int from = r.left - dx * (dx < 0); + for(int y = r.top; y < r.bottom; y++) + memmove(framebuffer[y] + to, framebuffer[y] + from, n * sizeof(RGBA)); + } + n = min(abs(dx), r.GetWidth()); + Refresh(dx < 0 ? r.left : r.right - n, r.top, n, r.GetHeight()); + } + else { + int n = r.GetHeight() - abs(dy); + for(int y = 0; y < n; y++) + memmove(framebuffer[dy < 0 ? r.top + y : r.bottom - 1 - y] + r.left, + framebuffer[dy < 0 ? r.top + y - dy : r.bottom - 1 - y - dy] + r.left, + r.GetWidth() * sizeof(RGBA)); + n = min(abs(dy), r.GetHeight()); + Refresh(r.left, dy < 0 ? r.bottom - n : r.top, r.GetWidth(), n); + } + } + + Vector ur; + for(int i = 0; i < invalid.GetCount(); i++) + if(invalid[i].Intersects(sr)) + ur.Add(invalid[i]); + for(int i = 0; i < ur.GetCount(); i++) + AddInvalid(ur[i].Offseted(dx, dy)); +} + +void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost) +{ + ASSERT(!IsChild() && !IsOpen() && FindTopCtrl() < 0); + NewTop(); + if(owner) { + Ctrl *owner_window = owner->GetTopWindow(); + if(!owner_window) + owner_window = owner->GetTopCtrl(); + ASSERT(owner_window->IsOpen()); + if(owner_window != desktop) { + owner_window->SetForeground(); + top->owner_window = owner_window; + } + } + topctrl.Add(this); + popup = isopen = true; + RefreshLayoutDeep(); + if(activate) SetFocusWnd(); + AddInvalid(GetRect()); +} + +Rect Ctrl::GetDefaultWindowRect() { + GuiLock __; + static int ii = 0; + Size sz = framebuffer.GetSize(); + Rect rect = framebuffer.GetSize(); + rect.Deflate(sz / 10); + rect.Offset(Size(GetStdFontCy(), 2 * GetStdFontCy()) * (++ii % 8)); + return rect; +} + +Vector SplitCmdLine__(const char *cmd) +{ + Vector out; + while(*cmd) + if((byte)*cmd <= ' ') + cmd++; + else if(*cmd == '\"') { + WString quoted; + while(*++cmd && (*cmd != '\"' || *++cmd == '\"')) + quoted.Cat(FromSystemCharset(String(cmd, 1)).ToWString()); + out.Add(quoted); + } + else { + const char *begin = cmd; + while((byte)*cmd > ' ') + cmd++; + out.Add(String(begin, cmd).ToWString()); + } + return out; +} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/Framebuffer/init b/reference/Framebuffer/init new file mode 100644 index 000000000..1628fe8ac --- /dev/null +++ b/reference/Framebuffer/init @@ -0,0 +1,5 @@ +#ifndef _Framebuffer_icpp_init_stub +#define _Framebuffer_icpp_init_stub +#include "Painter/init" +#include "CtrlLib/init" +#endif diff --git a/reference/LinuxFb/Keys.h b/reference/LinuxFb/Keys.h new file mode 100644 index 000000000..52801cf68 --- /dev/null +++ b/reference/LinuxFb/Keys.h @@ -0,0 +1,118 @@ +#ifndef _LinuxFb_Keys_h_ +#define _LinuxFb_Keys_h_ + +//translation of linux keycodes from MEDIUMRAM to ultimate +//thanks goes to svgalib + +K_BACK = SCANCODE_BACKSPACE + K_DELTA, +K_BACKSPACE = SCANCODE_BACKSPACE + K_DELTA, + +//handled extra in fbKEYtoK +K_TAB = 9, //SCANCODE_TAB + +K_SPACE = 32, //SCANCODE_SPACE + +K_RETURN = 13, //SCANCODE_ENTER +K_ENTER = K_RETURN, + +K_SHIFT_KEY = SCANCODE_LEFTSHIFT + K_DELTA, +K_CTRL_KEY = SCANCODE_LEFTCONTROL + K_DELTA, +K_ALT_KEY = SCANCODE_LEFTALT + K_DELTA, +K_CAPSLOCK = SCANCODE_CAPSLOCK + K_DELTA, +K_ESCAPE = SCANCODE_ESCAPE + K_DELTA, +K_PRIOR = SCANCODE_PAGEUP + K_DELTA, +K_PAGEUP = SCANCODE_PAGEUP + K_DELTA, +K_NEXT = SCANCODE_PAGEDOWN + K_DELTA, +K_PAGEDOWN = SCANCODE_PAGEDOWN + K_DELTA, +K_END = SCANCODE_END + K_DELTA, +K_HOME = SCANCODE_HOME + K_DELTA, +K_LEFT = SCANCODE_CURSORBLOCKLEFT + K_DELTA, +K_UP = SCANCODE_CURSORBLOCKUP + K_DELTA, +K_RIGHT = SCANCODE_CURSORBLOCKRIGHT + K_DELTA, +K_DOWN = SCANCODE_CURSORBLOCKDOWN + K_DELTA, +K_INSERT = SCANCODE_INSERT + K_DELTA, +K_DELETE = SCANCODE_REMOVE + K_DELTA, + +K_NUMPAD0 = SCANCODE_KEYPAD0 + K_DELTA, +K_NUMPAD1 = SCANCODE_KEYPAD1 + K_DELTA, +K_NUMPAD2 = SCANCODE_KEYPAD2 + K_DELTA, +K_NUMPAD3 = SCANCODE_KEYPAD3 + K_DELTA, +K_NUMPAD4 = SCANCODE_KEYPAD4 + K_DELTA, +K_NUMPAD5 = SCANCODE_KEYPAD5 + K_DELTA, +K_NUMPAD6 = SCANCODE_KEYPAD6 + K_DELTA, +K_NUMPAD7 = SCANCODE_KEYPAD7 + K_DELTA, +K_NUMPAD8 = SCANCODE_KEYPAD8 + K_DELTA, +K_NUMPAD9 = SCANCODE_KEYPAD9 + K_DELTA, +K_MULTIPLY = SCANCODE_KEYPADMULTIPLY + K_DELTA, +K_ADD = SCANCODE_KEYPADPLUS + K_DELTA, +K_SEPARATOR = SCANCODE_KEYPADPERIOD + K_DELTA, +K_SUBTRACT = SCANCODE_KEYPADMINUS + K_DELTA, +K_DECIMAL = SCANCODE_KEYPADPERIOD + K_DELTA, +K_DIVIDE = SCANCODE_KEYPADDIVIDE + K_DELTA, +K_SCROLL = SCANCODE_SCROLLLOCK + K_DELTA, + +K_F1 = SCANCODE_F1 + K_DELTA, +K_F2 = SCANCODE_F2 + K_DELTA, +K_F3 = SCANCODE_F3 + K_DELTA, +K_F4 = SCANCODE_F4 + K_DELTA, +K_F5 = SCANCODE_F5 + K_DELTA, +K_F6 = SCANCODE_F6 + K_DELTA, +K_F7 = SCANCODE_F7 + K_DELTA, +K_F8 = SCANCODE_F8 + K_DELTA, +K_F9 = SCANCODE_F9 + K_DELTA, +K_F10 = SCANCODE_F10 + K_DELTA, +K_F11 = SCANCODE_F11 + K_DELTA, +K_F12 = SCANCODE_F12 + K_DELTA, + +K_A = SCANCODE_A + K_DELTA, +K_B = SCANCODE_B + K_DELTA, +K_C = SCANCODE_C + K_DELTA, +K_D = SCANCODE_D + K_DELTA, +K_E = SCANCODE_E + K_DELTA, +K_F = SCANCODE_F + K_DELTA, +K_G = SCANCODE_G + K_DELTA, +K_H = SCANCODE_H + K_DELTA, +K_I = SCANCODE_I + K_DELTA, +K_J = SCANCODE_J + K_DELTA, +K_K = SCANCODE_K + K_DELTA, +K_L = SCANCODE_L + K_DELTA, +K_M = SCANCODE_M + K_DELTA, +K_N = SCANCODE_N + K_DELTA, +K_O = SCANCODE_O + K_DELTA, +K_P = SCANCODE_P + K_DELTA, +K_Q = SCANCODE_Q + K_DELTA, +K_R = SCANCODE_R + K_DELTA, +K_S = SCANCODE_S + K_DELTA, +K_T = SCANCODE_T + K_DELTA, +K_U = SCANCODE_U + K_DELTA, +K_V = SCANCODE_V + K_DELTA, +K_W = SCANCODE_W + K_DELTA, +K_X = SCANCODE_X + K_DELTA, +K_Y = SCANCODE_Y + K_DELTA, +K_Z = SCANCODE_Z + K_DELTA, +K_0 = SCANCODE_0 + K_DELTA, +K_1 = SCANCODE_1 + K_DELTA, +K_2 = SCANCODE_2 + K_DELTA, +K_3 = SCANCODE_3 + K_DELTA, +K_4 = SCANCODE_4 + K_DELTA, +K_5 = SCANCODE_5 + K_DELTA, +K_6 = SCANCODE_6 + K_DELTA, +K_7 = SCANCODE_7 + K_DELTA, +K_8 = SCANCODE_8 + K_DELTA, +K_9 = SCANCODE_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 = SCANCODE_BREAK + K_DELTA, //SCANCODE_BREAK_ALTERNATIVE + +#endif diff --git a/reference/LinuxFb/LinuxFb.h b/reference/LinuxFb/LinuxFb.h new file mode 100644 index 000000000..8cd11d0b1 --- /dev/null +++ b/reference/LinuxFb/LinuxFb.h @@ -0,0 +1,12 @@ +#ifndef _LinuxFb_LinuxFb_h_ +#define _LinuxFb_LinuxFb_h_ + +#include + +#include + +//used with thanks from svgalib +#include "vgakeyboard.h" + +#endif + diff --git a/reference/LinuxFb/LinuxFb.upp b/reference/LinuxFb/LinuxFb.upp new file mode 100644 index 000000000..bf0093282 --- /dev/null +++ b/reference/LinuxFb/LinuxFb.upp @@ -0,0 +1,13 @@ +uses + Framebuffer; + +file + vgakeyboard.h, + LinuxFb.h, + LinuxFbLocal.h, + Local.h, + Keys.h, + Win.cpp, + Proc.cpp, + keymap.cpp; + diff --git a/reference/LinuxFb/LinuxFbLocal.h b/reference/LinuxFb/LinuxFbLocal.h new file mode 100644 index 000000000..595f90c1b --- /dev/null +++ b/reference/LinuxFb/LinuxFbLocal.h @@ -0,0 +1,56 @@ +#ifndef _LinuxFb_LinuxFbLocal_h +#define _LinuxFb_LinuxFbLocal_h + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +//conflicts with upp +//#include + +NAMESPACE_UPP + +//video +extern int fbfd; +extern struct fb_var_screeninfo vinfo; +extern struct fb_fix_screeninfo finfo; +extern long int screensize; +extern char *fbp; + +//mouse +extern int mouse_fd; +extern bool mouse_imps2; +extern Point mousep; +extern dword mouseb; + +//keyb +extern int keyb_fd; +extern int cvt; +extern dword modkeys; + +int has_imps2(int fd); +int set_imps2(int fd, int b); +void dupkmap(int fd); + +void handle_mouse(); +void handle_keyboard(); +void switchvt(int ii); + +void SaveModKeys(dword keycode, dword pressed); +dword fbKEYtoK(dword keycode); +dword TranslateUnicode(dword keycode); + +END_UPP_NAMESPACE + +#endif + diff --git a/reference/LinuxFb/Local.h b/reference/LinuxFb/Local.h new file mode 100644 index 000000000..50a38a33a --- /dev/null +++ b/reference/LinuxFb/Local.h @@ -0,0 +1,23 @@ +#ifdef PLATFORM_POSIX + +void FBInit(const String& fbdevice); +void FBDeInit(); + +#define GUI_APP_MAIN \ +void GuiMainFn_();\ +\ +int main(int argc, const char **argv, const char **envptr) { \ + UPP::AppInit__(argc, argv, envptr); \ + FBInit("/dev/fb0"); \ + GuiMainFn_(); \ + UPP::Ctrl::CloseTopCtrls(); \ + FBDeInit(); \ + UPP::UsrLog("---------- About to delete this log of LinuxFB..."); \ + UPP::DeleteUsrLog(); \ + return UPP::GetExitCode(); \ +} \ +\ +void GuiMainFn_() + +#endif + diff --git a/reference/LinuxFb/Proc.cpp b/reference/LinuxFb/Proc.cpp new file mode 100644 index 000000000..5ed8b86f7 --- /dev/null +++ b/reference/LinuxFb/Proc.cpp @@ -0,0 +1,235 @@ +#include "LinuxFbLocal.h" + +NAMESPACE_UPP + +#define LLOG(x) //LOG(x) + +bool GetMouseLeft() { return mouseb & (1<<0); } +bool GetMouseRight() { return mouseb & (1<<1); } +bool GetMouseMiddle() { return mouseb & (1<<2); } + +void purgefd(int fd) +{ + fd_set fdset; + struct timeval tv; + char temp[64]; + + FD_ZERO(&fdset); + FD_SET(fd, &fdset); + tv.tv_sec = 0; + tv.tv_usec = 0; + while(select(fd+1, &fdset, 0, 0, &tv) > 0) + read(fd, temp, sizeof(temp)); +} + +int set_imps2(int fd, int b) +{ + uint8 set[] = {0xf3, 200, 0xf3, 100, 0xf3, 80}; + uint8 reset[] = {0xff}; + int retval = 0; + + if(b && write(fd, &set, sizeof(set)) != sizeof(set)) + return 0; + //SDL says not to reset, some mice wont work with it + if(!b && write(fd, &reset, sizeof (reset)) != sizeof(reset)) + return 0; + + purgefd(fd); + return 1; +} + +int has_imps2(int fd) +{ + uint8 query = 0xF2; + purgefd(fd); + if(write(fd, &query, sizeof (query)) != sizeof(query)) + return 0; + + uint8 ch = 0; + fd_set fdset; + struct timeval tv; + while(1) { + FD_ZERO(&fdset); + FD_SET(fd, &fdset); + tv.tv_sec = 1; + tv.tv_usec = 0; + if(select(fd+1, &fdset, 0, 0, &tv) < 1) break; + if(read(fd, &ch, sizeof(ch)) != sizeof(ch)) break; + switch(ch) { + case 0xFA: + case 0xAA: continue; + case 3: + case 4: return 1; + default: return 0; + } + } + return 0; +} + +dword lastbdowntime[8] = {0}; +dword isdblclick[8] = {0}; + +void handle_button(dword ct, dword mouseb, dword bm, int i, + dword df, dword rf, dword dbf, dword uf) +{ + dword m = (1<= 32 && unicode != 127) + b = Ctrl::DoKeyFB(unicode, 1); + } + + //helper quit + if(uppcode == (K_SHIFT_CTRL | K_ESCAPE)) + Ctrl::EndSession(); + } +} + +END_UPP_NAMESPACE diff --git a/reference/LinuxFb/Win.cpp b/reference/LinuxFb/Win.cpp new file mode 100644 index 000000000..0bf45ebcf --- /dev/null +++ b/reference/LinuxFb/Win.cpp @@ -0,0 +1,396 @@ +#include "LinuxFbLocal.h" + +#define LLOG(x) //LOG(x) + +NAMESPACE_UPP + +//video +int fbfd = -1; +struct fb_var_screeninfo vinfo; +struct fb_fix_screeninfo finfo; +long int screensize = 0; +char *fbp = 0; + +//mouse +int mouse_fd = -1; +bool mouse_imps2 = false; +Point mousep; +dword mouseb = 0; + +//keyb +int keyb_fd = -1; +int cvt = -1; + +// + +int oldvt; +struct termios oldtermios; +int oldmode; + +int entervt() +{ + struct termios kt; + + if(cvt > 0) { + struct vt_stat vtst; + if(ioctl(keyb_fd, VT_GETSTATE, &vtst) == 0) + oldvt = vtst.v_active; + if(ioctl(keyb_fd, VT_ACTIVATE, cvt) == 0) + ioctl(keyb_fd, VT_WAITACTIVE, cvt); + } + + if(tcgetattr(keyb_fd, &oldtermios) < 0) { + fprintf(stderr, "Error: saving terminal attributes"); + return -1; + } + + if(ioctl(keyb_fd, KDGKBMODE, &oldmode) < 0) { + fprintf(stderr, "Error: saving keyboard mode"); + return -1; + } + + kt = oldtermios; + kt.c_lflag &= ~(ICANON | ECHO | ISIG); + kt.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); + kt.c_cc[VMIN] = 0; + kt.c_cc[VTIME] = 0; + + if(tcsetattr(keyb_fd, TCSAFLUSH, &kt) < 0) { + fprintf(stderr, "Error: setting new terminal attributes"); + return -1; + } + + if(ioctl(keyb_fd, KDSKBMODE, K_MEDIUMRAW) < 0) { + fprintf(stderr, "Error: setting keyboard in mediumraw mode"); + return -1; + } + + if(ioctl(keyb_fd, KDSETMODE, KD_GRAPHICS) < 0) { + fprintf(stderr, "Error: setting keyboard in graphics mode"); + return -1; + } + + ioctl(keyb_fd, VT_LOCKSWITCH, 1); + + return 0; +} + +void switchvt_pre() +{ + ioctl(keyb_fd, KDSETMODE, KD_TEXT); + ioctl(keyb_fd, VT_UNLOCKSWITCH, 1); +} + +void switchvt_post() +{ + ioctl(keyb_fd, VT_LOCKSWITCH, 1); + ioctl(keyb_fd, KDSETMODE, KD_GRAPHICS); +} + +int switched_away = 0; + +void switchvt(int ii) +{ + struct vt_stat vtst; + + /* Figure out whether or not we're switching to a new console */ + if(ioctl(keyb_fd, VT_GETSTATE, &vtst) < 0) + { + fprintf(stderr, "Error: could not read tty state"); + return; + } + if(ii == vtst.v_active) + return; + + LLOG("trying to switch to VT " << ii); + + GuiLock __; + + switchvt_pre(); + + if(ioctl(keyb_fd, VT_ACTIVATE, ii) == 0) { + ioctl(keyb_fd, VT_WAITACTIVE, ii); + switched_away = 1; + return; + } + + switchvt_post(); +} + +void leavevt() +{ + if(oldmode < 0) return; + + if(ioctl(keyb_fd, KDSETMODE, KD_TEXT) < 0) + fprintf(stderr, "Error: setting keyboard in text mode"); + + if(ioctl(keyb_fd, KDSKBMODE, oldmode) < 0) + fprintf(stderr, "Error: restoring keyboard mode"); + + if(tcsetattr(keyb_fd, TCSAFLUSH, &oldtermios) < 0) + fprintf(stderr, "Error: setting new terminal attributes"); + + oldmode = -1; + + ioctl(keyb_fd, VT_UNLOCKSWITCH, 1); + + if(oldvt > 0) + ioctl(keyb_fd, VT_ACTIVATE, oldvt); +} + +int pend = 0; + +//returns 0 if timeout, 1 for mouse, 2 for keyboard +//common for waitforevents and sleep +int readevents(int ms) +{ + fd_set fdset; + int max_fd; + static struct timeval to; + to.tv_sec = ms / 1000; + to.tv_usec = ms % 1000 * 1000; + + if(switched_away) { + struct vt_stat vtst; + GuiLock __; + if((ioctl(keyb_fd, VT_GETSTATE, &vtst) == 0) && + vtst.v_active == cvt) { + switched_away = 0; + switchvt_post(); + } + } + + FD_ZERO(&fdset); + max_fd = 0; + if(mouse_fd >= 0) { + FD_SET(mouse_fd, &fdset); + if(max_fd < mouse_fd) max_fd = mouse_fd; + } + if(keyb_fd >= 0) { + FD_SET(keyb_fd, &fdset); + if(max_fd < keyb_fd) max_fd = keyb_fd; + } + if(select(max_fd+1, &fdset, NULL, NULL, &to) > 0) { + if(mouse_fd >= 0) { + if(FD_ISSET(mouse_fd, &fdset)) return 1; + } + if(keyb_fd >= 0) { + if(FD_ISSET(keyb_fd, &fdset)) return 2; + } + } + return 0; +} + +// + +void FBQuitSession() +{ + Ctrl::EndSession(); +} + +bool FBIsWaitingEvent() +{ + pend = readevents(0); + return pend > 0; +} + +bool FBProcessEvent(bool *quit) +{ + if(pend) + { + if(pend & 1) handle_mouse(); + if(pend & 2) handle_keyboard(); + pend = 0; //need to reset, since with repeated call is not updated here, would stuck + return true; + } + return false; +} + +void FBSleep(int ms) +{ + pend = readevents(ms); //interruptable sleep + + //keep queue busy, see SDLFb/Win.cpp for why + //this indicates that some stuff is pending, returning true in FBProcessEvent + //while nothing is actually processed + pend |= 4; +} + +void FBInitUpdate() +{ + +} + +void FBUpdate(const Rect& inv) +{ + if(switched_away) return; //backdraw + //FIXME accelerate + const ImageBuffer& framebuffer = Ctrl::GetFrameBuffer(); + memcpy(fbp, ~framebuffer, framebuffer.GetLength() * sizeof(RGBA)); +} + +void FBFlush() +{ + +} + +void FBInit(const String& fbdevice) +{ + Ctrl::InitFB(); + + fbfd = open(fbdevice, O_RDWR); + if (!fbfd) { + fprintf(stderr, "Error: cannot open framebuffer device.\n"); + exit(-1); + } + LLOG("The framebuffer device was opened successfully.\n"); + + if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) { + fprintf(stderr, "Error reading fixed information.\n"); + exit(-2); + } + + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { + fprintf(stderr, "Error reading variable information.\n"); + exit(-3); + } + RLOG("Framebuffer opened: " << fbdevice << ": " << vinfo.xres << "x" << vinfo.yres << " @ " << vinfo.bits_per_pixel); + + screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; //bytes + + fbp = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); + if((intptr_t)fbp == -1) { + fprintf(stderr, "Error: failed to map framebuffer device to memory.\n"); + exit(-4); + } + LLOG("The framebuffer device was mapped to memory successfully.\n"); + + Size fbsz(vinfo.xres, vinfo.yres); + Ctrl::SetFramebufferSize(fbsz); + + //mouse + + //mousep = fbsz / 2; + mousep.Clear(); + + static const char *mice[] = { + "/dev/input/mice" + , "/dev/usbmouse" + , "/dev/psaux" + , NULL + }; + + for(int i=0; (mouse_fd < 0) && mice[i]; ++i) { + mouse_fd = open(mice[i], O_RDWR, 0); + if(mouse_fd < 0) mouse_fd = open(mice[i], O_RDONLY, 0); + if(mouse_fd >= 0) { + set_imps2(mouse_fd, 1); + if(mouse_imps2 = has_imps2(mouse_fd)) { + LLOG("IMPS2 mouse enabled: " << mice[i]); + } + else + RLOG("no IMPS2 mouse present"); + } + else + fprintf(stderr, "Error: failed to open %s.\n", mice[i]); + } + + //keyb + + static const char* const tty0[] = { + "/dev/tty0" + , "/dev/vc/0" + , NULL + }; + static const char* const vcs[] = { + "/dev/vc/" + , "/dev/tty" + , NULL + }; + + int tfd = -1; + for(int i=0; tty0[i] && (tfd < 0); ++i) + tfd = open(tty0[i], O_WRONLY, 0); + if(tfd < 0) + tfd = dup(0); + ASSERT(tfd>=0); + + ioctl(tfd, VT_OPENQRY, &cvt); + close(tfd); + LLOG("probable new VT: " << cvt); + + if(geteuid() != 0) + { + fprintf(stderr, "Error: not running as ROOT, mouse handling pobably unavailable\n"); + } + else if(cvt > 0) { + LLOG("try to open the NEW assigned VT: " << cvt); + for(int i=0; vcs[i] && (keyb_fd < 0); ++i) { + char path[32]; + snprintf(path, 32, "%s%d", vcs[i], cvt); + keyb_fd = open(path, O_RDWR, 0); + + if(keyb_fd < 0) + continue; + + LLOG("TTY path opened: " << path); + tfd = open("/dev/tty", O_RDWR, 0); + if(tfd >= 0) { + LLOG("detaching from local stdin/out/err"); + ioctl(tfd, TIOCNOTTY, 0); + close(tfd); + } + else + fprintf(stderr, "Error: detaching from local stdin/out/err\n"); + } + } + + if(keyb_fd < 0) { + LLOG("Using already assigned VT, must not detach"); + struct vt_stat vtst; + + keyb_fd = open("/dev/tty", O_RDWR); + + if(ioctl(keyb_fd, VT_GETSTATE, &vtst) < 0) { + cvt = 0; + } else { + cvt = vtst.v_active; + } + } + + if(cvt>0) + fprintf(stdout, "started on VT %d\n", cvt); + + ASSERT(keyb_fd>=0); + oldmode = -1; + + { + int d; + if(ioctl(keyb_fd, KDGKBMODE, &d) < 0) { + close(keyb_fd); + keyb_fd = -1; + fprintf(stderr, "Error: opening a console terminal"); + exit(5); + } + } + + LLOG("tty opened: " << keyb_fd); + + dupkmap(keyb_fd); + + entervt(); + + pend = 4; //fake video expose event to cause first paint +} + +void FBDeInit() +{ + Ctrl::ExitFB(); + munmap(fbp, screensize); + close(fbfd); + + leavevt(); + close(mouse_fd); +} + +END_UPP_NAMESPACE diff --git a/reference/LinuxFb/init b/reference/LinuxFb/init new file mode 100644 index 000000000..d303230be --- /dev/null +++ b/reference/LinuxFb/init @@ -0,0 +1,4 @@ +#ifndef _LinuxFb_icpp_init_stub +#define _LinuxFb_icpp_init_stub +#include "Framebuffer/init" +#endif diff --git a/reference/LinuxFb/keymap.cpp b/reference/LinuxFb/keymap.cpp new file mode 100644 index 000000000..d96f4bdb8 --- /dev/null +++ b/reference/LinuxFb/keymap.cpp @@ -0,0 +1,162 @@ +#include "LinuxFbLocal.h" + +#define LLOG(x) //LOG(x) + +NAMESPACE_UPP + +dword modkeys = 0; + +enum KMOD { + KMOD_NONE = 0x00, + + KMOD_LSHIFT= 0x01, + KMOD_RSHIFT= 0x02, + KMOD_LCTRL = 0x04, + KMOD_RCTRL = 0x08, + KMOD_LALT = 0x10, + KMOD_RALT = 0x20, + + KMOD_CAPS = 0x40, + KMOD_NUM = 0x80, + + KMOD_CTRL = KMOD_LCTRL | KMOD_RCTRL, + KMOD_SHIFT = KMOD_LSHIFT | KMOD_RSHIFT, + KMOD_ALT = KMOD_LALT | KMOD_RALT, +}; + +#define CHFLAG(w, m, b) if(b) w |= m; else w &= ~m; +void SaveModKeys(dword keycode, dword pressed) +{ + switch(keycode) + { + case SCANCODE_LEFTSHIFT: CHFLAG(modkeys, KMOD_LSHIFT, pressed) break; + case SCANCODE_RIGHTSHIFT: CHFLAG(modkeys, KMOD_RSHIFT, pressed) break; + case SCANCODE_LEFTCONTROL: CHFLAG(modkeys, KMOD_LCTRL, pressed) break; + case SCANCODE_RIGHTCONTROL: CHFLAG(modkeys, KMOD_RCTRL, pressed) break; + case SCANCODE_LEFTALT: CHFLAG(modkeys, KMOD_LALT, pressed) break; + case SCANCODE_RIGHTALT: CHFLAG(modkeys, KMOD_RALT, pressed) break; + case SCANCODE_CAPSLOCK: CHFLAG(modkeys, KMOD_CAPS, pressed) break; + case SCANCODE_NUMLOCK: CHFLAG(modkeys, KMOD_NUM, pressed) break; + } +} + +bool GetShift() { return modkeys & KMOD_SHIFT; } +bool GetCtrl() { return modkeys & KMOD_CTRL; } +bool GetAlt() { return modkeys & KMOD_ALT; } +bool GetCapsLock() { return modkeys & KMOD_CAPS; } + +dword fbKEYtoK(dword chr) { + + if(chr == SCANCODE_TAB) + chr = K_TAB; + else + if(chr == SCANCODE_SPACE) + chr = K_SPACE; + else + if(chr == SCANCODE_ENTER) + chr = K_RETURN; + else + chr = chr + K_DELTA; + + //if the mod keys themselves, no need to have CTRL+ xxx behaviour indicator + 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; +} + +END_UPP_NAMESPACE + +//kernel defines conflict with some upp K_ enums, like K_SHIFT, K_ALT, K_CTRL +//so we separate as much as possible +#include + +NAMESPACE_UPP + +//The kernel copy of translation tables +//from a console keycode in MEDIUMRAW to unicode +static uint16 kmap[MAX_NR_KEYMAPS][NR_KEYS]; + +void dupkmap(int fd) +{ + struct kbentry entry; + + if(fd < 0) return; + + for(int m=0; m +#include + +using namespace Upp; + +#define IMAGECLASS UWordImg +#define IMAGEFILE +#include + +FileSel& UWordFs() +{ + static FileSel fs; + return fs; +} + +FileSel& PdfFs() +{ + static FileSel fs; + return fs; +} + +class UWord : public TopWindow { +public: + virtual void DragAndDrop(Point, PasteClip& d); + virtual void FrameDragAndDrop(Point, PasteClip& d); + + virtual void ShutdownWindow(); + +protected: + RichEdit editor; + MenuBar menubar; + ToolBar toolbar; + StatusBar statusbar; + String filename; + + static LRUList& lrufile() { static LRUList l; return l; } + + void Load(const String& filename); + void OpenFile(const String& fn); + void New(); + void Open(); + void Save0(); + void Save(); + void SaveAs(); + void Print(); + void Pdf(); + void About(); + void Destroy(bool shutdown); + void SetBar(); + void FileBar(Bar& bar); + void AboutMenu(Bar& bar); + void MainMenu(Bar& bar); + void MainBar(Bar& bar); + +public: + typedef UWord CLASSNAME; + + static void SerializeApp(Stream& s); + + UWord(); +}; + +void UWord::FileBar(Bar& bar) +{ + bar.Add("New", CtrlImg::new_doc(), THISBACK(New)) + .Key(K_CTRL_N) + .Help("Open new window"); + bar.Add("Open..", CtrlImg::open(), THISBACK(Open)) + .Key(K_CTRL_O) + .Help("Open existing document"); + bar.Add(editor.IsModified(), "Save", CtrlImg::save(), THISBACK(Save)) + .Key(K_CTRL_S) + .Help("Save current document"); + bar.Add("SaveAs", CtrlImg::save_as(), THISBACK(SaveAs)) + .Help("Save current document with a new name"); + bar.ToolGap(); + bar.MenuSeparator(); + bar.Add("Print..", CtrlImg::print(), THISBACK(Print)) + .Key(K_CTRL_P) + .Help("Print document"); + bar.Add("Export to PDF..", UWordImg::pdf(), THISBACK(Pdf)) + .Help("Export document to PDF file"); + if(bar.IsMenuBar()) { + if(lrufile().GetCount()) + lrufile()(bar, THISBACK(OpenFile)); + bar.Separator(); + bar.Add("Exit", THISBACK1(Destroy, false)); + } +} + +void UWord::AboutMenu(Bar& bar) +{ + bar.Add("About..", THISBACK(About)); +} + +void UWord::MainMenu(Bar& bar) +{ + bar.Add("File", THISBACK(FileBar)); + bar.Add("Window", callback(WindowsMenu)); + bar.Add("Help", THISBACK(AboutMenu)); +} + +void UWord::New() +{ + new UWord; +} + +void UWord::Load(const String& name) +{ + lrufile().NewEntry(name); + editor.SetQTF(LoadFile(name)); + filename = name; + editor.ClearModify(); + Title(filename); +} + +void UWord::OpenFile(const String& fn) +{ + if(filename.IsEmpty() && !editor.IsModified()) + Load(fn); + else + (new UWord)->Load(fn); +} + +void UWord::Open() +{ + FileSel& fs = UWordFs(); + if(fs.ExecuteOpen()) + OpenFile(fs); + else + statusbar.Temporary("Loading aborted."); +} + +void UWord::DragAndDrop(Point, PasteClip& d) +{ + if(AcceptFiles(d)) { + Vector fn = GetFiles(d); + for(int i = 0; i < fn.GetCount(); i++) + if(FileExists(fn[i])) + OpenFile(fn[i]); + } +} + +void UWord::FrameDragAndDrop(Point p, PasteClip& d) +{ + DragAndDrop(p, d); +} + +void UWord::Save0() +{ + lrufile().NewEntry(filename); + if(filename.IsEmpty()) + SaveAs(); + else + if(SaveFile(filename, editor.GetQTF())) { + statusbar.Temporary("File " + filename + " was saved."); + ClearModify(); + } + else + Exclamation("Error saving the file [* " + DeQtf(filename) + "]!"); +} + +void UWord::Save() +{ + if(!editor.IsModified()) return; + Save0(); +} + +void UWord::SaveAs() +{ + FileSel& fs = UWordFs(); + if(fs.ExecuteSaveAs()) { + filename = fs; + Title(filename); + Save0(); + } +} + +void UWord::Print() +{ + editor.Print(); +} + +void UWord::Pdf() +{ + FileSel& fs = PdfFs(); + if(!fs.ExecuteSaveAs("Output PDF file")) + return; + Size page = Size(3968, 6074); + PdfDraw pdf; + UPP::Print(pdf, editor.Get(), page); + SaveFile(~fs, pdf.Finish()); +} + +void UWord::About() +{ + PromptOK("[A5 uWord]&Using [*^www://upp.sf.net^ Ultimate`+`+] technology."); +} + +void UWord::Destroy(bool shutdown) +{ + if(editor.IsModified()) { + switch((shutdown ? PromptYesNo : PromptYesNoCancel)("Do you want to save the changes to the document?")) { + case 1: + Save(); + break; + case -1: + return; + } + } + delete this; +} + +void UWord::ShutdownWindow() +{ + Destroy(true); +} + +void UWord::MainBar(Bar& bar) +{ + FileBar(bar); + bar.Separator(); + editor.DefaultBar(bar); +} + +void UWord::SetBar() +{ + toolbar.Set(THISBACK(MainBar)); +} + +UWord::UWord() +{ + AddFrame(menubar); + AddFrame(TopSeparatorFrame()); + AddFrame(toolbar); + AddFrame(statusbar); + Add(editor.SizePos()); + menubar.Set(THISBACK(MainMenu)); + Sizeable().Zoomable(); + WhenClose = THISBACK1(Destroy, false); + menubar.WhenHelp = toolbar.WhenHelp = statusbar; + static int doc; + Title(Format("Document%d", ++doc)); + Icon(CtrlImg::File()); + editor.ClearModify(); + SetBar(); + editor.WhenRefreshBar = THISBACK(SetBar); + OpenMain(); + ActiveFocus(editor); +} + +void UWord::SerializeApp(Stream& s) +{ + int version = 1; + s / version; + s % UWordFs() + % PdfFs(); + if(version >= 1) + s % lrufile(); +} + +GUI_APP_MAIN +{ + SetLanguage(LNG_ENGLISH); + SetDefaultCharset(CHARSET_UTF8); + + UWordFs().Type("QTF files", "*.qtf") + .AllFilesType() + .DefaultExt("qtf"); + PdfFs().Type("PDF files", "*.pdf") + .AllFilesType() + .DefaultExt("pdf"); + + LoadFromFile(callback(UWord::SerializeApp)); + new UWord; + Ctrl::EventLoop(); + StoreToFile(callback(UWord::SerializeApp)); +} diff --git a/reference/UWord_FB/UWord.iml b/reference/UWord_FB/UWord.iml new file mode 100644 index 000000000..c5087e8d2 --- /dev/null +++ b/reference/UWord_FB/UWord.iml @@ -0,0 +1,10 @@ +PREMULTIPLIED +IMAGE_ID(pdf) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,157,146,129,13,192,32,8,4,29,193,1,216,67,23,113,16,55,112,186,14,226,34,212,198,154,98,85,16,63,33) +IMAGE_DATA(132,196,227,5,53,214,88,195,8,149,49,240,184,25,75,190,41,198,122,118,81,179,188,247,237,80,205,0,125,173,245,255) +IMAGE_DATA(231,222,31,6,158,206,42,251,103,210,99,206,79,238,67,120,36,61,242,193,254,145,244,240,111,214,254,131,22,151,115,206) +IMAGE_DATA(227,134,86,254,185,232,128,255,230,223,208,99,193,238,95,96,161,188,39,251,254,2,27,66,144,255,31,195,166,148,150,188) +IMAGE_DATA(38,110,182,2,234,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(160, 1) diff --git a/reference/UWord_FB/UWord_FB.upp b/reference/UWord_FB/UWord_FB.upp new file mode 100644 index 000000000..b74925032 --- /dev/null +++ b/reference/UWord_FB/UWord_FB.upp @@ -0,0 +1,29 @@ +description "Rainbow example, Framebuffer implementation of UWord\377"; + +uses + CtrlLib, + RichEdit, + PdfDraw, + plugin\jpg; + +uses(SKELETON) Skeleton; + +uses(WINALT) WinAlt; + +uses(WINFB) WinFb; + +uses(LINUXFB) LinuxFb; + +uses(SDLFB) SDLFb; + +uses(WINGL) WinGl; + +file + UWord.cpp, + UWord.iml; + +mainconfig + "" = "GUI WINFB", + "" = "GUI LINUXFB", + "" = "GUI"; + diff --git a/reference/UWord_FB/icon.ico b/reference/UWord_FB/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4012786aaf7d31ccf7f963c14aae96e0b80b9f39 GIT binary patch literal 6 NcmZQzU}Rum0000A00IC2 literal 0 HcmV?d00001 diff --git a/reference/UWord_FB/init b/reference/UWord_FB/init new file mode 100644 index 000000000..9e121d234 --- /dev/null +++ b/reference/UWord_FB/init @@ -0,0 +1,13 @@ +#ifndef _UWord_FB_icpp_init_stub +#define _UWord_FB_icpp_init_stub +#include "CtrlLib/init" +#include "RichEdit/init" +#include "PdfDraw/init" +#include "plugin\jpg/init" +#include "Skeleton/init" +#include "WinAlt/init" +#include "WinFb/init" +#include "LinuxFb/init" +#include "SDLFb/init" +#include "WinGl/init" +#endif diff --git a/reference/WinFb/Keys.h b/reference/WinFb/Keys.h new file mode 100644 index 000000000..d0ee88e90 --- /dev/null +++ b/reference/WinFb/Keys.h @@ -0,0 +1,113 @@ +#ifndef _WinFb_Keys_h_ +#define _WinFb_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/reference/WinFb/Local.h b/reference/WinFb/Local.h new file mode 100644 index 000000000..f23de235e --- /dev/null +++ b/reference/WinFb/Local.h @@ -0,0 +1,21 @@ +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::FBInit(hInstance); \ + GuiMainFn_(); \ + Ctrl::ExitFB(); \ + UPP::UsrLog("---------- About to delete this log of WinFB..."); \ + UPP::DeleteUsrLog(); \ + return UPP::GetExitCode(); \ +} \ +\ +void GuiMainFn_() diff --git a/reference/WinFb/Proc.cpp b/reference/WinFb/Proc.cpp new file mode 100644 index 000000000..163f43217 --- /dev/null +++ b/reference/WinFb/Proc.cpp @@ -0,0 +1,182 @@ +#include "WinFb.h" + +#ifdef flagWINFB + +NAMESPACE_UPP + +#define LLOG(x) //DLOG(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 fbWindowProc(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); + fbUpdate(dc, ps.rcPaint); + #if 0 + Rect r = ps.rcPaint; + ::PatBlt(dc, r.left, r.top, r.GetWidth(), r.GetHeight(), DSTINVERT); + Sleep(40); + ::PatBlt(dc, r.left, r.top, r.GetWidth(), r.GetHeight(), DSTINVERT); + #endif + 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)); +// LLOG("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: + Ctrl::SetFramebufferSize(Size(LOWORD(lParam), HIWORD(lParam))); + return 0L; + case WM_HELP: + return TRUE; + case WM_CLOSE: + Ctrl::EndSession(); + return 0L; + } + return DefWindowProc(hwnd, message, wParam, lParam); +} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/WinFb/Win.cpp b/reference/WinFb/Win.cpp new file mode 100644 index 000000000..5c2e157fe --- /dev/null +++ b/reference/WinFb/Win.cpp @@ -0,0 +1,120 @@ +#include "WinFb.h" + +#ifdef flagWINFB + +NAMESPACE_UPP + +#define LLOG(x) //DLOG(x) + +HWND fbHWND; + +bool FBIsWaitingEvent() +{ + MSG msg; + return PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); +} + +bool FBProcessEvent(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 FBQuitSession() +{ + ::PostQuitMessage(0); +} + +void FBSleep(int ms) +{ + TimeStop tm; + MsgWaitForMultipleObjects(0, NULL, FALSE, ms, QS_ALLINPUT); + LLOG("@ FBSleep " << tm.Elapsed()); +} + +void FBInit(HINSTANCE hInstance) +{ + GuiLock __; + + Ctrl::InitFB(); + + WNDCLASSW wc; + Zero(wc); + wc.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; + 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); + SetTimer(fbHWND, 1, 10, NULL); + +// Csizeinit(); +} + +void fbUpdate(HDC hdc, const Rect& r_) +{ + const ImageBuffer& framebuffer = Ctrl::GetFrameBuffer(); + Size sz = framebuffer.GetSize(); + Rect r = sz; +// Rect r = r_; + LLOG("fbUpdate " << r); + Buffer data; + data.Alloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256); + BITMAPINFOHEADER *hi = (BITMAPINFOHEADER *) ~data;; + memset(hi, 0, sizeof(BITMAPINFOHEADER)); + hi->biSize = sizeof(BITMAPINFOHEADER); + hi->biPlanes = 1; + hi->biBitCount = 32; + hi->biCompression = BI_RGB; + hi->biSizeImage = 0; + hi->biClrUsed = 0; + hi->biClrImportant = 0; + hi->biWidth = sz.cx; + hi->biHeight = -sz.cy; + ::SetDIBitsToDevice(hdc, r.left, r.top, r.GetWidth(), r.GetHeight(), + r.left, -r.top - r.GetHeight() + sz.cy, 0, sz.cy, + ~framebuffer, (BITMAPINFO *)~data, DIB_RGB_COLORS); +} + +void FBInitUpdate() +{ + +} + +void FBUpdate(const Rect& r) +{ + LLOG("FBUpdate " << r); + if(fbHWND) { + HDC hdc = GetDC(fbHWND); + fbUpdate(hdc, r); + #if 0 + ::PatBlt(hdc, r.left, r.top, r.GetWidth(), r.GetHeight(), DSTINVERT); + Sleep(40); + ::PatBlt(hdc, r.left, r.top, r.GetWidth(), r.GetHeight(), DSTINVERT); + #endif + ReleaseDC(fbHWND, hdc); + } +// ::InvalidateRect(fbHWND, NULL, false); +} + +void FBFlush() +{ + ::UpdateWindow(fbHWND); + GdiFlush(); +} + +END_UPP_NAMESPACE + +#endif diff --git a/reference/WinFb/WinFb.h b/reference/WinFb/WinFb.h new file mode 100644 index 000000000..dc134c746 --- /dev/null +++ b/reference/WinFb/WinFb.h @@ -0,0 +1,13 @@ +#ifndef _WinFb_WinFb_h +#define _WinFb_WinFb_h + +#include + +NAMESPACE_UPP + +LRESULT CALLBACK fbWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +void fbUpdate(HDC hdc, const Rect& r); + +END_UPP_NAMESPACE + +#endif diff --git a/reference/WinFb/WinFb.upp b/reference/WinFb/WinFb.upp new file mode 100644 index 000000000..cbc0fc628 --- /dev/null +++ b/reference/WinFb/WinFb.upp @@ -0,0 +1,10 @@ +uses + Framebuffer; + +file + WinFb.h, + Local.h, + Keys.h, + Win.cpp, + Proc.cpp; + diff --git a/reference/WinFb/init b/reference/WinFb/init new file mode 100644 index 000000000..0123400e9 --- /dev/null +++ b/reference/WinFb/init @@ -0,0 +1,4 @@ +#ifndef _WinFb_icpp_init_stub +#define _WinFb_icpp_init_stub +#include "Framebuffer/init" +#endif diff --git a/reference/guiplatform.h b/reference/guiplatform.h new file mode 100644 index 000000000..8f15e522b --- /dev/null +++ b/reference/guiplatform.h @@ -0,0 +1,31 @@ +#ifdef flagSKELETON +#define GUIPLATFORM_INCLUDE +#endif + +#ifdef flagWINALT +#define GUIPLATFORM_INCLUDE +#endif + +#ifdef flagWINFB +#define GUIPLATFORM_KEYCODES_INCLUDE +#define GUIPLATFORM_INCLUDE +#define FRAMEBUFFER_INCLUDE +#endif + +#ifdef flagLINUXFB +#define GUIPLATFORM_KEYCODES_INCLUDE +#define GUIPLATFORM_INCLUDE +#define FRAMEBUFFER_INCLUDE +#endif + +#ifdef flagSDLFB +#define GUIPLATFORM_KEYCODES_INCLUDE +//need to make SDL_keysym.h known before K_ enum +#define GUIPLATFORM_INCLUDE +#define FRAMEBUFFER_INCLUDE +#endif + +#ifdef flagWINGL +#define GUIPLATFORM_KEYCODES_INCLUDE +#define GUIPLATFORM_INCLUDE +#endif