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
HWND helper_window;
const TCHAR* window_class_name;
bool should_destruct;
bool quit_windows_loop;
bool set_window_title_done;
std::wstring window_title;
......@@ -114,7 +113,6 @@ namespace dlib
window_table_type window_table;
rsignaler window_close_signaler;
rsignaler et_signaler;
unsigned long existing_base_windows;
// note that this is the thread that will perform all the event
// processing.
......@@ -126,7 +124,6 @@ namespace dlib
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),
......@@ -141,8 +138,7 @@ namespace dlib
in_ime_composition(false),
event_thread_started(false),
window_close_signaler(window_table.get_mutex()),
et_signaler(window_table.get_mutex()),
existing_base_windows(0)
et_signaler(window_table.get_mutex())
{
status = uninitialized;
}
......@@ -280,47 +276,19 @@ namespace dlib
// 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
// globals() concurrently.
// global_data() concurrently.
struct call_global_mutex { call_global_mutex() { global_mutex(); } };
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();
try
{
static event_handler_thread* p = new event_handler_thread;
global_mutex()->unlock();
p->start_event_thread();
return *p;
}
catch (...)
{
global_mutex()->unlock();
throw;
}
auto_mutex M(*global_mutex());
static shared_ptr_thread_safe<event_handler_thread> 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;
// ----------------------------------------------------------------------------------------
struct ebh_param
......@@ -691,8 +659,10 @@ namespace dlib
SetThreadPriority(hand,THREAD_PRIORITY_ABOVE_NORMAL);
CloseHandle(hand);
window_table_type& window_table = globals().window_table;
HWND& helper_window = globals().helper_window;
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
window_table_type& window_table = globals->window_table;
HWND& helper_window = globals->helper_window;
auto_mutex M(window_table.get_mutex());
......@@ -708,7 +678,7 @@ namespace dlib
case WM_USER+QUIT_EVENT_HANDLER_THREAD:
if (hwnd == helper_window)
{
globals().quit_windows_loop = true;
globals->quit_windows_loop = true;
PostQuitMessage(0);
}
return 0;
......@@ -724,14 +694,14 @@ namespace dlib
if (hwnd == helper_window)
{
MoveWindow(
globals().move_window_hwnd,
globals().move_window_x,
globals().move_window_y,
globals().move_window_width,
globals().move_window_height,
globals->move_window_hwnd,
globals->move_window_x,
globals->move_window_y,
globals->move_window_width,
globals->move_window_height,
TRUE);
globals().move_window_done = true;
globals().et_signaler.broadcast();
globals->move_window_done = true;
globals->et_signaler.broadcast();
}
return 0;
......@@ -739,14 +709,14 @@ namespace dlib
if (hwnd == helper_window)
{
// this is the signal to look in the user_events queue
globals().user_events.lock();
globals().user_events.swap(globals().user_events_temp);
globals().user_events.unlock();
globals().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 (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;
// if this window exists in the window table then dispatch
// its event.
......@@ -754,12 +724,12 @@ namespace dlib
{
win = *win_;
win->on_user_event(
globals().user_events_temp.element().p,
globals().user_events_temp.element().i
globals->user_events_temp.element().p,
globals->user_events_temp.element().i
);
}
}
globals().user_events_temp.clear();
globals->user_events_temp.clear();
}
return 0;
......@@ -788,9 +758,9 @@ namespace dlib
case WM_USER+CALL_SET_WINDOW_TITLE:
if (hwnd == helper_window)
{
SetWindowTextW((HWND)wParam,globals().window_title.c_str());
globals().set_window_title_done = true;
globals().et_signaler.broadcast();
SetWindowTextW((HWND)wParam,globals->window_title.c_str());
globals->set_window_title_done = true;
globals->et_signaler.broadcast();
}
return 0;
......@@ -800,36 +770,36 @@ namespace dlib
{
// 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("");
globals().new_window = CreateWindowEx (WS_EX_TOOLWINDOW,globals().window_class_name, nothing,
globals().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, globals().hInstance, NULL);
SetParent(globals().new_window,NULL);
helper_window, NULL, globals->hInstance, NULL);
SetParent(globals->new_window,NULL);
}
else
{
TCHAR nothing[] = TEXT("");
globals().new_window = CreateWindow (globals().window_class_name, nothing,
globals().dwStyle,
globals->new_window = CreateWindow (globals->window_class_name, nothing,
globals->dwStyle,
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
if (globals().new_window == NULL)
globals().new_window = helper_window;
globals().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 (globals().in_ime_composition) break;
if (globals->in_ime_composition) break;
base_window** win_ = window_table[hwnd];
base_window* win;
......@@ -1350,7 +1320,7 @@ namespace dlib
window_table.destroy(hwnd);
win->has_been_destroyed = true;
win->hwnd = 0;
globals().window_close_signaler.broadcast();
globals->window_close_signaler.broadcast();
}
else
{
......@@ -1364,12 +1334,12 @@ namespace dlib
return DefWindowProc (hwnd, message, wParam, lParam);
case WM_IME_STARTCOMPOSITION:
globals().in_ime_composition = true;
globals->in_ime_composition = true;
break;
case WM_IME_COMPOSITION:
{
globals().in_ime_composition = false;
globals->in_ime_composition = false;
base_window** win_ = window_table[hwnd];
base_window* win;
if (win_)
......@@ -1407,12 +1377,12 @@ namespace dlib
catch (std::exception& e)
{
error_box("Exception thrown in event handler",e.what());
globals().quit_windows_loop = true;
globals->quit_windows_loop = true;
}
catch (...)
{
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) ;
......@@ -1426,7 +1396,7 @@ namespace dlib
)
{
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
)
{
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
!*/
{
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
!*/
{
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
!*/
{
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
// 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 (dwStyle_ == WS_CHILD)
{
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_,
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);
return tmp;
}
else
{
TCHAR nothing[] = TEXT("");
return CreateWindow (globals().window_class_name, nothing,
return CreateWindow (globals->window_class_name, nothing,
dwStyle_,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, globals().hInstance, NULL);
NULL, NULL, globals->hInstance, NULL);
}
}
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
while (globals().request_new_window)
globals().et_signaler.wait();
while (globals->request_new_window)
globals->et_signaler.wait();
globals().dwStyle = dwStyle_;
if (PostMessage(globals().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 (globals().new_window == NULL)
globals().et_signaler.wait();
while (globals->new_window == NULL)
globals->et_signaler.wait();
HWND temp = globals().new_window;
globals().new_window = NULL;
globals().request_new_window = false;
globals().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 == globals().helper_window)
if (temp == globals->helper_window)
temp = NULL;
return temp;
......@@ -1602,17 +1573,18 @@ namespace dlib
)
{
using namespace gui_core_kernel_1_globals;
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
user_event_type e;
e.w = hwnd;
e.p = p;
e.i = i;
{
auto_mutex M(globals().user_events.get_mutex());
globals().user_events.enqueue(e);
auto_mutex M(globals->user_events.get_mutex());
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.");
}
......@@ -1625,11 +1597,12 @@ namespace dlib
bool resizable,
bool undecorated
) :
globals(gui_core_kernel_1_globals::global_data()),
has_been_destroyed(false),
prevx(-1),
prevy(-1),
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;
DLIB_ASSERT(!(undecorated == true && resizable == true),
......@@ -1656,8 +1629,7 @@ namespace dlib
HWND temp = hwnd;
base_window* ttemp = this;
globals().window_table.add(temp,ttemp);
globals().existing_base_windows += 1;
globals->window_table.add(temp,ttemp);
}
// ----------------------------------------------------------------------------------------
......@@ -1668,21 +1640,6 @@ namespace dlib
{
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();
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
{
// do this just to make sure no one tries to call this window's
// calbacks.
globals().window_table.destroy(hwnd);
globals->window_table.destroy(hwnd);
gui_core_kernel_1_globals::destroy_window(hwnd);
hwnd = 0;
has_been_destroyed = true;
globals().window_close_signaler.broadcast();
globals->window_close_signaler.broadcast();
}
}
......@@ -1714,7 +1671,7 @@ namespace dlib
using namespace gui_core_kernel_1_globals;
auto_mutex M(wm);
while (has_been_destroyed == false)
globals().window_close_signaler.wait();
globals->window_close_signaler.wait();
}
// ----------------------------------------------------------------------------------------
......@@ -1763,23 +1720,23 @@ namespace dlib
// do this to avoid possible deadlocks.
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());
}
else
{
globals().window_title = title;
globals().set_window_title_done = false;
globals->window_title = title;
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.");
}
// wait for any SetWindowText() calls to finish
while (globals().set_window_title_done == false)
globals().et_signaler.wait();
while (globals->set_window_title_done == false)
globals->et_signaler.wait();
}
}
......@@ -1832,7 +1789,7 @@ namespace dlib
<< "\n\theight: " << height_
);
auto_mutex M(wm);
if (get_thread_id() == globals().event_thread_id)
if (get_thread_id() == globals->event_thread_id)
{
RECT info;
GetWindowRect(hwnd,&info);
......@@ -1884,21 +1841,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.
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;
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)
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 (globals().move_window_done == false)
globals().et_signaler.wait();
while (globals->move_window_done == false)
globals->et_signaler.wait();
}
}
......@@ -1920,7 +1877,7 @@ namespace dlib
<< "\n\ty: " << y_
);
auto_mutex M(wm);
if (get_thread_id() == globals().event_thread_id)
if (get_thread_id() == globals->event_thread_id)
{
RECT info;
GetWindowRect(hwnd,&info);
......@@ -1949,21 +1906,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.
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;
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)
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 (globals().move_window_done == false)
globals().et_signaler.wait();
while (globals->move_window_done == false)
globals->et_signaler.wait();
}
}
......@@ -2107,10 +2064,12 @@ namespace dlib
using namespace gui_core_kernel_1_globals;
using namespace std;
if (OpenClipboard(globals().helper_window))
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
if (OpenClipboard(globals->helper_window))
{
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');
......@@ -2172,9 +2131,10 @@ namespace dlib
{
using namespace gui_core_kernel_1_globals;
using namespace std;
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
auto_mutex M(globals().window_table.get_mutex());
if (OpenClipboard(globals().helper_window))
auto_mutex M(globals->window_table.get_mutex());
if (OpenClipboard(globals->helper_window))
{
HANDLE data = GetClipboardData(CF_UNICODETEXT);
......
......@@ -39,6 +39,7 @@
#include "../queue.h"
#include "../pixel.h"
#include "../unicode.h"
#include "../smart_pointers_thread_safe.h"
namespace dlib
......@@ -51,6 +52,7 @@ namespace dlib
{
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
class event_handler_thread;
}
......@@ -164,6 +166,7 @@ namespace dlib
class base_window
{
friend LRESULT CALLBACK gui_core_kernel_1_globals::WndProc (HWND, UINT, WPARAM, LPARAM);
shared_ptr_thread_safe<event_handler_thread> globals;
HWND hwnd;
DWORD style;
......
......@@ -24,6 +24,7 @@
#include "../logger.h"
#include <vector>
#include <set>
#include "../smart_pointers_thread_safe.h"
namespace dlib
{
......@@ -33,14 +34,6 @@ namespace dlib
namespace gui_core_kernel_2_globals
{
void init_keyboard_mod_masks();
struct x11_base_windowstuff
{
Window hwnd;
Time last_click_time;
XIC xic;
XFontSet fs;
};
struct user_event_type
{
Window w;
......@@ -75,8 +68,6 @@ namespace dlib
et_state status;
logger dlog;
// this is true if the application is trying to end
bool should_destruct;
int depth;
Display* disp;
......@@ -99,7 +90,6 @@ namespace dlib
rsignaler window_close_signaler;
rsignaler et_signaler;
unsigned long existing_base_windows;
queue_of_user_events user_events;
queue_of_user_events user_events_temp;
......@@ -107,7 +97,6 @@ namespace dlib
event_handler_thread(
) :
dlog("dlib.gui_core"),
should_destruct(false),
depth(0),
disp(0),
xim(0),
......@@ -117,8 +106,7 @@ namespace dlib
num_lock_mask(0),
scroll_lock_mask(0),
window_close_signaler(window_table.get_mutex()),
et_signaler(window_table.get_mutex()),
existing_base_windows(0)
et_signaler(window_table.get_mutex())
{
auto_mutex M(window_table.get_mutex());
......@@ -310,38 +298,29 @@ namespace dlib
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
// 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(); } };
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());
static event_handler_thread* p = 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();
static shared_ptr_thread_safe<event_handler_thread> p;
if (p.get() == 0)
p.reset(new event_handler_thread());
return p;
}
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
)
{
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
)
{
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();
unsigned char *data = 0;
wchar_t **plist = 0;
......@@ -1424,12 +1408,12 @@ namespace dlib
try
{
Atom atom_ct = XInternAtom(globals().disp, "COMPOUND_TEXT", False);
sown = XGetSelectionOwner (globals().disp, XA_PRIMARY);
if (sown == globals().exit_window)
Atom atom_ct = XInternAtom(globals->disp, "COMPOUND_TEXT", False);
sown = XGetSelectionOwner (globals->disp, XA_PRIMARY);
if (sown == globals->exit_window)
{
// 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)
{
......@@ -1437,15 +1421,15 @@ namespace dlib
// 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
// is easy to use here so that is what I'm using.
XConvertSelection (globals().disp, XA_PRIMARY, atom_ct, XA_PRIMARY,
globals().exit_window, CurrentTime);
XConvertSelection (globals->disp, XA_PRIMARY, atom_ct, XA_PRIMARY,
globals->exit_window, CurrentTime);
// This will wait until we get a SelectionNotify event which should happen
// really soon.
XPeekIfEvent(globals().disp,&e,clip_peek_helper,0);
XPeekIfEvent(globals->disp,&e,clip_peek_helper,0);
// See how much data we got
XGetWindowProperty (globals().disp, globals().exit_window,
XGetWindowProperty (globals->disp, globals->exit_window,
XA_PRIMARY, // Tricky..
0, 0, // offset - len
0, // Delete 0==FALSE
......@@ -1462,14 +1446,14 @@ namespace dlib
if (bytes_left > 0 && type == atom_ct)
{
XTextProperty p;
result = XGetWindowProperty (globals().disp, globals().exit_window,
result = XGetWindowProperty (globals->disp, globals->exit_window,
XA_PRIMARY, 0,bytes_left,0,
AnyPropertyType, &p.encoding,&p.format,
&p.nitems, &dummy, &p.value);
if (result == Success && p.encoding == atom_ct)
{
int n;
XwcTextPropertyToTextList(globals().disp, &p, &plist, &n);
XwcTextPropertyToTextList(globals->disp, &p, &plist, &n);
str = plist[0];
}
if (plist)
......@@ -1500,18 +1484,19 @@ namespace dlib
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.swap(globals().user_events_temp);
globals().user_events.unlock();
globals->user_events.lock();
globals->user_events.swap(globals->user_events_temp);
globals->user_events.unlock();
globals().user_events_temp.reset();
globals->user_events_temp.reset();
// 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;
// if this window exists in the window table then dispatch
// its event.
......@@ -1519,12 +1504,12 @@ namespace dlib
{
win = *win_;
win->on_user_event(
globals().user_events_temp.element().p,
globals().user_events_temp.element().i
globals->user_events_temp.element().p,
globals->user_events_temp.element().i
);
}
}
globals().user_events_temp.clear();
globals->user_events_temp.clear();
}
}
......@@ -1540,12 +1525,13 @@ namespace dlib
e.p = p;
e.i = i;
{
auto_mutex M(globals().user_events.get_mutex());
globals().user_events.enqueue(e);
shared_ptr_thread_safe<event_handler_thread> globals(global_data());
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
// 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);
}
}
......@@ -1563,7 +1549,7 @@ namespace dlib
has_been_destroyed(false),
has_been_resized(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),
"\tbase_window::base_window()"
......@@ -1574,6 +1560,8 @@ namespace dlib
auto_mutex M(wm);
x11_stuff.globals = global_data();
x11_stuff.last_click_time = 0;
last_click_x = 0;
last_click_y = 0;
......@@ -1591,14 +1579,14 @@ namespace dlib
x11_stuff.hwnd = XCreateWindow(
globals().disp,
DefaultRootWindow(globals().disp),
x11_stuff.globals->disp,
DefaultRootWindow(x11_stuff.globals->disp),
0,
0,
10, // this is the default width of a window
10, // this is the default width of a window
0,
globals().depth,
x11_stuff.globals->depth,
InputOutput,
CopyFromParent,
valuemask,
......@@ -1606,7 +1594,7 @@ namespace dlib
);
x11_stuff.xic = NULL;
if (globals().xim)
if (x11_stuff.globals->xim)
{
XVaNestedList xva_nlist;
XPoint xpoint;
......@@ -1617,13 +1605,13 @@ namespace dlib
char fontset[256];
const long native_font_height = 12;
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.y = 0;
xva_nlist = XVaCreateNestedList(0, XNSpotLocation, &xpoint, XNFontSet, x11_stuff.fs, (const void*)NULL);
x11_stuff.xic = XCreateIC(
globals().xim,
XNInputStyle, globals().xim_style,
x11_stuff.globals->xim,
XNInputStyle, x11_stuff.globals->xim_style,
XNClientWindow, x11_stuff.hwnd,
XNPreeditAttributes, xva_nlist,
(const void*)NULL
......@@ -1634,8 +1622,7 @@ namespace dlib
Window temp = x11_stuff.hwnd;
base_window* ttemp = this;
globals().window_table.add(temp,ttemp);
globals().existing_base_windows += 1;
x11_stuff.globals->window_table.add(temp,ttemp);
// query event mask required by input method
unsigned long event_xim = 0;
......@@ -1643,7 +1630,7 @@ namespace dlib
XGetICValues( x11_stuff.xic, XNFilterEvents, &event_xim, (const void*)NULL );
XSelectInput(
globals().disp,
x11_stuff.globals->disp,
x11_stuff.hwnd,
StructureNotifyMask|ExposureMask|ButtonPressMask|ButtonReleaseMask|
PointerMotionMask|LeaveWindowMask|EnterWindowMask|KeyPressMask|
......@@ -1651,9 +1638,9 @@ namespace dlib
);
XSetWMProtocols(
globals().disp,
x11_stuff.globals->disp,
x11_stuff.hwnd,
&globals().delete_window,
&x11_stuff.globals->delete_window,
1
);
......@@ -1672,7 +1659,7 @@ namespace dlib
hints->max_width = width;
hints->max_height = height;
hints->min_height = height;
XSetNormalHints(globals().disp,x11_stuff.hwnd,hints);
XSetNormalHints(x11_stuff.globals->disp,x11_stuff.hwnd,hints);
XFree(hints);
}
}
......@@ -1686,21 +1673,6 @@ namespace dlib
using namespace gui_core_kernel_2_globals;
close_window();
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
{
has_been_destroyed = true;
globals().window_table.destroy(x11_stuff.hwnd);
if (globals().xim != NULL)
x11_stuff.globals->window_table.destroy(x11_stuff.hwnd);
if (x11_stuff.globals->xim != NULL)
{
XDestroyIC(x11_stuff.xic);
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;
globals().window_close_signaler.broadcast();
x11_stuff.globals->window_close_signaler.broadcast();
}
}
......@@ -1773,10 +1745,10 @@ namespace dlib
// it isn't const anymore.
wchar_t *title = const_cast<wchar_t *>(title_.c_str());
XTextProperty property;
XwcTextListToTextProperty(globals().disp,&title,1,XStdICCTextStyle, &property);
XSetWMName(globals().disp,x11_stuff.hwnd,&property);
XwcTextListToTextProperty(x11_stuff.globals->disp,&title,1,XStdICCTextStyle, &property);
XSetWMName(x11_stuff.globals->disp,x11_stuff.hwnd,&property);
XFree(property.value);
XFlush(globals().disp);
XFlush(x11_stuff.globals->disp);
}
// ----------------------------------------------------------------------------------------
......@@ -1792,8 +1764,8 @@ namespace dlib
<< "\n\tYou can't do this to a window that has been closed."
<< "\n\tthis: " << this
);
XMapRaised(globals().disp,x11_stuff.hwnd);
XFlush(globals().disp);
XMapRaised(x11_stuff.globals->disp,x11_stuff.hwnd);
XFlush(x11_stuff.globals->disp);
}
// ----------------------------------------------------------------------------------------
......@@ -1805,7 +1777,7 @@ namespace dlib
using namespace gui_core_kernel_2_globals;
auto_mutex M(wm);
while (has_been_destroyed == false)
globals().window_close_signaler.wait();
x11_stuff.globals->window_close_signaler.wait();
}
// ----------------------------------------------------------------------------------------
......@@ -1821,8 +1793,8 @@ namespace dlib
<< "\n\tYou can't do this to a window that has been closed."
<< "\n\tthis: " << this
);
XUnmapWindow(globals().disp,x11_stuff.hwnd);
XFlush(globals().disp);
XUnmapWindow(x11_stuff.globals->disp,x11_stuff.hwnd);
XFlush(x11_stuff.globals->disp);
}
// ----------------------------------------------------------------------------------------
......@@ -1861,13 +1833,13 @@ namespace dlib
hints->max_width = width;
hints->max_height = height;
hints->min_height = height;
XSetNormalHints(globals().disp,x11_stuff.hwnd,hints);
XSetNormalHints(x11_stuff.globals->disp,x11_stuff.hwnd,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
has_been_moved = true;
XMoveWindow(globals().disp,x11_stuff.hwnd,x,y);
XFlush(globals().disp);
XMoveWindow(x11_stuff.globals->disp,x11_stuff.hwnd,x,y);
XFlush(x11_stuff.globals->disp);
}
// ----------------------------------------------------------------------------------------
......@@ -1917,9 +1889,9 @@ namespace dlib
// will have reported bogus values back in the ConfigureNotify event. So just to be
// on the safe side we will use XTranslateCoordinates()
int rx, ry;
Window desktop_window = DefaultRootWindow(globals().disp);
Window desktop_window = DefaultRootWindow(x11_stuff.globals->disp);
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;
y_ = ry;
x = rx;
......@@ -1961,9 +1933,9 @@ namespace dlib
<< "\n\tthis: " << this
);
int screen_number = XScreenNumberOfScreen(globals().screen);
width_ = DisplayWidth(globals().disp, screen_number);
height_ = DisplayHeight(globals().disp, screen_number);
int screen_number = XScreenNumberOfScreen(x11_stuff.globals->screen);
width_ = DisplayWidth(x11_stuff.globals->disp, screen_number);
height_ = DisplayHeight(x11_stuff.globals->disp, screen_number);
}
// ----------------------------------------------------------------------------------------
......@@ -1985,8 +1957,8 @@ namespace dlib
const unsigned long width = rect.width();
const unsigned long height = rect.height();
XClearArea(globals().disp,x11_stuff.hwnd,x,y,width,height,1);
XFlush(globals().disp);
XClearArea(x11_stuff.globals->disp,x11_stuff.hwnd,x,y,width,height,1);
XFlush(x11_stuff.globals->disp);
}
}
......@@ -2000,7 +1972,7 @@ namespace dlib
{
using namespace gui_core_kernel_2_globals;
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;
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