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

kwin

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

kwin

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

kwin

Skip menu "kwin"
  • kate
  • kwin
  •   lib
  • libkonq
Generated for kwin by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |