mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
.developing Turtle
git-svn-id: svn://ultimatepp.org/upp/trunk@6812 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
184ec3274a
commit
c364742944
15 changed files with 596 additions and 320 deletions
|
|
@ -2,11 +2,9 @@
|
||||||
private:
|
private:
|
||||||
static Ptr<Ctrl> desktop;
|
static Ptr<Ctrl> desktop;
|
||||||
static Vector<Ctrl *> topctrl;
|
static Vector<Ctrl *> topctrl;
|
||||||
static bool invalid;
|
|
||||||
|
|
||||||
static Point fbCursorPos;
|
static Point fbCursorPos;
|
||||||
static Image fbCursorImage;
|
static Image fbCursorImage;
|
||||||
static bool sdlMouseIsIn;
|
|
||||||
|
|
||||||
static Rect fbCaretRect;
|
static Rect fbCaretRect;
|
||||||
static int fbCaretTm;
|
static int fbCaretTm;
|
||||||
|
|
@ -14,8 +12,29 @@ private:
|
||||||
static bool fbEndSession;
|
static bool fbEndSession;
|
||||||
static int64 fbEventLoop;
|
static int64 fbEventLoop;
|
||||||
static int64 fbEndSessionLoop;
|
static int64 fbEndSessionLoop;
|
||||||
|
|
||||||
|
static Ctrl& Desktop();
|
||||||
|
|
||||||
|
static void TimerAndPaint();
|
||||||
|
static bool ProcessEvent(const String& event);
|
||||||
|
|
||||||
|
static bool quit;
|
||||||
|
static int main_pid;
|
||||||
|
static Vector<int> pid;
|
||||||
|
static TcpSocket socket;
|
||||||
|
static WebSocket websocket;
|
||||||
|
static int64 update_serial;
|
||||||
|
static int64 recieved_update_serial;
|
||||||
|
|
||||||
static void CursorSync();
|
static Vector<Rect> invalid;
|
||||||
|
|
||||||
|
static BiVector<String> event_queue;
|
||||||
|
static Size DesktopSize;
|
||||||
|
|
||||||
|
static void AddInvalid(const Rect& r);
|
||||||
|
void AddInvalid() { AddInvalid(GetScreenRect()); }
|
||||||
|
|
||||||
|
static void InvalidateDesktop();
|
||||||
|
|
||||||
int FindTopCtrl() const;
|
int FindTopCtrl() const;
|
||||||
static Rect GetClipBound(const Vector<Rect>& inv, const Rect& r);
|
static Rect GetClipBound(const Vector<Rect>& inv, const Rect& r);
|
||||||
|
|
@ -49,21 +68,17 @@ private:
|
||||||
|
|
||||||
void SetOpen(bool b) { isopen = b; }
|
void SetOpen(bool b) { isopen = b; }
|
||||||
|
|
||||||
protected:
|
|
||||||
static Ctrl& Desktop();
|
|
||||||
|
|
||||||
static void TimerAndPaint();
|
|
||||||
static bool ProcessEvent(const String& event);
|
|
||||||
|
|
||||||
static bool quit;
|
|
||||||
static int main_pid;
|
|
||||||
static Vector<int> pid;
|
|
||||||
static TcpSocket socket;
|
|
||||||
static WebSocket websocket;
|
|
||||||
|
|
||||||
static void Signal(int signal);
|
static void Signal(int signal);
|
||||||
static void Broadcast(int signal);
|
static void Broadcast(int signal);
|
||||||
|
|
||||||
|
static void Put8(int x) { turtle_stream.Put(x); }
|
||||||
|
static void Put16(int x);
|
||||||
|
static void Put32(int x);
|
||||||
|
static void Put(Point p);
|
||||||
|
static void Put(Size sz);
|
||||||
|
static void Put(const Rect& r);
|
||||||
|
static void Put(const String& s);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool DoKeyFB(dword key, int cnt);
|
static bool DoKeyFB(dword key, int cnt);
|
||||||
|
|
||||||
|
|
@ -71,6 +86,9 @@ public:
|
||||||
static int port;
|
static int port;
|
||||||
static bool debugmode;
|
static bool debugmode;
|
||||||
static String ip;
|
static String ip;
|
||||||
|
|
||||||
|
static Time stat_started;
|
||||||
|
static int64 stat_data_send;
|
||||||
|
|
||||||
static bool StartSession();
|
static bool StartSession();
|
||||||
static Callback WhenDisconnect;
|
static Callback WhenDisconnect;
|
||||||
|
|
@ -80,21 +98,12 @@ public:
|
||||||
static Ctrl *GetDesktop() { return desktop; }
|
static Ctrl *GetDesktop() { return desktop; }
|
||||||
static void SetDesktopSize(Size sz);
|
static void SetDesktopSize(Size sz);
|
||||||
|
|
||||||
static void Invalidate() { invalid = true; }
|
|
||||||
|
|
||||||
void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||||
Color color, int type, int animation);
|
Color color, int type, int animation);
|
||||||
|
|
||||||
static Ctrl *FindMouseTopCtrl();
|
static Ctrl *FindMouseTopCtrl();
|
||||||
|
|
||||||
static void PaintScene(SystemDraw& draw);
|
static void PaintScene(SystemDraw& draw);
|
||||||
static void PaintCaretCursor(SystemDraw& draw);
|
|
||||||
|
|
||||||
static bool SystemCursor;
|
|
||||||
|
|
||||||
enum { DRAWDRAGRECT_SCREEN = 0x8000 };
|
enum { DRAWDRAGRECT_SCREEN = 0x8000 };
|
||||||
|
|
||||||
_TODO_
|
|
||||||
static bool ProcessEventQueue(const String& event_queue);
|
|
||||||
|
|
||||||
//$ };
|
//$ };
|
||||||
|
|
|
||||||
|
|
@ -2,43 +2,10 @@
|
||||||
|
|
||||||
#ifdef GUI_TURTLE
|
#ifdef GUI_TURTLE
|
||||||
|
|
||||||
|
#define LLOG(x) // LOG(x)
|
||||||
|
|
||||||
NAMESPACE_UPP
|
NAMESPACE_UPP
|
||||||
|
|
||||||
void SystemDraw::Put16(int x)
|
|
||||||
{
|
|
||||||
Put8(LOBYTE(x));
|
|
||||||
Put8(HIBYTE(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemDraw::Put32(int x)
|
|
||||||
{
|
|
||||||
Put16(LOWORD(x));
|
|
||||||
Put16(HIWORD(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemDraw::Put(Point p)
|
|
||||||
{// TODO: Clamp?
|
|
||||||
Put16(p.x);
|
|
||||||
Put16(p.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemDraw::Put(Size sz)
|
|
||||||
{
|
|
||||||
Put((Point)sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemDraw::Put(const Rect& r)
|
|
||||||
{
|
|
||||||
Put(r.TopLeft());
|
|
||||||
Put(r.GetSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SystemDraw::Put(const String& s)
|
|
||||||
{
|
|
||||||
Put32(s.GetLength());
|
|
||||||
turtle_stream.Put(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
Index<int64> SystemDraw::img_index[3];
|
Index<int64> SystemDraw::img_index[3];
|
||||||
|
|
||||||
int SystemDraw::GetImageI(int from, Index<int64>& img_index, int maxcount, const Image& img)
|
int SystemDraw::GetImageI(int from, Index<int64>& img_index, int maxcount, const Image& img)
|
||||||
|
|
@ -54,15 +21,16 @@ int SystemDraw::GetImageI(int from, Index<int64>& img_index, int maxcount, const
|
||||||
q = Random(maxcount);
|
q = Random(maxcount);
|
||||||
img_index.Set(q, id);
|
img_index.Set(q, id);
|
||||||
}
|
}
|
||||||
Put8(SETIMAGE);
|
LLOG("SetImage " << q + from << ", size: " << img.GetLength());
|
||||||
Put16(q + from);
|
Ctrl::Put8(SETIMAGE);
|
||||||
Put(img.GetSize());
|
Ctrl::Put16(q + from);
|
||||||
|
Ctrl::Put(img.GetSize());
|
||||||
const RGBA *end = ~img + img.GetLength();
|
const RGBA *end = ~img + img.GetLength();
|
||||||
for(const RGBA *s = ~img; s < end; s++) {
|
for(const RGBA *s = ~img; s < end; s++) {
|
||||||
Put8(s->r);
|
Ctrl::Put8(s->r);
|
||||||
Put8(s->g);
|
Ctrl::Put8(s->g);
|
||||||
Put8(s->b);
|
Ctrl::Put8(s->b);
|
||||||
Put8(s->a);
|
Ctrl::Put8(s->a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return q + from;
|
return q + from;
|
||||||
|
|
@ -78,28 +46,55 @@ int SystemDraw::GetImageI(const Image& img)
|
||||||
|
|
||||||
void SystemDraw::PutImage(Point p, const Image& img, const Rect& src)
|
void SystemDraw::PutImage(Point p, const Image& img, const Rect& src)
|
||||||
{
|
{
|
||||||
|
LLOG("Ctrl::PutImage " << p << ", size: " << img.GetSize() << ", src: " << src << ", id: " << img.GetSerialId());
|
||||||
int i = GetImageI(img);
|
int i = GetImageI(img);
|
||||||
Put8(IMAGE);
|
if(Rect(img.GetSize()) == src) {
|
||||||
Put16(i);
|
Point dp = p - pos;
|
||||||
Put(p);
|
if(abs(dp.x) < 256 && abs(dp.y) < 256) {
|
||||||
Put(src);
|
Ctrl::Put8(dp.x < 0 ? dp.y < 0 ? IMAGENN : IMAGENP : dp.y < 0 ? IMAGEPN : IMAGEPP);
|
||||||
|
Ctrl::Put8(abs(dp.x));
|
||||||
|
Ctrl::Put8(abs(dp.y));
|
||||||
|
Ctrl::Put16(i);
|
||||||
|
pos = p;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ctrl::Put8(IMAGE);
|
||||||
|
Ctrl::Put16(i);
|
||||||
|
Ctrl::Put(p);
|
||||||
|
Ctrl::Put(src);
|
||||||
|
pos = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemDraw::PutRect(const Rect& r, Color color)
|
void SystemDraw::PutRect(const Rect& r, Color color)
|
||||||
{ // TODO: Support InvertColor
|
{
|
||||||
|
LLOG("Ctrl::PutRect " << r << ", color " << color);
|
||||||
|
Point p = r.TopLeft();
|
||||||
if(color == InvertColor()) {
|
if(color == InvertColor()) {
|
||||||
Put8(INVERTRECT);
|
Ctrl::Put8(INVERTRECT);
|
||||||
Put(r);
|
Ctrl::Put(r);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Put8(RECT);
|
Size sz = r.GetSize();
|
||||||
Put(r);
|
Point dp = p - pos;
|
||||||
Put8(color.GetR());
|
if(abs(dp.x) < 256 && abs(dp.y) < 256 && sz.cx < 256 && sz.cy < 256 && 0) {
|
||||||
Put8(color.GetG());
|
Ctrl::Put8(dp.x < 0 ? dp.y < 0 ? RECTNN : RECTNP : dp.y < 0 ? RECTPN : RECTPP);
|
||||||
Put8(color.GetB());
|
Ctrl::Put8(abs(dp.x));
|
||||||
|
Ctrl::Put8(abs(dp.y));
|
||||||
|
Ctrl::Put8(sz.cx);
|
||||||
|
Ctrl::Put8(sz.cy);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Ctrl::Put8(RECT);
|
||||||
|
Ctrl::Put(r);
|
||||||
|
}
|
||||||
|
Ctrl::Put8(color.GetR());
|
||||||
|
Ctrl::Put8(color.GetG());
|
||||||
|
Ctrl::Put8(color.GetB());
|
||||||
}
|
}
|
||||||
|
pos = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
END_UPP_NAMESPACE
|
END_UPP_NAMESPACE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f)
|
||||||
DrawDragFrame(w, f.rect1, f.n, dash, f.animation);
|
DrawDragFrame(w, f.rect1, f.n, dash, f.animation);
|
||||||
DrawDragFrame(w, f.rect2, f.n, dash, f.animation);
|
DrawDragFrame(w, f.rect2, f.n, dash, f.animation);
|
||||||
// w.End();
|
// w.End();
|
||||||
Ctrl::PaintCaretCursor(w);
|
// Ctrl::PaintCaretCursor(w);
|
||||||
// SDL_GL_SwapWindow(screen.win);
|
// SDL_GL_SwapWindow(screen.win);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ void FinishDragRect(Ctrl& q)
|
||||||
{
|
{
|
||||||
SystemDraw w;
|
SystemDraw w;
|
||||||
Ctrl::PaintScene(w);
|
Ctrl::PaintScene(w);
|
||||||
Ctrl::PaintCaretCursor(w);
|
// Ctrl::PaintCaretCursor(w);
|
||||||
_TODO_
|
_TODO_
|
||||||
//SDL_GL_SwapWindow(screen.win);
|
//SDL_GL_SwapWindow(screen.win);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,12 @@ NAMESPACE_UPP
|
||||||
#define LDUMP(x) // RDUMP(x)
|
#define LDUMP(x) // RDUMP(x)
|
||||||
#define LTIMING(x)
|
#define LTIMING(x)
|
||||||
|
|
||||||
|
Time Ctrl::stat_started;
|
||||||
|
int64 Ctrl::stat_data_send;
|
||||||
|
|
||||||
static Point MousePos;
|
static Point MousePos;
|
||||||
|
|
||||||
Size DesktopSize = Size(1000, 1000);
|
Size Ctrl::DesktopSize = Size(1000, 1000);
|
||||||
|
|
||||||
StaticRect& DesktopRect()
|
StaticRect& DesktopRect()
|
||||||
{
|
{
|
||||||
|
|
@ -23,24 +26,7 @@ Ctrl& Ctrl::Desktop()
|
||||||
return DesktopRect();
|
return DesktopRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
BiVector<String> event_queue;
|
BiVector<String> Ctrl::event_queue;
|
||||||
|
|
||||||
void Ctrl::TimerAndPaint()
|
|
||||||
{
|
|
||||||
LLOG("TimerAndPaint " << msecs());
|
|
||||||
TimerProc(GetTickCount());
|
|
||||||
DefferedFocusSync();
|
|
||||||
SyncCaret();
|
|
||||||
SyncTopWindows();
|
|
||||||
SweepMkImageCache();
|
|
||||||
DoPaint();
|
|
||||||
socket.Timeout(20000);
|
|
||||||
websocket.SendBinary(ZCompress(String(SystemDraw::DISABLESENDING, 1))); // Do not send events until data transfered and processed
|
|
||||||
String s = turtle_stream.FlushStream();
|
|
||||||
if(s.GetCount() > 10)
|
|
||||||
LLOG("Sending " << s.GetLength());
|
|
||||||
websocket.SendBinary(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ctrl::EndSession()
|
void Ctrl::EndSession()
|
||||||
{
|
{
|
||||||
|
|
@ -66,8 +52,20 @@ bool Ctrl::IsWaitingEvent()
|
||||||
}
|
}
|
||||||
LLOG("Recieved data " << s);
|
LLOG("Recieved data " << s);
|
||||||
StringStream ss(s);
|
StringStream ss(s);
|
||||||
while(!ss.IsEof())
|
while(!ss.IsEof()) {
|
||||||
event_queue.AddTail(ss.GetLine());
|
String s = ss.GetLine();
|
||||||
|
CParser p(s);
|
||||||
|
try {
|
||||||
|
if(p.Id("S")) {
|
||||||
|
uint32 l = p.ReadNumber();
|
||||||
|
uint32 h = p.ReadNumber();
|
||||||
|
recieved_update_serial = MAKEQWORD(l, h);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
event_queue.AddTail(s);
|
||||||
|
}
|
||||||
|
catch(CParser::Error) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
socket.Timeout(20000);
|
socket.Timeout(20000);
|
||||||
if(socket.IsError())
|
if(socket.IsError())
|
||||||
|
|
@ -148,86 +146,6 @@ void Ctrl::SetCaret(int x, int y, int cx, int cy)
|
||||||
SyncCaret();
|
SyncCaret();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ctrl::SyncCaret()
|
|
||||||
{
|
|
||||||
CursorSync();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ctrl::CursorSync()
|
|
||||||
{
|
|
||||||
// LLOG("@ CursorSync");
|
|
||||||
Point p = GetMousePos() - fbCursorImage.GetHotSpot();
|
|
||||||
Rect cr = Null;
|
|
||||||
if(focusCtrl && (((GetTickCount() - fbCaretTm) / 500) & 1) == 0)
|
|
||||||
cr = (RectC(focusCtrl->caretx, focusCtrl->carety, focusCtrl->caretcx, focusCtrl->caretcy)
|
|
||||||
+ focusCtrl->GetScreenView().TopLeft()) & focusCtrl->GetScreenView();
|
|
||||||
if(fbCursorPos != p && !SystemCursor || cr != fbCaretRect) {
|
|
||||||
fbCaretRect = cr;
|
|
||||||
fbCursorPos = p;
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ctrl::PaintScene(SystemDraw& draw)
|
|
||||||
{
|
|
||||||
if(!desktop)
|
|
||||||
return;
|
|
||||||
LLOG("@ DoPaint");
|
|
||||||
LTIMING("DoPaint paint");
|
|
||||||
draw.Init(DesktopSize);
|
|
||||||
draw.Begin();
|
|
||||||
Vector<Rect> invalid;
|
|
||||||
invalid.Add(DesktopSize); _TODO_
|
|
||||||
for(int i = topctrl.GetCount() - 1; i >= 0; i--) {
|
|
||||||
Rect r = topctrl[i]->GetRect();
|
|
||||||
Rect ri = GetClipBound(invalid, r);
|
|
||||||
if(!IsNull(ri)) {
|
|
||||||
draw.Clipoff(r);
|
|
||||||
topctrl[i]->UpdateArea(draw, ri - r.TopLeft());
|
|
||||||
draw.End();
|
|
||||||
Subtract(invalid, r);
|
|
||||||
draw.ExcludeClip(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Rect ri = GetClipBound(invalid, desktop->GetRect().GetSize());
|
|
||||||
if(!IsNull(ri))
|
|
||||||
desktop->UpdateArea(draw, ri);
|
|
||||||
draw.End();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ctrl::PaintCaretCursor(SystemDraw& draw)
|
|
||||||
{
|
|
||||||
if(!IsNull(fbCaretRect))
|
|
||||||
draw.DrawRect(fbCaretRect, InvertColor);
|
|
||||||
int64 q = fbCursorImage.GetAuxData();
|
|
||||||
if(q) {
|
|
||||||
draw.Put8(SystemDraw::STD_CURSORIMAGE);
|
|
||||||
draw.Put8(clamp((int)q, 1, 16));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
String h;
|
|
||||||
Point p = fbCursorImage.GetHotSpot();
|
|
||||||
h << "url('data:image/png;base64,"
|
|
||||||
<< Base64Encode(PNGEncoder().SaveString(fbCursorImage))
|
|
||||||
<< "') " << p.x << ' ' << p.y << ", default";
|
|
||||||
draw.Put8(SystemDraw::SETCURSORIMAGE);
|
|
||||||
draw.Put16(0); // _TODO_ Cursor cache
|
|
||||||
draw.Put(h);
|
|
||||||
draw.Put8(SystemDraw::CURSORIMAGE);
|
|
||||||
draw.Put16(0); // _TODO_ Cursor cache
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ctrl::DoPaint()
|
|
||||||
{
|
|
||||||
if(invalid && desktop) {
|
|
||||||
invalid = false;
|
|
||||||
SystemDraw draw;
|
|
||||||
PaintScene(draw);
|
|
||||||
PaintCaretCursor(draw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool keyShift;
|
bool keyShift;
|
||||||
bool keyCtrl;
|
bool keyCtrl;
|
||||||
bool keyAlt;
|
bool keyAlt;
|
||||||
|
|
@ -238,7 +156,8 @@ bool GetAlt() { return keyAlt; }
|
||||||
bool GetCapsLock() { return false; } // Impossible to implement
|
bool GetCapsLock() { return false; } // Impossible to implement
|
||||||
|
|
||||||
dword fbKEYtoK(dword chr) {
|
dword fbKEYtoK(dword chr) {
|
||||||
chr = chr + K_DELTA;
|
if(findarg(chr, 9, 0xd) < 0)
|
||||||
|
chr = chr + K_DELTA;
|
||||||
if(chr == K_ALT_KEY || chr == K_CTRL_KEY || chr == K_SHIFT_KEY)
|
if(chr == K_ALT_KEY || chr == K_CTRL_KEY || chr == K_SHIFT_KEY)
|
||||||
return chr;
|
return chr;
|
||||||
if(GetCtrl()) chr |= K_CTRL;
|
if(GetCtrl()) chr |= K_CTRL;
|
||||||
|
|
@ -409,7 +328,7 @@ bool Ctrl::ProcessEvent(const String& event)
|
||||||
int code = p.ReadInt();
|
int code = p.ReadInt();
|
||||||
int which = p.ReadInt();
|
int which = p.ReadInt();
|
||||||
ReadKeyMods(p);
|
ReadKeyMods(p);
|
||||||
if(which && !keyAlt && !keyCtrl)
|
if(which && !keyAlt && !keyCtrl && findarg(which, 9, 0xd) < 0)
|
||||||
DoKeyFB(which, 1);
|
DoKeyFB(which, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
146
rainbow/Turtle/Output.cpp
Normal file
146
rainbow/Turtle/Output.cpp
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
#include "Local.h"
|
||||||
|
|
||||||
|
#ifdef GUI_TURTLE
|
||||||
|
|
||||||
|
NAMESPACE_UPP
|
||||||
|
|
||||||
|
#define LLOG(x) // LLOG(x)
|
||||||
|
#define LDUMP(x) // RDUMP(x)
|
||||||
|
#define LTIMING(x)
|
||||||
|
|
||||||
|
void Ctrl::Put16(int x)
|
||||||
|
{
|
||||||
|
Put8(LOBYTE(x));
|
||||||
|
Put8(HIBYTE(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::Put32(int x)
|
||||||
|
{
|
||||||
|
Put16(LOWORD(x));
|
||||||
|
Put16(HIWORD(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::Put(Point p)
|
||||||
|
{// TODO: Clamp?
|
||||||
|
Put16(p.x);
|
||||||
|
Put16(p.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::Put(Size sz)
|
||||||
|
{
|
||||||
|
Put((Point)sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::Put(const Rect& r)
|
||||||
|
{
|
||||||
|
Put(r.TopLeft());
|
||||||
|
Put(r.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::Put(const String& s)
|
||||||
|
{
|
||||||
|
Put32(s.GetLength());
|
||||||
|
turtle_stream.Put(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::TimerAndPaint()
|
||||||
|
{
|
||||||
|
LLOG("TimerAndPaint " << msecs());
|
||||||
|
TimerProc(GetTickCount());
|
||||||
|
DefferedFocusSync();
|
||||||
|
SyncCaret();
|
||||||
|
SyncTopWindows();
|
||||||
|
SweepMkImageCache();
|
||||||
|
DoPaint();
|
||||||
|
socket.Timeout(20000);
|
||||||
|
if(turtle_stream.HasData()) {
|
||||||
|
websocket.SendBinary(ZCompress(String(SystemDraw::DISABLESENDING, 1))); // Do not send events until data transfered and processed
|
||||||
|
int64 x = ++update_serial;
|
||||||
|
Put8(SystemDraw::UPDATESERIAL);
|
||||||
|
Put32(LODWORD(x));
|
||||||
|
Put32(HIDWORD(x));
|
||||||
|
String s = turtle_stream.FlushStream();
|
||||||
|
stat_data_send += s.GetCount();
|
||||||
|
LLOG("Sending " << s.GetLength());
|
||||||
|
websocket.SendBinary(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::SyncCaret()
|
||||||
|
{
|
||||||
|
Rect cr = Null;
|
||||||
|
if(focusCtrl)
|
||||||
|
cr = (RectC(focusCtrl->caretx, focusCtrl->carety, focusCtrl->caretcx, focusCtrl->caretcy)
|
||||||
|
+ focusCtrl->GetScreenView().TopLeft()) & focusCtrl->GetScreenView();
|
||||||
|
if(cr != fbCaretRect) { // TODO: SetCaret should perhaps be called on Ctrl::SetCaret
|
||||||
|
Put8(SystemDraw::SETCARET);
|
||||||
|
Put(cr);
|
||||||
|
fbCaretRect = cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::PaintScene(SystemDraw& draw)
|
||||||
|
{
|
||||||
|
if(!desktop)
|
||||||
|
return;
|
||||||
|
LLOG("@ DoPaint");
|
||||||
|
LTIMING("DoPaint paint");
|
||||||
|
draw.Init(invalid, DesktopSize.cy);
|
||||||
|
// draw.Init(DesktopSize);
|
||||||
|
draw.Begin();
|
||||||
|
for(int i = topctrl.GetCount() - 1; i >= 0; i--) {
|
||||||
|
Rect r = topctrl[i]->GetRect();
|
||||||
|
Rect ri = GetClipBound(invalid, r);
|
||||||
|
LLOG(i << " Window " << r << ", bound " << ri);
|
||||||
|
if(!IsNull(ri)) {
|
||||||
|
draw.Clipoff(r);
|
||||||
|
topctrl[i]->UpdateArea(draw, ri - r.TopLeft());
|
||||||
|
draw.End();
|
||||||
|
draw.ExcludeClip(r);
|
||||||
|
Subtract(invalid, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rect ri = GetClipBound(invalid, DesktopSize);
|
||||||
|
if(!IsNull(ri))
|
||||||
|
desktop->UpdateArea(draw, ri);
|
||||||
|
invalid.Clear();
|
||||||
|
draw.End();
|
||||||
|
|
||||||
|
// DDUMP(turtle_stream.FlushStream().GetCount()); abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::DoPaint()
|
||||||
|
{
|
||||||
|
if(recieved_update_serial >= update_serial - 1) { // Prevent overloading of transfer
|
||||||
|
if(invalid.GetCount() && desktop) {
|
||||||
|
SystemDraw draw;
|
||||||
|
PaintScene(draw);
|
||||||
|
}
|
||||||
|
static int64 prev_cursor_id = Null;
|
||||||
|
int64 id = fbCursorImage.GetSerialId();
|
||||||
|
if(id != prev_cursor_id) {
|
||||||
|
prev_cursor_id = id;
|
||||||
|
int64 q = fbCursorImage.GetAuxData();
|
||||||
|
if(q) {
|
||||||
|
Put8(SystemDraw::STD_CURSORIMAGE);
|
||||||
|
Put8(clamp((int)q, 1, 16));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String h;
|
||||||
|
Point p = fbCursorImage.GetHotSpot();
|
||||||
|
h << "url('data:image/png;base64,"
|
||||||
|
<< Base64Encode(PNGEncoder().SaveString(fbCursorImage))
|
||||||
|
<< "') " << p.x << ' ' << p.y << ", default";
|
||||||
|
Put8(SystemDraw::SETCURSORIMAGE);
|
||||||
|
Put16(0); // _TODO_ Cursor cache
|
||||||
|
Put(h);
|
||||||
|
Put8(SystemDraw::CURSORIMAGE);
|
||||||
|
Put16(0); // _TODO_ Cursor cache
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END_UPP_NAMESPACE
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -25,35 +25,6 @@ void Ctrl::Broadcast(int signal) {
|
||||||
kill(pid[i], signal);
|
kill(pid[i], signal);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ctrl::Signal(int signal)
|
|
||||||
{
|
|
||||||
#ifdef PLATFORM_POSIX
|
|
||||||
int i = 0;
|
|
||||||
while(i < pid.GetCount())
|
|
||||||
if(pid[i] && waitpid(pid[i], 0, WNOHANG | WUNTRACED) > 0)
|
|
||||||
pid.Remove(i);
|
|
||||||
else
|
|
||||||
i++;
|
|
||||||
switch(signal) {
|
|
||||||
case SIGTERM:
|
|
||||||
case SIGHUP:
|
|
||||||
quit = true;
|
|
||||||
Broadcast(signal);
|
|
||||||
break;
|
|
||||||
case SIGINT:
|
|
||||||
Broadcast(signal);
|
|
||||||
exit(0);
|
|
||||||
break;
|
|
||||||
case SIGALRM:
|
|
||||||
if(getpid() != main_pid) {
|
|
||||||
// "Timeout - session stoped"
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
String Ctrl::host = "localhost";
|
String Ctrl::host = "localhost";
|
||||||
int Ctrl::port = 8088;
|
int Ctrl::port = 8088;
|
||||||
|
|
@ -61,21 +32,14 @@ bool Ctrl::debugmode;
|
||||||
String Ctrl::ip = "0.0.0.0";
|
String Ctrl::ip = "0.0.0.0";
|
||||||
TcpSocket Ctrl::socket;
|
TcpSocket Ctrl::socket;
|
||||||
WebSocket Ctrl::websocket;
|
WebSocket Ctrl::websocket;
|
||||||
|
int64 Ctrl::update_serial;
|
||||||
|
int64 Ctrl::recieved_update_serial;
|
||||||
|
|
||||||
bool Ctrl::StartSession()
|
bool Ctrl::StartSession()
|
||||||
{
|
{
|
||||||
LLOG("Connect");
|
LLOG("Connect");
|
||||||
|
|
||||||
#ifdef PLATFORM_POSIX
|
#ifdef PLATFORM_POSIX
|
||||||
struct sigaction sa;
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
|
||||||
sa.sa_handler = Signal;
|
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
|
||||||
sigaction(SIGINT, &sa, NULL);
|
|
||||||
sigaction(SIGHUP, &sa, NULL);
|
|
||||||
sigaction(SIGALRM, &sa, NULL);
|
|
||||||
sigaction(SIGCHLD, &sa, NULL);
|
|
||||||
|
|
||||||
main_pid = getpid();
|
main_pid = getpid();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -99,11 +63,19 @@ bool Ctrl::StartSession()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RLOG("Starting to listen on 8088");
|
RLOG("Starting to listen on 8088, pid: " << getpid());
|
||||||
socket.Timeout(2000); // TODO: Not quite ideal way to make quit work..
|
socket.Timeout(2000); // TODO: Not quite ideal way to make quit work..
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(quit)
|
if(quit)
|
||||||
return false;
|
return false;
|
||||||
|
#ifdef PLATFORM_POSIX
|
||||||
|
int i = 0;
|
||||||
|
while(i < pid.GetCount())
|
||||||
|
if(pid[i] && waitpid(pid[i], 0, WNOHANG | WUNTRACED) > 0)
|
||||||
|
pid.Remove(i);
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
#endif
|
||||||
if(server.IsError())
|
if(server.IsError())
|
||||||
server.ClearError();
|
server.ClearError();
|
||||||
if(socket.Accept(server)) {
|
if(socket.Accept(server)) {
|
||||||
|
|
@ -112,8 +84,10 @@ bool Ctrl::StartSession()
|
||||||
RLOG("Accepted, header read");
|
RLOG("Accepted, header read");
|
||||||
if(websocket.WebAccept(socket, http)) { // TODO: Connection limit, info
|
if(websocket.WebAccept(socket, http)) { // TODO: Connection limit, info
|
||||||
#ifdef PLATFORM_POSIX
|
#ifdef PLATFORM_POSIX
|
||||||
|
if(debugmode)
|
||||||
|
break;
|
||||||
int newpid = fork();
|
int newpid = fork();
|
||||||
if(debugmode || newpid == 0)
|
if(newpid == 0)
|
||||||
break;
|
break;
|
||||||
else {
|
else {
|
||||||
pid.Add(newpid);
|
pid.Add(newpid);
|
||||||
|
|
@ -132,7 +106,7 @@ bool Ctrl::StartSession()
|
||||||
socket.Close();
|
socket.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RLOG("Connection established with " << socket.GetPeerAddr());
|
RLOG("Connection established with " << socket.GetPeerAddr() << ", pid: " << getpid());
|
||||||
server.Close();
|
server.Close();
|
||||||
if(socket.IsError())
|
if(socket.IsError())
|
||||||
RLOG("CONNECT ERROR: " << socket.GetErrorDesc());
|
RLOG("CONNECT ERROR: " << socket.GetErrorDesc());
|
||||||
|
|
@ -145,12 +119,18 @@ bool Ctrl::StartSession()
|
||||||
#endif
|
#endif
|
||||||
ChStdSkin();
|
ChStdSkin();
|
||||||
|
|
||||||
extern Size DesktopSize;
|
|
||||||
extern StaticRect& DesktopRect();
|
extern StaticRect& DesktopRect();
|
||||||
|
|
||||||
DesktopRect().Color(Cyan());
|
DesktopRect().Color(Cyan());
|
||||||
DesktopRect().SetRect(0, 0, DesktopSize.cx, DesktopSize.cy);
|
DesktopRect().SetRect(0, 0, DesktopSize.cx, DesktopSize.cy);
|
||||||
SetDesktop(Desktop());
|
SetDesktop(Desktop());
|
||||||
|
|
||||||
|
stat_started = GetSysTime();
|
||||||
|
|
||||||
|
while(!IsWaitingEvent())
|
||||||
|
GuiSleep(10);
|
||||||
|
|
||||||
|
ProcessEvents();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,13 @@ void TurtleStream::Reset()
|
||||||
{
|
{
|
||||||
zlib.Clear();
|
zlib.Clear();
|
||||||
zlib.Compress();
|
zlib.Compress();
|
||||||
|
hasdata = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TurtleStream::Out(const void *data, dword size)
|
void TurtleStream::Out(const void *data, dword size)
|
||||||
{
|
{
|
||||||
zlib.Put(data, (int)size);
|
zlib.Put(data, (int)size);
|
||||||
|
hasdata = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String TurtleStream::FlushStream()
|
String TurtleStream::FlushStream()
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Zlib zlib;
|
Zlib zlib;
|
||||||
|
bool hasdata;
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
String FlushStream();
|
String FlushStream();
|
||||||
|
bool HasData() const { return hasdata; }
|
||||||
|
|
||||||
TurtleStream() { Reset(); }
|
TurtleStream() { Reset(); }
|
||||||
};
|
};
|
||||||
|
|
@ -46,24 +48,33 @@ public:
|
||||||
SETCURSORIMAGE = 5,
|
SETCURSORIMAGE = 5,
|
||||||
CURSORIMAGE = 6,
|
CURSORIMAGE = 6,
|
||||||
DISABLESENDING = 7,
|
DISABLESENDING = 7,
|
||||||
|
UPDATESERIAL = 8,
|
||||||
|
|
||||||
|
IMAGEPP = 9,
|
||||||
|
IMAGENP = 10,
|
||||||
|
IMAGEPN = 11,
|
||||||
|
IMAGENN = 12,
|
||||||
|
|
||||||
|
RECTPP = 13,
|
||||||
|
RECTNP = 14,
|
||||||
|
RECTPN = 15,
|
||||||
|
RECTNN = 16,
|
||||||
|
|
||||||
|
SETCARET = 17,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Index<int64> img_index[3];
|
static Index<int64> img_index[3];
|
||||||
|
|
||||||
|
Point pos;
|
||||||
|
|
||||||
int GetImageI(int from, Index<int64>& img_index, int maxcount, const Image& img);
|
int GetImageI(int from, Index<int64>& img_index, int maxcount, const Image& img);
|
||||||
int GetImageI(const Image& img);
|
int GetImageI(const Image& img);
|
||||||
static void ResetI() { for(int i = 0; i < 3; i++) img_index[i].Clear(); }
|
static void ResetI() { for(int i = 0; i < 3; i++) img_index[i].Clear(); }
|
||||||
|
|
||||||
void Put8(int x) { turtle_stream.Put(x); }
|
|
||||||
void Put16(int x);
|
|
||||||
void Put32(int x);
|
|
||||||
void Put(Point p);
|
|
||||||
void Put(Size sz);
|
|
||||||
void Put(const Rect& r);
|
|
||||||
void Put(const String& s);
|
|
||||||
|
|
||||||
bool CanSetSurface() { return false; }
|
bool CanSetSurface() { return false; }
|
||||||
static void Flush() {}
|
static void Flush() {}
|
||||||
|
|
||||||
|
SystemDraw() { pos = Point(0, 0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BackDraw__ : public SystemDraw {
|
struct BackDraw__ : public SystemDraw {
|
||||||
|
|
@ -114,7 +125,7 @@ class TopWindowFrame;
|
||||||
|
|
||||||
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE <Turtle/Top.h>
|
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE <Turtle/Top.h>
|
||||||
|
|
||||||
class PrinterJob { // Dummy only...
|
class PrinterJob { // _TODO_
|
||||||
NilDraw nil;
|
NilDraw nil;
|
||||||
Vector<int> pages;
|
Vector<int> pages;
|
||||||
|
|
||||||
|
|
@ -137,11 +148,6 @@ public:
|
||||||
~PrinterJob() {}
|
~PrinterJob() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void USDLSetup(dword flags);
|
|
||||||
|
|
||||||
|
|
||||||
void InitTelpp();
|
|
||||||
|
|
||||||
END_UPP_NAMESPACE
|
END_UPP_NAMESPACE
|
||||||
|
|
||||||
#define GUIPLATFORM_INCLUDE_AFTER <Turtle/After.h>
|
#define GUIPLATFORM_INCLUDE_AFTER <Turtle/After.h>
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ U.prototype.k=function(){var b=this.input,d,a;d=this.q.k();this.a=this.q.a;if(th
|
||||||
|
|
||||||
function Log(msg)
|
function Log(msg)
|
||||||
{
|
{
|
||||||
// if (window.console && console.log)
|
if (window.console && console.log)
|
||||||
// console.log(msg); //for firebug
|
console.log(msg); //for firebug
|
||||||
}
|
}
|
||||||
|
|
||||||
function Char(p, ch)
|
function Char(p, ch)
|
||||||
|
|
@ -83,19 +83,94 @@ function GetString(p)
|
||||||
|
|
||||||
var SendingEnabled = true;
|
var SendingEnabled = true;
|
||||||
|
|
||||||
|
var posx, posy;
|
||||||
|
var ctx;
|
||||||
|
|
||||||
|
var caretx = 0, carety = 0, caretcx = 0, caretcy = 0, caretshown = false;
|
||||||
|
var caretTimerID;
|
||||||
|
|
||||||
|
function InvertRect(x, y, cx, cy)
|
||||||
|
{
|
||||||
|
if(cx <= 0 || cy <= 0)
|
||||||
|
return;
|
||||||
|
var imageData = ctx.getImageData(x, y, cx, cy);
|
||||||
|
var data = imageData.data;
|
||||||
|
for(var i = 0; i < data.length; i += 4) {
|
||||||
|
data[i] = 255 - data[i];
|
||||||
|
data[i + 1] = 255 - data[i + 1];
|
||||||
|
data[i + 2] = 255 - data[i + 2];
|
||||||
|
}
|
||||||
|
ctx.putImageData(imageData, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function InvertCaret()
|
||||||
|
{
|
||||||
|
// Log("InvertCaret " + caretx + " " + carety + " " + caretcx + " " + caretcy);
|
||||||
|
if(caretcx >= 0 || caretcy >= 0)
|
||||||
|
InvertRect(caretx, carety, caretcx, caretcy);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ClearCaretTimer()
|
||||||
|
{
|
||||||
|
if(caretTimerID != undefined)
|
||||||
|
clearTimeout(caretTimerID);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CaretTimer()
|
||||||
|
{
|
||||||
|
ClearCaretTimer();
|
||||||
|
caretTimerID = setTimeout(DoCaret, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DoCaret()
|
||||||
|
{
|
||||||
|
if(caretcx || caretcy) {
|
||||||
|
InvertCaret();
|
||||||
|
caretshown = !caretshown;
|
||||||
|
CaretTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function InvertShownCaret()
|
||||||
|
{
|
||||||
|
if(caretshown)
|
||||||
|
InvertCaret();
|
||||||
|
}
|
||||||
|
|
||||||
|
function HideCaret(x, y, cx, cy)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
if(caretHidden)
|
||||||
|
return;
|
||||||
|
if(Math.max(x, caretx) < Math.min(x + cx, caretx + caretcx) &&
|
||||||
|
Math.max(y, carety) < Math.min(y + cy, carety + caretcy)) {
|
||||||
|
Log("Hiding caret");
|
||||||
|
InvertShownCaret();
|
||||||
|
caretHidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function ProcessDraw(s)
|
function ProcessDraw(s)
|
||||||
{
|
{
|
||||||
// console.clear();
|
// console.clear();
|
||||||
|
|
||||||
|
// window.document.title = "Processing draw";
|
||||||
|
|
||||||
var p = new Object;
|
var p = new Object;
|
||||||
p.data = s;
|
p.data = s;
|
||||||
p.pos = 0;
|
p.pos = 0;
|
||||||
|
|
||||||
var canvas = document.getElementById("myCanvas");
|
var canvas = document.getElementById("myCanvas");
|
||||||
var ctx = canvas.getContext("2d");
|
|
||||||
|
ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
SendingEnabled = true;
|
SendingEnabled = true;
|
||||||
|
|
||||||
|
posx = 0;
|
||||||
|
posy = 0;
|
||||||
|
|
||||||
|
InvertShownCaret();
|
||||||
|
|
||||||
while(p.pos < p.data.length) {
|
while(p.pos < p.data.length) {
|
||||||
// Log(p.pos + ": " + p.data[p.pos]);
|
// Log(p.pos + ": " + p.data[p.pos]);
|
||||||
if(Char(p, 0)) { // RECT
|
if(Char(p, 0)) { // RECT
|
||||||
|
|
@ -110,7 +185,10 @@ function ProcessDraw(s)
|
||||||
var c = "rgb(" + r + "," + g + "," + b + ")";
|
var c = "rgb(" + r + "," + g + "," + b + ")";
|
||||||
ctx.fillStyle = c;
|
ctx.fillStyle = c;
|
||||||
// Log("color: " + c);
|
// Log("color: " + c);
|
||||||
|
HideCaret(x, y, cx, cy);
|
||||||
ctx.fillRect(x, y, cx, cy);
|
ctx.fillRect(x, y, cx, cy);
|
||||||
|
posx = x;
|
||||||
|
posy = y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(Char(p, 3)) { // INVERTRECT
|
if(Char(p, 3)) { // INVERTRECT
|
||||||
|
|
@ -119,14 +197,8 @@ function ProcessDraw(s)
|
||||||
var cx = Get16(p);
|
var cx = Get16(p);
|
||||||
var cy = Get16(p);
|
var cy = Get16(p);
|
||||||
// Log("irect: " + x + ", " + y + ", " + cx + ", " + cy);
|
// Log("irect: " + x + ", " + y + ", " + cx + ", " + cy);
|
||||||
var imageData = ctx.getImageData(x, y, cx, cy);
|
HideCaret(x, y, cx, cy);
|
||||||
var data = imageData.data;
|
InvertRect(x, y, cx, cy);
|
||||||
for(var i = 0; i < data.length; i += 4) {
|
|
||||||
data[i] = 255 - data[i];
|
|
||||||
data[i + 1] = 255 - data[i + 1];
|
|
||||||
data[i + 2] = 255 - data[i + 2];
|
|
||||||
}
|
|
||||||
ctx.putImageData(imageData, x, y);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(Char(p, 2)) { // SETIMAGE
|
if(Char(p, 2)) { // SETIMAGE
|
||||||
|
|
@ -161,8 +233,12 @@ function ProcessDraw(s)
|
||||||
|
|
||||||
// Log("Draw image: " + n);
|
// Log("Draw image: " + n);
|
||||||
if(window.img_cache[n] == undefined)
|
if(window.img_cache[n] == undefined)
|
||||||
alert("Undefined: " + n);
|
alert("Undefined image: " + n);
|
||||||
|
HideCaret(x, y, cx, cy);
|
||||||
ctx.drawImage(window.img_cache[n], x, y, cx, cy, px, py, cx, cy);
|
ctx.drawImage(window.img_cache[n], x, y, cx, cy, px, py, cx, cy);
|
||||||
|
|
||||||
|
posx = px;
|
||||||
|
posy = py;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(Char(p, 4)) { // STD_CURSORIMAGE
|
if(Char(p, 4)) { // STD_CURSORIMAGE
|
||||||
|
|
@ -201,14 +277,93 @@ function ProcessDraw(s)
|
||||||
if(Char(p, 7)) { // DISABLESENDING
|
if(Char(p, 7)) { // DISABLESENDING
|
||||||
SendingEnabled = true;
|
SendingEnabled = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if(Char(p, 8)) { // UPDATESERIAL
|
||||||
|
update_serial_l = Get32(p);
|
||||||
|
update_serial_h = Get32(p);
|
||||||
|
ws.send("S " + update_serial_l + " " + update_serial_h + "\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(Char(p, 9)) // IMAGEPP
|
||||||
|
SImage(p, 1, 1);
|
||||||
|
else
|
||||||
|
if(Char(p, 10)) // IMAGENP
|
||||||
|
SImage(p, -1, 1);
|
||||||
|
else
|
||||||
|
if(Char(p, 11)) // IMAGEPN
|
||||||
|
SImage(p, 1, -1);
|
||||||
|
else
|
||||||
|
if(Char(p, 12)) // IMAGENN
|
||||||
|
SImage(p, -1, -1);
|
||||||
|
else
|
||||||
|
if(Char(p, 13)) // RECTPP
|
||||||
|
SRect(p, 1, 1);
|
||||||
|
else
|
||||||
|
if(Char(p, 14)) // RECTNP
|
||||||
|
SRect(p, -1, 1);
|
||||||
|
else
|
||||||
|
if(Char(p, 15)) // RECTPN
|
||||||
|
SRect(p, 1, -1);
|
||||||
|
else
|
||||||
|
if(Char(p, 16)) // RECTNN
|
||||||
|
SRect(p, -1, -1);
|
||||||
|
else
|
||||||
|
if(Char(p, 17)) { // SETCARET
|
||||||
|
caretx = Get16(p);
|
||||||
|
carety = Get16(p);
|
||||||
|
caretcx = Get16(p);
|
||||||
|
caretcy = Get16(p);
|
||||||
|
caretshown = true;
|
||||||
|
CaretTimer();
|
||||||
|
// Log("SET CARET " + caretx + " " + carety + " " + caretcx + " " + caretcy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
InvertShownCaret();
|
||||||
|
// window.document.title = "OK";
|
||||||
if(SendingEnabled && event_queue.length)
|
if(SendingEnabled && event_queue.length)
|
||||||
ScheduleSend();
|
ScheduleSend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SImage(p, sx, sy)
|
||||||
|
{
|
||||||
|
var px = posx + sx * Get8(p);
|
||||||
|
var py = posy + sy * Get8(p);
|
||||||
|
var n = Get16(p);
|
||||||
|
// Log("Draw opt image: " + px + " " + py + " " + n);
|
||||||
|
var img = window.img_cache[n];
|
||||||
|
if(img == undefined)
|
||||||
|
alert("Undefined image: " + n);
|
||||||
|
HideCaret(px, py, img.width, img.height);
|
||||||
|
ctx.drawImage(window.img_cache[n], px, py);
|
||||||
|
posx = px;
|
||||||
|
posy = py;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SRect(p, sx, sy)
|
||||||
|
{
|
||||||
|
var px = posx + sx * Get8(p);
|
||||||
|
var py = posy + sy * Get8(p);
|
||||||
|
var cx = Get8(p);
|
||||||
|
var cy = Get8(p);
|
||||||
|
var r = Get8(p);
|
||||||
|
var g = Get8(p);
|
||||||
|
var b = Get8(p);
|
||||||
|
// Log("rect: " + x + ", " + y + ", " + cx + ", " + cy);
|
||||||
|
var c = "rgb(" + r + "," + g + "," + b + ")";
|
||||||
|
ctx.fillStyle = c;
|
||||||
|
// Log("color: " + c);
|
||||||
|
HideCaret(x, y, cx, cy);
|
||||||
|
ctx.fillRect(x, y, cx, cy);
|
||||||
|
posx = px;
|
||||||
|
posy = py;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
window.img_cache = {};
|
window.img_cache = {};
|
||||||
window.event_queue = "I\n";
|
window.event_queue = "I\n";
|
||||||
window.cursor_cache = {};
|
window.cursor_cache = {};
|
||||||
|
window.update_serial_l = 0;
|
||||||
|
window.update_serial_h = 0;
|
||||||
|
|
||||||
var canvas = document.getElementById("myCanvas");
|
var canvas = document.getElementById("myCanvas");
|
||||||
|
|
||||||
|
|
@ -302,9 +457,10 @@ function ScheduleSend()
|
||||||
function SendEvents()
|
function SendEvents()
|
||||||
{
|
{
|
||||||
if(SendingEnabled) {
|
if(SendingEnabled) {
|
||||||
if(event_queue.length)
|
if(event_queue.length) {
|
||||||
Log("Sending " + event_queue);
|
Log(event_queue);
|
||||||
ws.send(event_queue);
|
ws.send(event_queue);
|
||||||
|
}
|
||||||
event_queue = "";
|
event_queue = "";
|
||||||
if(timerID != undefined)
|
if(timerID != undefined)
|
||||||
clearTimeout(timerID);
|
clearTimeout(timerID);
|
||||||
|
|
@ -320,7 +476,7 @@ ws.onopen = function()
|
||||||
|
|
||||||
ws.onmessage = function(event)
|
ws.onmessage = function(event)
|
||||||
{
|
{
|
||||||
Log("onmessage");
|
// Log("onmessage");
|
||||||
if(event.data instanceof ArrayBuffer) {
|
if(event.data instanceof ArrayBuffer) {
|
||||||
var inflate = new Zlib.Inflate(new Uint8Array(event.data));
|
var inflate = new Zlib.Inflate(new Uint8Array(event.data));
|
||||||
ProcessDraw(inflate.decompress());
|
ProcessDraw(inflate.decompress());
|
||||||
|
|
@ -329,6 +485,7 @@ ws.onmessage = function(event)
|
||||||
|
|
||||||
ws.onclose = function(ev)
|
ws.onclose = function(ev)
|
||||||
{
|
{
|
||||||
|
ClearCaretTimer();
|
||||||
alert("Connection closed.");
|
alert("Connection closed.");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ file
|
||||||
Cursor.cpp,
|
Cursor.cpp,
|
||||||
Stream.cpp,
|
Stream.cpp,
|
||||||
Server.cpp,
|
Server.cpp,
|
||||||
|
Output.cpp,
|
||||||
Event.cpp,
|
Event.cpp,
|
||||||
Top.h,
|
Top.h,
|
||||||
TopFrame.cpp,
|
TopFrame.cpp,
|
||||||
|
|
|
||||||
|
|
@ -12,31 +12,32 @@ NAMESPACE_UPP
|
||||||
Ptr<Ctrl> Ctrl::desktop;
|
Ptr<Ctrl> Ctrl::desktop;
|
||||||
Vector<Ctrl *> Ctrl::topctrl;
|
Vector<Ctrl *> Ctrl::topctrl;
|
||||||
|
|
||||||
bool Ctrl::invalid;
|
|
||||||
|
|
||||||
bool Ctrl::sdlMouseIsIn;
|
|
||||||
|
|
||||||
Point Ctrl::fbCursorPos = Null;
|
Point Ctrl::fbCursorPos = Null;
|
||||||
Image Ctrl::fbCursorImage;
|
Image Ctrl::fbCursorImage;
|
||||||
Rect Ctrl::fbCaretRect;
|
Rect Ctrl::fbCaretRect;
|
||||||
int Ctrl::fbCaretTm;
|
int Ctrl::fbCaretTm;
|
||||||
bool Ctrl::fbEndSession;
|
bool Ctrl::fbEndSession;
|
||||||
|
|
||||||
bool Ctrl::SystemCursor;
|
Vector<Rect> Ctrl::invalid;
|
||||||
|
|
||||||
|
void Ctrl::InvalidateDesktop()
|
||||||
|
{
|
||||||
|
AddInvalid(desktop->GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
void Ctrl::SetDesktop(Ctrl& q)
|
void Ctrl::SetDesktop(Ctrl& q)
|
||||||
{
|
{
|
||||||
desktop = &q;
|
desktop = &q;
|
||||||
desktop->SetOpen(true);
|
desktop->SetOpen(true);
|
||||||
desktop->NewTop();
|
desktop->NewTop();
|
||||||
invalid = true;
|
InvalidateDesktop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ctrl::SetDesktopSize(Size sz)
|
void Ctrl::SetDesktopSize(Size sz)
|
||||||
{
|
{
|
||||||
if(desktop)
|
if(desktop)
|
||||||
desktop->SetRect(sz);
|
desktop->SetRect(sz);
|
||||||
invalid = true;
|
InvalidateDesktop();
|
||||||
SyncTopWindows();
|
SyncTopWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,11 +165,11 @@ Rect Ctrl::GetClipBound(const Vector<Rect>& inv, const Rect& r)
|
||||||
return ri;
|
return ri;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ctrl::WndUpdate(const Rect&)
|
void Ctrl::WndUpdate(const Rect& r)
|
||||||
{
|
{
|
||||||
GuiLock __;
|
GuiLock __;
|
||||||
Invalidate();
|
// WndInvalidateRect(r);
|
||||||
DoPaint();
|
// DoPaint(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect Ctrl::GetWndScreenRect() const
|
Rect Ctrl::GetWndScreenRect() const
|
||||||
|
|
@ -255,7 +256,7 @@ void Ctrl::DestroyWnd()
|
||||||
topctrl[i]->WndDestroy();
|
topctrl[i]->WndDestroy();
|
||||||
int q = FindTopCtrl();
|
int q = FindTopCtrl();
|
||||||
if(q >= 0) {
|
if(q >= 0) {
|
||||||
Invalidate();
|
AddInvalid();
|
||||||
topctrl.Remove(q);
|
topctrl.Remove(q);
|
||||||
}
|
}
|
||||||
if(top) {
|
if(top) {
|
||||||
|
|
@ -279,7 +280,7 @@ void Ctrl::PutForeground()
|
||||||
{
|
{
|
||||||
int q = FindTopCtrl();
|
int q = FindTopCtrl();
|
||||||
if(q >= 0) {
|
if(q >= 0) {
|
||||||
Invalidate();
|
AddInvalid();
|
||||||
topctrl.Remove(q);
|
topctrl.Remove(q);
|
||||||
topctrl.Add(this);
|
topctrl.Add(this);
|
||||||
}
|
}
|
||||||
|
|
@ -355,10 +356,21 @@ bool Ctrl::HasWndCapture() const
|
||||||
return captureCtrl && captureCtrl->GetTopCtrl() == this;
|
return captureCtrl && captureCtrl->GetTopCtrl() == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ctrl::WndInvalidateRect(const Rect&)
|
void Ctrl::AddInvalid(const Rect& r_)
|
||||||
|
{
|
||||||
|
Rect r = r_ & Rect(DesktopSize);
|
||||||
|
if(!IsNull(r))
|
||||||
|
AddRefreshRect(invalid, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ctrl::WndInvalidateRect(const Rect& r)
|
||||||
{
|
{
|
||||||
GuiLock __;
|
GuiLock __;
|
||||||
Invalidate();
|
int q = FindTopCtrl();
|
||||||
|
if(q >= 0)
|
||||||
|
AddInvalid(r + topctrl[q]->GetRect().TopLeft());
|
||||||
|
else
|
||||||
|
AddInvalid(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ctrl::WndSetPos(const Rect& rect)
|
void Ctrl::WndSetPos(const Rect& rect)
|
||||||
|
|
@ -367,14 +379,15 @@ void Ctrl::WndSetPos(const Rect& rect)
|
||||||
TopWindow *w = dynamic_cast<TopWindow *>(this);
|
TopWindow *w = dynamic_cast<TopWindow *>(this);
|
||||||
if(w)
|
if(w)
|
||||||
w->SyncFrameRect(rect);
|
w->SyncFrameRect(rect);
|
||||||
Invalidate();
|
AddInvalid();
|
||||||
SetWndRect(rect);
|
SetWndRect(rect);
|
||||||
|
AddInvalid(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
|
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
|
||||||
{
|
{
|
||||||
GuiLock __;
|
GuiLock __;
|
||||||
LLOG("ScrollView " << rect);
|
LLOG("ScrollView " << r << ", size " << GetSize());
|
||||||
WndInvalidateRect(r);
|
WndInvalidateRect(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,7 +409,7 @@ void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, boo
|
||||||
popup = isopen = true;
|
popup = isopen = true;
|
||||||
RefreshLayoutDeep();
|
RefreshLayoutDeep();
|
||||||
if(activate) SetFocusWnd();
|
if(activate) SetFocusWnd();
|
||||||
Invalidate();
|
AddInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect Ctrl::GetDefaultWindowRect() {
|
Rect Ctrl::GetDefaultWindowRect() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
#include <RichEdit/RichEdit.h>
|
#include "WebWord.h"
|
||||||
#include <PdfDraw/PdfDraw.h>
|
|
||||||
|
|
||||||
using namespace Upp;
|
|
||||||
|
|
||||||
#define IMAGECLASS UWordImg
|
#define IMAGECLASS UWordImg
|
||||||
#define IMAGEFILE <UWord/UWord.iml>
|
#define IMAGEFILE <UWord/UWord.iml>
|
||||||
|
|
@ -19,46 +16,6 @@ FileSel& PdfFs()
|
||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UWord : public TopWindow {
|
|
||||||
public:
|
|
||||||
virtual void DragAndDrop(Point, PasteClip& d);
|
|
||||||
virtual void FrameDragAndDrop(Point, PasteClip& d);
|
|
||||||
|
|
||||||
virtual void ShutdownWindow();
|
|
||||||
|
|
||||||
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)
|
void UWord::FileBar(Bar& bar)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -94,6 +51,36 @@ void UWord::AboutMenu(Bar& bar)
|
||||||
bar.Add("About..", THISBACK(About));
|
bar.Add("About..", THISBACK(About));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String FormatSize(int64 n)
|
||||||
|
{
|
||||||
|
if(n < 10000)
|
||||||
|
return Format("%d B", n);
|
||||||
|
else
|
||||||
|
if(n < 10000 * 1024)
|
||||||
|
return Format("%d.%d KB", n >> 10, (n & 1023) / 103);
|
||||||
|
else
|
||||||
|
if(n < I64(10000000) * 1024)
|
||||||
|
return Format("%d.%d MB", n >> 20, (n & 1023) / 103);
|
||||||
|
else
|
||||||
|
return Format("%d.%d GB", n >> 30, (n & 1023) / 103);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UWord::ShowInfo()
|
||||||
|
{
|
||||||
|
String s;
|
||||||
|
s << "Mem " << MemoryUsedKb() << " KB";
|
||||||
|
int secs = GetSysTime() - Ctrl::stat_started;
|
||||||
|
Time tm = Time(1, 1, 1, 0, 0, 0) + secs;
|
||||||
|
s << ", uptime " << Format("%d:%0d:%02d:%02d", tm - Date(1, 1, 1), tm.hour, tm.minute, tm.second);
|
||||||
|
s << ", data sent " << FormatSize(Ctrl::stat_data_send);
|
||||||
|
if(secs)
|
||||||
|
s << ", average bandwidth " << FormatSize(Ctrl::stat_data_send / secs) << "/s";
|
||||||
|
s << ", actual bandwidth " << FormatSize(Ctrl::stat_data_send - sent_prev);
|
||||||
|
sent_prev = Ctrl::stat_data_send;
|
||||||
|
statusbar.Set(s);
|
||||||
|
}
|
||||||
|
|
||||||
void UWord::MainMenu(Bar& bar)
|
void UWord::MainMenu(Bar& bar)
|
||||||
{
|
{
|
||||||
// bar.Add("File", THISBACK(FileBar));
|
// bar.Add("File", THISBACK(FileBar));
|
||||||
|
|
@ -248,6 +235,9 @@ UWord::UWord()
|
||||||
editor.WhenRefreshBar = THISBACK(SetBar);
|
editor.WhenRefreshBar = THISBACK(SetBar);
|
||||||
OpenMain();
|
OpenMain();
|
||||||
ActiveFocus(editor);
|
ActiveFocus(editor);
|
||||||
|
|
||||||
|
SetTimeCallback(-1000, THISBACK(ShowInfo));
|
||||||
|
sent_prev = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UWord::SerializeApp(Stream& s)
|
void UWord::SerializeApp(Stream& s)
|
||||||
|
|
@ -294,7 +284,7 @@ struct EventsWnd : TopWindow {
|
||||||
|
|
||||||
EventsWnd() {
|
EventsWnd() {
|
||||||
Add(l.SizePos());
|
Add(l.SizePos());
|
||||||
SetTimeCallback(-100, THISBACK(Do));
|
SetTimeCallback(-1000, THISBACK(Do));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -311,7 +301,8 @@ CONSOLE_APP_MAIN
|
||||||
LOG("Session Started");
|
LOG("Session Started");
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
MemoryLimitKb(10000);
|
MemoryLimitKb(5000000);
|
||||||
|
Ctrl::debugmode = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Ctrl::WhenDisconnect = callback(FinishApp);
|
Ctrl::WhenDisconnect = callback(FinishApp);
|
||||||
|
|
@ -324,6 +315,8 @@ CONSOLE_APP_MAIN
|
||||||
{
|
{
|
||||||
SetLanguage(LNG_ENGLISH);
|
SetLanguage(LNG_ENGLISH);
|
||||||
SetDefaultCharset(CHARSET_UTF8);
|
SetDefaultCharset(CHARSET_UTF8);
|
||||||
|
|
||||||
|
PromptOK("Session started");
|
||||||
|
|
||||||
UWordFs().Type("QTF files", "*.qtf")
|
UWordFs().Type("QTF files", "*.qtf")
|
||||||
.AllFilesType()
|
.AllFilesType()
|
||||||
|
|
|
||||||
53
rainbow/WebWord/WebWord.h
Normal file
53
rainbow/WebWord/WebWord.h
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef _WebWord_WebWord_h_
|
||||||
|
#define _WebWord_WebWord_h_
|
||||||
|
|
||||||
|
#include <RichEdit/RichEdit.h>
|
||||||
|
#include <PdfDraw/PdfDraw.h>
|
||||||
|
|
||||||
|
using namespace Upp;
|
||||||
|
|
||||||
|
struct UWord : public TopWindow {
|
||||||
|
public:
|
||||||
|
virtual void DragAndDrop(Point, PasteClip& d);
|
||||||
|
virtual void FrameDragAndDrop(Point, PasteClip& d);
|
||||||
|
|
||||||
|
virtual void ShutdownWindow();
|
||||||
|
|
||||||
|
RichEdit editor;
|
||||||
|
MenuBar menubar;
|
||||||
|
ToolBar toolbar;
|
||||||
|
StatusBar statusbar;
|
||||||
|
String filename;
|
||||||
|
|
||||||
|
int64 sent_prev;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
void ShowInfo();
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef UWord CLASSNAME;
|
||||||
|
|
||||||
|
static void SerializeApp(Stream& s);
|
||||||
|
|
||||||
|
UWord();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -7,6 +7,7 @@ uses
|
||||||
|
|
||||||
file
|
file
|
||||||
test.qtf,
|
test.qtf,
|
||||||
|
WebWord.h,
|
||||||
WebWord.cpp;
|
WebWord.cpp;
|
||||||
|
|
||||||
mainconfig
|
mainconfig
|
||||||
|
|
|
||||||
|
|
@ -57,4 +57,5 @@
|
||||||
#define GUIPLATFORM_KEYCODES_INCLUDE <Turtle/Keys.h>
|
#define GUIPLATFORM_KEYCODES_INCLUDE <Turtle/Keys.h>
|
||||||
//need to make SDL_keysym.h known before K_ enum
|
//need to make SDL_keysym.h known before K_ enum
|
||||||
#define GUIPLATFORM_INCLUDE <Turtle/Turtle.h>
|
#define GUIPLATFORM_INCLUDE <Turtle/Turtle.h>
|
||||||
|
#define GUIPLATFORM_NOSCROLL
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue