r1053: Add Russian translation.
[cinelerra_cv.git] / guicast / bcwindowevents.C
blob5baf8004ff65e7c82f7fe8650982bf016233cfa0
1 #include "bcwindowbase.h"
2 #include "bcwindowevents.h"
3 #include "bctimer.h"
5 BC_WindowEvents::BC_WindowEvents(BC_WindowBase *window)
6  : Thread(1, 0, 0)
8         this->window = window;
9         done = 0;
12 BC_WindowEvents::~BC_WindowEvents()
14 // First set done, then send dummy event through XSendEvent to unlock the loop in ::run()
15         done = 1;
16         XEvent event;
17         XClientMessageEvent *ptr = (XClientMessageEvent*)&event;
18         event.type = ClientMessage;
19         ptr->message_type = XInternAtom(window->display, "DUMMY_XATOM", False);
20         ptr->format = 32;
21         XSendEvent(window->display, 
22                 window->win, 
23                 0, 
24                 0, 
25                 &event);
26         window->flush();
27         Thread::join();
30 void BC_WindowEvents::start()
32         done = 0;
33         Thread::start();
37 void BC_WindowEvents::run()
39 // Can't cancel in XNextEvent because X server never figures out it's not
40 // listening anymore and XCloseDisplay locks up.
41         XEvent *event;
42         while(!done)
43         {
44 // XNextEvent should also be protected by XLockDisplay ...
45 // Currently implemented is a hackish solution, FIXME
46 // Impact of this solution on the performance has not been analyzed
48 // The proper solution is HARD because of :
49 // 1. idiotic xlib does not have XTryLockDisplay - we will need to _completely_ implement XLockDisplay by ourselves (including cascaded locking - it is not the same as mutex!)
50 // 2. the locking shemantic inside new lock_window and here will be really tricky, we should:
51 //      in lock_window check wheather BC_WindowEvents is in XNextEvent and it is send custom xevent to break out of the loop and make sure lock is not taken again if lock_window() is waiting on it
52 // 3. Send custom events from previous point through _separate_ xwindows display connection since XSendEvent would need to be protected by XLockDisplay which obviously can't be
54                 window->lock_window();
55                 while (XPending(window->display))
56                 {
57                         event = new XEvent;
58                         XNextEvent(window->display, event);
59                         window->put_event(event);
60                 }
61                 
62                 window->unlock_window();
63                 Timer::delay(20);    // sleep 20ms
64         }