.reference: Rainbow example (RM #158)

git-svn-id: svn://ultimatepp.org/upp/trunk@4176 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2011-11-16 09:44:09 +00:00
parent 452430a587
commit 1bd36aa9cc
43 changed files with 4961 additions and 0 deletions

View file

@ -0,0 +1,17 @@
class ViewDraw : public SystemDraw {
public:
ViewDraw(Ctrl *ctrl);
~ViewDraw();
};
/*
class ViewDraw : public SystemDraw {
Vector<Rect> dummy;
public:
ViewDraw(Ctrl *) : SystemDraw(Ctrl::framebuffer, dummy) { dummy.Add(Rect(10, 10, 100, 100)); }
};
*/
class DHCtrl : Ctrl {};
#include FRAMEBUFFER_INCLUDE

View file

@ -0,0 +1,21 @@
#include <CtrlLib/CtrlLib.h>
#ifdef GUI_FB
NAMESPACE_UPP
void ChSysInit()
{
CtrlImg::Reset();
CtrlsImg::Reset();
ChReset();
}
void ChHostSkin()
{
ChSysInit();
}
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,238 @@
#include "Fb.h"
#ifdef GUI_FB
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
static VectorMap<String, ClipData> 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<String, ClipData>& data, const String& text)
{
data.GetAdd("text", ClipData(text, sText));
data.GetAdd("wtext", ClipData(text, sWText));
}
void Append(VectorMap<String, ClipData>& 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<Image>();
q = s;
}
return q;
}
bool AcceptImage(PasteClip& clip)
{
GuiLock __;
return clip.Accept(ClipFmtsImage());
}
Image GetImage(PasteClip& clip)
{
GuiLock __;
Image m;
if(Accept<Image>(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<Image&>(img));
}
String GetImageClip(const Image& img, const String& fmt)
{
GuiLock __;
if(img.IsEmpty()) return Null;
if(fmt == ClipFmt<Image>())
return sImage(img);
return Null;
}
void AppendClipboardImage(const Image& img)
{
GuiLock __;
if(img.IsEmpty()) return;
AppendClipboard(ClipFmt<Image>(), 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<String> GetFiles(PasteClip& clip)
{
GuiLock __;
Vector<String> f;
return f;
}
END_UPP_NAMESPACE
#endif

View file

@ -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

View file

@ -0,0 +1,86 @@
//$ class Ctrl {
private:
static Ptr<Ctrl> desktop;
static Vector<Ctrl *> topctrl;
static ImageBuffer framebuffer;
static Vector<Rect> 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<Rect>& 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<Ctrl> t, int event, Point p, int zdelta);
Vector<Rect> GetPaintRects();
static void DrawLine(const Vector<Rect>& clip, int x, int y, int cx, int cy, bool horz,
const byte *pattern, int animation);
static void DragRectDraw0(const Vector<Rect>& 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 };
//$ };

View file

@ -0,0 +1,150 @@
#include "Fb.h"
#ifdef GUI_FB
NAMESPACE_UPP
#define LLOG(x) // DLOG(x)
// --------------------------------------------------------------------------------------------
Ptr<Ctrl> sDnDSource;
Ctrl * Ctrl::GetDragAndDropSource()
{
return sDnDSource;
}
struct DnDLoop : LocalLoop {
const VectorMap<String, ClipData> *data;
Vector<String> fmts;
Image move, copy, reject;
Ptr<Ctrl> 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> 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<Ctrl> 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<String, ClipData>& 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

View file

@ -0,0 +1,105 @@
#include <CtrlCore/CtrlCore.h>
#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

View file

@ -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<Ctrl> t, int event, Point p, int zdelta)
{
if(!t->IsEnabled())
return;
Rect rr = t->GetRect();
if((event & Ctrl::ACTION) == DOWN) {
Ptr<Ctrl> q = t;
TopWindowFrame *wf = dynamic_cast<TopWindowFrame *>(~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<Ctrl> 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

View file

@ -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)

View file

@ -0,0 +1,64 @@
#ifndef _Framebuffer_Fb_h_
#define _Framebuffer_Fb_h_
#include <CtrlLib/CtrlLib.h>
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

View file

@ -0,0 +1,141 @@
#define GUI_FB
#include <Painter/Painter.h>
NAMESPACE_UPP
#define IMAGECLASS FBImg
#define IMAGEFILE <Framebuffer/FB.iml>
#include <Draw/iml_header.h>
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<Point> 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 <Framebuffer/Ctrl.h>
#define GUIPLATFORM_PASTECLIP_DECLS \
bool dnd; \
friend struct DnDLoop; \
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE <Framebuffer/Top.h>
// 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<int> pages;
public:
Draw& GetDraw() { return nil; }
operator Draw&() { return GetDraw(); }
const Vector<int>& 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 <Framebuffer/After.h>

View file

@ -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;

358
reference/Framebuffer/Gui.h Normal file
View file

@ -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<Cloff> {
Point org;
HRGN hrgn;
Rect drawingclip;
};
Array<Cloff> 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 <ShellAPI.h>
#endif
#endif
#define GUIPLATFORM_INCLUDE_AFTER "Win32GuiA.h"

View file

@ -0,0 +1,121 @@
#include <CtrlCore/CtrlCore.h>
#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 <Framebuffer/FB.iml>
#include <Draw/iml_source.h>
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

View file

@ -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

View file

@ -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();
//$ };

View file

@ -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

View file

@ -0,0 +1,71 @@
#include <CtrlCore/CtrlCore.h>
#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

View file

@ -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<Rect> Ctrl::invalid;
Vector<Rect> Ctrl::update;
Ptr<Ctrl> Ctrl::desktop;
Vector<Ctrl *> 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 *> Ctrl::GetTopCtrls()
{
Vector<Ctrl *> ctrl;
if(desktop)
ctrl.Add(desktop);
for(int i = 0; i < topctrl.GetCount(); i++)
if(!dynamic_cast<TopWindowFrame *>(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<TopWindowFrame *>(x) ? x->GetOwner() : x;
}
return NULL;
}
Ctrl *Ctrl::GetActiveCtrl()
{
GuiLock __;
return focusCtrl ? focusCtrl->GetTopCtrl() : NULL;
}
// Vector<Callback> 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<TopWindow *>(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<Rect>& 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<Rect> Ctrl::GetPaintRects()
{
Vector<Rect> 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<Rect>& clip, int x, int y, int cx, int cy, bool horz, const byte *pattern, int animation)
{
if(cx <= 0 || cy <= 0)
return;
Vector<Rect> 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<Rect>& 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<Rect> 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<Rect> 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<Ctrl> 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<Rect>& rc)
{
GuiLock __;
Array<Rect> 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<TopWindow *>(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<Ctrl> > 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<const TopWindow *>(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<TopWindow *>(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<Rect> 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<Rect> 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<WString> SplitCmdLine__(const char *cmd)
{
Vector<WString> 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

View file

@ -0,0 +1,5 @@
#ifndef _Framebuffer_icpp_init_stub
#define _Framebuffer_icpp_init_stub
#include "Painter/init"
#include "CtrlLib/init"
#endif

118
reference/LinuxFb/Keys.h Normal file
View file

@ -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

View file

@ -0,0 +1,12 @@
#ifndef _LinuxFb_LinuxFb_h_
#define _LinuxFb_LinuxFb_h_
#include <Framebuffer/Framebuffer.h>
#include <CtrlCore/stdids.h>
//used with thanks from svgalib
#include "vgakeyboard.h"
#endif

View file

@ -0,0 +1,13 @@
uses
Framebuffer;
file
vgakeyboard.h,
LinuxFb.h,
LinuxFbLocal.h,
Local.h,
Keys.h,
Win.cpp,
Proc.cpp,
keymap.cpp;

View file

@ -0,0 +1,56 @@
#ifndef _LinuxFb_LinuxFbLocal_h
#define _LinuxFb_LinuxFbLocal_h
#include <CtrlCore/CtrlCore.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <termios.h>
#include <linux/vt.h>
#include <linux/kd.h>
//conflicts with upp
//#include <linux/keyboard.h>
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

23
reference/LinuxFb/Local.h Normal file
View file

@ -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

235
reference/LinuxFb/Proc.cpp Normal file
View file

@ -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<<i);
if(bm & m)
{
if(mouseb & m) //down
{
if(isdblclick[i] && (abs(int(ct) - int(lastbdowntime[i])) < 400))
{
Ctrl::DoMouseFB(dbf, mousep);
isdblclick[i] = 0; //reset, to go ahead sending repeats
}
else if(!isdblclick[i])
{
//Ctrl::DoMouseFB(rf, mousep);
}
else
{
lastbdowntime[i] = ct;
isdblclick[i] = 0; //prepare for repeat
Ctrl::DoMouseFB(df, mousep);
}
}
else //up
{
isdblclick[i] = 1; //indicate maybe a dblclick
Ctrl::DoMouseFB(uf, mousep);
}
}
}
void handle_mouse()
{
static int offs = 0;
static unsigned char buf[BUFSIZ];
static int rel = 1;
int i, n;
int b = 0;
int dx = 0, dy = 0, dz = 0;
int rdsize = (!mouse_imps2)?(3):(4);
n = read(mouse_fd, &buf[offs], BUFSIZ-offs);
if(n < 0) return;
n += offs;
for(i=0; i<(n-(rdsize-1)); i += rdsize) {
if((buf[i] & 0xC0) != 0) {
i -= (rdsize-1);
continue;
}
if(!mouse_imps2)
{
b = (buf[i] & 0x07); /*MRL*/
dx = (buf[i] & 0x10) ? buf[i+1] - 256 : buf[i+1];
dy = (buf[i] & 0x20) ? -(buf[i+2] - 256) : -buf[i+2];
}
else
{
b = (buf[i] & 0xC7); /*54...MRL*/
dx = (buf[i] & 0x10) ? buf[i+1] - 256 : buf[i+1];
dy = (buf[i] & 0x20) ? -(buf[i+2] - 256) : -buf[i+2];
dz = (char)buf[i+3];
}
if(dx || dy)
{
mousep.x += dx;
mousep.y += dy;
mousep.x = minmax(mousep.x, 0, int(vinfo.xres));
mousep.y = minmax(mousep.y, 0, int(vinfo.yres));
Ctrl::DoMouseFB(Ctrl::MOUSEMOVE, mousep);
}
dword bm = b ^ mouseb;
mouseb = b; //for GetMouse*
dword ct = GetTickCount();
handle_button(ct, mouseb, bm, 0, Ctrl::LEFTDOWN, Ctrl::LEFTREPEAT, Ctrl::LEFTDOUBLE, Ctrl::LEFTUP);
handle_button(ct, mouseb, bm, 1, Ctrl::RIGHTDOWN, Ctrl::RIGHTREPEAT, Ctrl::RIGHTDOUBLE, Ctrl::RIGHTUP);
handle_button(ct, mouseb, bm, 2, Ctrl::MIDDLEDOWN, Ctrl::MIDDLEREPEAT, Ctrl::MIDDLEDOUBLE, Ctrl::MIDDLEUP);
if(dz) Ctrl::DoMouseFB(Ctrl::MOUSEWHEEL, mousep, dz*120);
}
if(i < n) {
memcpy(buf, &buf[i], (n-i));
offs = (n-i);
} else
offs = 0;
}
void handle_keyboard()
{
unsigned char buf[BUFSIZ];
int n;
int keyup;
int keycode;
n = read(keyb_fd, buf, BUFSIZ);
for(int i=0; i<n; ++i) {
keycode = buf[i] & 0x7F;
keyup = (buf[i] & 0x80)?(K_KEYUP):(0);
bool b;
SaveModKeys(keycode, !keyup);
//we dont support both sides, fall back to left
switch(keycode)
{
case SCANCODE_RIGHTALT: keycode = SCANCODE_LEFTALT; break;
case SCANCODE_RIGHTSHIFT: keycode = SCANCODE_LEFTSHIFT; break;
case SCANCODE_RIGHTCONTROL: keycode = SCANCODE_LEFTCONTROL; break;
}
dword uppcode = fbKEYtoK(keycode) | keyup;
if(!keyup && uppcode == K_SPACE)
uppcode = 0; //prevent double send with unicode
//vtswitch
int vtck = uppcode & (K_DELTA | 0xFFFF);
switch(vtck) {
case K_F11:
case K_F12:
vtck -= 18; //dirty hack: after F10 doesnt come F11, see vgakeyboard.h
case K_F1:
case K_F2:
case K_F3:
case K_F4:
case K_F5:
case K_F6:
case K_F7:
case K_F8:
case K_F9:
case K_F10:
if(GetCtrl() && GetAlt()) {
int ii = vtck - K_F1 + 1;
if(!keyup)
switchvt(ii);
return;
}
}
//first, the upp keycode
if(uppcode)
b = Ctrl::DoKeyFB(uppcode, 1);
//second, the unicode translation for a keypress
if(!keyup)
{
dword unicode = TranslateUnicode(keycode);
if(unicode >= 32 && unicode != 127)
b = Ctrl::DoKeyFB(unicode, 1);
}
//helper quit
if(uppcode == (K_SHIFT_CTRL | K_ESCAPE))
Ctrl::EndSession();
}
}
END_UPP_NAMESPACE

396
reference/LinuxFb/Win.cpp Normal file
View file

@ -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

4
reference/LinuxFb/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _LinuxFb_icpp_init_stub
#define _LinuxFb_icpp_init_stub
#include "Framebuffer/init"
#endif

View file

@ -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 <linux/keyboard.h>
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<MAX_NR_KEYMAPS; ++m) {
memset(kmap[m], 0, NR_KEYS*sizeof(uint16));
for(int i=0; i<NR_KEYS; ++i) {
entry.kb_table = m; entry.kb_index = i;
if(ioctl(fd, KDGKBENT, &entry) < 0)
{
fprintf(stderr, "Error: reading keymap\n");
return;
}
if(entry.kb_value == K_ENTER ) entry.kb_value = K(KT_ASCII,13);
//correct numpad
if(KTYP(entry.kb_value) == KT_PAD) {
switch(entry.kb_value) {
case K_P0:
case K_P1:
case K_P2:
case K_P3:
case K_P4:
case K_P5:
case K_P6:
case K_P7:
case K_P8:
case K_P9:
kmap[m][i]=entry.kb_value;
kmap[m][i]+= '0';
break;
case K_PPLUS: kmap[m][i]=K(KT_ASCII,'+'); break;
case K_PMINUS: kmap[m][i]=K(KT_ASCII,'-'); break;
case K_PSTAR: kmap[m][i]=K(KT_ASCII,'*'); break;
case K_PSLASH: kmap[m][i]=K(KT_ASCII,'/'); break;
case K_PENTER: kmap[m][i]=K(KT_ASCII,'\r'); break;
case K_PCOMMA: kmap[m][i]=K(KT_ASCII,','); break;
case K_PDOT: kmap[m][i]=K(KT_ASCII,'.'); break;
default: break;
}
}
if((KTYP(entry.kb_value) == KT_LATIN)
|| (KTYP(entry.kb_value) == KT_ASCII)
|| (KTYP(entry.kb_value) == KT_LETTER)
)
kmap[m][i] = entry.kb_value;
}
}
}
dword TranslateUnicode(dword keycode)
{
int m = 0;
if(modkeys & KMOD_SHIFT) m |= (1<<KG_SHIFT);
if(modkeys & KMOD_CTRL) m |= (1<<KG_CTRL);
if(modkeys & KMOD_LALT) m |= (1<<KG_ALT);
if(modkeys & KMOD_RALT) m |= (1<<KG_ALTGR);
//CAPS changes shift meaning in both directions
if((modkeys & KMOD_CAPS)
&& KTYP(kmap[m][keycode]) == KT_LETTER
)
m ^= (1<<KG_SHIFT);
//num pad handling stays same so far
if((modkeys & KMOD_NUM)
&& KTYP(kmap[m][keycode]) == KT_PAD
)
return KVAL(kmap[m][keycode]);
else
return KVAL(kmap[m][keycode]);
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,198 @@
/* Keyboard interface for svgalib. */
/* Can be used independently. */
#ifndef VGAKEYBOARD_H
#define VGAKEYBOARD_H
#ifdef __cplusplus
extern "C"
{
#endif
#define SCANCODE_ESCAPE 1
#define SCANCODE_1 2
#define SCANCODE_2 3
#define SCANCODE_3 4
#define SCANCODE_4 5
#define SCANCODE_5 6
#define SCANCODE_6 7
#define SCANCODE_7 8
#define SCANCODE_8 9
#define SCANCODE_9 10
#define SCANCODE_0 11
#define SCANCODE_MINUS 12
#define SCANCODE_EQUAL 13
#define SCANCODE_BACKSPACE 14
#define SCANCODE_TAB 15
#define SCANCODE_Q 16
#define SCANCODE_W 17
#define SCANCODE_E 18
#define SCANCODE_R 19
#define SCANCODE_T 20
#define SCANCODE_Y 21
#define SCANCODE_U 22
#define SCANCODE_I 23
#define SCANCODE_O 24
#define SCANCODE_P 25
#define SCANCODE_BRACKET_LEFT 26
#define SCANCODE_BRACKET_RIGHT 27
#define SCANCODE_ENTER 28
#define SCANCODE_LEFTCONTROL 29
#define SCANCODE_A 30
#define SCANCODE_S 31
#define SCANCODE_D 32
#define SCANCODE_F 33
#define SCANCODE_G 34
#define SCANCODE_H 35
#define SCANCODE_J 36
#define SCANCODE_K 37
#define SCANCODE_L 38
#define SCANCODE_SEMICOLON 39
#define SCANCODE_APOSTROPHE 40
#define SCANCODE_GRAVE 41
#define SCANCODE_LEFTSHIFT 42
#define SCANCODE_BACKSLASH 43
#define SCANCODE_Z 44
#define SCANCODE_X 45
#define SCANCODE_C 46
#define SCANCODE_V 47
#define SCANCODE_B 48
#define SCANCODE_N 49
#define SCANCODE_M 50
#define SCANCODE_COMMA 51
#define SCANCODE_PERIOD 52
#define SCANCODE_SLASH 53
#define SCANCODE_RIGHTSHIFT 54
#define SCANCODE_KEYPADMULTIPLY 55
#define SCANCODE_LEFTALT 56
#define SCANCODE_SPACE 57
#define SCANCODE_CAPSLOCK 58
#define SCANCODE_F1 59
#define SCANCODE_F2 60
#define SCANCODE_F3 61
#define SCANCODE_F4 62
#define SCANCODE_F5 63
#define SCANCODE_F6 64
#define SCANCODE_F7 65
#define SCANCODE_F8 66
#define SCANCODE_F9 67
#define SCANCODE_F10 68
#define SCANCODE_NUMLOCK 69
#define SCANCODE_SCROLLLOCK 70
#define SCANCODE_KEYPAD7 71
#define SCANCODE_CURSORUPLEFT 71
#define SCANCODE_KEYPAD8 72
#define SCANCODE_CURSORUP 72
#define SCANCODE_KEYPAD9 73
#define SCANCODE_CURSORUPRIGHT 73
#define SCANCODE_KEYPADMINUS 74
#define SCANCODE_KEYPAD4 75
#define SCANCODE_CURSORLEFT 75
#define SCANCODE_KEYPAD5 76
#define SCANCODE_KEYPAD6 77
#define SCANCODE_CURSORRIGHT 77
#define SCANCODE_KEYPADPLUS 78
#define SCANCODE_KEYPAD1 79
#define SCANCODE_CURSORDOWNLEFT 79
#define SCANCODE_KEYPAD2 80
#define SCANCODE_CURSORDOWN 80
#define SCANCODE_KEYPAD3 81
#define SCANCODE_CURSORDOWNRIGHT 81
#define SCANCODE_KEYPAD0 82
#define SCANCODE_KEYPADPERIOD 83
#define SCANCODE_LESS 86
#define SCANCODE_F11 87
#define SCANCODE_F12 88
#define SCANCODE_KEYPADENTER 96
#define SCANCODE_RIGHTCONTROL 97
#define SCANCODE_CONTROL 97
#define SCANCODE_KEYPADDIVIDE 98
#define SCANCODE_PRINTSCREEN 99
#define SCANCODE_RIGHTALT 100
#define SCANCODE_BREAK 101 /* Beware: is 119 */
#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */
#define SCANCODE_HOME 102
#define SCANCODE_CURSORBLOCKUP 103 /* Cursor key block */
#define SCANCODE_PAGEUP 104
#define SCANCODE_CURSORBLOCKLEFT 105 /* Cursor key block */
#define SCANCODE_CURSORBLOCKRIGHT 106 /* Cursor key block */
#define SCANCODE_END 107
#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */
#define SCANCODE_PAGEDOWN 109
#define SCANCODE_INSERT 110
#define SCANCODE_REMOVE 111
#define SCANCODE_RIGHTWIN 126
#define SCANCODE_LEFTWIN 125
#define KEY_EVENTRELEASE 0
#define KEY_EVENTPRESS 1
#define MAX_KEYNAME_LEN 20
/* Initialize keyboard handler (brings keyboard into RAW mode). Returns */
/* 0 if succesful, -1 otherwise. */
int keyboard_init(void);
/* Similar, but returns console fd if succesful. */
int keyboard_init_return_fd(void);
/* Set event handler invoked by keyboard_update(). */
typedef void (*__keyboard_handler) (int scancode, int press);
void keyboard_seteventhandler(__keyboard_handler handler);
/* Return keyboard to normal state. */
void keyboard_close(void);
/* Read raw keyboard device and handle events. Returns 0 if no event. */
int keyboard_update(void);
/* Similar to keyboard_update, but wait for an event to happen. */
/* [This doesn't seem to work very well -- use select on fd] */
void keyboard_waitforupdate(void);
/* keyboard_init sets default event handler that keeps track of complete */
/* keyboard state: */
/* Result of keypressed. */
#define KEY_NOTPRESSED 0
#define KEY_PRESSED 1
/* Modes for translatekeys. */
#define TRANSLATE_CURSORKEYS 1 /* Map cursor block to keypad cursor. */
#define TRANSLATE_DIAGONAL 2 /* Map keypad diagonal to keypad cursor. */
#define TRANSLATE_KEYPADENTER 4 /* Map keypad enter to main enter key. */
#define DONT_CATCH_CTRLC 8 /* Disable Crtl-C check. */
/* Revert to default handler. */
void keyboard_setdefaulteventhandler(void);
/* Return pointer to buffer holding state of each key (scancode). */
/* Value 1 corresponds to key that is pressed, 0 means not pressed. */
char *keyboard_getstate(void);
/* Force keyboard state to nothing pressed (all zeroes). */
void keyboard_clearstate(void);
/* Let default handler translate cursor key block events to numeric keypad */
/* cursor key events and other translations. */
void keyboard_translatekeys(int mask);
/* Return nonzero if key is depressed. */
int keyboard_keypressed(int scancode);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,278 @@
#include <RichEdit/RichEdit.h>
#include <PdfDraw/PdfDraw.h>
using namespace Upp;
#define IMAGECLASS UWordImg
#define IMAGEFILE <UWord_FB/UWord.iml>
#include <Draw/iml.h>
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<String> 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));
}

View file

@ -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)

View file

@ -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";

BIN
reference/UWord_FB/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 B

13
reference/UWord_FB/init Normal file
View file

@ -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

113
reference/WinFb/Keys.h Normal file
View file

@ -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

21
reference/WinFb/Local.h Normal file
View file

@ -0,0 +1,21 @@
Vector<WString>& coreCmdLine__();
Vector<WString> 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_()

182
reference/WinFb/Proc.cpp Normal file
View file

@ -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<int, const char *> sWinMsg[] = {
#include <CtrlCore/Win32Msg.i>
{0, NULL}
};
#endif
LRESULT CALLBACK fbWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
GuiLock __;
#ifdef _DEBUG
Tuple2<int, const char *> *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

120
reference/WinFb/Win.cpp Normal file
View file

@ -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<byte> 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

13
reference/WinFb/WinFb.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef _WinFb_WinFb_h
#define _WinFb_WinFb_h
#include <CtrlCore/CtrlCore.h>
NAMESPACE_UPP
LRESULT CALLBACK fbWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void fbUpdate(HDC hdc, const Rect& r);
END_UPP_NAMESPACE
#endif

10
reference/WinFb/WinFb.upp Normal file
View file

@ -0,0 +1,10 @@
uses
Framebuffer;
file
WinFb.h,
Local.h,
Keys.h,
Win.cpp,
Proc.cpp;

4
reference/WinFb/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _WinFb_icpp_init_stub
#define _WinFb_icpp_init_stub
#include "Framebuffer/init"
#endif

31
reference/guiplatform.h Normal file
View file

@ -0,0 +1,31 @@
#ifdef flagSKELETON
#define GUIPLATFORM_INCLUDE <Skeleton/Skeleton.h>
#endif
#ifdef flagWINALT
#define GUIPLATFORM_INCLUDE <WinAlt/WinAlt.h>
#endif
#ifdef flagWINFB
#define GUIPLATFORM_KEYCODES_INCLUDE <WinFb/Keys.h>
#define GUIPLATFORM_INCLUDE <Framebuffer/Framebuffer.h>
#define FRAMEBUFFER_INCLUDE <WinFb/Local.h>
#endif
#ifdef flagLINUXFB
#define GUIPLATFORM_KEYCODES_INCLUDE <LinuxFb/Keys.h>
#define GUIPLATFORM_INCLUDE <LinuxFb/LinuxFb.h>
#define FRAMEBUFFER_INCLUDE <LinuxFb/Local.h>
#endif
#ifdef flagSDLFB
#define GUIPLATFORM_KEYCODES_INCLUDE <SDLFb/Keys.h>
//need to make SDL_keysym.h known before K_ enum
#define GUIPLATFORM_INCLUDE <SDLFb/SDLFb.h>
#define FRAMEBUFFER_INCLUDE <SDLFb/Local.h>
#endif
#ifdef flagWINGL
#define GUIPLATFORM_KEYCODES_INCLUDE <WinGl/Keys.h>
#define GUIPLATFORM_INCLUDE <WinGl/WinGl.h>
#endif