mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-24 22:02:44 -06:00
CtrlCore: X11 and GTK MT fixes (#429)
git-svn-id: svn://ultimatepp.org/upp/trunk@5735 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
688ab69301
commit
13dbe1dd98
14 changed files with 78 additions and 14 deletions
|
|
@ -210,6 +210,7 @@ dword Random()
|
|||
|
||||
dword Random(dword n)
|
||||
{
|
||||
ASSERT(n);
|
||||
dword mask = n;
|
||||
mask |= mask >> 1;
|
||||
mask |= mask >> 2;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ public:
|
|||
void Insert(int i, const Vector& x);
|
||||
void Insert(int i, const Vector& x, int offset, int count);
|
||||
void InsertPick(int i, pick_ Vector& x);
|
||||
void InsertSplit(int i, Vector<T>& v, int from);
|
||||
void Append(const Vector& x) { Insert(GetCount(), x); }
|
||||
void Append(const Vector& x, int o, int c) { Insert(GetCount(), x, o, c); }
|
||||
void AppendPick(pick_ Vector& x) { InsertPick(GetCount(), x); }
|
||||
|
|
|
|||
|
|
@ -308,6 +308,20 @@ void Vector<T>::InsertPick(int i, pick_ Vector<T>& v) {
|
|||
SetPicked(v);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Vector<T>::InsertSplit(int i, Vector<T>& v, int from)
|
||||
{
|
||||
Chk();
|
||||
v.Chk();
|
||||
ASSERT(!vector || v.vector != vector && from <= v.GetCount());
|
||||
int n = v.GetCount() - from;
|
||||
if(n) {
|
||||
RawInsert(i, n);
|
||||
memcpy(vector + i, v.vector + from, sizeof(T) * n);
|
||||
}
|
||||
v.Trim(from);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Vector<T>::Set(int i, const T& x, int count) {
|
||||
Chk();
|
||||
|
|
|
|||
|
|
@ -354,6 +354,14 @@ copy constructor for T, but destroys source Vector.&]
|
|||
[s7; [*C@3 x]-|Source Vector.&]
|
||||
[s3;%- &]
|
||||
[s4;%- &]
|
||||
[s5;:Vector`:`:InsertSplit`(int`,Vector`<T`>`&`,int`):%- [@(0.0.255) void]_[* InsertSplit
|
||||
]([@(0.0.255) int]_[*@3 i], [_^Vector^ Vector]<[*@4 T]>`&_[*@3 v], [@(0.0.255) int]_[*@3 from])
|
||||
&]
|
||||
[s2; Insert the part of source vector [%-*@3 v] starting at element
|
||||
[%-*@3 from] till the end at position [%-*@3 i] and trims [%-*@3 v]
|
||||
at [%-*@3 from], effectively splitting [%-*@3 v] into two parts.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:Vector`:`:Append`(const Vector`&`):%- [@(0.0.255) void]_[* Append]([@(0.0.255) const]_
|
||||
[_^Vector^ Vector][@(0.0.255) `&]_[*@3 x])&]
|
||||
[s2; Appends all elements of source Vector.&]
|
||||
|
|
@ -538,4 +546,4 @@ simple constant time operation.&]
|
|||
[s7; [*C@3 a]-|First Vector to swap.&]
|
||||
[s7; [*C@3 b]-|Second Vector to swap.&]
|
||||
[s3; &]
|
||||
[s0; ]
|
||||
[s0; ]]
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include "CtrlCore.h"
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
|
|
@ -12,37 +12,41 @@ static thread__ int sGLockLevel = 0;
|
|||
|
||||
void EnterGuiMutex()
|
||||
{
|
||||
LLOG(">EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread());
|
||||
if(sGLockLevel++ == 0)
|
||||
sGLock.Enter();
|
||||
LLOG("EnterGuiMutex " << sGLockLevel);
|
||||
LLOG("EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread());
|
||||
}
|
||||
|
||||
void EnterGuiMutex(int n)
|
||||
{
|
||||
LLOG(">EnterGuiMutex: " << n << ' ' << sGLockLevel << ' ' << IsMainThread());
|
||||
if(n > 0) {
|
||||
if(sGLockLevel == 0)
|
||||
sGLock.Enter();
|
||||
sGLockLevel += n;
|
||||
}
|
||||
LLOG("EnterGuiMutex " << sGLockLevel);
|
||||
LLOG("EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread());
|
||||
}
|
||||
|
||||
void LeaveGuiMutex()
|
||||
{
|
||||
LLOG(">LeaveGuiMutex " << sGLockLevel << ' ' << IsMainThread());
|
||||
ASSERT(sGLockLevel > 0);
|
||||
if(--sGLockLevel == 0)
|
||||
sGLock.Leave();
|
||||
LLOG("LeaveGuiMutex " << sGLockLevel);
|
||||
LLOG("LeaveGuiMutex " << sGLockLevel << ' ' << IsMainThread());
|
||||
}
|
||||
|
||||
int LeaveGuiMutexAll()
|
||||
{
|
||||
LLOG(">LeaveGuiMutexAll " << sGLockLevel << ' ' << IsMainThread());
|
||||
int q = sGLockLevel;
|
||||
if(q) {
|
||||
sGLock.Leave();
|
||||
sGLockLevel = 0;
|
||||
}
|
||||
LLOG("LeaveGuiMutex all " << q);
|
||||
LLOG("LeaveGuiMutexAll " << q << ' ' << IsMainThread());
|
||||
return q;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f);
|
|||
class DHCtrl : Ctrl {};
|
||||
|
||||
void InitGtkApp(int argc, char **argv, const char **envptr);
|
||||
void ExitGtkApp();
|
||||
|
||||
#define GUI_APP_MAIN \
|
||||
void GuiMainFn_(); \
|
||||
|
|
@ -18,6 +19,7 @@ int main(int argc, char **argv, const char **envptr) { \
|
|||
UPP::InitGtkApp(argc, argv, envptr); \
|
||||
GuiMainFn_(); \
|
||||
UPP::Ctrl::CloseTopCtrls(); \
|
||||
ExitGtkApp(); \
|
||||
UPP::AppExit__(); \
|
||||
return UPP::GetExitCode(); \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@ void Ctrl::PanicMsgBox(const char *title, const char *text)
|
|||
void InitGtkApp(int argc, char **argv, const char **envptr)
|
||||
{
|
||||
LLOG(rmsecs() << " InitGtkApp");
|
||||
#ifdef _MULTITHREADED
|
||||
if(!g_thread_supported())
|
||||
g_thread_init( NULL );
|
||||
gdk_threads_set_lock_functions(EnterGuiMutex, LeaveGuiMutex);
|
||||
gdk_threads_init();
|
||||
EnterGuiMutex();
|
||||
#endif
|
||||
gtk_init(&argc, &argv);
|
||||
Ctrl::GlobalBackBuffer();
|
||||
Ctrl::ReSkin();
|
||||
|
|
@ -33,6 +40,13 @@ void InitGtkApp(int argc, char **argv, const char **envptr)
|
|||
gdk_window_add_filter(NULL, Ctrl::RootKeyFilter, NULL);
|
||||
}
|
||||
|
||||
void ExitGtkApp()
|
||||
{
|
||||
#ifdef _MULTITHREADED
|
||||
LeaveGuiMutex();
|
||||
#endif
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,9 +4,15 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
void Ctrl::Create(Ctrl *owner, bool popup)
|
||||
{
|
||||
LLOG("Create Call");
|
||||
Call(callback2(this, &Ctrl::Create0, owner, popup));
|
||||
}
|
||||
|
||||
void Ctrl::Create0(Ctrl *owner, bool popup)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(IsMainThread());
|
||||
|
|
@ -106,6 +112,11 @@ void Ctrl::GuiPlatformRemove()
|
|||
}
|
||||
|
||||
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
|
||||
{
|
||||
Call(callback2(this, &Ctrl::PopUp0, owner, activate));
|
||||
}
|
||||
|
||||
void Ctrl::PopUp0(Ctrl *owner, bool activate)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("POPUP " << Name() << ", " << GetRect() << ", activate " << activate);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#ifdef GUI_GTK
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
#define LLOG(x) DLOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//$ class Ctrl {
|
||||
void Create0(Ctrl *owner, bool popup);
|
||||
void Create(Ctrl *owner, bool popup);
|
||||
void PopUp0(Ctrl *owner, bool activate);
|
||||
|
||||
static gboolean GtkProc(GtkWidget *widget, GdkEvent *event, gpointer user_data);
|
||||
static void IMCommit(GtkIMContext *context, gchar *str, gpointer user_data);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(rmsecs() << ' ' << x)
|
||||
#define LLOG(x) // DLOG(rmsecs() << ' ' << x)
|
||||
// #define LOG_EVENTS _DBG_
|
||||
|
||||
bool Ctrl::EventMouseValid;
|
||||
|
|
@ -91,6 +91,7 @@ gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data)
|
|||
ev = f->b;
|
||||
LOG(rmsecs() << " FETCH EVENT " << ev);
|
||||
#endif
|
||||
GuiLock __;
|
||||
GdkEventKey *key;
|
||||
bool pressed = false;
|
||||
bool retval = true;
|
||||
|
|
@ -273,13 +274,17 @@ void Ctrl::AddEvent(gpointer user_data, int type, const Value& value)
|
|||
|
||||
void Ctrl::IMCommit(GtkIMContext *context, gchar *str, gpointer user_data)
|
||||
{
|
||||
GuiLock __;
|
||||
AddEvent(user_data, EVENT_TEXT, FromUtf8(str));
|
||||
}
|
||||
|
||||
void Ctrl::FetchEvents(bool may_block)
|
||||
{
|
||||
LLOG("FetchEvents " << may_block);
|
||||
int level = LeaveGuiMutexAll();
|
||||
while(g_main_context_iteration(NULL, may_block))
|
||||
may_block = false;
|
||||
EnterGuiMutex(level);
|
||||
}
|
||||
|
||||
bool Ctrl::IsWaitingEvent0(bool fetch)
|
||||
|
|
@ -591,8 +596,8 @@ void Ctrl::EventLoop0(Ctrl *ctrl)
|
|||
ctrl->inloop = true;
|
||||
}
|
||||
|
||||
while(!IsEndSession() && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount()))
|
||||
{
|
||||
while(!IsEndSession() &&
|
||||
(ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) {
|
||||
FetchEvents(TRUE);
|
||||
ProcessEvents();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(rmsecs() << ' ' << x)
|
||||
#define LLOG(x) // DLOG(rmsecs() << ' ' << x)
|
||||
|
||||
Vector<Callback> Ctrl::hotkey;
|
||||
Vector<dword> Ctrl::keyhot;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ Window Xroot()
|
|||
|
||||
String GetProperty(Window w, Atom property, Atom rtype)
|
||||
{
|
||||
GuiLock __;
|
||||
GuiLock __;
|
||||
String result;
|
||||
int format;
|
||||
unsigned long nitems, after = 1;
|
||||
|
|
@ -40,7 +40,6 @@ String GetProperty(Window w, Atom property, Atom rtype)
|
|||
Atom type = None;
|
||||
unsigned char *data;
|
||||
long rsize = minmax((long)(XMaxRequestSize(Xdisplay()) - 100), (long)256, (long)65536);
|
||||
|
||||
while(after > 0) {
|
||||
if(XGetWindowProperty(Xdisplay(), w, property, offset, rsize, 0,
|
||||
rtype, &type, &format, &nitems, &after, &data) != Success)
|
||||
|
|
|
|||
|
|
@ -400,6 +400,9 @@ void Ctrl::InstallPanicBox()
|
|||
void Ctrl::InitX11(const char *display)
|
||||
{
|
||||
GuiLock __;
|
||||
|
||||
XInitThreads();
|
||||
|
||||
InstallPanicMessageBox(sPanicMessageBox);
|
||||
|
||||
InitX11Draw(display);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue