VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/platform/os2/VBoxHlp.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.9 KB
Line 
1/* $Id: VBoxHlp.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - Implementation of OS/2-specific helpers that require to reside in a DLL
4 */
5
6/*
7 * Copyright (C) 2008-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define OS2EMX_PLAIN_CHAR
29
30#define INCL_BASE
31#define INCL_PM
32#define INCL_DOSINFOSEG
33#define INCL_DOSDEVIOCTL
34#include <os2.h>
35
36#include "VBoxHlp.h"
37
38/**
39 * Undocumented PM hook that is called before the pressed key is checked
40 * against the global accelerator table.
41 *
42 * Taken from the xWorkplace source code where it appears to come from the
43 * ProgramCommander/2 source code. Thanks to Ulrich Moeller and Roman Stangl.
44 */
45#define HK_PREACCEL 17
46
47/* NOTE: all global data is per-process (DATA32 is multiple, nonshared). */
48
49/* Module handle of this DLL */
50static HMODULE gThisModule = NULLHANDLE;
51
52static PGINFOSEG gGIS = NULL;
53static PLINFOSEG gLIS = NULL;
54
55/* Parameters for the keyboard hook (VBoxHlpInstallKbdHook()) */
56HAB gKbdHookHab = NULLHANDLE;
57HWND gKbdHookHwnd = NULLHANDLE;
58ULONG gKbdHookMsg = 0;
59
60/**
61 * Message Input hook used to monitor the system message queue.
62 *
63 * @param aHab Anchor handle.
64 * @param aHwnd Pointer to the QMSG structure.
65 * @param aFS Flags from WinPeekMsg(), either PM_NOREMOVE or
66 * PM_REMOVE.
67 *
68 * @return @c TRUE to steal the given message or @c FALSE to pass it to the
69 * rest of the hook chain.
70 */
71static
72BOOL EXPENTRY vboxInputHook (HAB aHab, PQMSG aMsg, ULONG aFS)
73{
74 if (aMsg->msg == WM_CHAR)
75 {
76 /* For foreign processes that didn't call VBoxHlpInstallKbdHook(),
77 * gKbdHookHwnd remains NULL. If it's the case while in this input
78 * hook, it means that the given foreign process is in foreground
79 * now. Since forwarding should work only for processes that
80 * called VBoxHlpInstallKbdHook(), we ignore the message. */
81 if (gKbdHookHwnd != NULLHANDLE)
82 {
83 MRESULT reply =
84 WinSendMsg (gKbdHookHwnd, gKbdHookMsg, aMsg->mp1, aMsg->mp2);
85 return (BOOL) reply;
86 }
87 }
88
89 return FALSE;
90}
91
92/**
93 * Installs a hook that will intercept all keyboard input (WM_CHAR) messages
94 * and forward them to the given window handle using the given message
95 * identifier. Messages are intercepted only when the given top-level window
96 * is the active desktop window (i.e. a window receiving keyboard input).
97 *
98 * When the WM_CHAR message is intercepted, it is forwarded as is (including
99 * all parameters) except that the message ID is changed to the given message
100 * ID. The result of the WinSendMsg() call is then converted to BOOL and if
101 * it results to TRUE then the message is considered to be processed,
102 * otherwise it is passed back to the system for normal processing.
103 *
104 * If the hook is already installed for the same or another window, this
105 * method will return @c false.
106 *
107 * @note This function is not thread-safe and must be called only on the main
108 * thread once per process.
109 *
110 * @param aHab Window anchor block.
111 * @param aHwnd Top-level window handle to forward WM_CHAR messages to.
112 * @param aMsg Message ID to use when forwarding.
113 *
114 * @return @c true on success and @c false otherwise. */
115VBOXHLPDECL(bool) VBoxHlpInstallKbdHook (HAB aHab, HWND aHwnd,
116 unsigned long aMsg)
117{
118 if (gKbdHookHwnd != NULLHANDLE ||
119 aHwnd == NULLHANDLE)
120 return false;
121
122 BOOL ok = WinSetHook (aHab, NULLHANDLE, HK_PREACCEL,
123 (PFN) vboxInputHook, gThisModule);
124
125 if (ok)
126 {
127 gKbdHookHab = aHab;
128 gKbdHookHwnd = aHwnd;
129 gKbdHookMsg = aMsg;
130 }
131
132 return (bool) ok;
133}
134
135/**
136 * Uninstalls the keyboard hook installed by VBoxHlpInstallKbdHook().
137 * All arguments must match arguments passed to VBoxHlpInstallKbdHook(),
138 * otherwise this method will do nothing and return @c false.
139 *
140 * @return @c true on success and @c false otherwise.
141 */
142VBOXHLPDECL(bool) VBoxHlpUninstallKbdHook (HAB aHab, HWND aHwnd,
143 unsigned long aMsg)
144{
145 if (gKbdHookHab != aHab ||
146 gKbdHookHwnd != aHwnd ||
147 gKbdHookMsg != aMsg)
148 return false;
149
150 BOOL ok = WinReleaseHook (aHab, NULLHANDLE, HK_PREACCEL,
151 (PFN) vboxInputHook, gThisModule);
152
153 if (ok)
154 {
155 gKbdHookHab = NULLHANDLE;
156 gKbdHookHwnd = NULLHANDLE;
157 gKbdHookMsg = 0;
158 }
159
160 return (bool) ok;
161}
162
163/**
164 * DLL entry point.
165 *
166 * @param aHandle DLL module handle.
167 * @param aFlag 0 on initialization or 1 on termination.
168 *
169 * @return Non-zero for success or 0 for failure.
170 */
171ULONG _System _DLL_InitTerm (HMODULE aHandle, ULONG aFlag)
172{
173 bool ok = true;
174
175 if (aFlag == 0)
176 {
177 /* DLL initialization */
178
179 gThisModule = aHandle;
180
181 gGIS = GETGINFOSEG();
182 gLIS = GETLINFOSEG();
183 }
184 else
185 {
186 /* DLL termination */
187
188 /* Make sure we release the hook if the user forgets to do so. */
189 if (gKbdHookHwnd != NULLHANDLE)
190 WinReleaseHook (gKbdHookHab, NULLHANDLE, HK_PREACCEL,
191 (PFN) vboxInputHook, gThisModule);
192
193 gThisModule = NULLHANDLE;
194 }
195
196 return (unsigned long) ok;
197}
198
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use