• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • twin
 

twin

  • twin
utils.cpp
1/*****************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
7
8You can Freely distribute this program under the GNU General Public
9License. See the file "COPYING" for the exact licensing terms.
10******************************************************************/
11
12/*
13
14 This file is for (very) small utility functions/classes.
15
16*/
17
18#include "utils.h"
19
20#include <unistd.h>
21#include <string.h>
22#include <netdb.h>
23
24#include <sys/socket.h>
25
26#ifndef KCMRULES
27
28#include <tqapplication.h>
29#include <kxerrorhandler.h>
30#include <assert.h>
31#include <kdebug.h>
32
33#include <X11/Xlib.h>
34#include <X11/extensions/shape.h>
35#include <X11/Xatom.h>
36
37#include "atoms.h"
38#include "notifications.h"
39
40#endif
41
42namespace KWinInternal
43{
44
45#ifndef KCMRULES
46
47// used to store the return values of
48// XShapeQueryExtension.
49// Necessary since shaped window are an extension to X
50int Shape::twin_shape_version = 0;
51int Shape::twin_shape_event = 0;
52
53// does the window w need a shape combine mask around it?
54bool Shape::hasShape( WId w)
55 {
56 int xws, yws, xbs, ybs;
57 unsigned int wws, hws, wbs, hbs;
58 int boundingShaped = 0, clipShaped = 0;
59 if (!available())
60 return FALSE;
61 XShapeQueryExtents(tqt_xdisplay(), w,
62 &boundingShaped, &xws, &yws, &wws, &hws,
63 &clipShaped, &xbs, &ybs, &wbs, &hbs);
64 return boundingShaped != 0;
65 }
66
67int Shape::shapeEvent()
68 {
69 return twin_shape_event;
70 }
71
72void Shape::init()
73 {
74 twin_shape_version = 0;
75 int dummy;
76 if( !XShapeQueryExtension(tqt_xdisplay(), &twin_shape_event, &dummy))
77 return;
78 int major, minor;
79 if( !XShapeQueryVersion( tqt_xdisplay(), &major, &minor ))
80 return;
81 twin_shape_version = major * 0x10 + minor;
82 }
83
84void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
85 bool& minimize, bool& maximize, bool& close )
86 {
87 Atom type;
88 int format;
89 unsigned long length, after;
90 unsigned char* data;
91 MwmHints* hints = 0;
92 if ( XGetWindowProperty( tqt_xdisplay(), w, atoms->motif_wm_hints, 0, 5,
93 FALSE, atoms->motif_wm_hints, &type, &format,
94 &length, &after, &data ) == Success )
95 {
96 if ( data )
97 hints = (MwmHints*) data;
98 }
99 noborder = false;
100 resize = true;
101 move = true;
102 minimize = true;
103 maximize = true;
104 close = true;
105 if ( hints )
106 {
107 // To quote from Metacity 'We support those MWM hints deemed non-stupid'
108 if ( hints->flags & MWM_HINTS_FUNCTIONS )
109 {
110 // if MWM_FUNC_ALL is set, other flags say what to turn _off_
111 bool set_value = (( hints->functions & MWM_FUNC_ALL ) == 0 );
112 resize = move = minimize = maximize = close = !set_value;
113 if( hints->functions & MWM_FUNC_RESIZE )
114 resize = set_value;
115 if( hints->functions & MWM_FUNC_MOVE )
116 move = set_value;
117 if( hints->functions & MWM_FUNC_MINIMIZE )
118 minimize = set_value;
119 if( hints->functions & MWM_FUNC_MAXIMIZE )
120 maximize = set_value;
121 if( hints->functions & MWM_FUNC_CLOSE )
122 close = set_value;
123 }
124 if ( hints->flags & MWM_HINTS_DECORATIONS )
125 {
126 if ( hints->decorations == 0 )
127 noborder = true;
128 }
129 XFree( data );
130 }
131 }
132
133//************************************
134// KWinSelectionOwner
135//************************************
136
137KWinSelectionOwner::KWinSelectionOwner( int screen_P )
138 : TDESelectionOwner( make_selection_atom( screen_P ), screen_P )
139 {
140 }
141
142Atom KWinSelectionOwner::make_selection_atom( int screen_P )
143 {
144 if( screen_P < 0 )
145 screen_P = DefaultScreen( tqt_xdisplay());
146 char tmp[ 30 ];
147 sprintf( tmp, "WM_S%d", screen_P );
148 return XInternAtom( tqt_xdisplay(), tmp, False );
149 }
150
151void KWinSelectionOwner::getAtoms()
152 {
153 TDESelectionOwner::getAtoms();
154 if( xa_version == None )
155 {
156 Atom atoms[ 1 ];
157 const char* const names[] =
158 { "VERSION" };
159 XInternAtoms( tqt_xdisplay(), const_cast< char** >( names ), 1, False, atoms );
160 xa_version = atoms[ 0 ];
161 }
162 }
163
164void KWinSelectionOwner::replyTargets( Atom property_P, Window requestor_P )
165 {
166 TDESelectionOwner::replyTargets( property_P, requestor_P );
167 Atom atoms[ 1 ] = { xa_version };
168 // PropModeAppend !
169 XChangeProperty( tqt_xdisplay(), requestor_P, property_P, XA_ATOM, 32, PropModeAppend,
170 reinterpret_cast< unsigned char* >( atoms ), 1 );
171 }
172
173bool KWinSelectionOwner::genericReply( Atom target_P, Atom property_P, Window requestor_P )
174 {
175 if( target_P == xa_version )
176 {
177 long version[] = { 2, 0 };
178 XChangeProperty( tqt_xdisplay(), requestor_P, property_P, XA_INTEGER, 32,
179 PropModeReplace, reinterpret_cast< unsigned char* >( &version ), 2 );
180 }
181 else
182 return TDESelectionOwner::genericReply( target_P, property_P, requestor_P );
183 return true;
184 }
185
186Atom KWinSelectionOwner::xa_version = None;
187
188
189TQCString getStringProperty(WId w, Atom prop, char separator)
190 {
191 Atom type;
192 int format, status;
193 unsigned long nitems = 0;
194 unsigned long extra = 0;
195 unsigned char *data = 0;
196 TQCString result = "";
197 KXErrorHandler handler; // ignore errors
198 status = XGetWindowProperty( tqt_xdisplay(), w, prop, 0, 10000,
199 FALSE, XA_STRING, &type, &format,
200 &nitems, &extra, &data );
201 if ( status == Success)
202 {
203 if (data && separator)
204 {
205 for (int i=0; i<(int)nitems; i++)
206 if (!data[i] && i+1<(int)nitems)
207 data[i] = separator;
208 }
209 if (data)
210 result = (const char*) data;
211 XFree(data);
212 }
213 return result;
214 }
215
216static Time next_x_time;
217static Bool update_x_time_predicate( Display*, XEvent* event, XPointer )
218{
219 if( next_x_time != CurrentTime )
220 return False;
221 // from qapplication_x11.cpp
222 switch ( event->type ) {
223 case ButtonPress:
224 // fallthrough intended
225 case ButtonRelease:
226 next_x_time = event->xbutton.time;
227 break;
228 case MotionNotify:
229 next_x_time = event->xmotion.time;
230 break;
231 case KeyPress:
232 // fallthrough intended
233 case KeyRelease:
234 next_x_time = event->xkey.time;
235 break;
236 case PropertyNotify:
237 next_x_time = event->xproperty.time;
238 break;
239 case EnterNotify:
240 case LeaveNotify:
241 next_x_time = event->xcrossing.time;
242 break;
243 case SelectionClear:
244 next_x_time = event->xselectionclear.time;
245 break;
246 default:
247 break;
248 }
249 return False;
250}
251
252/*
253 Updates tqt_x_time. This used to simply fetch current timestamp from the server,
254 but that can cause tqt_x_time to be newer than timestamp of events that are
255 still in our events queue, thus e.g. making XSetInputFocus() caused by such
256 event to be ignored. Therefore events queue is searched for first
257 event with timestamp, and extra PropertyNotify is generated in order to make
258 sure such event is found.
259*/
260void updateXTime()
261 {
262 static TQWidget* w = 0;
263 if ( !w )
264 w = new TQWidget;
265 long data = 1;
266 XChangeProperty(tqt_xdisplay(), w->winId(), atoms->twin_running, atoms->twin_running, 32,
267 PropModeAppend, (unsigned char*) &data, 1);
268 next_x_time = CurrentTime;
269 XEvent dummy;
270 XCheckIfEvent( tqt_xdisplay(), &dummy, update_x_time_predicate, NULL );
271 if( next_x_time == CurrentTime )
272 {
273 XSync( tqt_xdisplay(), False );
274 XCheckIfEvent( tqt_xdisplay(), &dummy, update_x_time_predicate, NULL );
275 }
276 assert( next_x_time != CurrentTime );
277 set_tqt_x_time(next_x_time);
278 XEvent ev; // remove the PropertyNotify event from the events queue
279 XWindowEvent( tqt_xdisplay(), w->winId(), PropertyChangeMask, &ev );
280 }
281
282static int server_grab_count = 0;
283
284void grabXServer()
285 {
286 if( ++server_grab_count == 1 )
287 XGrabServer( tqt_xdisplay());
288 }
289
290void ungrabXServer()
291 {
292 assert( server_grab_count > 0 );
293 if( --server_grab_count == 0 )
294 {
295 XUngrabServer( tqt_xdisplay());
296 XFlush( tqt_xdisplay());
297 Notify::sendPendingEvents();
298 }
299 }
300
301bool grabbedXServer()
302 {
303 return server_grab_count > 0;
304 }
305
306#endif
307
308bool isLocalMachine( const TQCString& host )
309 {
310#ifdef HOST_NAME_MAX
311 char hostnamebuf[HOST_NAME_MAX];
312#else
313 char hostnamebuf[256];
314#endif
315 if (gethostname (hostnamebuf, sizeof hostnamebuf) >= 0)
316 {
317 hostnamebuf[sizeof(hostnamebuf)-1] = 0;
318 if (host == hostnamebuf)
319 return true;
320 if( char *dot = strchr(hostnamebuf, '.'))
321 {
322 *dot = '\0';
323 if( host == hostnamebuf )
324 return true;
325 }
326 else
327 { // e.g. LibreOffice likes to give FQDN, even if gethostname() doesn't include domain
328 struct addrinfo hints, *res, *addr;
329 bool is_local = false;
330
331 memset (&hints, 0, sizeof (hints));
332 hints.ai_family = PF_UNSPEC;
333 hints.ai_socktype = SOCK_STREAM;
334 hints.ai_flags |= AI_CANONNAME;
335
336 if( getaddrinfo( host, NULL, &hints, &res ) != 0)
337 return false;
338 for(addr = res; !is_local && addr; addr = addr->ai_next)
339 {
340 if( addr->ai_canonname &&
341 host == TQCString( addr->ai_canonname ))
342 is_local = true;
343 }
344 freeaddrinfo(res);
345 return is_local;
346 }
347 }
348 return false;
349 }
350
351#ifndef KCMRULES
352ShortcutDialog::ShortcutDialog( const TDEShortcut& cut )
353 : TDEShortcutDialog( cut, false /*TODO???*/ )
354 {
355 // make it a popup, so that it has the grab
356 XSetWindowAttributes attrs;
357 attrs.override_redirect = True;
358 XChangeWindowAttributes( tqt_xdisplay(), winId(), CWOverrideRedirect, &attrs );
359 setWFlags( WType_Popup );
360 }
361
362void ShortcutDialog::accept()
363 {
364 for( int i = 0;
365 ;
366 ++i )
367 {
368 KKeySequence seq = shortcut().seq( i );
369 if( seq.isNull())
370 break;
371 if( seq.key( 0 ) == Key_Escape )
372 {
373 reject();
374 return;
375 }
376 if( seq.key( 0 ) == Key_Space )
377 { // clear
378 setShortcut( TDEShortcut());
379 TDEShortcutDialog::accept();
380 return;
381 }
382 if( seq.key( 0 ).modFlags() == 0 )
383 { // no shortcuts without modifiers
384 TDEShortcut cut = shortcut();
385 cut.setSeq( i, KKeySequence());
386 setShortcut( cut );
387 return;
388 }
389 }
390 TDEShortcutDialog::accept();
391 }
392
393// Workaround for Qt bug causing #119142 - wheel event causes only calling
394// of hide() but not close(), so dialog closing is not performed.
395// Possible recursive calling close->hide->close should be fine, as close()
396// has checks against that.
397void ShortcutDialog::hide()
398 {
399 close();
400 return TDEShortcutDialog::hide();
401 }
402
403#endif
404
405
406} // namespace
407
408#ifndef KCMRULES
409#include "utils.moc"
410#endif

twin

Skip menu "twin"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members

twin

Skip menu "twin"
  • kate
  • libkonq
  • twin
  •   lib
Generated for twin by doxygen 1.9.4
This website is maintained by Timothy Pearson.