Commit d1487bb1 authored by Davis King's avatar Davis King

Cleaned up the gui_core code. Also made it so that the gui event handler thread

isn't created at all unless some part of an application calls some of the
gui_core code.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402563
parent 02f6a1ad
...@@ -90,7 +90,6 @@ namespace dlib ...@@ -90,7 +90,6 @@ namespace dlib
HWND helper_window; HWND helper_window;
const TCHAR* window_class_name; const TCHAR* window_class_name;
bool should_destruct;
bool quit_windows_loop; bool quit_windows_loop;
bool set_window_title_done; bool set_window_title_done;
std::wstring window_title; std::wstring window_title;
...@@ -114,7 +113,6 @@ namespace dlib ...@@ -114,7 +113,6 @@ namespace dlib
window_table_type window_table; window_table_type window_table;
rsignaler window_close_signaler; rsignaler window_close_signaler;
rsignaler et_signaler; rsignaler et_signaler;
unsigned long existing_base_windows;
// note that this is the thread that will perform all the event // note that this is the thread that will perform all the event
// processing. // processing.
...@@ -126,7 +124,6 @@ namespace dlib ...@@ -126,7 +124,6 @@ namespace dlib
hInstance(0), hInstance(0),
helper_window(0), helper_window(0),
window_class_name(TEXT ("w3049u6qc2d94thw9m34f4we0gvwa3-tgkser0-b9gm 05")), window_class_name(TEXT ("w3049u6qc2d94thw9m34f4we0gvwa3-tgkser0-b9gm 05")),
should_destruct(false),
quit_windows_loop(false), quit_windows_loop(false),
set_window_title_done(true), set_window_title_done(true),
move_window_done(true), move_window_done(true),
...@@ -141,8 +138,7 @@ namespace dlib ...@@ -141,8 +138,7 @@ namespace dlib
in_ime_composition(false), in_ime_composition(false),
event_thread_started(false), event_thread_started(false),
window_close_signaler(window_table.get_mutex()), window_close_signaler(window_table.get_mutex()),
et_signaler(window_table.get_mutex()), et_signaler(window_table.get_mutex())
existing_base_windows(0)
{ {
status = uninitialized; status = uninitialized;
} }
...@@ -280,47 +276,19 @@ namespace dlib ...@@ -280,47 +276,19 @@ namespace dlib
// Do all this just to make sure global_mutex() is initialized at program start // Do all this just to make sure global_mutex() is initialized at program start
// and thus hopefully before any threads have the chance to startup and call // and thus hopefully before any threads have the chance to startup and call
// globals() concurrently. // global_data() concurrently.
struct call_global_mutex { call_global_mutex() { global_mutex(); } }; struct call_global_mutex { call_global_mutex() { global_mutex(); } };
static call_global_mutex call_global_mutex_instance; static call_global_mutex call_global_mutex_instance;
event_handler_thread& globals() const shared_ptr_thread_safe<event_handler_thread>& global_data()
{ {
global_mutex()->lock(); auto_mutex M(*global_mutex());
try static shared_ptr_thread_safe<event_handler_thread> p;
{ if (p.get() == 0)
static event_handler_thread* p = new event_handler_thread; p.reset(new event_handler_thread());
global_mutex()->unlock(); return p;
p->start_event_thread();
return *p;
}
catch (...)
{
global_mutex()->unlock();
throw;
}
} }
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().existing_base_windows == 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 struct ebh_param
...@@ -691,8 +659,10 @@ namespace dlib ...@@ -691,8 +659,10 @@ namespace dlib
SetThreadPriority(hand,THREAD_PRIORITY_ABOVE_NORMAL); SetThreadPriority(hand,THREAD_PRIORITY_ABOVE_NORMAL);
CloseHandle(hand); CloseHandle(hand);
window_table_type& window_table = globals().window_table; shared_ptr_thread_safe<event_handler_thread> globals(global_data());
HWND& helper_window = globals().helper_window;
window_table_type& window_table = globals->window_table;
HWND& helper_window = globals->helper_window;
auto_mutex M(window_table.get_mutex()); auto_mutex M(window_table.get_mutex());
...@@ -708,7 +678,7 @@ namespace dlib ...@@ -708,7 +678,7 @@ namespace dlib
case WM_USER+QUIT_EVENT_HANDLER_THREAD: case WM_USER+QUIT_EVENT_HANDLER_THREAD:
if (hwnd == helper_window) if (hwnd == helper_window)
{ {
globals().quit_windows_loop = true; globals->quit_windows_loop = true;
PostQuitMessage(0); PostQuitMessage(0);
} }
return 0; return 0;
...@@ -724,14 +694,14 @@ namespace dlib ...@@ -724,14 +694,14 @@ namespace dlib
if (hwnd == helper_window) if (hwnd == helper_window)
{ {
MoveWindow( MoveWindow(
globals().move_window_hwnd, globals->move_window_hwnd,
globals().move_window_x, globals->move_window_x,
globals().move_window_y, globals->move_window_y,
globals().move_window_width, globals->move_window_width,
globals().move_window_height, globals->move_window_height,
TRUE); TRUE);
globals().move_window_done = true; globals->move_window_done = true;
globals().et_signaler.broadcast(); globals->et_signaler.broadcast();
} }
return 0; return 0;
...@@ -739,14 +709,14 @@ namespace dlib ...@@ -739,14 +709,14 @@ namespace dlib
if (hwnd == helper_window) if (hwnd == helper_window)
{ {
// this is the signal to look in the user_events queue // this is the signal to look in the user_events queue
globals().user_events.lock(); globals->user_events.lock();
globals().user_events.swap(globals().user_events_temp); globals->user_events.swap(globals->user_events_temp);
globals().user_events.unlock(); globals->user_events.unlock();
globals().user_events_temp.reset(); globals->user_events_temp.reset();
// now dispatch all these user events // now dispatch all these user events
while (globals().user_events_temp.move_next()) while (globals->user_events_temp.move_next())
{ {
base_window** win_ = window_table[globals().user_events_temp.element().w]; base_window** win_ = window_table[globals->user_events_temp.element().w];
base_window* win; base_window* win;
// if this window exists in the window table then dispatch // if this window exists in the window table then dispatch
// its event. // its event.
...@@ -754,12 +724,12 @@ namespace dlib ...@@ -754,12 +724,12 @@ namespace dlib
{ {
win = *win_; win = *win_;
win->on_user_event( win->on_user_event(
globals().user_events_temp.element().p, globals->user_events_temp.element().p,
globals().user_events_temp.element().i globals->user_events_temp.element().i
); );
} }
} }
globals().user_events_temp.clear(); globals->user_events_temp.clear();
} }
return 0; return 0;
...@@ -788,9 +758,9 @@ namespace dlib ...@@ -788,9 +758,9 @@ namespace dlib
case WM_USER+CALL_SET_WINDOW_TITLE: case WM_USER+CALL_SET_WINDOW_TITLE:
if (hwnd == helper_window) if (hwnd == helper_window)
{ {
SetWindowTextW((HWND)wParam,globals().window_title.c_str()); SetWindowTextW((HWND)wParam,globals->window_title.c_str());
globals().set_window_title_done = true; globals->set_window_title_done = true;
globals().et_signaler.broadcast(); globals->et_signaler.broadcast();
} }
return 0; return 0;
...@@ -800,36 +770,36 @@ namespace dlib ...@@ -800,36 +770,36 @@ namespace dlib
{ {
// if this is stupposed to be a popup window then do the popup window thing // if this is stupposed to be a popup window then do the popup window thing
if (globals().dwStyle == WS_CHILD) if (globals->dwStyle == WS_CHILD)
{ {
TCHAR nothing[] = TEXT(""); TCHAR nothing[] = TEXT("");
globals().new_window = CreateWindowEx (WS_EX_TOOLWINDOW,globals().window_class_name, nothing, globals->new_window = CreateWindowEx (WS_EX_TOOLWINDOW,globals->window_class_name, nothing,
globals().dwStyle, globals->dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
helper_window, NULL, globals().hInstance, NULL); helper_window, NULL, globals->hInstance, NULL);
SetParent(globals().new_window,NULL); SetParent(globals->new_window,NULL);
} }
else else
{ {
TCHAR nothing[] = TEXT(""); TCHAR nothing[] = TEXT("");
globals().new_window = CreateWindow (globals().window_class_name, nothing, globals->new_window = CreateWindow (globals->window_class_name, nothing,
globals().dwStyle, globals->dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, globals().hInstance, NULL); NULL, NULL, globals->hInstance, NULL);
} }
// use the helper_window to indicate that CreateWindow failed // use the helper_window to indicate that CreateWindow failed
if (globals().new_window == NULL) if (globals->new_window == NULL)
globals().new_window = helper_window; globals->new_window = helper_window;
globals().et_signaler.broadcast(); globals->et_signaler.broadcast();
} }
return 0; return 0;
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
case WM_KEYDOWN: case WM_KEYDOWN:
{ {
if (globals().in_ime_composition) break; if (globals->in_ime_composition) break;
base_window** win_ = window_table[hwnd]; base_window** win_ = window_table[hwnd];
base_window* win; base_window* win;
...@@ -1350,7 +1320,7 @@ namespace dlib ...@@ -1350,7 +1320,7 @@ namespace dlib
window_table.destroy(hwnd); window_table.destroy(hwnd);
win->has_been_destroyed = true; win->has_been_destroyed = true;
win->hwnd = 0; win->hwnd = 0;
globals().window_close_signaler.broadcast(); globals->window_close_signaler.broadcast();
} }
else else
{ {
...@@ -1364,12 +1334,12 @@ namespace dlib ...@@ -1364,12 +1334,12 @@ namespace dlib
return DefWindowProc (hwnd, message, wParam, lParam); return DefWindowProc (hwnd, message, wParam, lParam);
case WM_IME_STARTCOMPOSITION: case WM_IME_STARTCOMPOSITION:
globals().in_ime_composition = true; globals->in_ime_composition = true;
break; break;
case WM_IME_COMPOSITION: case WM_IME_COMPOSITION:
{ {
globals().in_ime_composition = false; globals->in_ime_composition = false;
base_window** win_ = window_table[hwnd]; base_window** win_ = window_table[hwnd];
base_window* win; base_window* win;
if (win_) if (win_)
...@@ -1407,12 +1377,12 @@ namespace dlib ...@@ -1407,12 +1377,12 @@ namespace dlib
catch (std::exception& e) catch (std::exception& e)
{ {
error_box("Exception thrown in event handler",e.what()); error_box("Exception thrown in event handler",e.what());
globals().quit_windows_loop = true; globals->quit_windows_loop = true;
} }
catch (...) catch (...)
{ {
error_box("Exception thrown in event handler","Unknown Exception type."); error_box("Exception thrown in event handler","Unknown Exception type.");
globals().quit_windows_loop = true; globals->quit_windows_loop = true;
} }
return DefWindowProc (hwnd, message, wParam, lParam) ; return DefWindowProc (hwnd, message, wParam, lParam) ;
...@@ -1426,7 +1396,7 @@ namespace dlib ...@@ -1426,7 +1396,7 @@ namespace dlib
) )
{ {
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
PostMessage(globals().helper_window,WM_USER+SHOW_WINDOW_SHOW,(WPARAM)hwnd,0); PostMessage(global_data()->helper_window,WM_USER+SHOW_WINDOW_SHOW,(WPARAM)hwnd,0);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1436,7 +1406,7 @@ namespace dlib ...@@ -1436,7 +1406,7 @@ namespace dlib
) )
{ {
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
PostMessage(globals().helper_window,WM_USER+SHOW_WINDOW_HIDE,(WPARAM)hwnd,0); PostMessage(global_data()->helper_window,WM_USER+SHOW_WINDOW_HIDE,(WPARAM)hwnd,0);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1450,7 +1420,7 @@ namespace dlib ...@@ -1450,7 +1420,7 @@ namespace dlib
!*/ !*/
{ {
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
PostMessage(globals().helper_window,WM_USER+SET_ACTIVE_WINDOW,(WPARAM)hwnd,0); PostMessage(global_data()->helper_window,WM_USER+SET_ACTIVE_WINDOW,(WPARAM)hwnd,0);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1464,7 +1434,7 @@ namespace dlib ...@@ -1464,7 +1434,7 @@ namespace dlib
!*/ !*/
{ {
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
PostMessage(globals().helper_window,WM_USER+DESTROY_WINDOW,(WPARAM)hwnd,0); PostMessage(global_data()->helper_window,WM_USER+DESTROY_WINDOW,(WPARAM)hwnd,0);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1483,58 +1453,59 @@ namespace dlib ...@@ -1483,58 +1453,59 @@ namespace dlib
!*/ !*/
{ {
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
// if we are running in the event handling thread then just call // if we are running in the event handling thread then just call
// CreateWindow directly // CreateWindow directly
if (get_thread_id() == 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 this is stupposed to be a popup window then do the popup window thing
if (dwStyle_ == WS_CHILD) if (dwStyle_ == WS_CHILD)
{ {
TCHAR nothing[] = TEXT(""); TCHAR nothing[] = TEXT("");
HWND tmp = CreateWindowEx (WS_EX_TOOLWINDOW|WS_EX_TOPMOST, globals().window_class_name, nothing, HWND tmp = CreateWindowEx (WS_EX_TOOLWINDOW|WS_EX_TOPMOST, globals->window_class_name, nothing,
dwStyle_, dwStyle_,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
globals().helper_window, NULL, globals().hInstance, NULL); globals->helper_window, NULL, globals->hInstance, NULL);
SetParent(tmp,NULL); SetParent(tmp,NULL);
return tmp; return tmp;
} }
else else
{ {
TCHAR nothing[] = TEXT(""); TCHAR nothing[] = TEXT("");
return CreateWindow (globals().window_class_name, nothing, return CreateWindow (globals->window_class_name, nothing,
dwStyle_, dwStyle_,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, globals().hInstance, NULL); NULL, NULL, globals->hInstance, NULL);
} }
} }
else else
{ {
auto_mutex M(globals().window_table.get_mutex()); auto_mutex M(globals->window_table.get_mutex());
// wait for our chance to make a new window request // wait for our chance to make a new window request
while (globals().request_new_window) while (globals->request_new_window)
globals().et_signaler.wait(); globals->et_signaler.wait();
globals().dwStyle = dwStyle_; globals->dwStyle = dwStyle_;
if (PostMessage(globals().helper_window,WM_USER+CREATE_WINDOW,0,0)==0) 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."); throw gui_error("Unable to schedule function for execution in event handling thread.");
} }
// wait for our request to be serviced // wait for our request to be serviced
while (globals().new_window == NULL) while (globals->new_window == NULL)
globals().et_signaler.wait(); globals->et_signaler.wait();
HWND temp = globals().new_window; HWND temp = globals->new_window;
globals().new_window = NULL; globals->new_window = NULL;
globals().request_new_window = false; globals->request_new_window = false;
globals().et_signaler.broadcast(); globals->et_signaler.broadcast();
// if make_window() returns the helper_window then it means it failed // if make_window() returns the helper_window then it means it failed
// to make a new window // to make a new window
if (temp == globals().helper_window) if (temp == globals->helper_window)
temp = NULL; temp = NULL;
return temp; return temp;
...@@ -1602,17 +1573,18 @@ namespace dlib ...@@ -1602,17 +1573,18 @@ namespace dlib
) )
{ {
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
user_event_type e; user_event_type e;
e.w = hwnd; e.w = hwnd;
e.p = p; e.p = p;
e.i = i; e.i = i;
{ {
auto_mutex M(globals().user_events.get_mutex()); auto_mutex M(globals->user_events.get_mutex());
globals().user_events.enqueue(e); globals->user_events.enqueue(e);
} }
if (PostMessage(globals().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."); throw gui_error("Unable to schedule function for execution in event handling thread.");
} }
...@@ -1625,11 +1597,12 @@ namespace dlib ...@@ -1625,11 +1597,12 @@ namespace dlib
bool resizable, bool resizable,
bool undecorated bool undecorated
) : ) :
globals(gui_core_kernel_1_globals::global_data()),
has_been_destroyed(false), has_been_destroyed(false),
prevx(-1), prevx(-1),
prevy(-1), prevy(-1),
prev_state(0), prev_state(0),
wm(gui_core_kernel_1_globals::globals().window_table.get_mutex()) wm(globals->window_table.get_mutex())
{ {
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
DLIB_ASSERT(!(undecorated == true && resizable == true), DLIB_ASSERT(!(undecorated == true && resizable == true),
...@@ -1656,8 +1629,7 @@ namespace dlib ...@@ -1656,8 +1629,7 @@ namespace dlib
HWND temp = hwnd; HWND temp = hwnd;
base_window* ttemp = this; base_window* ttemp = this;
globals().window_table.add(temp,ttemp); globals->window_table.add(temp,ttemp);
globals().existing_base_windows += 1;
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1668,21 +1640,6 @@ namespace dlib ...@@ -1668,21 +1640,6 @@ namespace dlib
{ {
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
close_window(); 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();
globals().existing_base_windows -= 1;
if (globals().existing_base_windows == 0 && globals().should_destruct == true)
{
wm.unlock();
delete &globals();
}
else
{
// don't do anything except remember to unlock the wm mutex
wm.unlock();
}
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1697,11 +1654,11 @@ namespace dlib ...@@ -1697,11 +1654,11 @@ namespace dlib
{ {
// do this just to make sure no one tries to call this window's // do this just to make sure no one tries to call this window's
// calbacks. // calbacks.
globals().window_table.destroy(hwnd); globals->window_table.destroy(hwnd);
gui_core_kernel_1_globals::destroy_window(hwnd); gui_core_kernel_1_globals::destroy_window(hwnd);
hwnd = 0; hwnd = 0;
has_been_destroyed = true; has_been_destroyed = true;
globals().window_close_signaler.broadcast(); globals->window_close_signaler.broadcast();
} }
} }
...@@ -1714,7 +1671,7 @@ namespace dlib ...@@ -1714,7 +1671,7 @@ namespace dlib
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
auto_mutex M(wm); auto_mutex M(wm);
while (has_been_destroyed == false) while (has_been_destroyed == false)
globals().window_close_signaler.wait(); globals->window_close_signaler.wait();
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1763,23 +1720,23 @@ namespace dlib ...@@ -1763,23 +1720,23 @@ namespace dlib
// do this to avoid possible deadlocks. // do this to avoid possible deadlocks.
auto_mutex M(wm); auto_mutex M(wm);
if (get_thread_id() == globals().event_thread_id) if (get_thread_id() == globals->event_thread_id)
{ {
SetWindowTextW(hwnd,title.c_str()); SetWindowTextW(hwnd,title.c_str());
} }
else else
{ {
globals().window_title = title; globals->window_title = title;
globals().set_window_title_done = false; globals->set_window_title_done = false;
if (PostMessage(globals().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."); throw gui_error("Unable to schedule SetWindowText function for execution in event handling thread.");
} }
// wait for any SetWindowText() calls to finish // wait for any SetWindowText() calls to finish
while (globals().set_window_title_done == false) while (globals->set_window_title_done == false)
globals().et_signaler.wait(); globals->et_signaler.wait();
} }
} }
...@@ -1832,7 +1789,7 @@ namespace dlib ...@@ -1832,7 +1789,7 @@ namespace dlib
<< "\n\theight: " << height_ << "\n\theight: " << height_
); );
auto_mutex M(wm); auto_mutex M(wm);
if (get_thread_id() == globals().event_thread_id) if (get_thread_id() == globals->event_thread_id)
{ {
RECT info; RECT info;
GetWindowRect(hwnd,&info); GetWindowRect(hwnd,&info);
...@@ -1884,21 +1841,21 @@ namespace dlib ...@@ -1884,21 +1841,21 @@ namespace dlib
// have to do this because the MoveWindow() apparently blocks // have to do this because the MoveWindow() apparently blocks
// until something happens in the event thread so we have to // until something happens in the event thread so we have to
// do this to avoid possible deadlocks. // do this to avoid possible deadlocks.
globals().move_window_hwnd = hwnd; globals->move_window_hwnd = hwnd;
globals().move_window_x = x; globals->move_window_x = x;
globals().move_window_y = y; globals->move_window_y = y;
globals().move_window_width = width; globals->move_window_width = width;
globals().move_window_height = height; globals->move_window_height = height;
globals().move_window_done = false; globals->move_window_done = false;
if (PostMessage(globals().helper_window,WM_USER+CALL_MOVE_WINDOW,0,0)==0) 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."); throw gui_error("Unable to schedule MoveWindow function for execution in event handling thread.");
} }
// wait for any MoveWindow calls to finish // wait for any MoveWindow calls to finish
while (globals().move_window_done == false) while (globals->move_window_done == false)
globals().et_signaler.wait(); globals->et_signaler.wait();
} }
} }
...@@ -1920,7 +1877,7 @@ namespace dlib ...@@ -1920,7 +1877,7 @@ namespace dlib
<< "\n\ty: " << y_ << "\n\ty: " << y_
); );
auto_mutex M(wm); auto_mutex M(wm);
if (get_thread_id() == globals().event_thread_id) if (get_thread_id() == globals->event_thread_id)
{ {
RECT info; RECT info;
GetWindowRect(hwnd,&info); GetWindowRect(hwnd,&info);
...@@ -1949,21 +1906,21 @@ namespace dlib ...@@ -1949,21 +1906,21 @@ namespace dlib
// have to do this because the MoveWindow() apparently blocks // have to do this because the MoveWindow() apparently blocks
// until something happens in the event thread so we have to // until something happens in the event thread so we have to
// do this to avoid possible deadlocks. // do this to avoid possible deadlocks.
globals().move_window_hwnd = hwnd; globals->move_window_hwnd = hwnd;
globals().move_window_x = x_; globals->move_window_x = x_;
globals().move_window_y = y_; globals->move_window_y = y_;
globals().move_window_width = width; globals->move_window_width = width;
globals().move_window_height = height; globals->move_window_height = height;
globals().move_window_done = false; globals->move_window_done = false;
if (PostMessage(globals().helper_window,WM_USER+CALL_MOVE_WINDOW,0,0)==0) 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."); throw gui_error("Unable to schedule MoveWindow function for execution in event handling thread.");
} }
// wait for any MoveWindow calls to finish // wait for any MoveWindow calls to finish
while (globals().move_window_done == false) while (globals->move_window_done == false)
globals().et_signaler.wait(); globals->et_signaler.wait();
} }
} }
...@@ -2107,10 +2064,12 @@ namespace dlib ...@@ -2107,10 +2064,12 @@ namespace dlib
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
using namespace std; using namespace std;
if (OpenClipboard(globals().helper_window)) shared_ptr_thread_safe<event_handler_thread> globals(global_data());
if (OpenClipboard(globals->helper_window))
{ {
EmptyClipboard(); EmptyClipboard();
auto_mutex M(globals().window_table.get_mutex()); auto_mutex M(globals->window_table.get_mutex());
const unsigned long newlines = count(str.begin(),str.end(),L'\n'); const unsigned long newlines = count(str.begin(),str.end(),L'\n');
...@@ -2172,9 +2131,10 @@ namespace dlib ...@@ -2172,9 +2131,10 @@ namespace dlib
{ {
using namespace gui_core_kernel_1_globals; using namespace gui_core_kernel_1_globals;
using namespace std; using namespace std;
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
auto_mutex M(globals().window_table.get_mutex()); auto_mutex M(globals->window_table.get_mutex());
if (OpenClipboard(globals().helper_window)) if (OpenClipboard(globals->helper_window))
{ {
HANDLE data = GetClipboardData(CF_UNICODETEXT); HANDLE data = GetClipboardData(CF_UNICODETEXT);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "../queue.h" #include "../queue.h"
#include "../pixel.h" #include "../pixel.h"
#include "../unicode.h" #include "../unicode.h"
#include "../smart_pointers_thread_safe.h"
namespace dlib namespace dlib
...@@ -51,6 +52,7 @@ namespace dlib ...@@ -51,6 +52,7 @@ namespace dlib
{ {
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
class event_handler_thread;
} }
...@@ -164,6 +166,7 @@ namespace dlib ...@@ -164,6 +166,7 @@ namespace dlib
class base_window class base_window
{ {
friend LRESULT CALLBACK gui_core_kernel_1_globals::WndProc (HWND, UINT, WPARAM, LPARAM); friend LRESULT CALLBACK gui_core_kernel_1_globals::WndProc (HWND, UINT, WPARAM, LPARAM);
shared_ptr_thread_safe<event_handler_thread> globals;
HWND hwnd; HWND hwnd;
DWORD style; DWORD style;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "../logger.h" #include "../logger.h"
#include <vector> #include <vector>
#include <set> #include <set>
#include "../smart_pointers_thread_safe.h"
namespace dlib namespace dlib
{ {
...@@ -33,14 +34,6 @@ namespace dlib ...@@ -33,14 +34,6 @@ namespace dlib
namespace gui_core_kernel_2_globals namespace gui_core_kernel_2_globals
{ {
void init_keyboard_mod_masks(); void init_keyboard_mod_masks();
struct x11_base_windowstuff
{
Window hwnd;
Time last_click_time;
XIC xic;
XFontSet fs;
};
struct user_event_type struct user_event_type
{ {
Window w; Window w;
...@@ -75,8 +68,6 @@ namespace dlib ...@@ -75,8 +68,6 @@ namespace dlib
et_state status; et_state status;
logger dlog; logger dlog;
// this is true if the application is trying to end
bool should_destruct;
int depth; int depth;
Display* disp; Display* disp;
...@@ -99,7 +90,6 @@ namespace dlib ...@@ -99,7 +90,6 @@ namespace dlib
rsignaler window_close_signaler; rsignaler window_close_signaler;
rsignaler et_signaler; rsignaler et_signaler;
unsigned long existing_base_windows;
queue_of_user_events user_events; queue_of_user_events user_events;
queue_of_user_events user_events_temp; queue_of_user_events user_events_temp;
...@@ -107,7 +97,6 @@ namespace dlib ...@@ -107,7 +97,6 @@ namespace dlib
event_handler_thread( event_handler_thread(
) : ) :
dlog("dlib.gui_core"), dlog("dlib.gui_core"),
should_destruct(false),
depth(0), depth(0),
disp(0), disp(0),
xim(0), xim(0),
...@@ -117,8 +106,7 @@ namespace dlib ...@@ -117,8 +106,7 @@ namespace dlib
num_lock_mask(0), num_lock_mask(0),
scroll_lock_mask(0), scroll_lock_mask(0),
window_close_signaler(window_table.get_mutex()), window_close_signaler(window_table.get_mutex()),
et_signaler(window_table.get_mutex()), et_signaler(window_table.get_mutex())
existing_base_windows(0)
{ {
auto_mutex M(window_table.get_mutex()); auto_mutex M(window_table.get_mutex());
...@@ -310,38 +298,29 @@ namespace dlib ...@@ -310,38 +298,29 @@ namespace dlib
void init_keyboard_mod_masks(); void init_keyboard_mod_masks();
}; };
struct x11_base_windowstuff
{
Window hwnd;
Time last_click_time;
XIC xic;
XFontSet fs;
shared_ptr_thread_safe<event_handler_thread> globals;
};
// Do all this just to make sure global_mutex() is initialized at program start // Do all this just to make sure global_mutex() is initialized at program start
// and thus hopefully before any threads have the chance to startup and call // and thus hopefully before any threads have the chance to startup and call
// globals() concurrently. // global_data() concurrently.
struct call_global_mutex { call_global_mutex() { global_mutex(); } }; struct call_global_mutex { call_global_mutex() { global_mutex(); } };
static call_global_mutex call_global_mutex_instance; static call_global_mutex call_global_mutex_instance;
event_handler_thread& globals() const shared_ptr_thread_safe<event_handler_thread>& global_data()
{ {
auto_mutex M(*global_mutex()); auto_mutex M(*global_mutex());
static event_handler_thread* p = new event_handler_thread(); static shared_ptr_thread_safe<event_handler_thread> p;
return *p; if (p.get() == 0)
} p.reset(new event_handler_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().existing_base_windows == 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;
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1365,10 +1344,13 @@ namespace dlib ...@@ -1365,10 +1344,13 @@ namespace dlib
) )
{ {
using namespace gui_core_kernel_2_globals; using namespace gui_core_kernel_2_globals;
auto_mutex M(globals().window_table.get_mutex());
globals().clipboard = str.c_str();
XSetSelectionOwner(globals().disp,XA_PRIMARY,globals().exit_window,CurrentTime); shared_ptr_thread_safe<event_handler_thread> globals(global_data());
auto_mutex M(globals->window_table.get_mutex());
globals->clipboard = str.c_str();
XSetSelectionOwner(globals->disp,XA_PRIMARY,globals->exit_window,CurrentTime);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1412,7 +1394,9 @@ namespace dlib ...@@ -1412,7 +1394,9 @@ namespace dlib
) )
{ {
using namespace gui_core_kernel_2_globals; using namespace gui_core_kernel_2_globals;
auto_mutex M(globals().window_table.get_mutex()); shared_ptr_thread_safe<event_handler_thread> globals(global_data());
auto_mutex M(globals->window_table.get_mutex());
str.clear(); str.clear();
unsigned char *data = 0; unsigned char *data = 0;
wchar_t **plist = 0; wchar_t **plist = 0;
...@@ -1424,12 +1408,12 @@ namespace dlib ...@@ -1424,12 +1408,12 @@ namespace dlib
try try
{ {
Atom atom_ct = XInternAtom(globals().disp, "COMPOUND_TEXT", False); Atom atom_ct = XInternAtom(globals->disp, "COMPOUND_TEXT", False);
sown = XGetSelectionOwner (globals().disp, XA_PRIMARY); sown = XGetSelectionOwner (globals->disp, XA_PRIMARY);
if (sown == globals().exit_window) if (sown == globals->exit_window)
{ {
// if we are copying from ourselfs then don't fool with the Xwindows junk. // if we are copying from ourselfs then don't fool with the Xwindows junk.
str = globals().clipboard.c_str(); str = globals->clipboard.c_str();
} }
else if (sown != None) else if (sown != None)
{ {
...@@ -1437,15 +1421,15 @@ namespace dlib ...@@ -1437,15 +1421,15 @@ namespace dlib
// of the exit_window. It doesn't matter what window we put it in // of the exit_window. It doesn't matter what window we put it in
// so long as it is one under the control of this process and exit_window // so long as it is one under the control of this process and exit_window
// is easy to use here so that is what I'm using. // is easy to use here so that is what I'm using.
XConvertSelection (globals().disp, XA_PRIMARY, atom_ct, XA_PRIMARY, XConvertSelection (globals->disp, XA_PRIMARY, atom_ct, XA_PRIMARY,
globals().exit_window, CurrentTime); globals->exit_window, CurrentTime);
// This will wait until we get a SelectionNotify event which should happen // This will wait until we get a SelectionNotify event which should happen
// really soon. // really soon.
XPeekIfEvent(globals().disp,&e,clip_peek_helper,0); XPeekIfEvent(globals->disp,&e,clip_peek_helper,0);
// See how much data we got // See how much data we got
XGetWindowProperty (globals().disp, globals().exit_window, XGetWindowProperty (globals->disp, globals->exit_window,
XA_PRIMARY, // Tricky.. XA_PRIMARY, // Tricky..
0, 0, // offset - len 0, 0, // offset - len
0, // Delete 0==FALSE 0, // Delete 0==FALSE
...@@ -1462,14 +1446,14 @@ namespace dlib ...@@ -1462,14 +1446,14 @@ namespace dlib
if (bytes_left > 0 && type == atom_ct) if (bytes_left > 0 && type == atom_ct)
{ {
XTextProperty p; XTextProperty p;
result = XGetWindowProperty (globals().disp, globals().exit_window, result = XGetWindowProperty (globals->disp, globals->exit_window,
XA_PRIMARY, 0,bytes_left,0, XA_PRIMARY, 0,bytes_left,0,
AnyPropertyType, &p.encoding,&p.format, AnyPropertyType, &p.encoding,&p.format,
&p.nitems, &dummy, &p.value); &p.nitems, &dummy, &p.value);
if (result == Success && p.encoding == atom_ct) if (result == Success && p.encoding == atom_ct)
{ {
int n; int n;
XwcTextPropertyToTextList(globals().disp, &p, &plist, &n); XwcTextPropertyToTextList(globals->disp, &p, &plist, &n);
str = plist[0]; str = plist[0];
} }
if (plist) if (plist)
...@@ -1500,18 +1484,19 @@ namespace dlib ...@@ -1500,18 +1484,19 @@ namespace dlib
void* void*
) )
{ {
auto_mutex M(globals().window_table.get_mutex()); shared_ptr_thread_safe<event_handler_thread> globals(global_data());
auto_mutex M(globals->window_table.get_mutex());
globals().user_events.lock(); globals->user_events.lock();
globals().user_events.swap(globals().user_events_temp); globals->user_events.swap(globals->user_events_temp);
globals().user_events.unlock(); globals->user_events.unlock();
globals().user_events_temp.reset(); globals->user_events_temp.reset();
// now dispatch all these user events // now dispatch all these user events
while (globals().user_events_temp.move_next()) while (globals->user_events_temp.move_next())
{ {
base_window** win_ = globals().window_table[globals().user_events_temp.element().w]; base_window** win_ = globals->window_table[globals->user_events_temp.element().w];
base_window* win; base_window* win;
// if this window exists in the window table then dispatch // if this window exists in the window table then dispatch
// its event. // its event.
...@@ -1519,12 +1504,12 @@ namespace dlib ...@@ -1519,12 +1504,12 @@ namespace dlib
{ {
win = *win_; win = *win_;
win->on_user_event( win->on_user_event(
globals().user_events_temp.element().p, globals->user_events_temp.element().p,
globals().user_events_temp.element().i globals->user_events_temp.element().i
); );
} }
} }
globals().user_events_temp.clear(); globals->user_events_temp.clear();
} }
} }
...@@ -1540,12 +1525,13 @@ namespace dlib ...@@ -1540,12 +1525,13 @@ namespace dlib
e.p = p; e.p = p;
e.i = i; e.i = i;
{ {
auto_mutex M(globals().user_events.get_mutex()); shared_ptr_thread_safe<event_handler_thread> globals(global_data());
globals().user_events.enqueue(e); auto_mutex M(globals->user_events.get_mutex());
globals->user_events.enqueue(e);
// we only need to start a thread to deal with this if there isn't already // we only need to start a thread to deal with this if there isn't already
// one out working on the queue // one out working on the queue
if (globals().user_events.size() == 1) if (globals->user_events.size() == 1)
create_new_thread (trigger_user_event_threadproc,0); create_new_thread (trigger_user_event_threadproc,0);
} }
} }
...@@ -1563,7 +1549,7 @@ namespace dlib ...@@ -1563,7 +1549,7 @@ namespace dlib
has_been_destroyed(false), has_been_destroyed(false),
has_been_resized(false), has_been_resized(false),
has_been_moved(false), has_been_moved(false),
wm(gui_core_kernel_2_globals::globals().window_table.get_mutex()) wm(gui_core_kernel_2_globals::global_data()->window_table.get_mutex())
{ {
DLIB_ASSERT(!(undecorated == true && resizable_ == true), DLIB_ASSERT(!(undecorated == true && resizable_ == true),
"\tbase_window::base_window()" "\tbase_window::base_window()"
...@@ -1574,6 +1560,8 @@ namespace dlib ...@@ -1574,6 +1560,8 @@ namespace dlib
auto_mutex M(wm); auto_mutex M(wm);
x11_stuff.globals = global_data();
x11_stuff.last_click_time = 0; x11_stuff.last_click_time = 0;
last_click_x = 0; last_click_x = 0;
last_click_y = 0; last_click_y = 0;
...@@ -1591,14 +1579,14 @@ namespace dlib ...@@ -1591,14 +1579,14 @@ namespace dlib
x11_stuff.hwnd = XCreateWindow( x11_stuff.hwnd = XCreateWindow(
globals().disp, x11_stuff.globals->disp,
DefaultRootWindow(globals().disp), DefaultRootWindow(x11_stuff.globals->disp),
0, 0,
0, 0,
10, // this is the default width of a window 10, // this is the default width of a window
10, // this is the default width of a window 10, // this is the default width of a window
0, 0,
globals().depth, x11_stuff.globals->depth,
InputOutput, InputOutput,
CopyFromParent, CopyFromParent,
valuemask, valuemask,
...@@ -1606,7 +1594,7 @@ namespace dlib ...@@ -1606,7 +1594,7 @@ namespace dlib
); );
x11_stuff.xic = NULL; x11_stuff.xic = NULL;
if (globals().xim) if (x11_stuff.globals->xim)
{ {
XVaNestedList xva_nlist; XVaNestedList xva_nlist;
XPoint xpoint; XPoint xpoint;
...@@ -1617,13 +1605,13 @@ namespace dlib ...@@ -1617,13 +1605,13 @@ namespace dlib
char fontset[256]; char fontset[256];
const long native_font_height = 12; const long native_font_height = 12;
sprintf(fontset, "-*-*-medium-r-normal--%lu-*-*-*-", native_font_height); sprintf(fontset, "-*-*-medium-r-normal--%lu-*-*-*-", native_font_height);
x11_stuff.fs = XCreateFontSet(globals().disp, fontset, &mlist, &mcount, &def_str); x11_stuff.fs = XCreateFontSet(x11_stuff.globals->disp, fontset, &mlist, &mcount, &def_str);
xpoint.x = 0; xpoint.x = 0;
xpoint.y = 0; xpoint.y = 0;
xva_nlist = XVaCreateNestedList(0, XNSpotLocation, &xpoint, XNFontSet, x11_stuff.fs, (const void*)NULL); xva_nlist = XVaCreateNestedList(0, XNSpotLocation, &xpoint, XNFontSet, x11_stuff.fs, (const void*)NULL);
x11_stuff.xic = XCreateIC( x11_stuff.xic = XCreateIC(
globals().xim, x11_stuff.globals->xim,
XNInputStyle, globals().xim_style, XNInputStyle, x11_stuff.globals->xim_style,
XNClientWindow, x11_stuff.hwnd, XNClientWindow, x11_stuff.hwnd,
XNPreeditAttributes, xva_nlist, XNPreeditAttributes, xva_nlist,
(const void*)NULL (const void*)NULL
...@@ -1634,8 +1622,7 @@ namespace dlib ...@@ -1634,8 +1622,7 @@ namespace dlib
Window temp = x11_stuff.hwnd; Window temp = x11_stuff.hwnd;
base_window* ttemp = this; base_window* ttemp = this;
globals().window_table.add(temp,ttemp); x11_stuff.globals->window_table.add(temp,ttemp);
globals().existing_base_windows += 1;
// query event mask required by input method // query event mask required by input method
unsigned long event_xim = 0; unsigned long event_xim = 0;
...@@ -1643,7 +1630,7 @@ namespace dlib ...@@ -1643,7 +1630,7 @@ namespace dlib
XGetICValues( x11_stuff.xic, XNFilterEvents, &event_xim, (const void*)NULL ); XGetICValues( x11_stuff.xic, XNFilterEvents, &event_xim, (const void*)NULL );
XSelectInput( XSelectInput(
globals().disp, x11_stuff.globals->disp,
x11_stuff.hwnd, x11_stuff.hwnd,
StructureNotifyMask|ExposureMask|ButtonPressMask|ButtonReleaseMask| StructureNotifyMask|ExposureMask|ButtonPressMask|ButtonReleaseMask|
PointerMotionMask|LeaveWindowMask|EnterWindowMask|KeyPressMask| PointerMotionMask|LeaveWindowMask|EnterWindowMask|KeyPressMask|
...@@ -1651,9 +1638,9 @@ namespace dlib ...@@ -1651,9 +1638,9 @@ namespace dlib
); );
XSetWMProtocols( XSetWMProtocols(
globals().disp, x11_stuff.globals->disp,
x11_stuff.hwnd, x11_stuff.hwnd,
&globals().delete_window, &x11_stuff.globals->delete_window,
1 1
); );
...@@ -1672,7 +1659,7 @@ namespace dlib ...@@ -1672,7 +1659,7 @@ namespace dlib
hints->max_width = width; hints->max_width = width;
hints->max_height = height; hints->max_height = height;
hints->min_height = height; hints->min_height = height;
XSetNormalHints(globals().disp,x11_stuff.hwnd,hints); XSetNormalHints(x11_stuff.globals->disp,x11_stuff.hwnd,hints);
XFree(hints); XFree(hints);
} }
} }
...@@ -1686,21 +1673,6 @@ namespace dlib ...@@ -1686,21 +1673,6 @@ namespace dlib
using namespace gui_core_kernel_2_globals; using namespace gui_core_kernel_2_globals;
close_window(); close_window();
delete &x11_stuff; delete &x11_stuff;
// 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();
globals().existing_base_windows -= 1;
if (globals().existing_base_windows == 0 && globals().should_destruct == true)
{
wm.unlock();
delete &globals();
}
else
{
// don't do anything except remember to unlock the wm mutex
wm.unlock();
}
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1715,17 +1687,17 @@ namespace dlib ...@@ -1715,17 +1687,17 @@ namespace dlib
{ {
has_been_destroyed = true; has_been_destroyed = true;
globals().window_table.destroy(x11_stuff.hwnd); x11_stuff.globals->window_table.destroy(x11_stuff.hwnd);
if (globals().xim != NULL) if (x11_stuff.globals->xim != NULL)
{ {
XDestroyIC(x11_stuff.xic); XDestroyIC(x11_stuff.xic);
x11_stuff.xic = 0; x11_stuff.xic = 0;
XFreeFontSet(globals().disp,x11_stuff.fs); XFreeFontSet(x11_stuff.globals->disp,x11_stuff.fs);
} }
XDestroyWindow(globals().disp,x11_stuff.hwnd); XDestroyWindow(x11_stuff.globals->disp,x11_stuff.hwnd);
x11_stuff.hwnd = 0; x11_stuff.hwnd = 0;
globals().window_close_signaler.broadcast(); x11_stuff.globals->window_close_signaler.broadcast();
} }
} }
...@@ -1773,10 +1745,10 @@ namespace dlib ...@@ -1773,10 +1745,10 @@ namespace dlib
// it isn't const anymore. // it isn't const anymore.
wchar_t *title = const_cast<wchar_t *>(title_.c_str()); wchar_t *title = const_cast<wchar_t *>(title_.c_str());
XTextProperty property; XTextProperty property;
XwcTextListToTextProperty(globals().disp,&title,1,XStdICCTextStyle, &property); XwcTextListToTextProperty(x11_stuff.globals->disp,&title,1,XStdICCTextStyle, &property);
XSetWMName(globals().disp,x11_stuff.hwnd,&property); XSetWMName(x11_stuff.globals->disp,x11_stuff.hwnd,&property);
XFree(property.value); XFree(property.value);
XFlush(globals().disp); XFlush(x11_stuff.globals->disp);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1792,8 +1764,8 @@ namespace dlib ...@@ -1792,8 +1764,8 @@ namespace dlib
<< "\n\tYou can't do this to a window that has been closed." << "\n\tYou can't do this to a window that has been closed."
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
XMapRaised(globals().disp,x11_stuff.hwnd); XMapRaised(x11_stuff.globals->disp,x11_stuff.hwnd);
XFlush(globals().disp); XFlush(x11_stuff.globals->disp);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1805,7 +1777,7 @@ namespace dlib ...@@ -1805,7 +1777,7 @@ namespace dlib
using namespace gui_core_kernel_2_globals; using namespace gui_core_kernel_2_globals;
auto_mutex M(wm); auto_mutex M(wm);
while (has_been_destroyed == false) while (has_been_destroyed == false)
globals().window_close_signaler.wait(); x11_stuff.globals->window_close_signaler.wait();
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1821,8 +1793,8 @@ namespace dlib ...@@ -1821,8 +1793,8 @@ namespace dlib
<< "\n\tYou can't do this to a window that has been closed." << "\n\tYou can't do this to a window that has been closed."
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
XUnmapWindow(globals().disp,x11_stuff.hwnd); XUnmapWindow(x11_stuff.globals->disp,x11_stuff.hwnd);
XFlush(globals().disp); XFlush(x11_stuff.globals->disp);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1861,13 +1833,13 @@ namespace dlib ...@@ -1861,13 +1833,13 @@ namespace dlib
hints->max_width = width; hints->max_width = width;
hints->max_height = height; hints->max_height = height;
hints->min_height = height; hints->min_height = height;
XSetNormalHints(globals().disp,x11_stuff.hwnd,hints); XSetNormalHints(x11_stuff.globals->disp,x11_stuff.hwnd,hints);
XFree(hints); XFree(hints);
} }
XResizeWindow(globals().disp,x11_stuff.hwnd,width,height); XResizeWindow(x11_stuff.globals->disp,x11_stuff.hwnd,width,height);
XFlush(globals().disp); XFlush(x11_stuff.globals->disp);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1893,8 +1865,8 @@ namespace dlib ...@@ -1893,8 +1865,8 @@ namespace dlib
has_been_moved = true; has_been_moved = true;
XMoveWindow(globals().disp,x11_stuff.hwnd,x,y); XMoveWindow(x11_stuff.globals->disp,x11_stuff.hwnd,x,y);
XFlush(globals().disp); XFlush(x11_stuff.globals->disp);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1917,9 +1889,9 @@ namespace dlib ...@@ -1917,9 +1889,9 @@ namespace dlib
// will have reported bogus values back in the ConfigureNotify event. So just to be // will have reported bogus values back in the ConfigureNotify event. So just to be
// on the safe side we will use XTranslateCoordinates() // on the safe side we will use XTranslateCoordinates()
int rx, ry; int rx, ry;
Window desktop_window = DefaultRootWindow(globals().disp); Window desktop_window = DefaultRootWindow(x11_stuff.globals->disp);
Window junk; Window junk;
XTranslateCoordinates(globals().disp,x11_stuff.hwnd,desktop_window,0,0,&rx, &ry, &junk); XTranslateCoordinates(x11_stuff.globals->disp,x11_stuff.hwnd,desktop_window,0,0,&rx, &ry, &junk);
x_ = rx; x_ = rx;
y_ = ry; y_ = ry;
x = rx; x = rx;
...@@ -1961,9 +1933,9 @@ namespace dlib ...@@ -1961,9 +1933,9 @@ namespace dlib
<< "\n\tthis: " << this << "\n\tthis: " << this
); );
int screen_number = XScreenNumberOfScreen(globals().screen); int screen_number = XScreenNumberOfScreen(x11_stuff.globals->screen);
width_ = DisplayWidth(globals().disp, screen_number); width_ = DisplayWidth(x11_stuff.globals->disp, screen_number);
height_ = DisplayHeight(globals().disp, screen_number); height_ = DisplayHeight(x11_stuff.globals->disp, screen_number);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -1985,8 +1957,8 @@ namespace dlib ...@@ -1985,8 +1957,8 @@ namespace dlib
const unsigned long width = rect.width(); const unsigned long width = rect.width();
const unsigned long height = rect.height(); const unsigned long height = rect.height();
XClearArea(globals().disp,x11_stuff.hwnd,x,y,width,height,1); XClearArea(x11_stuff.globals->disp,x11_stuff.hwnd,x,y,width,height,1);
XFlush(globals().disp); XFlush(x11_stuff.globals->disp);
} }
} }
...@@ -2000,7 +1972,7 @@ namespace dlib ...@@ -2000,7 +1972,7 @@ namespace dlib
{ {
using namespace gui_core_kernel_2_globals; using namespace gui_core_kernel_2_globals;
auto_mutex a(wm); auto_mutex a(wm);
if (!x11_stuff.xic || !(globals().xim_style & XIMPreeditPosition)) return; if (!x11_stuff.xic || !(x11_stuff.globals->xim_style & XIMPreeditPosition)) return;
XVaNestedList xva_nlist; XVaNestedList xva_nlist;
XPoint xpoint; XPoint xpoint;
......
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