1 // wminterface.cc for bbtools.
2 //
3 // Copyright (c) 1998-2000 by John Kennis, jkennis@chello.nl
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //
19 // (See the included file COPYING / GPL-2.0)
20 //
21
22 #include "wminterface.h"
23 #include "resource.h"
24
25 #include <stdio.h>
26
WMInterface(ToolWindow * toolwindow)27 WMInterface::WMInterface(ToolWindow *toolwindow) :
28 bt::EventHandler(), bbtool(toolwindow)
29 {
30 root_window = bbtool->getCurrentScreenInfo()->rootWindow();
31 XSelectInput(bbtool->XDisplay(), root_window, PropertyChangeMask);
32 bbtool->insertEventHandler(root_window, this);
33 ewmh = bbtool->ewmh();
34 }
35
~WMInterface()36 WMInterface::~WMInterface()
37 {
38 }
39
sendClientMessage(Window window,Atom atom,XID data,XID data1)40 void WMInterface::sendClientMessage(Window window, Atom atom, XID data, XID data1) {
41 XEvent e;
42 unsigned long mask;
43
44 e.xclient.type = ClientMessage;
45 e.xclient.window = window;
46 e.xclient.message_type = atom;
47 e.xclient.format = 32;
48 e.xclient.data.l[0] = (unsigned long) data;
49 e.xclient.data.l[1] = (unsigned long) data1;
50 mask = SubstructureRedirectMask;
51 XSendEvent(bbtool->XDisplay(),
52 root_window,
53 False, mask, &e);
54 }
55
56
updateWindowList(void)57 void WMInterface::updateWindowList(void)
58 {
59 bt::EWMH::WindowList window_vect;
60 PagerWindow *pwindow;
61
62 if (ewmh->readClientList(bbtool->getCurrentScreenInfo()->rootWindow(), window_vect)) {
63 /* add any new window windows */
64 bt::EWMH::WindowList::iterator it = window_vect.begin();
65 bt::EWMH::WindowList::iterator it_end = window_vect.end();
66 for (; it != it_end; it++) {
67 // skip myself
68 if ((*it) == bbtool->frameWindow()->window())
69 {
70 continue;
71 }
72 pwindow = bbtool->findPagerWindow((*it));
73 if ( pwindow == NULL) {
74 PagerWindow *pager_window = new PagerWindow(bbtool, *it);
75 bbtool->pagerWindowList().push_back(pager_window);
76 } else {
77 pwindow->mark(true);
78 }
79 }
80 /* delete any windows not in list */
81 std::list<PagerWindow *>::iterator pit = bbtool->pagerWindowList().begin();
82 std::list<PagerWindow *>::iterator pit_end = bbtool->pagerWindowList().end();
83
84 for (; pit != pit_end; pit++) {
85 if (!(*pit)->isMarked()) {
86 delete (*pit);
87 bbtool->pagerWindowList().erase(pit);
88 pit--;
89 } else {
90 }
91 }
92
93 }
94 }
95
updateWindowStack()96 void WMInterface::updateWindowStack()
97 {
98 bt::EWMH::WindowList window_vect;
99 if (ewmh->readClientListStacking(bbtool->getCurrentScreenInfo()->rootWindow(), window_vect)) {
100 // some check to see if we need update
101 PagerWindow *pwindow;
102 bt::EWMH::WindowList::iterator it = window_vect.begin();
103 bt::EWMH::WindowList::iterator it_end = window_vect.end();
104 for (; it != it_end; it++) {
105 pwindow = bbtool->findPagerWindow((*it));
106 if ( pwindow == NULL) continue;
107 pwindow->raise();
108 }
109 }
110 }
111
112
changeDesktop(int desk_number)113 void WMInterface::changeDesktop(int desk_number)
114 {
115
116 sendClientMessage(root_window, ewmh->currentDesktop(), desk_number);
117 }
118
119
sendWindowToDesktop(Window win,int desk_number)120 void WMInterface::sendWindowToDesktop(Window win,int desk_number)
121 {
122 sendClientMessage(win, ewmh->wmDesktop(), desk_number);
123 }
124
setWindowFocus(Window win)125 void WMInterface::setWindowFocus(Window win)
126 {
127 //ewmh->setActiveWindow(root_window, win);
128 sendClientMessage(win, ewmh->activeWindow(), win);
129
130 }
131
isIconicState(Window win)132 int WMInterface::isIconicState(Window win)
133 {
134 Atom real_type;
135 int format;
136 unsigned long n, extra;
137 int status;
138 long *p=0;
139 int result = -1;
140
141 status = XGetWindowProperty(bbtool->XDisplay(), win,
142 bbtool->wmStateAtom(), 0L, 1L,
143 False, bbtool->wmStateAtom(), &real_type,
144 &format, &n, &extra, (unsigned char**)&p);
145 if (!status) {
146 if (p) {
147 result = (p[0]==IconicState) ? 1 : 0;
148 XFree(p);
149 } else
150 result = 0;
151 }
152
153 return(result);
154 }
155
changeNumberOfDesktops(int number_of_desktops)156 void WMInterface::changeNumberOfDesktops(int number_of_desktops)
157 {
158 int old_number_of_desktops = bbtool->getNumberOfDesktops();
159 bbtool->setNumberOfDesktops(number_of_desktops);
160 if (number_of_desktops > old_number_of_desktops) {
161 int i;
162 for (i=old_number_of_desktops;i<number_of_desktops;i++) {
163 bbtool->addDesktopWindow(i);
164 }
165 } else if (number_of_desktops<old_number_of_desktops)
166 bbtool->removeDesktopWindow();
167 }
168
169
readActiveWindow(Window target,Window * active)170 bool WMInterface::readActiveWindow(Window target, Window *active)
171 {
172 unsigned char* data = NULL;
173 if (ewmh->getProperty(target, XA_WINDOW, ewmh->activeWindow(), &data)) {
174 *active = * (reinterpret_cast<Window *>(data));
175 XFree(data);
176 return True;
177 }
178 return False;
179 }
180
181 //property notify events, send to root window.
propertyNotifyEvent(const XPropertyEvent * const event)182 void WMInterface::propertyNotifyEvent(const XPropertyEvent * const event)
183 {
184 if (event->atom == ewmh->clientList()) {
185 updateWindowList();
186 } else if (event->atom == ewmh->clientListStacking()) {
187 updateWindowStack();
188 } else if (event->atom == ewmh->numberOfDesktops()) {
189 unsigned int number;
190 if (ewmh->readNumberOfDesktops(root_window, &number))
191 changeNumberOfDesktops(number);
192 } else if (event->atom == ewmh->desktopGeometry()) {
193
194 } else if (event->atom == ewmh->currentDesktop()) {
195 unsigned int current_desktop;
196 if (!ewmh->readCurrentDesktop(root_window, ¤t_desktop))
197 fprintf(stderr, "Error: Cannot read current desktop\n");
198 else {
199 bbtool->desktopChange(current_desktop);
200 }
201 } else if (event->atom == ewmh->desktopNames()) {
202
203 } else if (event->atom == ewmh->activeWindow()) {
204 Window active;
205 if (!readActiveWindow(root_window, &active)) {
206 fprintf(stderr, "Error: Cannot read active window\n");
207 } else {
208 bbtool->focusWindow(active);
209 }
210 } else if (event->atom == ewmh->workarea()) {
211
212 } else {
213 // ignore
214 }
215
216
217
218 //wminterface->windowAttributeChange(event->xproperty.window);
219 }
220
221
222