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