VirtualBox

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

Last change on this file since 26166 was 26166, checked in by vboxsync, 15 years ago

PDM: s/szDriverName/szName/g - PDMDRVREG.

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