Commit 5d29b7b3 authored by Davis King's avatar Davis King

Changed the gui core code around so that it should be safe to make window

objects at the global scope

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402526
parent 82be8506
......@@ -36,42 +36,6 @@ namespace dlib
namespace gui_core_kernel_1_globals
{
static logger dlog("dlib.gui_core");
static TCHAR window_class_name[] = TEXT ("w3049u6qc2d94thw9m34f4we0gvwa3-tgkser0-b9gm 05");
static HINSTANCE hInstance;
static HWND helper_window = NULL;
static bool core_has_been_initialized = false;
static bool quit_windows_loop = false;
static bool set_window_title_done = true;
static std::wstring window_title;
static bool move_window_done = true;
static HWND move_window_hwnd = NULL;
static int move_window_width = 0;
static int move_window_height = 0;
static int move_window_x = 0;
static int move_window_y = 0;
static bool request_new_window = false;
static DWORD dwStyle;
static HWND new_window = NULL;
static bool in_ime_composition = false;
// the window_table.get_mutex() mutex locks the above 11 variables
typedef sync_extension<binary_search_tree<HWND,base_window*>::kernel_1a>::kernel_1a
window_table_type;
// this variable holds a mapping from window handles to the base_window
// objects which represent them. Note that this objects mutex is always locked
// when inside the event loop.
static window_table_type window_table;
static rsignaler window_close_signaler(window_table.get_mutex());
static rsignaler et_signaler(window_table.get_mutex());
// note that this is the thread that will perform all the event
// processing.
thread_id_type event_thread_id;
struct user_event_type
{
......@@ -80,8 +44,9 @@ namespace dlib
int i;
};
typedef sync_extension<binary_search_tree<HWND,base_window*>::kernel_1a>::kernel_1a window_table_type;
typedef sync_extension<queue<user_event_type,memory_manager<char>::kernel_1b>::kernel_2a_c>::kernel_1a queue_of_user_events;
queue_of_user_events user_events;
enum USER_OFFSETS
{
......@@ -96,6 +61,240 @@ namespace dlib
CALL_SET_WINDOW_TITLE
};
// ----------------------------------------------------------------------------------------
class event_handler_thread : public threaded_object
{
public:
enum et_state
{
uninitialized,
initialized,
failure_to_init
};
et_state status;
queue_of_user_events user_events;
queue_of_user_events user_events_temp;
logger dlog;
HINSTANCE hInstance;
HWND helper_window;
const TCHAR* window_class_name;
bool should_destruct;
bool quit_windows_loop;
bool set_window_title_done;
std::wstring window_title;
bool move_window_done;
HWND move_window_hwnd;
int move_window_width;
int move_window_height;
int move_window_x;
int move_window_y;
bool request_new_window;
DWORD dwStyle;
HWND new_window;
bool in_ime_composition;
bool event_thread_started;
// the window_table.get_mutex() mutex locks the above 11 variables
// this variable holds a mapping from window handles to the base_window
// objects which represent them. Note that this objects mutex is always locked
// when inside the event loop.
window_table_type window_table;
rsignaler window_close_signaler;
rsignaler et_signaler;
// note that this is the thread that will perform all the event
// processing.
thread_id_type event_thread_id;
event_handler_thread(
) :
dlog("dlib.gui_core"),
hInstance(0),
helper_window(0),
window_class_name(TEXT ("w3049u6qc2d94thw9m34f4we0gvwa3-tgkser0-b9gm 05")),
should_destruct(false),
quit_windows_loop(false),
set_window_title_done(true),
move_window_done(true),
move_window_hwnd(0),
move_window_width(0),
move_window_height(0),
move_window_x(0),
move_window_y(0),
request_new_window(false),
dwStyle(0),
new_window(0),
in_ime_composition(false),
event_thread_started(false),
window_close_signaler(window_table.get_mutex()),
et_signaler(window_table.get_mutex())
{
status = uninitialized;
}
void start_event_thread (
)
/*!
we can't call this function from this objects constructor because
starting the event thread in windows involves sending messages to the
WndProc() and that requires this object to be fully constructed.
!*/
{
if (event_thread_started == false)
{
auto_mutex M(window_table.get_mutex());
if (event_thread_started == false)
{
event_thread_started = true;
// start up the event handler thread
start();
// wait for the event thread to get up and running
while (status == uninitialized)
et_signaler.wait();
if (status == failure_to_init)
throw gui_error("Failed to start event thread");
}
}
}
~event_handler_thread ()
{
using namespace gui_core_kernel_1_globals;
if (is_alive())
{
if (PostMessage(helper_window,WM_USER+QUIT_EVENT_HANDLER_THREAD,0,0)==0)
{
dlog << LERROR << "Unable to schedule function for execution in event handling thread.";
}
wait();
}
}
private:
void thread (
)
{
event_thread_id = get_thread_id();
hInstance = GetModuleHandle(NULL);
if (hInstance == NULL)
{
dlog << LFATAL << "Error gathering needed resources";
// signal that an error has occurred
window_table.get_mutex().lock();
status = failure_to_init;
et_signaler.broadcast();
window_table.get_mutex().unlock();
return;
}
// register the main window class
WNDCLASS wndclass ;
wndclass.style = CS_DBLCLKS;
wndclass.lpfnWndProc = dlib::gui_core_kernel_1_globals::WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = window_class_name ;
if (!RegisterClass (&wndclass))
{
dlog << LFATAL << "Error registering window class";
// signal that an error has occurred
window_table.get_mutex().lock();
status = failure_to_init;
et_signaler.broadcast();
window_table.get_mutex().unlock();
return;
}
// make the helper window that is used to trigger events in the
// event handler loop from other threads
TCHAR nothing[] = TEXT("");
helper_window = CreateWindow(window_class_name,nothing,WS_DISABLED,0,0,0,0,HWND_MESSAGE,NULL,hInstance,NULL);
if (helper_window == NULL)
{
dlog << LFATAL << "Error gathering needed resources";
// signal that an error has occurred
window_table.get_mutex().lock();
status = failure_to_init;
et_signaler.broadcast();
window_table.get_mutex().unlock();
return;
}
// signal that the event thread is now up and running
window_table.get_mutex().lock();
status = initialized;
et_signaler.broadcast();
window_table.get_mutex().unlock();
// start the event handler loop.
/*
A note about this quit_windows_loop thing. If the user is holding
the mouse button down on the title bar of a window it will cause
the PostQuitMessage() function to be ignored!! This extra bool
is a work around to prevent that from happening.
*/
MSG msg;
while (GetMessage (&msg, NULL, 0, 0) &&
quit_windows_loop == false)
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
};
event_handler_thread& globals()
{
static event_handler_thread* p = new event_handler_thread;
p->start_event_thread();
return *p;
}
struct event_handler_thread_destruct_helper
{
~event_handler_thread_destruct_helper()
{
globals().window_table.get_mutex().lock();
// if there aren't any more gui windows then we can destroy the event handler thread
if (globals().window_table.size() == 0)
{
globals().window_table.get_mutex().unlock();
delete &globals();
}
else
{
globals().should_destruct = true;
globals().window_table.get_mutex().unlock();
}
}
};
static event_handler_thread_destruct_helper just_a_name;
// ----------------------------------------------------------------------------------------
struct ebh_param
......@@ -460,13 +659,15 @@ namespace dlib
)
{
using namespace gui_core_kernel_1_globals;
queue_of_user_events user_events_temp;
// Make the event processing thread have a priority slightly above normal.
// This makes the GUI smother if you do heavy processing in other threads.
HANDLE hand = OpenThread(THREAD_ALL_ACCESS,FALSE,GetCurrentThreadId());
SetThreadPriority(hand,THREAD_PRIORITY_ABOVE_NORMAL);
CloseHandle(hand);
window_table_type& window_table = globals().window_table;
HWND& helper_window = globals().helper_window;
auto_mutex M(window_table.get_mutex());
try
......@@ -481,7 +682,7 @@ namespace dlib
case WM_USER+QUIT_EVENT_HANDLER_THREAD:
if (hwnd == helper_window)
{
quit_windows_loop = true;
globals().quit_windows_loop = true;
PostQuitMessage(0);
}
return 0;
......@@ -497,14 +698,14 @@ namespace dlib
if (hwnd == helper_window)
{
MoveWindow(
move_window_hwnd,
move_window_x,
move_window_y,
move_window_width,
move_window_height,
globals().move_window_hwnd,
globals().move_window_x,
globals().move_window_y,
globals().move_window_width,
globals().move_window_height,
TRUE);
move_window_done = true;
et_signaler.broadcast();
globals().move_window_done = true;
globals().et_signaler.broadcast();
}
return 0;
......@@ -512,14 +713,14 @@ namespace dlib
if (hwnd == helper_window)
{
// this is the signal to look in the user_events queue
user_events.lock();
user_events.swap(user_events_temp);
user_events.unlock();
user_events_temp.reset();
globals().user_events.lock();
globals().user_events.swap(globals().user_events_temp);
globals().user_events.unlock();
globals().user_events_temp.reset();
// now dispatch all these user events
while (user_events_temp.move_next())
while (globals().user_events_temp.move_next())
{
base_window** win_ = window_table[user_events_temp.element().w];
base_window** win_ = window_table[globals().user_events_temp.element().w];
base_window* win;
// if this window exists in the window table then dispatch
// its event.
......@@ -527,12 +728,12 @@ namespace dlib
{
win = *win_;
win->on_user_event(
user_events_temp.element().p,
user_events_temp.element().i
globals().user_events_temp.element().p,
globals().user_events_temp.element().i
);
}
}
user_events_temp.clear();
globals().user_events_temp.clear();
}
return 0;
......@@ -561,9 +762,9 @@ namespace dlib
case WM_USER+CALL_SET_WINDOW_TITLE:
if (hwnd == helper_window)
{
SetWindowTextW((HWND)wParam,window_title.c_str());
set_window_title_done = true;
et_signaler.broadcast();
SetWindowTextW((HWND)wParam,globals().window_title.c_str());
globals().set_window_title_done = true;
globals().et_signaler.broadcast();
}
return 0;
......@@ -573,36 +774,36 @@ namespace dlib
{
// if this is stupposed to be a popup window then do the popup window thing
if (dwStyle == WS_CHILD)
if (globals().dwStyle == WS_CHILD)
{
TCHAR nothing[] = TEXT("");
new_window = CreateWindowEx (WS_EX_TOOLWINDOW,window_class_name, nothing,
dwStyle,
globals().new_window = CreateWindowEx (WS_EX_TOOLWINDOW,globals().window_class_name, nothing,
globals().dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
helper_window, NULL, hInstance, NULL);
SetParent(new_window,NULL);
helper_window, NULL, globals().hInstance, NULL);
SetParent(globals().new_window,NULL);
}
else
{
TCHAR nothing[] = TEXT("");
new_window = CreateWindow (window_class_name, nothing,
dwStyle,
globals().new_window = CreateWindow (globals().window_class_name, nothing,
globals().dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
NULL, NULL, globals().hInstance, NULL);
}
// use the helper_window to indicate that CreateWindow failed
if (new_window == NULL)
new_window = helper_window;
et_signaler.broadcast();
if (globals().new_window == NULL)
globals().new_window = helper_window;
globals().et_signaler.broadcast();
}
return 0;
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
{
if (in_ime_composition) break;
if (globals().in_ime_composition) break;
base_window** win_ = window_table[hwnd];
base_window* win;
......@@ -1123,7 +1324,7 @@ namespace dlib
window_table.destroy(hwnd);
win->has_been_destroyed = true;
win->hwnd = 0;
gui_core_kernel_1_globals::window_close_signaler.broadcast();
globals().window_close_signaler.broadcast();
}
else
{
......@@ -1137,12 +1338,12 @@ namespace dlib
return DefWindowProc (hwnd, message, wParam, lParam);
case WM_IME_STARTCOMPOSITION:
in_ime_composition = true;
globals().in_ime_composition = true;
break;
case WM_IME_COMPOSITION:
{
in_ime_composition = false;
globals().in_ime_composition = false;
base_window** win_ = window_table[hwnd];
base_window* win;
if (win_)
......@@ -1180,12 +1381,12 @@ namespace dlib
catch (std::exception& e)
{
error_box("Exception thrown in event handler",e.what());
quit_windows_loop = true;
globals().quit_windows_loop = true;
}
catch (...)
{
error_box("Exception thrown in event handler","Unknown Exception type.");
quit_windows_loop = true;
globals().quit_windows_loop = true;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
......@@ -1199,7 +1400,7 @@ namespace dlib
)
{
using namespace gui_core_kernel_1_globals;
PostMessage(helper_window,WM_USER+SHOW_WINDOW_SHOW,(WPARAM)hwnd,0);
PostMessage(globals().helper_window,WM_USER+SHOW_WINDOW_SHOW,(WPARAM)hwnd,0);
}
// ----------------------------------------------------------------------------------------
......@@ -1209,7 +1410,7 @@ namespace dlib
)
{
using namespace gui_core_kernel_1_globals;
PostMessage(helper_window,WM_USER+SHOW_WINDOW_HIDE,(WPARAM)hwnd,0);
PostMessage(globals().helper_window,WM_USER+SHOW_WINDOW_HIDE,(WPARAM)hwnd,0);
}
// ----------------------------------------------------------------------------------------
......@@ -1223,7 +1424,7 @@ namespace dlib
!*/
{
using namespace gui_core_kernel_1_globals;
PostMessage(helper_window,WM_USER+SET_ACTIVE_WINDOW,(WPARAM)hwnd,0);
PostMessage(globals().helper_window,WM_USER+SET_ACTIVE_WINDOW,(WPARAM)hwnd,0);
}
// ----------------------------------------------------------------------------------------
......@@ -1237,7 +1438,7 @@ namespace dlib
!*/
{
using namespace gui_core_kernel_1_globals;
PostMessage(helper_window,WM_USER+DESTROY_WINDOW,(WPARAM)hwnd,0);
PostMessage(globals().helper_window,WM_USER+DESTROY_WINDOW,(WPARAM)hwnd,0);
}
// ----------------------------------------------------------------------------------------
......@@ -1258,56 +1459,56 @@ namespace dlib
using namespace gui_core_kernel_1_globals;
// if we are running in the event handling thread then just call
// CreateWindow directly
if (get_thread_id() == gui_core_kernel_1_globals::event_thread_id)
if (get_thread_id() == globals().event_thread_id)
{
// if this is stupposed to be a popup window then do the popup window thing
if (dwStyle_ == WS_CHILD)
{
TCHAR nothing[] = TEXT("");
HWND tmp = CreateWindowEx (WS_EX_TOOLWINDOW|WS_EX_TOPMOST, window_class_name, nothing,
HWND tmp = CreateWindowEx (WS_EX_TOOLWINDOW|WS_EX_TOPMOST, globals().window_class_name, nothing,
dwStyle_,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
helper_window, NULL, hInstance, NULL);
globals().helper_window, NULL, globals().hInstance, NULL);
SetParent(tmp,NULL);
return tmp;
}
else
{
TCHAR nothing[] = TEXT("");
return CreateWindow (window_class_name, nothing,
return CreateWindow (globals().window_class_name, nothing,
dwStyle_,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
NULL, NULL, globals().hInstance, NULL);
}
}
else
{
auto_mutex M(window_table.get_mutex());
auto_mutex M(globals().window_table.get_mutex());
// wait for our chance to make a new window request
while (request_new_window)
et_signaler.wait();
while (globals().request_new_window)
globals().et_signaler.wait();
dwStyle = dwStyle_;
if (PostMessage(helper_window,WM_USER+CREATE_WINDOW,0,0)==0)
globals().dwStyle = dwStyle_;
if (PostMessage(globals().helper_window,WM_USER+CREATE_WINDOW,0,0)==0)
{
throw gui_error("Unable to schedule function for execution in event handling thread.");
}
// wait for our request to be serviced
while (new_window == NULL)
et_signaler.wait();
while (globals().new_window == NULL)
globals().et_signaler.wait();
HWND temp = new_window;
new_window = NULL;
request_new_window = false;
et_signaler.broadcast();
HWND temp = globals().new_window;
globals().new_window = NULL;
globals().request_new_window = false;
globals().et_signaler.broadcast();
// if make_window() returns the helper_window then it means it failed
// to make a new window
if (temp == helper_window)
if (temp == globals().helper_window)
temp = NULL;
return temp;
......@@ -1316,151 +1517,6 @@ namespace dlib
// ------------------------------------------------------------------------------------
class event_handler_thread : public threaded_object
{
public:
enum et_state
{
uninitialized,
initialized,
failure_to_init
};
et_state status;
event_handler_thread(
)
{
status = uninitialized;
}
~event_handler_thread ()
{
using namespace gui_core_kernel_1_globals;
if (is_alive())
{
if (PostMessage(helper_window,WM_USER+QUIT_EVENT_HANDLER_THREAD,0,0)==0)
{
dlog << LERROR << "Unable to schedule function for execution in event handling thread.";
}
wait();
}
}
private:
void thread (
)
{
event_thread_id = get_thread_id();
hInstance = GetModuleHandle(NULL);
if (hInstance == NULL)
{
dlog << LFATAL << "Error gathering needed resources";
// signal that an error has occurred
window_table.get_mutex().lock();
status = failure_to_init;
et_signaler.broadcast();
window_table.get_mutex().unlock();
return;
}
// register the main window class
WNDCLASS wndclass ;
wndclass.style = CS_DBLCLKS;
wndclass.lpfnWndProc = dlib::gui_core_kernel_1_globals::WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = window_class_name ;
if (!RegisterClass (&wndclass))
{
dlog << LFATAL << "Error registering window class";
// signal that an error has occurred
window_table.get_mutex().lock();
status = failure_to_init;
et_signaler.broadcast();
window_table.get_mutex().unlock();
return;
}
// make the helper window that is used to trigger events in the
// event handler loop from other threads
TCHAR nothing[] = TEXT("");
helper_window = CreateWindow(window_class_name,nothing,WS_DISABLED,0,0,0,0,HWND_MESSAGE,NULL,hInstance,NULL);
if (helper_window == NULL)
{
dlog << LFATAL << "Error gathering needed resources";
// signal that an error has occurred
window_table.get_mutex().lock();
status = failure_to_init;
et_signaler.broadcast();
window_table.get_mutex().unlock();
return;
}
// signal that the event thread is now up and running
window_table.get_mutex().lock();
status = initialized;
et_signaler.broadcast();
window_table.get_mutex().unlock();
// start the event handler loop.
/*
A note about this quit_windows_loop thing. If the user is holding
the mouse button down on the title bar of a window it will cause
the PostQuitMessage() function to be ignored!! This extra bool
is a work around to prevent that from happening.
*/
MSG msg;
while (GetMessage (&msg, NULL, 0, 0) &&
quit_windows_loop == false)
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
};
// ----------------------------------------------------------------------------------------
static event_handler_thread event_handler;
void init_gui_core ()
{
using namespace dlib::gui_core_kernel_1_globals;
auto_mutex M(window_table.get_mutex());
if (core_has_been_initialized == false)
{
core_has_been_initialized = true;
// start up the event handler thread
event_handler.start();
// wait for the event thread to get up and running
while (event_handler.status == event_handler_thread::uninitialized)
et_signaler.wait();
if (event_handler.status == event_handler_thread::failure_to_init)
throw gui_error("Failed to start event thread");
}
}
} // end namespace gui_core_kernel_1_globals
......@@ -1526,11 +1582,11 @@ namespace dlib
e.p = p;
e.i = i;
{
auto_mutex M(user_events.get_mutex());
user_events.enqueue(e);
auto_mutex M(globals().user_events.get_mutex());
globals().user_events.enqueue(e);
}
if (PostMessage(helper_window,WM_USER+USER_EVENTS_READY,0,0)==0)
if (PostMessage(globals().helper_window,WM_USER+USER_EVENTS_READY,0,0)==0)
{
throw gui_error("Unable to schedule function for execution in event handling thread.");
}
......@@ -1547,16 +1603,15 @@ namespace dlib
prevx(-1),
prevy(-1),
prev_state(0),
wm(gui_core_kernel_1_globals::window_table.get_mutex())
wm(gui_core_kernel_1_globals::globals().window_table.get_mutex())
{
using namespace gui_core_kernel_1_globals;
DLIB_ASSERT(!(undecorated == true && resizable == true),
"\tbase_window::base_window()"
<< "\n\tThere is no such thing as an undecorated window that is resizable by the user."
<< "\n\tthis: " << this
);
gui_core_kernel_1_globals::init_gui_core();
if (resizable)
style = WS_OVERLAPPEDWINDOW;
else if (undecorated)
......@@ -1575,7 +1630,7 @@ namespace dlib
HWND temp = hwnd;
base_window* ttemp = this;
gui_core_kernel_1_globals::window_table.add(temp,ttemp);
globals().window_table.add(temp,ttemp);
}
// ----------------------------------------------------------------------------------------
......@@ -1584,7 +1639,22 @@ namespace dlib
~base_window (
)
{
using namespace gui_core_kernel_1_globals;
close_window();
// check if we were the last window to be destroyed and the program is
// ending. If so then destroy the event handler thread's global object
wm.lock();
if (globals().window_table.size() == 0 && globals().should_destruct == true)
{
wm.unlock();
delete &globals();
}
else
{
// don't do anything except remember to unlock the wm mutex
wm.unlock();
}
}
// ----------------------------------------------------------------------------------------
......@@ -1593,16 +1663,17 @@ namespace dlib
close_window (
)
{
using namespace gui_core_kernel_1_globals;
auto_mutex M(wm);
if (has_been_destroyed == false)
{
// do this just to make sure no one tries to call this window's
// calbacks.
gui_core_kernel_1_globals::window_table.destroy(hwnd);
globals().window_table.destroy(hwnd);
gui_core_kernel_1_globals::destroy_window(hwnd);
hwnd = 0;
has_been_destroyed = true;
gui_core_kernel_1_globals::window_close_signaler.broadcast();
globals().window_close_signaler.broadcast();
}
}
......@@ -1612,9 +1683,10 @@ namespace dlib
wait_until_closed (
) const
{
using namespace gui_core_kernel_1_globals;
auto_mutex M(wm);
while (has_been_destroyed == false)
gui_core_kernel_1_globals::window_close_signaler.wait();
globals().window_close_signaler.wait();
}
// ----------------------------------------------------------------------------------------
......@@ -1663,23 +1735,23 @@ namespace dlib
// do this to avoid possible deadlocks.
auto_mutex M(wm);
if (get_thread_id() == gui_core_kernel_1_globals::event_thread_id)
if (get_thread_id() == globals().event_thread_id)
{
SetWindowTextW(hwnd,title.c_str());
}
else
{
window_title = title;
set_window_title_done = false;
globals().window_title = title;
globals().set_window_title_done = false;
if (PostMessage(helper_window,WM_USER+CALL_SET_WINDOW_TITLE,(WPARAM)hwnd,0)==0)
if (PostMessage(globals().helper_window,WM_USER+CALL_SET_WINDOW_TITLE,(WPARAM)hwnd,0)==0)
{
throw gui_error("Unable to schedule SetWindowText function for execution in event handling thread.");
}
// wait for any SetWindowText() calls to finish
while (set_window_title_done == false)
et_signaler.wait();
while (globals().set_window_title_done == false)
globals().et_signaler.wait();
}
}
......@@ -1732,7 +1804,7 @@ namespace dlib
<< "\n\theight: " << height_
);
auto_mutex M(wm);
if (get_thread_id() == gui_core_kernel_1_globals::event_thread_id)
if (get_thread_id() == globals().event_thread_id)
{
RECT info;
GetWindowRect(hwnd,&info);
......@@ -1784,21 +1856,21 @@ namespace dlib
// have to do this because the MoveWindow() apparently blocks
// until something happens in the event thread so we have to
// do this to avoid possible deadlocks.
move_window_hwnd = hwnd;
move_window_x = x;
move_window_y = y;
move_window_width = width;
move_window_height = height;
move_window_done = false;
if (PostMessage(helper_window,WM_USER+CALL_MOVE_WINDOW,0,0)==0)
globals().move_window_hwnd = hwnd;
globals().move_window_x = x;
globals().move_window_y = y;
globals().move_window_width = width;
globals().move_window_height = height;
globals().move_window_done = false;
if (PostMessage(globals().helper_window,WM_USER+CALL_MOVE_WINDOW,0,0)==0)
{
throw gui_error("Unable to schedule MoveWindow function for execution in event handling thread.");
}
// wait for any MoveWindow calls to finish
while (move_window_done == false)
et_signaler.wait();
while (globals().move_window_done == false)
globals().et_signaler.wait();
}
}
......@@ -1820,7 +1892,7 @@ namespace dlib
<< "\n\ty: " << y_
);
auto_mutex M(wm);
if (get_thread_id() == gui_core_kernel_1_globals::event_thread_id)
if (get_thread_id() == globals().event_thread_id)
{
RECT info;
GetWindowRect(hwnd,&info);
......@@ -1849,21 +1921,21 @@ namespace dlib
// have to do this because the MoveWindow() apparently blocks
// until something happens in the event thread so we have to
// do this to avoid possible deadlocks.
move_window_hwnd = hwnd;
move_window_x = x_;
move_window_y = y_;
move_window_width = width;
move_window_height = height;
move_window_done = false;
if (PostMessage(helper_window,WM_USER+CALL_MOVE_WINDOW,0,0)==0)
globals().move_window_hwnd = hwnd;
globals().move_window_x = x_;
globals().move_window_y = y_;
globals().move_window_width = width;
globals().move_window_height = height;
globals().move_window_done = false;
if (PostMessage(globals().helper_window,WM_USER+CALL_MOVE_WINDOW,0,0)==0)
{
throw gui_error("Unable to schedule MoveWindow function for execution in event handling thread.");
}
// wait for any MoveWindow calls to finish
while (move_window_done == false)
et_signaler.wait();
while (globals().move_window_done == false)
globals().et_signaler.wait();
}
}
......@@ -2007,12 +2079,10 @@ namespace dlib
using namespace gui_core_kernel_1_globals;
using namespace std;
init_gui_core();
if (OpenClipboard(helper_window))
if (OpenClipboard(globals().helper_window))
{
EmptyClipboard();
auto_mutex M(window_table.get_mutex());
auto_mutex M(globals().window_table.get_mutex());
const unsigned long newlines = count(str.begin(),str.end(),L'\n');
......@@ -2075,10 +2145,8 @@ namespace dlib
using namespace gui_core_kernel_1_globals;
using namespace std;
init_gui_core();
auto_mutex M(window_table.get_mutex());
if (OpenClipboard(helper_window))
auto_mutex M(globals().window_table.get_mutex());
if (OpenClipboard(globals().helper_window))
{
HANDLE data = GetClipboardData(CF_UNICODETEXT);
......
......@@ -16,9 +16,6 @@
namespace dlib
{
scoped_ptr<default_font> default_font::f;
mutex default_font::m;
// ----------------------------------------------------------------------------------------
const std::string get_decoded_string_with_default_font_data()
......
......@@ -491,13 +491,14 @@ namespace dlib
default_font(default_font&); // copy constructor
default_font& operator=(default_font&); // assignment operator
static scoped_ptr<default_font> f;
static mutex m;
public:
static const font* get_font (
)
{
{
static mutex m;
static scoped_ptr<default_font> f;
auto_mutex M(m);
if (f.get() == 0)
f.reset(new default_font);
......
......@@ -771,13 +771,13 @@ private:
};
win w;
int main()
{
try
{
win w;
w.set_pos (100,200);
w.set_title("test window");
w.show();
......
......@@ -15,7 +15,7 @@ namespace dlib
static const unichar SURROGATE_FIRST_TOP = 0xD800;
static const unichar SURROGATE_SECOND_TOP = 0xDC00;
static const unichar SURROGATE_CLEARING_MASK = 0x03FF;
static const unichar &SURROGATE_TOP = SURROGATE_FIRST_TOP;
static const unichar SURROGATE_TOP = SURROGATE_FIRST_TOP;
static const unichar SURROGATE_END = 0xE000;
static const unichar SMP_TOP = 0x10000;
static const int VALID_BITS = 10;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment