source: psi/trunk/src/psiapplication.cpp@ 64

Last change on this file since 64 was 53, checked in by dmik, 19 years ago

Psi: General: Added automatic support for the Innotek Font Engine on the OS/2 platform.

File size: 7.6 KB
Line 
1/*
2 * psiapplication.cpp - subclass of QApplication to do some workarounds
3 * Copyright (C) 2003 Michail Pishchagin
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (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 library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include "psiapplication.h"
22
23#ifdef Q_WS_MAC
24#include<Carbon/Carbon.h>
25#endif
26
27#ifdef Q_WS_X11
28#include <time.h>
29#include <sys/time.h>
30
31#include <X11/Xlib.h>
32#include <X11/Xutil.h>
33#include <X11/Xatom.h>
34#include <X11/SM/SMlib.h>
35
36// Atoms required for monitoring the freedesktop.org notification area
37static Atom manager_atom = 0;
38static Atom tray_selection_atom = 0;
39Window root_window = 0;
40Window tray_owner = None;
41
42//static Atom atom_KdeNetUserTime;
43static Atom kde_net_wm_user_time = 0;
44
45//#if QT_VERSION > 0x030201
46//#warning "Possibly, now it's time to clean up some 'focus stealing prevention' workaround code"
47//#endif
48
49Time qt_x_last_input_time = CurrentTime;
50//extern Time qt_x_time;
51
52#ifdef KeyPress
53#ifndef FIXX11H_KeyPress
54#define FIXX11H_KeyPress
55const int XKeyPress = KeyPress;
56#undef KeyPress
57const int KeyPress = XKeyPress;
58#endif
59#undef KeyPress
60#endif
61#endif
62
63// mblsha:
64// currently this file contains some Anti-"focus steling prevention" code by
65// Lubos Lunak (l.lunak@kde.org)
66//
67// This should resolve all bugs with KWin3 and old Qt, but maybe it'll be useful for
68// other window managers?
69
70#ifdef Q_WS_X11
71//#undef Q_WS_X11
72#endif
73
74#ifdef Q_WS_X11
75void setTrayOwnerWindow(Display *dsp)
76{
77 /* This code is basically trying to mirror what happens in
78 * eggtrayicon.c:egg_tray_icon_update_manager_window()
79 */
80 // ignore events from the old tray owner
81 if (tray_owner != None)
82 {
83 XSelectInput(dsp, tray_owner, 0);
84 }
85
86 // obtain the Window handle for the new tray owner
87 XGrabServer(dsp);
88 tray_owner = XGetSelectionOwner(dsp, tray_selection_atom);
89
90 // we have to be able to spot DestroyNotify messages on the tray owner
91 if (tray_owner != None)
92 {
93 XSelectInput(dsp, tray_owner, StructureNotifyMask|PropertyChangeMask);
94 }
95 XUngrabServer(dsp);
96 XFlush(dsp);
97}
98
99#endif
100
101#ifdef Q_WS_PM
102// support for the Innotek Font Engine (Freetype 2) library
103// (so far, we use it directly here rather than making Qt/2 Freetype2-aware,
104// because ft2lib has some problems (e.g. font transformations) that makes it
105// dangerous to enable it globally in Qt)
106#include <qlibrary.h>
107typedef VOID (APIENTRY *Ft2EnableFontEngine_T)( BOOL fEnable );
108static Ft2EnableFontEngine_T Ft2EnableFontEngine = 0;
109static QLibrary ft2lib( "ft2lib.dll" );
110#endif
111
112//----------------------------------------------------------------------------
113// PsiApplication
114//----------------------------------------------------------------------------
115
116PsiApplication::PsiApplication(int &argc, char **argv, bool GUIenabled)
117: QApplication(argc, argv, GUIenabled)
118{
119 init(GUIenabled);
120}
121
122PsiApplication::~PsiApplication()
123{
124}
125
126void PsiApplication::init(bool GUIenabled)
127{
128 Q_UNUSED(GUIenabled);
129#ifdef Q_WS_PM
130 if ( GUIenabled ) {
131 Ft2EnableFontEngine =
132 (Ft2EnableFontEngine_T) ft2lib.resolve( "Ft2EnableFontEngine" );
133 if ( Ft2EnableFontEngine ) {
134 // enable Innotek Font Engine
135 Ft2EnableFontEngine( TRUE );
136 }
137 }
138#endif
139#ifdef Q_WS_X11
140 if ( GUIenabled ) {
141 const int max = 20;
142 Atom* atoms[max];
143 char* names[max];
144 Atom atoms_return[max];
145 int n = 0;
146
147 //atoms[n] = &atom_KdeNetUserTime;
148 //names[n++] = (char *) "_KDE_NET_USER_TIME";
149
150 atoms[n] = &kde_net_wm_user_time;
151 names[n++] = (char *) "_NET_WM_USER_TIME";
152 atoms[n] = &manager_atom;
153 names[n++] = (char *) "MANAGER";
154
155 Display *dsp = qt_xdisplay();
156
157 XInternAtoms( dsp, names, n, false, atoms_return );
158
159 for (int i = 0; i < n; i++ )
160 *atoms[i] = atoms_return[i];
161
162 // get the selection type we'll use to locate the notification tray
163 char buf[32];
164 snprintf(buf, sizeof(buf), "_NET_SYSTEM_TRAY_S%d", XScreenNumberOfScreen( XDefaultScreenOfDisplay(dsp) ));
165 tray_selection_atom = XInternAtom(dsp, buf, false);
166
167 // make a note of the window handle for the root window
168 root_window = QApplication::desktop()->winId();
169
170 XWindowAttributes attr;
171
172 // this is actually futile, since Qt overrides it at some
173 // unknown point in the near future.
174 XGetWindowAttributes(dsp, root_window, &attr);
175 XSelectInput(dsp, root_window, attr.your_event_mask | StructureNotifyMask);
176
177 setTrayOwnerWindow(dsp);
178 }
179#endif
180}
181
182bool PsiApplication::notify(QObject *receiver, QEvent *event)
183{
184#ifdef Q_WS_X11
185 if( event->type() == QEvent::Show && receiver->isWidgetType())
186 {
187 QWidget* w = static_cast< QWidget* >( receiver );
188 if( w->isTopLevel() && qt_x_last_input_time != CurrentTime ) // CurrentTime means no input event yet
189 XChangeProperty( qt_xdisplay(), w->winId(), kde_net_wm_user_time, XA_CARDINAL,
190 32, PropModeReplace, (unsigned char*)&qt_x_last_input_time, 1 );
191 }
192 if( event->type() == QEvent::Hide && receiver->isWidgetType())
193 {
194 QWidget* w = static_cast< QWidget* >( receiver );
195 if( w->isTopLevel() && w->winId() != 0 )
196 XDeleteProperty( qt_xdisplay(), w->winId(), kde_net_wm_user_time );
197 }
198#endif
199 return QApplication::notify(receiver, event);
200}
201
202#ifdef Q_WS_X11
203bool PsiApplication::x11EventFilter( XEvent *_event )
204{
205 switch ( _event->type ) {
206
207 case ClientMessage:
208 if (_event->xclient.window == root_window && _event->xclient.message_type == manager_atom)
209 {
210 // A new notification area application has
211 // announced its presence
212 setTrayOwnerWindow(_event->xclient.display);
213 newTrayOwner();
214 }
215 break;
216
217 case DestroyNotify:
218 if (_event->xdestroywindow.event == tray_owner)
219 {
220 // there is now no known notification area.
221 // We're still looking out for the MANAGER
222 // message sent to the root window, at which
223 // point we'll have another look to see
224 // whether a notification area is available.
225 tray_owner = 0;
226 trayOwnerDied();
227 }
228 break;
229
230 case ButtonPress:
231 case XKeyPress:
232 {
233 if( _event->type == ButtonPress )
234 qt_x_last_input_time = _event->xbutton.time;
235 else // KeyPress
236 qt_x_last_input_time = _event->xkey.time;
237 QWidget *w = activeWindow();
238 if( w ) {
239 XChangeProperty( qt_xdisplay(), w->winId(), kde_net_wm_user_time, XA_CARDINAL,
240 32, PropModeReplace, (unsigned char*)&qt_x_last_input_time, 1 );
241 /*timeval tv;
242 gettimeofday( &tv, NULL );
243 unsigned long now = tv.tv_sec * 10 + tv.tv_usec / 100000;
244 XChangeProperty(qt_xdisplay(), w->winId(),
245 atom_KdeNetUserTime, XA_CARDINAL,
246 32, PropModeReplace, (unsigned char *)&now, 1);*/
247 }
248 break;
249 }
250
251 default:
252 break;
253 }
254
255 // process the event normally
256 return false;
257}
258#endif
259
260#ifdef Q_WS_MAC
261bool PsiApplication::macEventFilter( EventHandlerCallRef, EventRef inEvent )
262{
263 UInt32 eclass = GetEventClass(inEvent);
264 int etype = GetEventKind(inEvent);
265 if(eclass == 'eppc' && etype == kEventAppleEvent) {
266 dockActivated();
267 }
268 return false;
269}
270#endif
271
Note: See TracBrowser for help on using the repository browser.