VirtualBox

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

Last change on this file since 4071 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 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 innotek GmbH
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 as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * 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#endif
24#include <VBox/pdm.h>
25#include <VBox/cfgm.h>
26#include <VBox/err.h>
27#include <iprt/assert.h>
28#include <VBox/log.h>
29#include <iprt/asm.h>
30#include "KeyboardImpl.h"
31
32// defines
33////////////////////////////////////////////////////////////////////////////////
34
35// globals
36////////////////////////////////////////////////////////////////////////////////
37
38/**
39 * Keyboard driver instance data.
40 */
41typedef struct DRVMAINKEYBOARD
42{
43 /** Pointer to the keyboard object. */
44 Keyboard *pKeyboard;
45 /** Pointer to the driver instance structure. */
46 PPDMDRVINS pDrvIns;
47 /** Pointer to the keyboard port interface of the driver/device above us. */
48 PPDMIKEYBOARDPORT pUpPort;
49 /** Our mouse connector interface. */
50 PDMIKEYBOARDCONNECTOR Connector;
51} DRVMAINKEYBOARD, *PDRVMAINKEYBOARD;
52
53// constructor / destructor
54////////////////////////////////////////////////////////////////////////////////
55
56Keyboard::Keyboard()
57{
58 mpDrv = NULL;
59 mpVMMDev = NULL;
60 mfVMMDevInited = false;
61}
62
63Keyboard::~Keyboard()
64{
65 if (mpDrv)
66 mpDrv->pKeyboard = NULL;
67 mpDrv = NULL;
68 mpVMMDev = NULL;
69 mfVMMDevInited = true;
70}
71
72// public methods
73////////////////////////////////////////////////////////////////////////////////
74
75/**
76 * Sends a scancode to the keyboard.
77 *
78 * @returns COM status code
79 * @param scancode The scancode to send
80 */
81STDMETHODIMP Keyboard::PutScancode(LONG scancode)
82{
83 if (!mpDrv)
84 return S_OK;
85
86 int rcVBox = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, (uint8_t)scancode);
87 if (VBOX_FAILURE (rcVBox))
88 return E_FAIL;
89
90 return S_OK;
91}
92
93/**
94 * Sends a list of scancodes to the keyboard.
95 *
96 * @returns COM status code
97 * @param scancodes Pointer to the first scancode
98 * @param count Number of scancodes
99 * @param codesStored Address of variable to store the number
100 * of scancodes that were sent to the keyboard.
101 This value can be NULL.
102 */
103STDMETHODIMP Keyboard::PutScancodes(LONG *scancodes,
104 ULONG count,
105 ULONG *codesStored)
106{
107 if (!scancodes)
108 return E_INVALIDARG;
109 if (!mpDrv)
110 return S_OK;
111
112 LONG *currentScancode = scancodes;
113 int rcVBox = VINF_SUCCESS;
114
115 for (uint32_t i = 0; (i < count) && VBOX_SUCCESS(rcVBox); i++, currentScancode++)
116 {
117 rcVBox = mpDrv->pUpPort->pfnPutEvent(mpDrv->pUpPort, *(uint8_t*)currentScancode);
118 }
119
120 if (VBOX_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 = count;
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 LONG cadSequence[] = {
140 0x1d, // Ctrl down
141 0x38, // Alt down
142 0x53, // Del down
143 0xd3, // Del up
144 0xb8, // Alt up
145 0x9d // Ctrl up
146 };
147
148 return PutScancodes (cadSequence, ELEMENTS (cadSequence), NULL);
149}
150
151//
152// private methods
153//
154
155/**
156 * Queries an interface to the driver.
157 *
158 * @returns Pointer to interface.
159 * @returns NULL if the interface was not supported by the driver.
160 * @param pInterface Pointer to this interface structure.
161 * @param enmInterface The requested interface identification.
162 */
163DECLCALLBACK(void *) Keyboard::drvQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
164{
165 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
166 PDRVMAINKEYBOARD pDrv = PDMINS2DATA(pDrvIns, PDRVMAINKEYBOARD);
167 switch (enmInterface)
168 {
169 case PDMINTERFACE_BASE:
170 return &pDrvIns->IBase;
171 case PDMINTERFACE_KEYBOARD_CONNECTOR:
172 return &pDrv->Connector;
173 default:
174 return NULL;
175 }
176}
177
178
179/**
180 * Destruct a keyboard driver instance.
181 *
182 * @returns VBox status.
183 * @param pDrvIns The driver instance data.
184 */
185DECLCALLBACK(void) Keyboard::drvDestruct(PPDMDRVINS pDrvIns)
186{
187 PDRVMAINKEYBOARD pData = PDMINS2DATA(pDrvIns, PDRVMAINKEYBOARD);
188 LogFlow(("Keyboard::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
189 if (pData->pKeyboard)
190 {
191 pData->pKeyboard->mpDrv = NULL;
192 pData->pKeyboard->mpVMMDev = NULL;
193 }
194}
195
196
197/** @copydoc PDMIKEYBOARDCONNECTOR::pfnLedStatusChange */
198DECLCALLBACK(void) keyboardLedStatusChange(PPDMIKEYBOARDCONNECTOR pInterface, PDMKEYBLEDS enmLeds)
199{
200 /** @todo Implement me. */
201}
202
203
204/**
205 * Construct a keyboard driver instance.
206 *
207 * @returns VBox status.
208 * @param pDrvIns The driver instance data.
209 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
210 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
211 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
212 * iInstance it's expected to be used a bit in this function.
213 */
214DECLCALLBACK(int) Keyboard::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
215{
216 PDRVMAINKEYBOARD pData = PDMINS2DATA(pDrvIns, PDRVMAINKEYBOARD);
217 LogFlow(("Keyboard::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
218
219 /*
220 * Validate configuration.
221 */
222 if (!CFGMR3AreValuesValid(pCfgHandle, "Object\0"))
223 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
224 PPDMIBASE pBaseIgnore;
225 int rc = pDrvIns->pDrvHlp->pfnAttach(pDrvIns, &pBaseIgnore);
226 if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
227 {
228 AssertMsgFailed(("Configuration error: Not possible to attach anything to this driver!\n"));
229 return VERR_PDM_DRVINS_NO_ATTACH;
230 }
231
232 /*
233 * IBase.
234 */
235 pDrvIns->IBase.pfnQueryInterface = Keyboard::drvQueryInterface;
236
237 pData->Connector.pfnLedStatusChange = keyboardLedStatusChange;
238
239 /*
240 * Get the IKeyboardPort interface of the above driver/device.
241 */
242 pData->pUpPort = (PPDMIKEYBOARDPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_KEYBOARD_PORT);
243 if (!pData->pUpPort)
244 {
245 AssertMsgFailed(("Configuration error: No keyboard port interface above!\n"));
246 return VERR_PDM_MISSING_INTERFACE_ABOVE;
247 }
248
249 /*
250 * Get the Keyboard object pointer and update the mpDrv member.
251 */
252 void *pv;
253 rc = CFGMR3QueryPtr(pCfgHandle, "Object", &pv);
254 if (VBOX_FAILURE(rc))
255 {
256 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Vrc\n", rc));
257 return rc;
258 }
259 pData->pKeyboard = (Keyboard *)pv; /** @todo Check this cast! */
260 pData->pKeyboard->mpDrv = pData;
261
262 return VINF_SUCCESS;
263}
264
265
266/**
267 * Keyboard driver registration record.
268 */
269const PDMDRVREG Keyboard::DrvReg =
270{
271 /* u32Version */
272 PDM_DRVREG_VERSION,
273 /* szDriverName */
274 "MainKeyboard",
275 /* pszDescription */
276 "Main keyboard driver (Main as in the API).",
277 /* fFlags */
278 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
279 /* fClass. */
280 PDM_DRVREG_CLASS_KEYBOARD,
281 /* cMaxInstances */
282 ~0,
283 /* cbInstance */
284 sizeof(DRVMAINKEYBOARD),
285 /* pfnConstruct */
286 Keyboard::drvConstruct,
287 /* pfnDestruct */
288 Keyboard::drvDestruct,
289 /* pfnIOCtl */
290 NULL,
291 /* pfnPowerOn */
292 NULL,
293 /* pfnReset */
294 NULL,
295 /* pfnSuspend */
296 NULL,
297 /* pfnResume */
298 NULL,
299 /* pfnDetach */
300 NULL
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