VirtualBox

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

Last change on this file since 38876 was 35346, checked in by vboxsync, 14 years ago

VMM reorg: Moving the public include files from include/VBox to include/VBox/vmm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.9 KB
Line 
1/* $Id: KeyboardImpl.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
2/** @file
3 * VBox frontends: Basic Frontend (BFE):
4 * Implementation of Keyboard class and related things
5 */
6
7/*
8 * Copyright (C) 2006-2007 Oracle Corporation
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
19#ifdef VBOXBFE_WITHOUT_COM
20# include "COMDefs.h"
21#else
22# include <VBox/com/defs.h>
23# include <VBox/com/array.h>
24#endif
25#include <VBox/vmm/pdm.h>
26#include <VBox/vmm/cfgm.h>
27#include <VBox/err.h>
28#include <iprt/assert.h>
29#include <VBox/log.h>
30#include <iprt/asm.h>
31#include <iprt/uuid.h>
32#include "KeyboardImpl.h"
33
34// defines
35////////////////////////////////////////////////////////////////////////////////
36
37// globals
38////////////////////////////////////////////////////////////////////////////////
39
40/**
41 * Keyboard driver instance data.
42 */
43typedef struct DRVMAINKEYBOARD
44{
45 /** Pointer to the keyboard object. */
46 Keyboard *pKeyboard;
47 /** Pointer to the driver instance structure. */
48 PPDMDRVINS pDrvIns;
49 /** Pointer to the keyboard port interface of the driver/device above us. */
50 PPDMIKEYBOARDPORT pUpPort;
51 /** Our mouse connector interface. */
52 PDMIKEYBOARDCONNECTOR Connector;
53} DRVMAINKEYBOARD, *PDRVMAINKEYBOARD;
54
55// constructor / destructor
56////////////////////////////////////////////////////////////////////////////////
57
58Keyboard::Keyboard()
59{
60 mpDrv = NULL;
61 mpVMMDev = NULL;
62 mfVMMDevInited = false;
63}
64
65Keyboard::~Keyboard()
66{
67 if (mpDrv)
68 mpDrv->pKeyboard = NULL;
69 mpDrv = NULL;
70 mpVMMDev = NULL;
71 mfVMMDevInited = true;
72}
73
74// public methods
75////////////////////////////////////////////////////////////////////////////////
76
77/**
78 * Sends a scancode to the keyboard.
79 *
80 * @returns COM status code
81 * @param scancode The scancode to send
82 */
83STDMETHODIMP Keyboard::PutScancode(LONG scancode)
84{
85 if (!mpDrv)
86 return S_OK;
87
88 int rcVBox = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, (uint8_t)scancode);
89 if (RT_FAILURE (rcVBox))
90 return E_FAIL;
91
92 return S_OK;
93}
94
95/**
96 * Sends a list of scancodes to the keyboard.
97 *
98 * @returns COM status code
99 * @param scancodes Safe array of scancodes
100 * @param codesStored Address of variable to store the number
101 * of scancodes that were sent to the keyboard.
102 This value can be NULL.
103 */
104STDMETHODIMP Keyboard::PutScancodes(ComSafeArrayIn (LONG, scancodes),
105 ULONG *codesStored)
106{
107 if (ComSafeArrayInIsNull(scancodes))
108 return E_INVALIDARG;
109 if (!mpDrv)
110 return S_OK;
111
112 com::SafeArray <LONG> keys(ComSafeArrayInArg(scancodes));
113 int rcVBox = VINF_SUCCESS;
114
115 for (uint32_t i = 0; (i < keys.size()) && RT_SUCCESS(rcVBox); i++)
116 {
117 rcVBox = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, (uint8_t)keys[i]);
118 }
119
120 if (RT_FAILURE (rcVBox))
121 return E_FAIL;
122
123 /// @todo is it actually possible that not all scancodes can be transmitted?
124 if (codesStored)
125 *codesStored = keys.size();
126
127 return S_OK;
128}
129
130/**
131 * Sends Control-Alt-Delete to the keyboard. This could be done otherwise
132 * but it's so common that we'll be nice and supply a convenience API.
133 *
134 * @returns COM status code
135 *
136 */
137STDMETHODIMP Keyboard::PutCAD()
138{
139 static com::SafeArray<LONG> cadSequence(6);
140
141 cadSequence[0] = 0x1d; // Ctrl down
142 cadSequence[1] = 0x38; // Alt down
143 cadSequence[2] = 0x53; // Del down
144 cadSequence[3] = 0xd3; // Del up
145 cadSequence[4] = 0xb8; // Alt up
146 cadSequence[5] = 0x9d; // Ctrl up
147
148 return PutScancodes (ComSafeArrayAsInParam(cadSequence), NULL);
149}
150
151//
152// private methods
153//
154
155/**
156 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
157 */
158DECLCALLBACK(void *) Keyboard::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
159{
160 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
161 PDRVMAINKEYBOARD pDrv = PDMINS_2_DATA(pDrvIns, PDRVMAINKEYBOARD);
162 if (RTUuidCompare2Strs(pszIID, PDMIBASE_IID) == 0)
163 return &pDrvIns->IBase;
164 if (RTUuidCompare2Strs(pszIID, PDMIKEYBOARDCONNECTOR_IID) == 0)
165 return &pDrv->Connector;
166 return NULL;
167}
168
169
170/**
171 * Destruct a keyboard driver instance.
172 *
173 * @returns VBox status.
174 * @param pDrvIns The driver instance data.
175 */
176DECLCALLBACK(void) Keyboard::drvDestruct(PPDMDRVINS pDrvIns)
177{
178 PDRVMAINKEYBOARD pData = PDMINS_2_DATA(pDrvIns, PDRVMAINKEYBOARD);
179 LogFlow(("Keyboard::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
180 if (pData->pKeyboard)
181 {
182 pData->pKeyboard->mpDrv = NULL;
183 pData->pKeyboard->mpVMMDev = NULL;
184 }
185}
186
187
188/** @copydoc PDMIKEYBOARDCONNECTOR::pfnLedStatusChange */
189DECLCALLBACK(void) keyboardLedStatusChange(PPDMIKEYBOARDCONNECTOR pInterface, PDMKEYBLEDS enmLeds)
190{
191 /** @todo Implement me. */
192}
193
194/** @copydoc PDMIKEYBOARDCONNECTOR::pfnLedStatusChange */
195DECLCALLBACK(void) keyboardSetActive(PPDMIKEYBOARDCONNECTOR pInterface, bool fActive)
196{
197 /** @todo Implement me. */
198}
199
200/**
201 * Construct a keyboard driver instance.
202 *
203 * @copydoc FNPDMDRVCONSTRUCT
204 */
205DECLCALLBACK(int) Keyboard::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
206{
207 PDRVMAINKEYBOARD pData = PDMINS_2_DATA(pDrvIns, PDRVMAINKEYBOARD);
208 LogFlow(("Keyboard::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
209
210 /*
211 * Validate configuration.
212 */
213 if (!CFGMR3AreValuesValid(pCfg, "Object\0"))
214 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
215 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
216 ("Configuration error: Not possible to attach anything to this driver!\n"),
217 VERR_PDM_DRVINS_NO_ATTACH);
218
219 /*
220 * IBase.
221 */
222 pDrvIns->IBase.pfnQueryInterface = Keyboard::drvQueryInterface;
223
224 pData->Connector.pfnLedStatusChange = keyboardLedStatusChange;
225 pData->Connector.pfnSetActive = keyboardSetActive;
226
227 /*
228 * Get the IKeyboardPort interface of the above driver/device.
229 */
230 pData->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIKEYBOARDPORT);
231 if (!pData->pUpPort)
232 {
233 AssertMsgFailed(("Configuration error: No keyboard port interface above!\n"));
234 return VERR_PDM_MISSING_INTERFACE_ABOVE;
235 }
236
237 /*
238 * Get the Keyboard object pointer and update the mpDrv member.
239 */
240 void *pv;
241 int rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
242 if (RT_FAILURE(rc))
243 {
244 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
245 return rc;
246 }
247 pData->pKeyboard = (Keyboard *)pv; /** @todo Check this cast! */
248 pData->pKeyboard->mpDrv = pData;
249
250 return VINF_SUCCESS;
251}
252
253
254/**
255 * Keyboard driver registration record.
256 */
257const PDMDRVREG Keyboard::DrvReg =
258{
259 /* u32Version */
260 PDM_DRVREG_VERSION,
261 /* szName */
262 "MainKeyboard",
263 /* szRCMod */
264 "",
265 /* szR0Mod */
266 "",
267 /* pszDescription */
268 "Main keyboard driver (Main as in the API).",
269 /* fFlags */
270 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
271 /* fClass. */
272 PDM_DRVREG_CLASS_KEYBOARD,
273 /* cMaxInstances */
274 ~0,
275 /* cbInstance */
276 sizeof(DRVMAINKEYBOARD),
277 /* pfnConstruct */
278 Keyboard::drvConstruct,
279 /* pfnDestruct */
280 Keyboard::drvDestruct,
281 /* pfnRelocate */
282 NULL,
283 /* pfnIOCtl */
284 NULL,
285 /* pfnPowerOn */
286 NULL,
287 /* pfnReset */
288 NULL,
289 /* pfnSuspend */
290 NULL,
291 /* pfnResume */
292 NULL,
293 /* pfnAttach */
294 NULL,
295 /* pfnDetach */
296 NULL,
297 /* pfnPowerOff */
298 NULL,
299 /* pfnSoftReset */
300 NULL,
301 /* u32EndVersion */
302 PDM_DRVREG_VERSION
303};
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