MT issues X11 fix

git-svn-id: svn://ultimatepp.org/upp/trunk@1507 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2009-08-13 16:08:34 +00:00
parent 1205935960
commit 57a34eb230
4 changed files with 228 additions and 221 deletions

View file

@ -580,8 +580,10 @@ private:
static Callback CtrlCall;
static bool DoCall();
static bool PeekMsg(MSG& msg);
#ifdef PLATFORM_WIN32
static bool PeekMsg(MSG& msg);
#endif
// System window interface...
void WndShow0(bool b);
@ -693,8 +695,6 @@ protected:
friend void sSetCursor(Ctrl *ctrl, const Image& m);
typedef Ctrl CLASSNAME;
public:
virtual void NcCreate(HWND hwnd);
virtual void NcDestroy();
@ -707,6 +707,8 @@ public:
static Ctrl *CtrlFromHWND(HWND hwnd);
#endif
typedef Ctrl CLASSNAME;
#ifdef PLATFORM_X11
protected:
struct XWindow {

View file

@ -1,192 +1,194 @@
#include "CtrlCore.h"
#define LLOG(x) // LOG(x)
NAMESPACE_UPP
#ifdef _MULTITHREADED
static int NonMain;
static StaticMutex NonMainLock;
void EnterGuiMutex()
{
LLOG("Thread " << IsMainThread() << " trying to lock");
bool nonmain = !IsMainThread();
if(nonmain)
NonMainLock.Enter();
EnterGMutex();
if(nonmain)
NonMain++;
LLOG("Thread " << IsMainThread() << " LOCK");
}
void LeaveGuiMutex()
{
LLOG("Thread " << IsMainThread() << " trying to unlock");
bool nonmain = !IsMainThread();
if(nonmain)
NonMain--;
LeaveGMutex();
if(nonmain)
NonMainLock.Leave();
LLOG("Thread " << IsMainThread() << " UNLOCK");
}
struct Ctrl::CallBox {
Semaphore sem;
Callback cb;
};
void Ctrl::PerformCall(Ctrl::CallBox *cbox)
{
cbox->cb();
LLOG("Sem release");
cbox->sem.Release();
}
Callback Ctrl::CtrlCall;
void WakeUpGuiThread();
bool Ctrl::DoCall()
{
LLOG("DoCall");
CtrlCall();
CtrlCall.Clear();
LLOG("--- DoCall, nonmain: " << NonMain);
return NonMain;
}
void Ctrl::ICall(Callback cb)
{
LLOG("Ctrl::Call " << IsMainThread() << ", nonmain: " << NonMain);
if(IsMainThread())
cb();
else {
CallBox cbox;
cbox.cb = cb;
CtrlCall = callback1(PerformCall, &cbox);
int level = LeaveGMutexAll();
WakeUpGuiThread();
LLOG("Waiting for semaphore");
if(!Thread::IsShutdownThreads())
cbox.sem.Wait();
EnterGMutex(level);
}
LLOG("-- Ctrl::Call " << IsMainThread());
}
void Ctrl::Call(Callback cb)
{
if(IsMainThread())
cb();
else {
CallBox cbox;
DLOG("EventLoop 1");
cbox.cb = cb;
DLOG("EventLoop 2");
UPP::PostCallback(callback1(PerformCall, &cbox));
int n = NonMain;
int nn = n;
NonMain = 0;
for(int i = 0; i < n; i++)
NonMainLock.Leave();
int level = LeaveGMutexAll();
WakeUpGuiThread();
if(!Thread::IsShutdownThreads())
cbox.sem.Wait();
for(int i = 0; i < n; i++)
NonMainLock.Enter();
EnterGMutex(level);
NonMain = n;
}
}
#else
bool Ctrl::DoCall()
{
return false;
}
void Ctrl::ICall(Callback cb)
{
cb();
}
void Ctrl::Call(Callback cb)
{
cb();
}
#endif
void Ctrl::GuiSleep(int ms)
{
Call(callback1(&Ctrl::GuiSleep0, ms));
}
void Ctrl::WndDestroy()
{
ICall(callback(this, &Ctrl::WndDestroy0));
}
void Ctrl::WndCreateCaret(const Rect& cr)
{
ICall(THISBACK1(WndCreateCaret0, cr));
}
void Ctrl::WndShow(bool b)
{
ICall(THISBACK1(WndShow0, b));
}
void Ctrl::WndUpdate()
{
ICall(THISBACK(WndUpdate0));
}
void Ctrl::SetWndForeground()
{
ICall(THISBACK(SetWndForeground0));
}
bool Ctrl::WndEnable(bool b)
{
ICall(THISBACK1(WndEnable0, &b));
return b;
}
bool Ctrl::SetWndFocus()
{
bool b;
ICall(THISBACK1(SetWndFocus0, &b));
return b;
}
void Ctrl::WndInvalidateRect(const Rect& r)
{
ICall(THISBACK1(WndInvalidateRect0, r));
}
void Ctrl::WndSetPos(const Rect& rect)
{
ICall(THISBACK1(WndSetPos0, rect));
}
void Ctrl::WndUpdate(const Rect& r)
{
ICall(THISBACK1(WndUpdate0r, r));
}
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
{
ICall(THISBACK3(WndScrollView0, r, dx, dy));
}
void Ctrl::EventLoop(Ctrl *ctrl)
{
Call(callback1(&Ctrl::EventLoop0, ctrl));
}
END_UPP_NAMESPACE
#include "CtrlCore.h"
#define LLOG(x) // LOG(x)
NAMESPACE_UPP
#ifdef _MULTITHREADED
static int NonMain;
static StaticMutex NonMainLock;
void EnterGuiMutex()
{
LLOG("Thread " << IsMainThread() << " trying to lock");
bool nonmain = !IsMainThread();
if(nonmain)
NonMainLock.Enter();
EnterGMutex();
if(nonmain)
NonMain++;
LLOG("Thread " << IsMainThread() << " LOCK");
}
void LeaveGuiMutex()
{
LLOG("Thread " << IsMainThread() << " trying to unlock");
bool nonmain = !IsMainThread();
if(nonmain)
NonMain--;
LeaveGMutex();
if(nonmain)
NonMainLock.Leave();
LLOG("Thread " << IsMainThread() << " UNLOCK");
}
struct Ctrl::CallBox {
Semaphore sem;
Callback cb;
};
void Ctrl::PerformCall(Ctrl::CallBox *cbox)
{
cbox->cb();
LLOG("Sem release");
cbox->sem.Release();
}
Callback Ctrl::CtrlCall;
void WakeUpGuiThread();
bool Ctrl::DoCall()
{
LLOG("DoCall");
CtrlCall();
CtrlCall.Clear();
LLOG("--- DoCall, nonmain: " << NonMain);
return NonMain;
}
void Ctrl::ICall(Callback cb)
{
LLOG("Ctrl::Call " << IsMainThread() << ", nonmain: " << NonMain);
if(IsMainThread())
cb();
else {
CallBox cbox;
cbox.cb = cb;
CtrlCall = callback1(PerformCall, &cbox);
int level = LeaveGMutexAll();
WakeUpGuiThread();
LLOG("Waiting for semaphore");
if(!Thread::IsShutdownThreads())
cbox.sem.Wait();
EnterGMutex(level);
}
LLOG("-- Ctrl::Call " << IsMainThread());
}
void Ctrl::Call(Callback cb)
{
if(IsMainThread())
cb();
else {
CallBox cbox;
DLOG("EventLoop 1");
cbox.cb = cb;
DLOG("EventLoop 2");
UPP::PostCallback(callback1(PerformCall, &cbox));
int n = NonMain;
int nn = n;
NonMain = 0;
for(int i = 0; i < n; i++)
NonMainLock.Leave();
int level = LeaveGMutexAll();
WakeUpGuiThread();
if(!Thread::IsShutdownThreads())
cbox.sem.Wait();
for(int i = 0; i < n; i++)
NonMainLock.Enter();
EnterGMutex(level);
NonMain = n;
}
}
#else
bool Ctrl::DoCall()
{
return false;
}
void Ctrl::ICall(Callback cb)
{
cb();
}
void Ctrl::Call(Callback cb)
{
cb();
}
#endif
void Ctrl::GuiSleep(int ms)
{
Call(callback1(&Ctrl::GuiSleep0, ms));
}
void Ctrl::WndDestroy()
{
ICall(callback(this, &Ctrl::WndDestroy0));
}
#ifdef PLATFORM_WIN32
void Ctrl::WndCreateCaret(const Rect& cr)
{
ICall(THISBACK1(WndCreateCaret0, cr));
}
#endif
void Ctrl::WndShow(bool b)
{
ICall(THISBACK1(WndShow0, b));
}
void Ctrl::WndUpdate()
{
ICall(THISBACK(WndUpdate0));
}
void Ctrl::SetWndForeground()
{
ICall(THISBACK(SetWndForeground0));
}
bool Ctrl::WndEnable(bool b)
{
ICall(THISBACK1(WndEnable0, &b));
return b;
}
bool Ctrl::SetWndFocus()
{
bool b;
ICall(THISBACK1(SetWndFocus0, &b));
return b;
}
void Ctrl::WndInvalidateRect(const Rect& r)
{
ICall(THISBACK1(WndInvalidateRect0, r));
}
void Ctrl::WndSetPos(const Rect& rect)
{
ICall(THISBACK1(WndSetPos0, rect));
}
void Ctrl::WndUpdate(const Rect& r)
{
ICall(THISBACK1(WndUpdate0r, r));
}
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
{
ICall(THISBACK3(WndScrollView0, r, dx, dy));
}
void Ctrl::EventLoop(Ctrl *ctrl)
{
Call(callback1(&Ctrl::EventLoop0, ctrl));
}
END_UPP_NAMESPACE

View file

@ -70,7 +70,7 @@ void Ctrl::DoPaint(const Vector<Rect>& invalid)
}
}
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
void Ctrl::WndScrollView0(const Rect& r, int dx, int dy)
{
GuiLock __;
if(r.IsEmpty() || !GetWindow()) return;
@ -314,9 +314,12 @@ void Ctrl::GuiSleep0(int ms)
timeout.tv_sec = ms / 1000;
timeout.tv_usec = ms % 1000 * 1000;
XFlush(Xdisplay);
int level = LeaveGuiMutexAll();
select(Xconnection + 1, &fdset, NULL, NULL, &timeout);
PerformCall();
do {
int level = LeaveGMutexAll();
select(Xconnection + 1, &fdset, NULL, NULL, &timeout);
EnterGMutex(level);
}
while(DoCall());
}
static int granularity = 10;
@ -350,9 +353,12 @@ void Ctrl::EventLoop0(Ctrl *ctrl)
timeout.tv_sec = 0;
timeout.tv_usec = 1000 * granularity;
XFlush(Xdisplay);
int level = LeaveGuiMutexAll();
select(Xconnection + 1, &fdset, NULL, NULL, &timeout);
PerformCall();
do {
int level = LeaveGMutexAll();
select(Xconnection + 1, &fdset, NULL, NULL, &timeout);
EnterGMutex(level);
}
while(DoCall());
// GuiSleep()(granularity);
SyncMousePos();
while(IsWaitingEvent()) {
@ -606,7 +612,7 @@ Ctrl *Ctrl::GetOwner()
return q >= 0 ? Xwindow()[q].owner : NULL;
}
void Ctrl::WndShow(bool b)
void Ctrl::WndShow0(bool b)
{
GuiLock __;
LLOG("WndShow " << b);
@ -624,7 +630,7 @@ void Ctrl::WndShow(bool b)
}
}
void Ctrl::WndUpdate()
void Ctrl::WndUpdate0()
{
GuiLock __;
LTIMING("WndUpdate");
@ -641,7 +647,7 @@ void Ctrl::WndUpdate()
}
}
void Ctrl::WndUpdate(const Rect& r)
void Ctrl::WndUpdate0r(const Rect& r)
{
GuiLock __;
LTIMING("WndUpdate Rect");
@ -657,7 +663,7 @@ void Ctrl::WndUpdate(const Rect& r)
xw.invalid = Subtract(xw.invalid, r, dummy);
}
void Ctrl::WndSetPos(const Rect& r)
void Ctrl::WndSetPos0(const Rect& r)
{
GuiLock __;
if(!top) return;
@ -798,10 +804,11 @@ void Ctrl::KillFocus(Window window)
w.ctrl->KillFocusWnd();
}
bool Ctrl::SetWndFocus()
void Ctrl::SetWndFocus0(bool *b)
{
GuiLock __;
LLOG("SetWndFocus " << Name());
*b = false;
if(top && top->window != focusWindow && IsEnabled() && IsVisible()) {
LLOG("Setting focus... ");
LTIMING("XSetInfputFocus");
@ -809,9 +816,8 @@ bool Ctrl::SetWndFocus()
XSetInputFocus(Xdisplay, top->window, RevertToParent, CurrentTime);
focusWindow = top->window;
SetFocusWnd();
return true;
*b = true;
}
return false;
}
bool Ctrl::HasWndFocus() const
@ -934,7 +940,7 @@ void Ctrl::AddGlobalRepaint()
}
}
void Ctrl::WndInvalidateRect(const Rect& r)
void Ctrl::WndInvalidateRect0(const Rect& r)
{
GuiLock __;
if(!top) return;
@ -942,7 +948,7 @@ void Ctrl::WndInvalidateRect(const Rect& r)
Invalidate(Xwindow().Get(top->window), r);
}
void Ctrl::SetWndForeground()
void Ctrl::SetWndForeground0()
{
GuiLock __;
LLOG("SetWndForeground " << Name());
@ -967,17 +973,20 @@ bool Ctrl::IsWndForeground() const
return ~focusCtrlWnd == (q ? q : GetTopCtrl());
}
bool Ctrl::WndEnable(bool b)
void Ctrl::WndEnable0(bool *b)
{
GuiLock __;
LLOG("WndEnable");
if(!top) return false;
if(!b) {
if(!top) {
*b = false;
return;
}
if(!*b) {
ReleaseCapture();
if(HasWndFocus())
XSetInputFocus(Xdisplay, None, RevertToPointerRoot, CurrentTime);
}
return true;
*b = true;
}
// 01/12/2007 - mdelfede

View file

@ -560,13 +560,7 @@ bool IsEmptyImage(const Image& m)
Image GtkThemeIcon(const char *name, int size)
{
<<<<<<< .mine
Image m = GetGTK(gtk__parent(), size, 0, name, GTK_THEMEICON, 0, 0);
=======
Image m = GetGTK(gtk__parent(), size ? GTK_ICON_SIZE_LARGE_TOOLBAR
: GTK_ICON_SIZE_SMALL_TOOLBAR,
0, name, GTK_THEMEICON, 0, 0);
>>>>>>> .r1505
Size sz = m.GetSize();
int rsz = size ? 48 : 16;
if(sz.cx > rsz || sz.cy > rsz)