3
* VBox frontends: Framebuffer (FB, DirectFB):
8
* Copyright (C) 2006-2007 innotek GmbH
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.
20
#include "Framebuffer.h"
22
#include <VBox/param.h>
23
#include <iprt/path.h>
28
uint32_t useFixedVideoMode = 0;
30
videoMode fixedVideoMode = {0};
31
int32_t initialVideoMode = -1;
35
printf("\nThe following parameters are supported:\n"
36
"--startvm uuid start VM with UUID 'uuid'\n"
37
"--fixedres WxHxBPP always use fixed host resolution\n"
38
"--listhostmodes display list of suported host display modes and exit\n"
39
"--scale scale guest video mode to host video mode\n"
40
"--nodirectblit disable direct blitting, use intermediate framebuffer\n"
41
"--showlabel show VM name on top of the VM display\n");
45
int main(int argc, char *argv[])
49
int listHostModes = 0;
51
const struct option options[] =
53
{ "help", no_argument, NULL, 'h' },
54
{ "startvm", required_argument, NULL, 's' },
55
{ "fixedres", required_argument, NULL, 'f' },
56
{ "listhostmodes", no_argument, NULL, 'l' },
57
{ "scale", no_argument, NULL, 'c' }
60
printf("VirtualBox DirectFB GUI built %s %s\n"
61
"(C) 2004-2007 innotek GmbH\n"
62
"(C) 2004-2005 secunet Security Networks AG\n", __DATE__, __TIME__);
64
RTUuidClear((PRTUUID)&uuid);
68
c = getopt_long(argc, argv, "s:", options, NULL);
81
// UUID as string, parse it
82
if (!VBOX_SUCCESS(RTUuidFromStr((PRTUUID)&uuid, optarg)))
84
printf("Error, invalid UUID format given!\n");
92
if (sscanf(optarg, "%ux%ux%u", &fixedVideoMode.width, &fixedVideoMode.height,
93
&fixedVideoMode.bpp) != 3)
95
printf("Error, invalid resolution argument!\n");
99
useFixedVideoMode = 1;
117
// check if we got a UUID
118
if (RTUuidIsNull((PRTUUID)&uuid))
120
printf("Error, no UUID given!\n");
131
XPCOMGlueStartup(nsnull);
133
// get the path to the executable
134
char appPath [RTPATH_MAX];
135
RTPathProgram (appPath, RTPATH_MAX);
137
nsCOMPtr<nsIFile> nsAppPath;
139
nsCOMPtr<nsILocalFile> file;
140
rc = NS_NewNativeLocalFile(nsEmbedCString (appPath), PR_FALSE,
141
getter_AddRefs (file));
142
if (NS_SUCCEEDED(rc))
144
nsAppPath = do_QueryInterface(file, &rc);
149
printf ("Error: failed to create file object! (rc=%08X)\n", rc);
153
nsCOMPtr<nsIServiceManager> serviceManager;
154
rc = NS_InitXPCOM2(getter_AddRefs(serviceManager), nsAppPath, nsnull);
157
printf("Error: XPCOM could not be initialized! rc=0x%x\n", rc);
161
// register our component
162
nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(serviceManager);
165
printf("Error: could not query nsIComponentRegistrar interface!\n");
168
registrar->AutoRegister(nsnull);
170
nsCOMPtr<ipcIService> ipcServ = do_GetService(IPC_SERVICE_CONTRACTID, &rc);
173
printf("Error: could not get IPC service! rc = %08X\n", rc);
177
nsCOMPtr<ipcIDConnectService> dcon = do_GetService(IPC_DCONNECTSERVICE_CONTRACTID, &rc);
180
printf("Error: could not get DCONNECT service! rc = %08X\n", rc);
184
PRUint32 serverID = 0;
185
rc = ipcServ->ResolveClientName("VirtualBoxServer", &serverID);
188
printf("Error: could not get VirtualBox server ID! rc = %08X\n", rc);
192
nsCOMPtr<nsIComponentManager> manager = do_QueryInterface(registrar);
195
printf("Error: could not query nsIComponentManager interface!\n");
199
nsCOMPtr<IVirtualBox> virtualBox;
200
rc = dcon->CreateInstanceByContractID(
202
NS_VIRTUALBOX_CONTRACTID,
203
NS_GET_IID(IVirtualBox),
204
getter_AddRefs(virtualBox));
207
printf("Error, could not instantiate object! rc=0x%x\n", rc);
211
nsCOMPtr<ISession> session;
212
rc = manager->CreateInstance((nsCID)NS_SESSION_CID,
214
NS_GET_IID(ISession),
215
getter_AddRefs(session));
218
printf("Error: could not instantiate Session object! rc = %08X\n", rc);
222
// open session for this VM
223
rc = virtualBox->OpenSession(session, uuid);
226
printf("Error: given machine not found!\n");
229
IMachine *machine = NULL;
230
session->GetMachine(&machine);
233
printf("Error: given machine not found!\n");
236
IConsole *console = NULL;
237
session->GetConsole(&console);
240
printf("Error: cannot get console!\n");
244
IDisplay *display = NULL;
245
console->GetDisplay(&display);
248
printf("Error: could not get display object!\n");
252
IKeyboard *keyboard = NULL;
253
IMouse *mouse = NULL;
254
VBoxDirectFB *frameBuffer = NULL;
259
IDirectFB *dfb = NULL;
260
IDirectFBSurface *surface = NULL;
261
IDirectFBInputDevice *dfbKeyboard = NULL;
262
IDirectFBInputDevice *dfbMouse = NULL;
263
IDirectFBEventBuffer *dfbEventBuffer = NULL;
264
DFBSurfaceDescription dsc;
265
int screen_width, screen_height;
267
DFBCHECK(DirectFBInit(&argc, &argv));
268
DFBCHECK(DirectFBCreate(&dfb));
269
DFBCHECK(dfb->SetCooperativeLevel(dfb, DFSCL_FULLSCREEN));
270
// populate our structure of supported video modes
271
DFBCHECK(dfb->EnumVideoModes(dfb, enumVideoModesHandler, NULL));
275
printf("*****************************************************\n");
276
printf("Number of available host video modes: %u\n", numVideoModes);
277
for (uint32_t i = 0; i < numVideoModes; i++)
279
printf("Mode %u: xres = %u, yres = %u, bpp = %u\n", i,
280
videoModes[i].width, videoModes[i].height, videoModes[i].bpp);
282
printf("Note: display modes with bpp < have been filtered out\n");
283
printf("*****************************************************\n");
287
if (useFixedVideoMode)
289
int32_t bestVideoMode = getBestVideoMode(fixedVideoMode.width,
290
fixedVideoMode.height,
292
// validate the fixed mode
293
if ((bestVideoMode == -1) ||
294
((fixedVideoMode.width != videoModes[bestVideoMode].width) ||
295
(fixedVideoMode.height != videoModes[bestVideoMode].height) ||
296
(fixedVideoMode.bpp != videoModes[bestVideoMode].bpp)))
298
printf("Error: the specified fixed video mode is not available!\n");
303
initialVideoMode = getBestVideoMode(640, 480, 16);
304
if (initialVideoMode == -1)
306
printf("Error: initial video mode 640x480x16 is not available!\n");
311
dsc.flags = DSDESC_CAPS;
312
dsc.caps = DSCAPS_PRIMARY;
313
DFBCHECK(dfb->CreateSurface(dfb, &dsc, &surface));
314
DFBCHECK(surface->Clear(surface, 0, 0, 0, 0));
315
DFBCHECK(surface->GetSize(surface, &screen_width, &screen_height));
316
DFBCHECK(dfb->GetInputDevice(dfb, DIDID_KEYBOARD, &dfbKeyboard));
317
DFBCHECK(dfbKeyboard->CreateEventBuffer(dfbKeyboard, &dfbEventBuffer));
318
DFBCHECK(dfb->GetInputDevice(dfb, DIDID_MOUSE, &dfbMouse));
319
DFBCHECK(dfbMouse->AttachEventBuffer(dfbMouse, dfbEventBuffer));
322
if (useFixedVideoMode)
324
printf("Information: setting video mode to %ux%ux%u\n", fixedVideoMode.width,
325
fixedVideoMode.height, fixedVideoMode.bpp);
326
DFBCHECK(dfb->SetVideoMode(dfb, fixedVideoMode.width,
327
fixedVideoMode.height, fixedVideoMode.bpp));
330
printf("Information: starting with default video mode %ux%ux%u\n",
331
videoModes[initialVideoMode].width, videoModes[initialVideoMode].height,
332
videoModes[initialVideoMode].bpp);
333
DFBCHECK(dfb->SetVideoMode(dfb, videoModes[initialVideoMode].width,
334
videoModes[initialVideoMode].height,
335
videoModes[initialVideoMode].bpp));
338
// register our framebuffer
339
frameBuffer = new VBoxDirectFB(dfb, surface);
340
display->RegisterExternalFramebuffer(frameBuffer);
343
* Start the VM execution thread
345
console->PowerUp(NULL);
347
console->GetKeyboard(&keyboard);
348
console->GetMouse(&mouse);
353
#define MAX_KEYEVENTS 10
354
int keyEvents[MAX_KEYEVENTS];
362
DFBCHECK(dfbEventBuffer->WaitForEvent(dfbEventBuffer));
363
while (dfbEventBuffer->GetEvent(dfbEventBuffer, DFB_EVENT(&event)) == DFB_OK)
370
#define QUEUEEXT() keyEvents[numKeyEvents++] = 0xe0
371
#define QUEUEKEY(scan) keyEvents[numKeyEvents++] = scan | (event.type == DIET_KEYRELEASE ? 0x80 : 0x00)
372
#define QUEUEKEYRAW(scan) keyEvents[numKeyEvents++] = scan
374
case DIET_KEYRELEASE:
376
// @@@AH development hack to get out of it!
377
if ((event.key_id == DIKI_ESCAPE) && (event.modifiers & (DIMM_CONTROL | DIMM_ALT)))
380
if (numKeyEvents < MAX_KEYEVENTS)
382
//printf("%s: key_code: 0x%x\n", event.type == DIET_KEYPRESS ? "DIET_KEYPRESS" : "DIET_KEYRELEASE", event.key_code);
383
switch ((uint32_t)event.key_id)
442
// the break code is inverted!
443
if (event.type == DIET_KEYPRESS)
458
// This is a super weird key. No break code and a 6 byte
460
if (event.type == DIET_KEYPRESS)
471
// the left Windows logo is a bit different
472
if (event.type == DIET_KEYPRESS)
484
// the right Windows logo is a bit different
485
if (event.type == DIET_KEYPRESS)
497
// the popup menu is a bit different
498
if (event.type == DIET_KEYPRESS)
511
// check if we got a hardware scancode
512
if (event.key_code != -1)
514
// take the scancode from DirectFB as is
515
QUEUEKEY(event.key_code);
518
// XXX need extra handling!
528
case DIET_AXISMOTION:
533
mouseXDelta += event.axisrel;
536
mouseYDelta += event.axisrel;
539
mouseZDelta += event.axisrel;
546
case DIET_BUTTONPRESS:
548
case DIET_BUTTONRELEASE:
551
if (event.buttons & DIBM_LEFT)
552
buttonState |= MouseButtonState::LeftButton;
553
if (event.buttons & DIBM_RIGHT)
554
buttonState |= MouseButtonState::RightButton;
555
if (event.buttons & DIBM_MIDDLE)
556
buttonState |= MouseButtonState::MiddleButton;
557
mouse->PutMouseEvent(mouseXDelta, mouseYDelta, mouseZDelta,
565
// did we get any keyboard events?
566
if (numKeyEvents > 0)
568
uint32_t codesStored;
569
if (numKeyEvents > 1)
571
keyboard->PutScancodes((PRInt32*)keyEvents, numKeyEvents,
575
keyboard->PutScancode(keyEvents[0]);
579
console->PowerDown();
594
dfbEventBuffer->Release(dfbEventBuffer);
596
dfbMouse->Release(dfbMouse);
598
dfbKeyboard->Release(dfbKeyboard);
600
surface->Release(surface);