4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcdisplay.h"
23 #include "bcsignals.h"
24 #include "bcwindowbase.h"
25 #include "bcwindowevents.h"
27 #include "condition.h"
30 BC_WindowEvents::BC_WindowEvents(BC_WindowBase *window)
33 this->window = window;
39 BC_WindowEvents::BC_WindowEvents(BC_Display *display)
42 this->display = display;
47 BC_WindowEvents::~BC_WindowEvents()
49 // no more external events, send one last event into X to flush out all of the
50 // pending events so that no straglers or shm leaks are possible.
51 //printf("BC_WindowEvents::~BC_WindowEvents %d %s\n", __LINE__, window->title);
52 XSelectInput(window->display, window->win, 0);
53 XEvent event; memset(&event,0,sizeof(event));
54 XClientMessageEvent *ptr = (XClientMessageEvent*)&event;
55 event.type = ClientMessage;
56 ptr->message_type = window->DestroyAtom;
58 XSendEvent(window->display, window->win, 0, 0, &event);
61 //printf("BC_WindowEvents::~BC_WindowEvents %d %s\n", __LINE__, window->title);
64 void BC_WindowEvents::start()
71 void BC_WindowEvents::run()
73 // Can't cancel in XNextEvent because X server never figures out it's not
74 // listening anymore and XCloseDisplay locks up.
78 int x_fd = ConnectionNumber(window->display);
85 // Can't cancel in XNextEvent because X server never figures out it's not
86 // listening anymore and XCloseDisplay locks up.
89 XNextEvent(display->display, event);
91 // This came from a linuxquestions post.
92 // We can get a file descriptor for the X display & use select instead of XNextEvent.
93 // The newest X11 library requires locking the display to use XNextEvent.
99 tv.tv_sec = 0; tv.tv_usec = 200000;
100 //printf("BC_WindowEvents::run %d %s\n", __LINE__, window->title);
101 select(x_fd + 1, &x_fds, 0, 0, &tv);
105 XLockDisplay(window->display);
106 while(!done && XPending(window->display))
109 XNextEvent(window->display, event);
111 if( event->type == BC_WindowBase::shm_completion_event ) {
112 window->active_bitmaps.reque(event);
116 if( event->type == ClientMessage ) {
117 XClientMessageEvent *ptr = (XClientMessageEvent*)event;
118 if( ptr->message_type == window->DestroyAtom ) {
124 #ifndef SINGLE_THREAD
125 // HACK: delay is required to get the close event
127 //if(window && event)
128 //printf("BC_WindowEvents::run %d %s %d\n", __LINE__, window->title, event->type);
129 window->put_event(event);
131 XUnlockDisplay(window->display);
132 //printf("BC_WindowEvents::run %d %s\n", __LINE__, window->title);
134 display->put_event(event);