VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxFB/VBoxFB.cpp@ 8155

最後變更 在這個檔案從8155是 8155,由 vboxsync 提交於 17 年 前

The Big Sun Rebranding Header Change

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 20.8 KB
 
1/** @file
2 *
3 * VBox frontends: Framebuffer (FB, DirectFB):
4 * main() routine
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.alldomusa.eu.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#include "VBoxFB.h"
24#include "Framebuffer.h"
25#include <getopt.h>
26#include <VBox/param.h>
27#include <iprt/path.h>
28
29/**
30 * Globals
31 */
32uint32_t useFixedVideoMode = 0;
33int scaleGuest = 0;
34videoMode fixedVideoMode = {0};
35int32_t initialVideoMode = -1;
36
37void showusage()
38{
39 printf("\nThe following parameters are supported:\n"
40 "--startvm uuid start VM with UUID 'uuid'\n"
41 "--fixedres WxHxBPP always use fixed host resolution\n"
42 "--listhostmodes display list of suported host display modes and exit\n"
43 "--scale scale guest video mode to host video mode\n"
44 "--nodirectblit disable direct blitting, use intermediate framebuffer\n"
45 "--showlabel show VM name on top of the VM display\n");
46}
47
48/** entry point */
49int main(int argc, char *argv[])
50{
51 nsID uuid;
52 int c;
53 int listHostModes = 0;
54 int quit = 0;
55 const struct option options[] =
56 {
57 { "help", no_argument, NULL, 'h' },
58 { "startvm", required_argument, NULL, 's' },
59 { "fixedres", required_argument, NULL, 'f' },
60 { "listhostmodes", no_argument, NULL, 'l' },
61 { "scale", no_argument, NULL, 'c' }
62 };
63
64 printf("VirtualBox DirectFB GUI built %s %s\n"
65 "(C) 2008 Sun Microsystems, Inc.\n"
66 "(C) 2004-2007 innotek GmbH\n"
67 "(C) 2004-2005 secunet Security Networks AG\n", __DATE__, __TIME__);
68
69 RTUuidClear((PRTUUID)&uuid);
70
71 for (;;)
72 {
73 c = getopt_long(argc, argv, "s:", options, NULL);
74 if (c == -1)
75 break;
76 switch (c)
77 {
78 case 'h':
79 {
80 showusage();
81 exit(0);
82 break;
83 }
84 case 's':
85 {
86 // UUID as string, parse it
87 if (!VBOX_SUCCESS(RTUuidFromStr((PRTUUID)&uuid, optarg)))
88 {
89 printf("Error, invalid UUID format given!\n");
90 showusage();
91 exit(-1);
92 }
93 break;
94 }
95 case 'f':
96 {
97 if (sscanf(optarg, "%ux%ux%u", &fixedVideoMode.width, &fixedVideoMode.height,
98 &fixedVideoMode.bpp) != 3)
99 {
100 printf("Error, invalid resolution argument!\n");
101 showusage();
102 exit(-1);
103 }
104 useFixedVideoMode = 1;
105 break;
106 }
107 case 'l':
108 {
109 listHostModes = 1;
110 break;
111 }
112 case 'c':
113 {
114 scaleGuest = 1;
115 break;
116 }
117 default:
118 break;
119 }
120 }
121
122 // check if we got a UUID
123 if (RTUuidIsNull((PRTUUID)&uuid))
124 {
125 printf("Error, no UUID given!\n");
126 showusage();
127 exit(-1);
128 }
129
130
131 /**
132 * XPCOM setup
133 */
134
135 nsresult rc;
136 XPCOMGlueStartup(nsnull);
137
138 // get the path to the executable
139 char appPath [RTPATH_MAX];
140 RTPathProgram (appPath, RTPATH_MAX);
141
142 nsCOMPtr<nsIFile> nsAppPath;
143 {
144 nsCOMPtr<nsILocalFile> file;
145 rc = NS_NewNativeLocalFile(nsEmbedCString (appPath), PR_FALSE,
146 getter_AddRefs (file));
147 if (NS_SUCCEEDED(rc))
148 {
149 nsAppPath = do_QueryInterface(file, &rc);
150 }
151 }
152 if (NS_FAILED(rc))
153 {
154 printf ("Error: failed to create file object! (rc=%08X)\n", rc);
155 exit(-1);
156 }
157
158 nsCOMPtr<nsIServiceManager> serviceManager;
159 rc = NS_InitXPCOM2(getter_AddRefs(serviceManager), nsAppPath, nsnull);
160 if (NS_FAILED(rc))
161 {
162 printf("Error: XPCOM could not be initialized! rc=0x%x\n", rc);
163 exit(-1);
164 }
165
166 // register our component
167 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(serviceManager);
168 if (!registrar)
169 {
170 printf("Error: could not query nsIComponentRegistrar interface!\n");
171 exit(-1);
172 }
173 registrar->AutoRegister(nsnull);
174
175 nsCOMPtr<ipcIService> ipcServ = do_GetService(IPC_SERVICE_CONTRACTID, &rc);
176 if (NS_FAILED(rc))
177 {
178 printf("Error: could not get IPC service! rc = %08X\n", rc);
179 exit(-1);
180 }
181
182 nsCOMPtr<ipcIDConnectService> dcon = do_GetService(IPC_DCONNECTSERVICE_CONTRACTID, &rc);
183 if (NS_FAILED(rc))
184 {
185 printf("Error: could not get DCONNECT service! rc = %08X\n", rc);
186 exit(-1);
187 }
188
189 PRUint32 serverID = 0;
190 rc = ipcServ->ResolveClientName("VirtualBoxServer", &serverID);
191 if (NS_FAILED(rc))
192 {
193 printf("Error: could not get VirtualBox server ID! rc = %08X\n", rc);
194 exit(-1);
195 }
196
197 nsCOMPtr<nsIComponentManager> manager = do_QueryInterface(registrar);
198 if (!manager)
199 {
200 printf("Error: could not query nsIComponentManager interface!\n");
201 exit(-1);
202 }
203
204 nsCOMPtr<IVirtualBox> virtualBox;
205 rc = dcon->CreateInstanceByContractID(
206 serverID,
207 NS_VIRTUALBOX_CONTRACTID,
208 NS_GET_IID(IVirtualBox),
209 getter_AddRefs(virtualBox));
210 if (NS_FAILED(rc))
211 {
212 printf("Error, could not instantiate object! rc=0x%x\n", rc);
213 exit(-1);
214 }
215
216 nsCOMPtr<ISession> session;
217 rc = manager->CreateInstance((nsCID)NS_SESSION_CID,
218 nsnull,
219 NS_GET_IID(ISession),
220 getter_AddRefs(session));
221 if (NS_FAILED(rc))
222 {
223 printf("Error: could not instantiate Session object! rc = %08X\n", rc);
224 exit(-1);
225 }
226
227 // open session for this VM
228 rc = virtualBox->OpenSession(session, uuid);
229 if (NS_FAILED(rc))
230 {
231 printf("Error: given machine not found!\n");
232 exit(-1);
233 }
234 IMachine *machine = NULL;
235 session->GetMachine(&machine);
236 if (!machine)
237 {
238 printf("Error: given machine not found!\n");
239 exit(-1);
240 }
241 IConsole *console = NULL;
242 session->GetConsole(&console);
243 if (!console)
244 {
245 printf("Error: cannot get console!\n");
246 exit(-1);
247 }
248
249 IDisplay *display = NULL;
250 console->GetDisplay(&display);
251 if (!display)
252 {
253 printf("Error: could not get display object!\n");
254 exit(-1);
255 }
256
257 IKeyboard *keyboard = NULL;
258 IMouse *mouse = NULL;
259 VBoxDirectFB *frameBuffer = NULL;
260
261 /**
262 * Init DirectFB
263 */
264 IDirectFB *dfb = NULL;
265 IDirectFBSurface *surface = NULL;
266 IDirectFBInputDevice *dfbKeyboard = NULL;
267 IDirectFBInputDevice *dfbMouse = NULL;
268 IDirectFBEventBuffer *dfbEventBuffer = NULL;
269 DFBSurfaceDescription dsc;
270 int screen_width, screen_height;
271
272 DFBCHECK(DirectFBInit(&argc, &argv));
273 DFBCHECK(DirectFBCreate(&dfb));
274 DFBCHECK(dfb->SetCooperativeLevel(dfb, DFSCL_FULLSCREEN));
275 // populate our structure of supported video modes
276 DFBCHECK(dfb->EnumVideoModes(dfb, enumVideoModesHandler, NULL));
277
278 if (listHostModes)
279 {
280 printf("*****************************************************\n");
281 printf("Number of available host video modes: %u\n", numVideoModes);
282 for (uint32_t i = 0; i < numVideoModes; i++)
283 {
284 printf("Mode %u: xres = %u, yres = %u, bpp = %u\n", i,
285 videoModes[i].width, videoModes[i].height, videoModes[i].bpp);
286 }
287 printf("Note: display modes with bpp < have been filtered out\n");
288 printf("*****************************************************\n");
289 goto Leave;
290 }
291
292 if (useFixedVideoMode)
293 {
294 int32_t bestVideoMode = getBestVideoMode(fixedVideoMode.width,
295 fixedVideoMode.height,
296 fixedVideoMode.bpp);
297 // validate the fixed mode
298 if ((bestVideoMode == -1) ||
299 ((fixedVideoMode.width != videoModes[bestVideoMode].width) ||
300 (fixedVideoMode.height != videoModes[bestVideoMode].height) ||
301 (fixedVideoMode.bpp != videoModes[bestVideoMode].bpp)))
302 {
303 printf("Error: the specified fixed video mode is not available!\n");
304 exit(-1);
305 }
306 } else
307 {
308 initialVideoMode = getBestVideoMode(640, 480, 16);
309 if (initialVideoMode == -1)
310 {
311 printf("Error: initial video mode 640x480x16 is not available!\n");
312 exit(-1);
313 }
314 }
315
316 dsc.flags = DSDESC_CAPS;
317 dsc.caps = DSCAPS_PRIMARY;
318 DFBCHECK(dfb->CreateSurface(dfb, &dsc, &surface));
319 DFBCHECK(surface->Clear(surface, 0, 0, 0, 0));
320 DFBCHECK(surface->GetSize(surface, &screen_width, &screen_height));
321 DFBCHECK(dfb->GetInputDevice(dfb, DIDID_KEYBOARD, &dfbKeyboard));
322 DFBCHECK(dfbKeyboard->CreateEventBuffer(dfbKeyboard, &dfbEventBuffer));
323 DFBCHECK(dfb->GetInputDevice(dfb, DIDID_MOUSE, &dfbMouse));
324 DFBCHECK(dfbMouse->AttachEventBuffer(dfbMouse, dfbEventBuffer));
325
326
327 if (useFixedVideoMode)
328 {
329 printf("Information: setting video mode to %ux%ux%u\n", fixedVideoMode.width,
330 fixedVideoMode.height, fixedVideoMode.bpp);
331 DFBCHECK(dfb->SetVideoMode(dfb, fixedVideoMode.width,
332 fixedVideoMode.height, fixedVideoMode.bpp));
333 } else
334 {
335 printf("Information: starting with default video mode %ux%ux%u\n",
336 videoModes[initialVideoMode].width, videoModes[initialVideoMode].height,
337 videoModes[initialVideoMode].bpp);
338 DFBCHECK(dfb->SetVideoMode(dfb, videoModes[initialVideoMode].width,
339 videoModes[initialVideoMode].height,
340 videoModes[initialVideoMode].bpp));
341 }
342
343 // register our framebuffer
344 frameBuffer = new VBoxDirectFB(dfb, surface);
345 display->RegisterExternalFramebuffer(frameBuffer);
346
347 /**
348 * Start the VM execution thread
349 */
350 console->PowerUp(NULL);
351
352 console->GetKeyboard(&keyboard);
353 console->GetMouse(&mouse);
354
355 /**
356 * Main event loop
357 */
358 #define MAX_KEYEVENTS 10
359 int keyEvents[MAX_KEYEVENTS];
360 int numKeyEvents;
361
362 while (!quit)
363 {
364 DFBInputEvent event;
365
366 numKeyEvents = 0;
367 DFBCHECK(dfbEventBuffer->WaitForEvent(dfbEventBuffer));
368 while (dfbEventBuffer->GetEvent(dfbEventBuffer, DFB_EVENT(&event)) == DFB_OK)
369 {
370 int mouseXDelta = 0;
371 int mouseYDelta = 0;
372 int mouseZDelta = 0;
373 switch (event.type)
374 {
375 #define QUEUEEXT() keyEvents[numKeyEvents++] = 0xe0
376 #define QUEUEKEY(scan) keyEvents[numKeyEvents++] = scan | (event.type == DIET_KEYRELEASE ? 0x80 : 0x00)
377 #define QUEUEKEYRAW(scan) keyEvents[numKeyEvents++] = scan
378 case DIET_KEYPRESS:
379 case DIET_KEYRELEASE:
380 {
381 // @@@AH development hack to get out of it!
382 if ((event.key_id == DIKI_ESCAPE) && (event.modifiers & (DIMM_CONTROL | DIMM_ALT)))
383 quit = 1;
384
385 if (numKeyEvents < MAX_KEYEVENTS)
386 {
387 //printf("%s: key_code: 0x%x\n", event.type == DIET_KEYPRESS ? "DIET_KEYPRESS" : "DIET_KEYRELEASE", event.key_code);
388 switch ((uint32_t)event.key_id)
389 {
390 case DIKI_ALTGR:
391 QUEUEEXT();
392 QUEUEKEY(0x38);
393 break;
394 case DIKI_CONTROL_R:
395 QUEUEEXT();
396 QUEUEKEY(0x1d);
397 break;
398 case DIKI_INSERT:
399 QUEUEEXT();
400 QUEUEKEY(0x52);
401 break;
402 case DIKI_DELETE:
403 QUEUEEXT();
404 QUEUEKEY(0x53);
405 break;
406 case DIKI_HOME:
407 QUEUEEXT();
408 QUEUEKEY(0x47);
409 break;
410 case DIKI_END:
411 QUEUEEXT();
412 QUEUEKEY(0x4f);
413 break;
414 case DIKI_PAGE_UP:
415 QUEUEEXT();
416 QUEUEKEY(0x49);
417 break;
418 case DIKI_PAGE_DOWN:
419 QUEUEEXT();
420 QUEUEKEY(0x51);
421 break;
422 case DIKI_LEFT:
423 QUEUEEXT();
424 QUEUEKEY(0x4b);
425 break;
426 case DIKI_RIGHT:
427 QUEUEEXT();
428 QUEUEKEY(0x4d);
429 break;
430 case DIKI_UP:
431 QUEUEEXT();
432 QUEUEKEY(0x48);
433 break;
434 case DIKI_DOWN:
435 QUEUEEXT();
436 QUEUEKEY(0x50);
437 break;
438 case DIKI_KP_DIV:
439 QUEUEEXT();
440 QUEUEKEY(0x35);
441 break;
442 case DIKI_KP_ENTER:
443 QUEUEEXT();
444 QUEUEKEY(0x1c);
445 break;
446 case DIKI_PRINT:
447 // the break code is inverted!
448 if (event.type == DIET_KEYPRESS)
449 {
450 QUEUEEXT();
451 QUEUEKEY(0x2a);
452 QUEUEEXT();
453 QUEUEKEY(0x37);
454 } else
455 {
456 QUEUEEXT();
457 QUEUEKEY(0x37);
458 QUEUEEXT();
459 QUEUEKEY(0x2a);
460 }
461 break;
462 case DIKI_PAUSE:
463 // This is a super weird key. No break code and a 6 byte
464 // combination.
465 if (event.type == DIET_KEYPRESS)
466 {
467 QUEUEKEY(0xe1);
468 QUEUEKEY(0x1d);
469 QUEUEKEY(0x45);
470 QUEUEKEY(0xe1);
471 QUEUEKEY(0x9d);
472 QUEUEKEY(0xc5);
473 }
474 break;
475 case DIKI_META_L:
476 // the left Windows logo is a bit different
477 if (event.type == DIET_KEYPRESS)
478 {
479 QUEUEEXT();
480 QUEUEKEYRAW(0x1f);
481 } else
482 {
483 QUEUEEXT();
484 QUEUEKEYRAW(0xf0);
485 QUEUEKEYRAW(0x1f);
486 }
487 break;
488 case DIKI_META_R:
489 // the right Windows logo is a bit different
490 if (event.type == DIET_KEYPRESS)
491 {
492 QUEUEEXT();
493 QUEUEKEYRAW(0x27);
494 } else
495 {
496 QUEUEEXT();
497 QUEUEKEYRAW(0xf0);
498 QUEUEKEYRAW(0x27);
499 }
500 break;
501 case DIKI_SUPER_R:
502 // the popup menu is a bit different
503 if (event.type == DIET_KEYPRESS)
504 {
505 QUEUEEXT();
506 QUEUEKEYRAW(0x2f);
507 } else
508 {
509 QUEUEEXT();
510 QUEUEKEYRAW(0xf0);
511 QUEUEKEYRAW(0x2f);
512 }
513 break;
514
515 default:
516 // check if we got a hardware scancode
517 if (event.key_code != -1)
518 {
519 // take the scancode from DirectFB as is
520 QUEUEKEY(event.key_code);
521 } else
522 {
523 // XXX need extra handling!
524 }
525 }
526 }
527 break;
528 }
529 #undef QUEUEEXT
530 #undef QUEUEKEY
531 #undef QUEUEKEYRAW
532
533 case DIET_AXISMOTION:
534 {
535 switch (event.axis)
536 {
537 case DIAI_X:
538 mouseXDelta += event.axisrel;
539 break;
540 case DIAI_Y:
541 mouseYDelta += event.axisrel;
542 break;
543 case DIAI_Z:
544 mouseZDelta += event.axisrel;
545 break;
546 default:
547 break;
548 }
549 // fall through
550 }
551 case DIET_BUTTONPRESS:
552 // fall through;
553 case DIET_BUTTONRELEASE:
554 {
555 int buttonState = 0;
556 if (event.buttons & DIBM_LEFT)
557 buttonState |= MouseButtonState::LeftButton;
558 if (event.buttons & DIBM_RIGHT)
559 buttonState |= MouseButtonState::RightButton;
560 if (event.buttons & DIBM_MIDDLE)
561 buttonState |= MouseButtonState::MiddleButton;
562 mouse->PutMouseEvent(mouseXDelta, mouseYDelta, mouseZDelta,
563 buttonState);
564 break;
565 }
566 default:
567 break;
568 }
569 }
570 // did we get any keyboard events?
571 if (numKeyEvents > 0)
572 {
573 uint32_t codesStored;
574 if (numKeyEvents > 1)
575 {
576 keyboard->PutScancodes((PRInt32*)keyEvents, numKeyEvents,
577 &codesStored);
578 } else
579 {
580 keyboard->PutScancode(keyEvents[0]);
581 }
582 }
583 }
584 console->PowerDown();
585Leave:
586 if (mouse)
587 mouse->Release();
588 if (keyboard)
589 keyboard->Release();
590 if (display)
591 display->Release();
592 if (console)
593 console->Release();
594 if (machine)
595 machine->Release();
596 virtualBox = NULL;
597
598 if (dfbEventBuffer)
599 dfbEventBuffer->Release(dfbEventBuffer);
600 if (dfbMouse)
601 dfbMouse->Release(dfbMouse);
602 if (dfbKeyboard)
603 dfbKeyboard->Release(dfbKeyboard);
604 if (surface)
605 surface->Release(surface);
606 if (dfb)
607 dfb->Release(dfb);
608
609 return 0;
610}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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