1 /****************************************************************************
2 **
3 ** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved.
4 **
5 ** This file is part of a Qt Solutions component.
6 **
7 ** This file may be used under the terms of the GNU General Public
8 ** License version 2.0 as published by the Free Software Foundation
9 ** and appearing in the file LICENSE.GPL included in the packaging of
10 ** this file. Please review the following information to ensure GNU
11 ** General Public Licensing requirements will be met:
12 ** http://www.trolltech.com/products/qt/opensource.html
13 **
14 ** If you are unsure which license is appropriate for your use, please
15 ** review the following information:
16 ** http://www.trolltech.com/products/qt/licensing.html or contact the
17 ** Trolltech sales department at sales@trolltech.com.
18 **
19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 **
22 ****************************************************************************/
23 #include <QtGui>
24
25 #include "qtbrowserplugin.h"
26 #include "qtbrowserplugin_p.h"
27
28 #include <windows.h>
29 #include "qtnpapi.h"
30
31 #if QT_VERSION >= 0x050000
32 # define QT_WA(unicode, ansi) unicode
33 #endif
34
35 static HHOOK hhook = 0;
36 static bool ownsqapp = false;
37
38
39 static const uint keytbl[256] = { // Keyboard mapping table
40 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Cancel,
41 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
42 Qt::Key_Backspace, Qt::Key_Tab, Qt::Key_unknown, Qt::Key_unknown,
43 Qt::Key_Clear, Qt::Key_Return, Qt::Key_unknown, Qt::Key_unknown,
44 Qt::Key_Shift, Qt::Key_Control, Qt::Key_Alt, Qt::Key_Pause,
45 Qt::Key_CapsLock, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
46 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Escape,
47 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Mode_switch,
48 Qt::Key_Space, Qt::Key_PageUp, Qt::Key_PageDown, Qt::Key_End,
49 Qt::Key_Home, Qt::Key_Left, Qt::Key_Up, Qt::Key_Right,
50 Qt::Key_Down, Qt::Key_Select, Qt::Key_Printer, Qt::Key_Execute,
51 Qt::Key_Print, Qt::Key_Insert, Qt::Key_Delete, Qt::Key_Help,
52 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
53 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
54 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
55 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
56 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
57 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
58 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
59 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
60 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
61 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
62 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Meta,
63 Qt::Key_Meta, Qt::Key_Menu, Qt::Key_unknown, Qt::Key_Sleep,
64 Qt::Key_0, Qt::Key_1, Qt::Key_2, Qt::Key_3,
65 Qt::Key_4, Qt::Key_5, Qt::Key_6, Qt::Key_7,
66 Qt::Key_8, Qt::Key_9, Qt::Key_Asterisk, Qt::Key_Plus,
67 Qt::Key_Comma, Qt::Key_Minus, Qt::Key_Period, Qt::Key_Slash,
68 Qt::Key_F1, Qt::Key_F2, Qt::Key_F3, Qt::Key_F4,
69 Qt::Key_F5, Qt::Key_F6, Qt::Key_F7, Qt::Key_F8,
70 Qt::Key_F9, Qt::Key_F10, Qt::Key_F11, Qt::Key_F12,
71 Qt::Key_F13, Qt::Key_F14, Qt::Key_F15, Qt::Key_F16,
72 Qt::Key_F17, Qt::Key_F18, Qt::Key_F19, Qt::Key_F20,
73 Qt::Key_F21, Qt::Key_F22, Qt::Key_F23, Qt::Key_F24,
74 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
75 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
76 Qt::Key_NumLock, Qt::Key_ScrollLock, Qt::Key_unknown, Qt::Key_Massyo,
77 Qt::Key_Touroku, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
78 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
79 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
80 Qt::Key_Shift, Qt::Key_Shift, Qt::Key_Control, Qt::Key_Control,
81 Qt::Key_Alt, Qt::Key_Alt, Qt::Key_Back, Qt::Key_Forward,
82 Qt::Key_Refresh, Qt::Key_Stop, Qt::Key_Search, Qt::Key_Favorites,
83 Qt::Key_HomePage, Qt::Key_VolumeMute, Qt::Key_VolumeDown, Qt::Key_VolumeUp,
84 Qt::Key_MediaNext, Qt::Key_MediaPrevious, Qt::Key_MediaStop, Qt::Key_MediaPlay,
85 Qt::Key_LaunchMail, Qt::Key_LaunchMedia, Qt::Key_Launch0, Qt::Key_Launch1,
86 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
87 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
88 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
89 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
90 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
91 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
92 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
93 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
94 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
95 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
96 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
97 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
98 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
99 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
100 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
101 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown,
102 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Play, Qt::Key_Zoom,
103 Qt::Key_unknown, Qt::Key_unknown, Qt::Key_Clear, 0
104 };
105
qt_translateKeyCode(int vk)106 static int qt_translateKeyCode(int vk)
107 {
108 if (vk >= 0 && vk <= 255)
109 return keytbl[vk];
110 return Qt::Key_unknown;
111 }
112
FilterProc(int nCode,WPARAM wParam,LPARAM lParam)113 LRESULT CALLBACK FilterProc( int nCode, WPARAM wParam, LPARAM lParam )
114 {
115 if (qApp)
116 qApp->sendPostedEvents(0, -1);
117 if (nCode < 0 || !(wParam & PM_REMOVE))
118 return CallNextHookEx(hhook, nCode, wParam, lParam);
119 MSG *msg = (MSG*)lParam;
120 bool processed = false;
121 // (some) support for key-sequences via QAction and QShortcut
122 if(msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) {
123 QWidget *focusWidget = QWidget::find(msg->hwnd);
124 if (focusWidget) {
125 int key = msg->wParam;
126 if (!(key >= 'A' && key <= 'Z') && !(key >= '0' && key <= '9'))
127 key = qt_translateKeyCode(msg->wParam);
128 Qt::KeyboardModifiers modifiers = 0;
129 int modifierKey = 0;
130 if (GetKeyState(VK_SHIFT) < 0) {
131 modifierKey |= Qt::SHIFT;
132 modifiers |= Qt::ShiftModifier;
133 }
134 if (GetKeyState(VK_CONTROL) < 0) {
135 modifierKey |= Qt::CTRL;
136 modifiers |= Qt::ControlModifier;
137 }
138 if (GetKeyState(VK_MENU) < 0) {
139 modifierKey |= Qt::ALT;
140 modifiers |= Qt::AltModifier;
141 }
142 QKeyEvent override(QEvent::ShortcutOverride, key, modifiers);
143 override.ignore();
144 QApplication::sendEvent(focusWidget, &override);
145 processed = override.isAccepted();
146 QKeySequence shortcutKey(modifierKey + key);
147 if (!processed) {
148 QList<QAction*> actions = focusWidget->window()->findChildren<QAction*>();
149 for (int i = 0; i < actions.count() && !processed; ++i) {
150 QAction *action = actions.at(i);
151 if (!action->isEnabled() || action->shortcut() != shortcutKey)
152 continue;
153 QShortcutEvent event(shortcutKey, 0);
154 processed = QApplication::sendEvent(action, &event);
155 }
156 }
157 if (!processed) {
158 QList<QShortcut*> shortcuts = focusWidget->window()->findChildren<QShortcut*>();
159 for (int i = 0; i < shortcuts.count() && !processed; ++i) {
160 QShortcut *shortcut = shortcuts.at(i);
161 if (!shortcut->isEnabled() || shortcut->key() != shortcutKey)
162 continue;
163 QShortcutEvent event(shortcutKey, shortcut->id());
164 processed = QApplication::sendEvent(shortcut, &event);
165 }
166 }
167 }
168 }
169 return CallNextHookEx(hhook, nCode, wParam, lParam);
170 }
171
qtns_event(QtNPInstance *,NPEvent *)172 extern "C" bool qtns_event(QtNPInstance *, NPEvent *)
173 {
174 return false;
175 }
176
qtns_initialize(QtNPInstance *)177 extern "C" void qtns_initialize(QtNPInstance*)
178 {
179 if (!qApp) {
180 ownsqapp = true;
181 static int argc=0;
182 static char **argv={ 0 };
183 (void)new QApplication(argc, argv);
184 QT_WA({
185 hhook = SetWindowsHookExW( WH_GETMESSAGE, FilterProc, 0, GetCurrentThreadId() );
186 }, {
187 hhook = SetWindowsHookExA( WH_GETMESSAGE, FilterProc, 0, GetCurrentThreadId() );
188 });
189 }
190 }
191
qtns_destroy(QtNPInstance *)192 extern "C" void qtns_destroy(QtNPInstance *)
193 {
194 }
195
qtns_shutdown()196 extern "C" void qtns_shutdown()
197 {
198 if (!ownsqapp)
199 return;
200
201 // check if qApp still runs widgets (in other DLLs)
202 QWidgetList widgets = qApp->allWidgets();
203 int count = widgets.count();
204 for (int w = 0; w < widgets.count(); ++w) {
205 // ignore all Qt generated widgets
206 QWidget *widget = widgets.at(w);
207 if (widget->windowFlags() & Qt::Desktop)
208 count--;
209 }
210 if (count) // qApp still used
211 return;
212
213 delete qApp;
214 ownsqapp = false;
215 if ( hhook )
216 UnhookWindowsHookEx( hhook );
217 hhook = 0;
218 }
219
qtns_embed(QtNPInstance * This)220 extern "C" void qtns_embed(QtNPInstance *This)
221 {
222 Q_ASSERT(qobject_cast<QWidget*>(This->qt.object));
223
224 LONG oldLong = GetWindowLong(This->window, GWL_STYLE);
225 ::SetWindowLong(This->window, GWL_STYLE, oldLong | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
226 ::SetWindowLong(This->qt.widget->winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
227 ::SetParent(This->qt.widget->winId(), This->window);
228 }
229
qtns_setGeometry(QtNPInstance * This,const QRect & rect,const QRect &)230 extern "C" void qtns_setGeometry(QtNPInstance *This, const QRect &rect, const QRect &)
231 {
232 Q_ASSERT(qobject_cast<QWidget*>(This->qt.object));
233
234 This->qt.widget->setGeometry(QRect(0, 0, rect.width(), rect.height()));
235 }
236
237 /*
238 extern "C" void qtns_print(QtNPInstance * This, NPPrint *printInfo)
239 {
240 NPWindow* printWindow = &(printInfo->print.embedPrint.window);
241 void* platformPrint = printInfo->print.embedPrint.platformPrint;
242 // #### Nothing yet.
243 }
244 */
245