VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp@ 17826

Last change on this file since 17826 was 13837, checked in by vboxsync, 16 years ago

s/%Vr\([acfs]\)/%Rr\1/g - since I'm upsetting everyone anyway, better make the most of it...

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/** @file
2 *
3 * VBox frontends: Basic Frontend (BFE):
4 * Implementation of Keyboard class and related things
5 */
6
7/*
8 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#ifdef VBOXBFE_WITHOUT_COM
24# include "COMDefs.h"
25#else
26# include <VBox/com/defs.h>
27# include <VBox/com/array.h>
28#endif
29#include <VBox/pdm.h>
30#include <VBox/cfgm.h>
31#include <VBox/err.h>
32#include <iprt/assert.h>
33#include <VBox/log.h>
34#include <iprt/asm.h>
35#include "KeyboardImpl.h"
36
37// defines
38////////////////////////////////////////////////////////////////////////////////
39
40// globals
41////////////////////////////////////////////////////////////////////////////////
42
43/**
44 * Keyboard driver instance data.
45 */
46typedef struct DRVMAINKEYBOARD
47{
48 /** Pointer to the keyboard object. */
49 Keyboard *pKeyboard;
50 /** Pointer to the driver instance structure. */
51 PPDMDRVINS pDrvIns;
52 /** Pointer to the keyboard port interface of the driver/device above us. */
53 PPDMIKEYBOARDPORT pUpPort;
54 /** Our mouse connector interface. */
55 PDMIKEYBOARDCONNECTOR Connector;
56} DRVMAINKEYBOARD, *PDRVMAINKEYBOARD;
57
58// constructor / destructor
59////////////////////////////////////////////////////////////////////////////////
60
61Keyboard::Keyboard()
62{
63 mpDrv = NULL;
64 mpVMMDev = NULL;
65 mfVMMDevInited = false;
66}
67
68Keyboard::~Keyboard()
69{
70 if (mpDrv)
71 mpDrv->pKeyboard = NULL;
72 mpDrv = NULL;
73 mpVMMDev = NULL;
74 mfVMMDevInited = true;
75}
76
77// public methods
78////////////////////////////////////////////////////////////////////////////////
79
80/**
81 * Sends a scancode to the keyboard.
82 *
83 * @returns COM status code
84 * @param scancode The scancode to send
85 */
86STDMETHODIMP Keyboard::PutScancode(LONG scancode)
87{
88 if (!mpDrv)
89 return S_OK;
90
91 int rcVBox = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, (uint8_t)scancode);
92 if (RT_FAILURE (rcVBox))
93 return E_FAIL;
94
95 return S_OK;
96}
97
98/**
99 * Sends a list of scancodes to the keyboard.
100 *
101 * @returns COM status code
102 * @param scancodes Safe array of scancodes
103 * @param codesStored Address of variable to store the number
104 * of scancodes that were sent to the keyboard.
105 This value can be NULL.
106 */
107STDMETHODIMP Keyboard::PutScancodes(ComSafeArrayIn (LONG, scancodes),
108 ULONG *codesStored)
109{
110 if (ComSafeArrayInIsNull(scancodes))
111 return E_INVALIDARG;
112 if (!mpDrv)
113 return S_OK;
114
115 com::SafeArray <LONG> keys(ComSafeArrayInArg(scancodes));
116 int rcVBox = VINF_SUCCESS;
117
118 for (uint32_t i = 0; (i < keys.size()) && RT_SUCCESS(rcVBox); i++)
119 {
120 rcVBox = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, (uint8_t)keys[i]);
121 }
122
123 if (RT_FAILURE (rcVBox))
124 return E_FAIL;
125
126 /// @todo is it actually possible that not all scancodes can be transmitted?
127 if (codesStored)
128 *codesStored = keys.size();
129
130 return S_OK;
131}
132
133/**
134 * Sends Control-Alt-Delete to the keyboard. This could be done otherwise
135 * but it's so common that we'll be nice and supply a convenience API.
136 *
137 * @returns COM status code
138 *
139 */
140STDMETHODIMP Keyboard::PutCAD()
141{
142 static com::SafeArray<LONG> cadSequence(6);
143
144 cadSequence[0] = 0x1d; // Ctrl down
145 cadSequence[1] = 0x38; // Alt down
146 cadSequence[2] = 0x53; // Del down
147 cadSequence[3] = 0xd3; // Del up
148 cadSequence[4] = 0xb8; // Alt up
149 cadSequence[5] = 0x9d; // Ctrl up
150
151 return PutScancodes (ComSafeArrayAsInParam(cadSequence), NULL);
152}
153
154//
155// private methods
156//
157
158/**
159 * Queries an interface to the driver.
160 *
161 * @returns Pointer to interface.
162 * @returns NULL if the interface was not supported by the driver.
163 * @param pInterface Pointer to this interface structure.
164 * @param enmInterface The requested interface identification.
165 */
166DECLCALLBACK(void *) Keyboard::drvQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
167{
168 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
169 PDRVMAINKEYBOARD pDrv = PDMINS_2_DATA(pDrvIns, PDRVMAINKEYBOARD);
170 switch (enmInterface)
171 {
172 case PDMINTERFACE_BASE:
173 return &pDrvIns->IBase;
174 case PDMINTERFACE_KEYBOARD_CONNECTOR:
175 return &pDrv->Connector;
176 default:
177 return NULL;
178 }
179}
180
181
182/**
183 * Destruct a keyboard driver instance.
184 *
185 * @returns VBox status.
186 * @param pDrvIns The driver instance data.
187 */
188DECLCALLBACK(void) Keyboard::drvDestruct(PPDMDRVINS pDrvIns)
189{
190 PDRVMAINKEYBOARD pData = PDMINS_2_DATA(pDrvIns, PDRVMAINKEYBOARD);
191 LogFlow(("Keyboard::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
192 if (pData->pKeyboard)
193 {
194 pData->pKeyboard->mpDrv = NULL;
195 pData->pKeyboard->mpVMMDev = NULL;
196 }
197}
198
199
200/** @copydoc PDMIKEYBOARDCONNECTOR::pfnLedStatusChange */
201DECLCALLBACK(void) keyboardLedStatusChange(PPDMIKEYBOARDCONNECTOR pInterface, PDMKEYBLEDS enmLeds)
202{
203 /** @todo Implement me. */
204}
205
206
207/**
208 * Construct a keyboard driver instance.
209 *
210 * @returns VBox status.
211 * @param pDrvIns The driver instance data.
212 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
213 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
214 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
215 * iInstance it's expected to be used a bit in this function.
216 */
217DECLCALLBACK(int) Keyboard::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
218{
219 PDRVMAINKEYBOARD pData = PDMINS_2_DATA(pDrvIns, PDRVMAINKEYBOARD);
220 LogFlow(("Keyboard::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
221
222 /*
223 * Validate configuration.
224 */
225 if (!CFGMR3AreValuesValid(pCfgHandle, "Object\0"))
226 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
227 PPDMIBASE pBaseIgnore;
228 int rc = pDrvIns->pDrvHlp->pfnAttach(pDrvIns, &pBaseIgnore);
229 if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
230 {
231 AssertMsgFailed(("Configuration error: Not possible to attach anything to this driver!\n"));
232 return VERR_PDM_DRVINS_NO_ATTACH;
233 }
234
235 /*
236 * IBase.
237 */
238 pDrvIns->IBase.pfnQueryInterface = Keyboard::drvQueryInterface;
239
240 pData->Connector.pfnLedStatusChange = keyboardLedStatusChange;
241
242 /*
243 * Get the IKeyboardPort interface of the above driver/device.
244 */
245 pData->pUpPort = (PPDMIKEYBOARDPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_KEYBOARD_PORT);
246 if (!pData->pUpPort)
247 {
248 AssertMsgFailed(("Configuration error: No keyboard port interface above!\n"));
249 return VERR_PDM_MISSING_INTERFACE_ABOVE;
250 }
251
252 /*
253 * Get the Keyboard object pointer and update the mpDrv member.
254 */
255 void *pv;
256 rc = CFGMR3QueryPtr(pCfgHandle, "Object", &pv);
257 if (RT_FAILURE(rc))
258 {
259 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
260 return rc;
261 }
262 pData->pKeyboard = (Keyboard *)pv; /** @todo Check this cast! */
263 pData->pKeyboard->mpDrv = pData;
264
265 return VINF_SUCCESS;
266}
267
268
269/**
270 * Keyboard driver registration record.
271 */
272const PDMDRVREG Keyboard::DrvReg =
273{
274 /* u32Version */
275 PDM_DRVREG_VERSION,
276 /* szDriverName */
277 "MainKeyboard",
278 /* pszDescription */
279 "Main keyboard driver (Main as in the API).",
280 /* fFlags */
281 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
282 /* fClass. */
283 PDM_DRVREG_CLASS_KEYBOARD,
284 /* cMaxInstances */
285 ~0,
286 /* cbInstance */
287 sizeof(DRVMAINKEYBOARD),
288 /* pfnConstruct */
289 Keyboard::drvConstruct,
290 /* pfnDestruct */
291 Keyboard::drvDestruct,
292 /* pfnIOCtl */
293 NULL,
294 /* pfnPowerOn */
295 NULL,
296 /* pfnReset */
297 NULL,
298 /* pfnSuspend */
299 NULL,
300 /* pfnResume */
301 NULL,
302 /* pfnDetach */
303 NULL
304};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette