VBoxSDL.cpp revision dced478b440a327fb550155c0f73c1ac968ad93b
0N/A * VBox frontends: VBoxSDL (simple frontend based on SDL): 0N/A * Copyright (C) 2006-2007 Sun Microsystems, Inc. 0N/A * This file is part of VirtualBox Open Source Edition (OSE), as 0N/A * you can redistribute it and/or modify it under the terms of the GNU 0N/A * General Public License (GPL) as published by the Free Software 0N/A * Foundation, in version 2 as it comes in the "COPYING" file of the 0N/A * VirtualBox OSE distribution. VirtualBox OSE is distributed in the 0N/A * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa 873N/A * additional information or have any questions. 0N/A/******************************************************************************* 0N/A*******************************************************************************/ 0N/A/* Xlib would re-define our enums */ 0N/A/******************************************************************************* 0N/A* Defined Constants And Macros * 0N/A*******************************************************************************/ 0N/A/** extra data key for the secure label */ 0N/A/** label area height in pixels */ 0N/A/** Enables the rawr[0|3], patm, and casm options. */ 0N/A/******************************************************************************* 0N/A* Structures and Typedefs * 2464N/A*******************************************************************************/ 0N/A/** Pointer shape change event data strucure */ 0N/A // make a copy of the shape 2086N/A/******************************************************************************* 0N/A* Internal Functions * 0N/A*******************************************************************************/ 0N/A/******************************************************************************* 0N/A*******************************************************************************/ 4134N/A// my mini kbd doesn't have RCTRL... 2464N/A/** modifier keypress status (scancode as index) */ 0N/A * Callback handler for VirtualBox events 4134N/A * check if we're interested in the message 5266N/A * Notify SDL thread of the string update 868N/A#
endif /* VBOX_SECURELABEL */ 4134N/A * Callback handler for machine events 0N/A /* Don't bother the guest with NumLock scancodes if he doesn't set the NumLock LED */ 0N/A * We have to inform the SDL thread that the application has be terminated 260N/A * Inform the SDL thread to refresh the titlebar fPaused ?
"The VM was paused. Continue with HostKey + P after you solved the problem.\n" :
"");
/* SDL feature not available on Quartz */ #
endif /* !RT_OS_DARWIN */ default:
return "no idea";
#
endif /* VBOX_WITH_XPCOM */ " -vm <id|name> Virtual machine to start, either UUID or name\n" " -hda <file> Set temporary first hard disk to file\n" " -fda <file> Set temporary first floppy disk to file\n" " -boot <a|c|d|n> Set temporary boot device (a = floppy, c = 1st HD, d = DVD, n = network)\n" " -m <size> Set temporary memory size in megabytes\n" " -vram <size> Set temporary size of video memory in megabytes\n" " -fullscreen Start VM in fullscreen mode\n" " -fullscreenresize Resize the guest on fullscreen\n" " -fixedmode <w> <h> <bpp> Use a fixed SDL video mode with given width, height and bits per pixel\n" " -nofstoggle Forbid switching to/from fullscreen mode\n" " -noresize Make the SDL frame non resizable\n" " -nohostkey Disable all hostkey combinations\n" " -nohostkeys ... Disable specific hostkey combinations, see below for valid keys\n" " -nograbonclick Disable mouse/keyboard grabbing on mouse click w/o additions\n" " -detecthostkey Get the hostkey identifier and modifier state\n" " -hostkey <key> {<key2>} <mod> Set the host key to the values obtained using -detecthostkey\n" " -termacpi Send an ACPI power button event when closing the window\n" " -tapdev<1-N> <dev> Use existing persistent TAP device with the given name\n" " -tapfd<1-N> <fd> Use existing TAP device, don't allocate\n" " -evdevkeymap Use evdev keycode map\n" " -vrdp <port> Listen for VRDP connections on port (default if not specified)\n" " -discardstate Discard saved state (if present) and revert to last snapshot (if present)\n" " -securelabel Display a secure VM label at the top of the screen\n" " -seclabelfnt TrueType (.ttf) font file for secure session label\n" " -seclabelsiz Font point size for secure session label (default 12)\n" " -seclabelofs Font offset within the secure label (default 0)\n" " -seclabelfgcol <rgb> Secure label text color RGB value in 6 digit hexadecimal (eg: FFFF00)\n" " -seclabelbgcol <rgb> Secure label background color RGB value in 6 digit hexadecimal (eg: FF0000)\n" " -[no]rawr0 Enable or disable raw ring 3\n" " -[no]rawr3 Enable or disable raw ring 0\n" " -[no]patm Enable or disable PATM\n" " -[no]csam Enable or disable CSAM\n" " -[no]hwvirtex Permit or deny the usage of VMX/SVN\n" " -convertSettings Allow to auto-convert settings files\n" " -convertSettingsBackup Allow to auto-convert settings files\n" " but create backup copies before\n" " -convertSettingsIgnore Allow to auto-convert settings files\n" " but don't explicitly save the results\n" " <hostkey> + f Switch to full screen / restore to previous view\n" " h Press ACPI power button\n" " n Take a snapshot and continue execution\n" " p Pause / resume execution\n" " s Save state and power off\n" " <del> Send <ctrl><alt><del>\n" " <F1>...<F12> Send <ctrl><alt><Fx>\n" "Further key bindings useful for debugging:\n" " LCtrl + Alt + F12 Reset statistics counter\n" " LCtrl + Alt + F11 Dump statistics to logfile\n" " Alt + F12 Toggle R0 recompiler\n" " Alt + F11 Toggle R3 recompiler\n" " Alt + F10 Toggle PATM\n" " Alt + F9 Toggle CSAM\n" " Alt + F8 Toggle single step mode\n" " F12 Write log marker to logfile\n" * Custom signal handler. Currently it is only used to release modifier * keys when receiving the USR1 signal. When switching VTs, we might not * get release events for Ctrl-Alt and in case a savestate is performed * on the new VT, the VM will be saved with modifier keys stuck. This is * annoying enough for introducing this hack. /* only SIGUSR1 is interesting */ /* just release the modifiers */ * Custom signal handler for catching exit events. #
endif /* VBOXSDL_WITH_X11 */ * Checks if any of the settings files were auto-converted and informs the * @return @false if the program should terminate and @true otherwise. * @note The function is taken from VBoxManage.cpp almost unchanged (except the /* return early if nothing to do */ "WARNING! The following VirtualBox settings files have been automatically\n" "converted to the new settings file format version '%ls':\n" "The current command was aborted to prevent overwriting the above settings\n" "files with the results of the auto-conversion without your permission.\n" "Please add one of the following command line switches to the VBoxSDL command\n" "line and repeat the command:\n" " -convertSettings - to save all auto-converted files (it will not\n" " be possible to use these settings files with an\n" " older version of VirtualBox in the future);\n" " -convertSettingsBackup - to create backup copies of the settings files in\n" " the old format before saving them in the new format;\n" " -convertSettingsIgnore - to not save the auto-converted settings files.\n" "Note that if you use -convertSettingsIgnore, the auto-converted settings files\n" "will be implicitly saved in the new format anyway once you change a setting or\n" "start a virtual machine, but NO backup copies will be created in this case.\n");
/* open a session for the VM */ * Lock keys on SDL behave different from normal keys: A KeyPress event is generated * if the lock mode gets active and a keyRelease event is genereated if the lock mode * gets inactive, that is KeyPress and KeyRelease are sent when pressing the lock key * to change the mode. The current lock mode is reflected in SDL_GetModState(). * Debian patched libSDL to make the lock keys behave like normal keys generating a * is not reflected in the mod status anymore. We disable the Debian-specific extension * events in ProcessKeys(). * the hostkey detection mode is unrelated to VM processing, so handle it before * we initialize anything COM related /* we need a video window for the keyboard stuff to work */ RTPrintf(
"Error: could not set SDL video mode\n");
RTPrintf(
"Please hit one or two function key(s) to get the -hostkey value...\n");
/* pressed additional host key */ /* The damned GOTOs forces this to be up here - totally out of place. */ * The golden rule is that host-key combinations should not be seen * by the guest. For instance a CAD should not have any extra RCtrl down * and RCtrl up around itself. Nor should a resume be followed by a Ctrl-P * that could encourage applications to start printing. * We must not confuse the hostkey processing into any release sequences * either, the host key is supposed to be explicitly pressing one key. * (Normal) --------------- * | | v host combination key down * | | (Host key down) ---------------- * | |-------------- | other key down v host combination key down * | | (host key used) ------------- * | (not host key)-- | |--------------- * ----------------------------------------------- /** The initial and most common state, pass keystrokes to the guest. * Next state: HKEYSTATE_DOWN /** The first host key was pressed down /** The second host key was pressed down (if gHostKeySym2 != SDLK_UNKNOWN) /** The host key has been pressed down. * Prev state: HKEYSTATE_NORMAL * Next state: HKEYSTATE_NORMAL - host key up, capture toggle. * Next state: HKEYSTATE_USED - host key combination down. * Next state: HKEYSTATE_NOT_IT - non-host key combination down. /** A host key combination was pressed. * Prev state: HKEYSTATE_DOWN * Next state: HKEYSTATE_NORMAL - when modifiers are all 0 /** A non-host key combination was attempted. Send hostkey down to the * guest and continue until all modifiers have been released. * Prev state: HKEYSTATE_DOWN * Next state: HKEYSTATE_NORMAL - when modifiers are all 0 /** The host key down event which we have been hiding from the guest. * Used when going from HKEYSTATE_DOWN to HKEYSTATE_NOT_IT. */ RTPrintf(
"VirtualBox SDL GUI %s built %s %s\n",
// less than one parameter is not possible RTPrintf(
"Error: COM initialization failed, rc = 0x%x!\n",
rc);
// scopes all the stuff till shutdown //////////////////////////////////////////////////////////////////////////// RTPrintf(
"Failed to create VirtualBox object! No error information available (rc = 0x%x).\n",
rc);
RTPrintf(
"Failed to create session object, rc = 0x%x!\n",
rc);
// create the event queue // (here it is necessary only to process remaining XPCOM/IPC events // after the session is closed) #
endif /* USE_XPCOM_QUEUE_THREAD */ /* Get the number of network adapters */ // command line argument parsing stuff RTPrintf(
"Error: VM not specified (UUID or name)!\n");
// first check if a UUID was supplied LogFlow((
"invalid UUID format, assuming it's a VM name\n"));
RTPrintf(
"Error: missing argument for boot drive!\n");
RTPrintf(
"Error: wrong argument for boot drive!\n");
RTPrintf(
"Error: missing argument for memory size!\n");
RTPrintf(
"Error: missing argument for vram size!\n");
/* three parameters follow */ RTPrintf(
"Error: missing arguments for fixed video mode!\n");
RTPrintf(
"Error: missing a string of disabled hostkey combinations\n");
RTPrintf(
"Error: <hostkey> + '%c' is not a valid combination\n",
RTPrintf(
"Error: missing file name for -pidfile!\n");
RTPrintf(
"Error: missing file name for first hard disk!\n");
RTPrintf(
"Error: The path to the specified harddisk, '%s', could not be resolved.\n",
argv[
curArg]);
RTPrintf(
"Error: The path to the specified floppy disk, '%s', could not be resolved.\n",
argv[
curArg]);
RTPrintf(
"Error: The path to the specified cdrom, '%s', could not be resolved.\n",
argv[
curArg]);
RTPrintf(
"Error: invalid TAP device option!\n");
RTPrintf(
"Error: invalid TAP file descriptor option!\n");
#
endif /* RT_OS_LINUX || RT_OS_DARWIN */ // start with the standard VRDP port // is there another argument // check if the next argument is a number #
endif /* VBOX_WITH_VRDP */ LogFlow((
"Secure labelling turned on\n"));
RTPrintf(
"Error: missing font file name for secure label!\n");
RTPrintf(
"Error: missing font point size for secure label!\n");
RTPrintf(
"Error: missing font pixel offset for secure label!\n");
RTPrintf(
"Error: missing text color value for secure label!\n");
RTPrintf(
"Error: missing background color value for secure label!\n");
RTPrintf(
"Error: missing the rate value for the -warpdrive option!\n");
#
endif /* VBOXSDL_ADVANCED_OPTIONS */ RTPrintf(
"Error: not enough arguments for host keys!\n");
/* two-key sequence as host key specified */ /* just show the help screen */ * Do we have a name but no UUID? RTPrintf(
"Error: machine with the given ID not found!\n");
RTPrintf(
"Error: no machine specified!\n");
/* create SDL event semaphore */ RTPrintf(
"Could not open VirtualBox session!\n");
// get the VM we're dealing with RTPrintf(
"Error: given machine not found!\n");
* Are we supposed to use a different hard disk file? * Strategy: iterate through all registered hard disk * and see if one of them points to the same file. If * so, assign it. If not, register a new image and assing /* we've not found the image */ /* do we have the right image now? */ /// @todo why is this attachment saved? RTPrintf(
"Error: failed to mount the specified hard disk image!\n");
* Mount a floppy if requested. * First special case 'none' to unmount /* Assume it's a host drive name */ /* try to find an existing one */ * Mount a CD-ROM if requested. * First special case 'none' to unmount /* Assume it's a host drive name */ /* try to find an existing one */ * If the machine is currently saved, * discard the saved state first. * If there are snapshots, discard the current state, * i.e. revert to the last snapshot. // get the machine debugger (does not have to be there) Log((
"Machine debugger available!\n"));
RTPrintf(
"Error: could not get display object!\n");
RTPrintf(
"Error: could not set boot device, using default.\n");
// set the memory size if not default RTPrintf(
"Error: could not set memory size, using current setting of %d MBytes\n",
ramSize);
RTPrintf(
"Error: could not set VRAM size, using current setting of %d MBytes\n",
vramSize);
// we're always able to process absolute mouse events and we prefer that /* initialize the Win32 user interface inside which SDL will be embedded */ // create our SDL framebuffer instance RTPrintf(
"Error: could not create framebuffer object!\n");
RTPrintf(
"Error: no font file specified for secure label!\n");
/* load the SDL_ttf library and get the required imports */ /* silently ignore errors here */ RTPrintf(
"Error: could not initialize secure labeling: rc = %Vrc\n",
rcVBox);
/* NOTE1: We still want Ctrl-C to work, so we undo the SDL redirections. * NOTE2: We have to remove the PidFile if this file exists. */ // register our framebuffer RTPrintf(
"Error: could not register framebuffer object!\n");
// register a callback for global events // register a callback for machine events // until we've tried to to start the VM, ignore power off events * Do we have a TAP device name or file descriptor? If so, communicate * it to the network adapter so that it doesn't allocate a new one * in case TAP is already configured. RTPrintf(
"Warning: network adapter %d is not configured for TAP. Command ignored!\n", i +
1);
RTPrintf(
"Warning: network adapter %d not defined. Command ignored!\n", i +
1);
#
endif /* RT_OS_LINUX || RT_OS_DARWIN */ // has a non standard VRDP port been requested? RTPrintf(
"Error: could not set VRDP port! rc = 0x%x\n",
rc);
RTPrintf(
"Error: could not enable VRDP server! rc = 0x%x\n",
rc);
RTPrintf(
"Error: No debugger object; -%srawr0 cannot be executed!\n",
fRawR0 ?
"" :
"no");
RTPrintf(
"Error: No debugger object; -%srawr3 cannot be executed!\n",
fRawR0 ?
"" :
"no");
RTPrintf(
"Error: No debugger object; -%spatm cannot be executed!\n",
fRawR0 ?
"" :
"no");
RTPrintf(
"Error: No debugger object; -%scsam cannot be executed!\n",
fRawR0 ?
"" :
"no");
#
endif /* VBOXSDL_ADVANCED_OPTIONS */ /* start with something in the titlebar */ /* memorize the default cursor */ /* Get Window Manager info. We only need the X11 display. */ RTPrintf(
"Error: could not get SDL Window Manager info!\n");
/* SDL uses its own (plain) default cursor. Use the left arrow cursor instead which might look * much better if a mouse cursor theme is installed. */ #
endif /* VBOXSDL_WITH_X11 */ /* create a fake empty cursor */ * Register our user signal handler. #
endif /* VBOXSDL_WITH_X11 */ * Start the VM execution thread. This has to be done * asynchronously as powering up can take some time * (accessing devices such as the host DVD drive). In * the meantime, we have to service the SDL event loop. LogFlow((
"Powering up the VM...\n"));
RTPrintf(
"Error: failed to power up VM! No error text available.\n");
* Before we starting to do stuff, we have to launch the XPCOM * event queue thread. It will wait for events and send messages * to the SDL thread. After having done this, we should fairly * quickly start to process the SDL event queue as an XPCOM * event storm might arrive. Stupid SDL has a ridiculously small #
endif /* USE_XPCOM_QUEUE_THREAD */ LogRel((
"VBoxSDL: NUM lock initially %s, CAPS lock initially %s\n",
/* start regular timer so we don't starve in the event loop */ /* loop until the powerup processing is done */ * wait for the next event. This is uncritical as * power up guarantees to change the machine state * to either running or aborted and a machine state * change will send us an event. However, we have to * service the XPCOM event queue! * Timer event. Used to have the titlebar updated. * User specific resize event. LogFlow((
"SDL_USER_EVENT_RESIZE\n"));
/* notify the display that the resize has been completed */ * User specific XPCOM event queue event LogFlow((
"SDL_USER_EVENT_XPCOM_EVENTQUEUE: processing XPCOM event queue...\n"));
#
endif /* USE_XPCOM_QUEUE_THREAD */ * Termination event from the on state change callback. RTPrintf(
"Error: failed to power up VM! No error text available.\n");
/* kill the timer again */ /* are we supposed to terminate the process? */ /* did the power up succeed? */ // accept power off events from now on because we're running // note that there's a possible race condition here... RTPrintf(
"Error: could not get keyboard object!\n");
RTPrintf(
"Error: could not get mouse object!\n");
* Enable keyboard repeats LogFlow((
"VBoxSDL: Entering big event loop\n"));
* The screen needs to be repainted. /// @todo that somehow doesn't seem to work! /* fall through if no two-key sequence is used */ /* potential host key combination, try execute it */ /* toggle grabbing state */ /* SDL doesn't always reset the keystates, correct it */ * A mouse button has been clicked or released. /* don't grab on mouse click if we have guest additions */ /* start grabbing all events */ /* end host key combination (CTRL+MouseButton) */ * The window has gained or lost focus. * There is a strange behaviour in SDL when running without a window * manager: When SDL_WM_GrabInput(SDL_GRAB_ON) is called we receive two * consecutive events SDL_ACTIVEEVENTs (input lost, input gained). * Asking SDL_GetAppState() seems the better choice. * another window has stolen the (keyboard) input focus * The SDL window was resized * User specific update event. /** @todo use a common user event handler so that SDL_PeepEvents() won't * possibly remove other events in the queue! * Decode event parameters. LogFlow((
"SDL_USER_EVENT_UPDATERECT: x = %d, y = %d, w = %d, h = %d\n",
* User event: Window resize done * @todo This is a workaround for synchronization problems between EMT and the * SDL main thread. It can happen that the SDL thread already starts a * new resize operation while the EMT is still busy with the old one * leading to a deadlock. Therefore we call SetVideoModeHint only once * when the mouse button was released. /* communicate the resize event to the guest */ * User specific resize event. LogFlow((
"SDL_USER_EVENT_RESIZE\n"));
/* notify the display that the resize has been completed */ * User specific XPCOM event queue event LogFlow((
"SDL_USER_EVENT_XPCOM_EVENTQUEUE: processing XPCOM event queue...\n"));
#
endif /* USE_XPCOM_QUEUE_THREAD */ * User specific update title bar notification event * User specific termination event RTPrintf(
"Error: VM terminated abnormally!\n");
* User specific secure label update event * Query the new label text #
endif /* VBOX_SECURELABEL */ * User specific pointer shape change event * User specific guest capabilities changed /* make sure the XPCOM event queue thread doesn't do anything harmful */ #
endif /* VBOX_WITH_XPCOM */ * Turn off the VM if it's running RTPrintf(
"Failed to power down virtual machine! No error information available (rc = 0x%x).\n",
rc);
* Now we discard all settings so that our changes will * not be flushed to the permanent configuration /* restore the default cursor and free the custom one if any */ #
endif /* VBOXSDL_WITH_X11 */#
endif /* VBOXSDL_WITH_X11 */ LogFlow((
"Releasing mouse, keyboard, vrdpserver, display, console...\n"));
// we can only uninitialize SDL here because it is not threadsafe LogFlow((
"Releasing framebuffer...\n"));
/* must do this after destructing the framebuffer */ LogFlow((
"Releasing machine, session...\n"));
LogFlow((
"Releasing callback handlers...\n"));
LogFlow((
"Releasing VirtualBox object...\n"));
//////////////////////////////////////////////////////////////////////////// LogFlow((
"Uninitializing COM...\n"));
LogFlow((
"Returning from main()!\n"));
* Before we do *anything*, we initialize the runtime. #
endif /* !VBOX_WITH_HARDENING */ * Returns whether the absolute mouse is in use, i.e. both host * and guest have opted to enable it. * @returns bool Flag whether the absolute mouse is in use * Fallback keycode conversion using SDL symbols. * This is used to catch keycodes that's missing from the translation table. Log((
"SDL key event: sym=%d scancode=%#x unicode=%#x\n",
Log((
"Unhandled sdl key event: sym=%d scancode=%#x unicode=%#x\n",
#
endif /* RT_OS_DARWIN */ * Converts an SDL keyboard eventcode to a XT scancode. // start with the scancode determined by SDL // workaround for SDL keyboard translation issues on Linux // keycodes > 0x100 are sent as 0xe0 keycode // servers on a Linux host, and will almost certainly not // work on other hosts or on other servers on Linux hosts. // For a more general approach, see the Wine code in the GUI. 0x47|
0x100,
/* 97 Home */ 0x49|
0x100,
/* 99 PgUp */ 0x4b|
0x100,
/* 100 Left */ 0x4d|
0x100,
/* 102 Right */ 0x4f|
0x100,
/* 103 End */ 0x50|
0x100,
/* 104 Down */ 0x51|
0x100,
/* 105 PgDn */ 0x52|
0x100,
/* 106 Ins */ 0x53|
0x100,
/* 107 Del */ 0x1c|
0x100,
/* 108 Enter */ 0x1d|
0x100,
/* 109 Ctrl-R */ 0x37|
0x100,
/* 111 Print */ 0x35|
0x100,
/* 112 Divide */ 0x38|
0x100,
/* 113 Alt-R */ 0x46|
0x100,
/* 114 Break */ 0x5b|
0x100,
/* 115 Win Left */ 0x5c|
0x100,
/* 116 Win Right */ 0x5d|
0x100,
/* 117 Win Menu */ 0xf1,
/* 121 Korean Hangul to Latin?? */ 0xf2,
/* 122 Korean Hangul to Hanja?? */ 0x79,
/* 129 Japanese Henkan */ 0x7b,
/* 131 Japanese Muhenkan */ 0x7d,
/* 133 Japanese Yen */ 0x7e,
/* 134 Brazilian keypad */ // workaround for SDL keyboard translation issues on EVDEV // keycodes > 0x100 are sent as 0xe0 keycode // these values are simply pulled from x_keycode_to_pc_keycode // not a whole lot of testing of the 'weird' values has taken // place (I don't own a Japanese or Korean keyboard) 0x0,
/* 97 EVDEV - RO ("Internet" Keyboards) */ 0x0,
/* 98 EVDEV - KATA (Katakana) */ 0x0,
/* 99 EVDEV - HIRA (Hiragana) */ 0x79,
/* 100 EVDEV - HENK (Henkan) */ 0x7b,
/* 102 EVDEV - MUHE (Muhenkan) */ 0x0,
/* 103 EVDEV - JPCM (KPJPComma) */ 0x1c|
0x100,
/* 104 EVDEV - KPEN */ 0x1d|
0x100,
/* 105 EVDEV - RCTL */ 0x35|
0x100,
/* 106 EVDEV - KPDV */ 0x37|
0x100,
/* 107 EVDEV - PRSC ***FIXME*** */ 0x38|
0x100,
/* 108 EVDEV - RALT */ 0x0,
/* 109 EVDEV - LNFD ("Internet" Keyboards) */ 0x47|
0x100,
/* 110 EVDEV - HOME ***FIXME*** */ 0x48|
0x100,
/* 111 EVDEV - UP */ 0x49|
0x100,
/* 112 EVDEV - PGUP */ 0x4b|
0x100,
/* 113 EVDEV - LEFT */ 0x4d|
0x100,
/* 114 EVDEV - RGHT */ 0x4f|
0x100,
/* 115 EVDEV - END */ 0x50|
0x100,
/* 116 EVDEV - DOWN */ 0x51|
0x100,
/* 117 EVDEV - PGDN */ 0x52|
0x100,
/* 118 EVDEV - INS */ 0x53|
0x100,
/* 119 EVDEV - DELE */ 0x0,
/* 120 EVDEV - I120 ("Internet" Keyboards) */ //121-124 Solaris Compatibilty Stuff 0x0,
/* 121 EVDEV - MUTE */ 0x0,
/* 122 EVDEV - VOL- */ 0x0,
/* 123 EVDEV - VOL+ */ 0x0,
/* 124 EVDEV - POWR */ 0x0,
/* 125 EVDEV - KPEQ */ 0x0,
/* 126 EVDEV - I126 ("Internet" Keyboards) */ 0x0,
/* 127 EVDEV - PAUS */ 0x0,
/* 128 EVDEV - ???? */ 0x0,
/* 129 EVDEV - I129 ("Internet" Keyboards) */ 0xf1,
/* 130 EVDEV - HNGL (Korean Hangul Latin toggle) */ 0xf2,
/* 131 EVDEV - HJCV (Korean Hangul Hanja toggle) */ 0x7d,
/* 132 EVDEV - AE13 (Yen) */ 0x5b|
0x100,
/* 133 EVDEV - LWIN */ 0x5c|
0x100,
/* 134 EVDEV - RWIN */ 0x5d|
0x100,
/* 135 EVDEV - MENU */ 0x0,
/* 136 EVDEV - STOP */ 0x0,
/* 137 EVDEV - AGAI */ 0x0,
/* 138 EVDEV - PROP */ 0x0,
/* 139 EVDEV - UNDO */ 0x0,
/* 140 EVDEV - FRNT */ 0x0,
/* 141 EVDEV - COPY */ 0x0,
/* 142 EVDEV - OPEN */ 0x0,
/* 143 EVDEV - PAST */ 0x0,
/* 144 EVDEV - FIND */ 0x0,
/* 145 EVDEV - CUT */ 0x0,
/* 146 EVDEV - HELP */ //Extended Keys ("Internet" Keyboards) 0x0,
/* 147 EVDEV - I147 */ 0x0,
/* 148 EVDEV - I148 */ 0x0,
/* 149 EVDEV - I149 */ 0x0,
/* 150 EVDEV - I150 */ 0x0,
/* 151 EVDEV - I151 */ 0x0,
/* 152 EVDEV - I152 */ 0x0,
/* 153 EVDEV - I153 */ 0x0,
/* 154 EVDEV - I154 */ 0x0,
/* 155 EVDEV - I156 */ 0x0,
/* 156 EVDEV - I157 */ 0x0,
/* 157 EVDEV - I158 */ // just an offset (Xorg MIN_KEYCODE) // apply EVDEV conversion table // apply conversion table // Japanese Hiragana to Katakana /* This is derived partially from SDL_QuartzKeys.h and partially from testing. */ 0x56,
/* between lshift and z. 'INT 1'? */ 0x0d,
/* QZ_EQUALS 0x18 */ 0x0c,
/* QZ_MINUS 0x1B */ 0x1b,
/* QZ_RIGHTBRACKET 0x1E */ 0x1a,
/* QZ_LEFTBRACKET 0x21 */ 0x1c,
/* QZ_RETURN 0x24 */ 0x28,
/* QZ_QUOTE 0x27 */ 0x27,
/* QZ_SEMICOLON 0x29 */ 0x2b,
/* QZ_BACKSLASH 0x2A */ 0x33,
/* QZ_COMMA 0x2B */ 0x35,
/* QZ_SLASH 0x2C */ 0x34,
/* QZ_PERIOD 0x2F */ 0x39,
/* QZ_SPACE 0x31 */ 0x29,
/* QZ_BACKQUOTE 0x32 */ 0x0e,
/* QZ_BACKSPACE 0x33 */ 0x9c,
/* QZ_IBOOK_ENTER 0x34 */ 0x01,
/* QZ_ESCAPE 0x35 */ 0x5c|
0x100,
/* QZ_RMETA 0x36 */ 0x5b|
0x100,
/* QZ_LMETA 0x37 */ 0x2a,
/* QZ_LSHIFT 0x38 */ 0x3a,
/* QZ_CAPSLOCK 0x39 */ 0x1d,
/* QZ_LCTRL 0x3B */ 0x36,
/* QZ_RSHIFT 0x3C */ 0x38|
0x100,
/* QZ_RALT 0x3D */ 0x1d|
0x100,
/* QZ_RCTRL 0x3E */ 0x53,
/* QZ_KP_PERIOD 0x41 */ 0x37,
/* QZ_KP_MULTIPLY 0x43 */ 0x4e,
/* QZ_KP_PLUS 0x45 */ 0x45,
/* QZ_NUMLOCK 0x47 */ 0x35|
0x100,
/* QZ_KP_DIVIDE 0x4B */ 0x1c|
0x100,
/* QZ_KP_ENTER 0x4C */ 0x4a,
/* QZ_KP_MINUS 0x4E */ 0x0d/*?*/,
/* QZ_KP_EQUALS 0x51 */ 0x37|
0x100,
/* QZ_PRINT / F13 0x69 */ 0x46,
/* QZ_SCROLLOCK 0x6B */ 0
/* 0xe1,0x1d,0x45*/,
/* QZ_PAUSE 0x71 */ 0x52|
0x100,
/* QZ_INSERT / HELP 0x72 */ 0x47|
0x100,
/* QZ_HOME 0x73 */ 0x49|
0x100,
/* QZ_PAGEUP 0x74 */ 0x53|
0x100,
/* QZ_DELETE 0x75 */ 0x4f|
0x100,
/* QZ_END 0x77 */ 0x51|
0x100,
/* QZ_PAGEDOWN 0x79 */ 0x4b|
0x100,
/* QZ_LEFT 0x7B */ 0x4d|
0x100,
/* QZ_RIGHT 0x7C */ 0x50|
0x100,
/* QZ_DOWN 0x7D */ 0x48|
0x100,
/* QZ_UP 0x7E */ 0x5e|
0x100,
/* QZ_POWER 0x7F */ /* have different break key! */ /* This could be a modifier or it could be 'a'. */ /* Sssumes normal key. */ #
endif /* RT_OS_DARWIN */ * Releases any modifier keys that are currently in pressed state. * Keyboard event handler. * @param ev SDL keyboard event. // first handle the debugger hotkeys // CTRL+ALT+Fn is not free on Linux hosts with Xorg .. // pressing CTRL+ALT+F11 dumps the statistics counter RTPrintf(
"ResetStats\n");
/* Visual feedback in console window */ // pressing CTRL+ALT+F12 resets all statistics counter RTPrintf(
"DumpStats\n");
/* Vistual feedback in console window */ // pressing Alt-F12 toggles the supervisor recompiler // pressing Alt-F11 toggles the user recompiler // pressing Alt-F10 toggles the patch manager // pressing Alt-F9 toggles CSAM // pressing Alt-F8 toggles singlestepping mode // pressing Ctrl-F12 toggles the logger // pressing F12 sets a logmark // now update the titlebar flags #
endif // DEBUG || VBOX_WITH_STATISTICS // the pause key is the weirdest, needs special handling * Perform SDL key event to scancode conversion /* sent when leaving window: reset the modifiers state */ case 0x2a:
/* Left Shift */ case 0x36:
/* Right Shift */ case 0x1d:
/* Left CTRL */ case 0x1d|
0x100:
/* Right CTRL */ case 0x38:
/* Left ALT */ case 0x38|
0x100:
/* Right ALT */ case 0x45:
/* Num Lock */ case 0x3a:
/* Caps Lock */ * SDL generates a KEYDOWN event if the lock key is active and a KEYUP event * if the lock key is inactive. See SDL_DISABLE_LOCK_KEYS. * Some keyboards (e.g. the one of mine T60) don't send a NumLock scan code on every * press of the key. Both the guest and the host should agree on the NumLock state. * If they differ, we try to alter the guest NumLock state by sending the NumLock key * scancode. We will get a feedback through the KBD_CMD_SET_LEDS command if the guest * tries to set/clear the NumLock LED. If a (silly) guest doesn't change the LED, don't * bother him with NumLock scancodes. At least our BIOS, Linux and Windows handle the * Now we send the event. Apply extended and release prefixes. /* Private interface in 10.3 and later. */ /** Keeping track of whether we disabled the hotkeys or not. */ /** Whether we've connected or not. */ /** Cached connection. */ * Disables or enabled global hot keys. /*|| !g_fHotKeysDisabled*/)
/* try set it and check the actual result. */ #
endif /* RT_OS_DARWIN */ * Start grabbing the mouse. // dummy read to avoid moving the mouse * Query mouse position and button state from SDL and send to the VM * @param dz Relative mouse wheel movement * If supported and we're not in grabbed mode, we'll use the absolute mouse. * If we are in grabbed mode and the guest is not able to draw the mouse cursor * itself, we have to use absolute coordinates, otherwise the host cursor and * the coordinates the guest thinks the mouse is at could get out-of-sync. From * "The event processing is usually asynchronous and so somewhat delayed, and * SDL_GetMouseState is returning the immediate mouse state. So at the time you * call SDL_GetMouseState, the "button" is already up." /* only used if abs == TRUE */ * Check if the mouse event is inside the guest area. This solves the * following problem: Some guests switch off the VBox hardware mouse * cursor and draw the mouse cursor itself instead. Moving the mouse * outside the guest area then leads to annoying mouse hangs if we * don't pass mouse motion events into the guest. * Cursor outside of valid guest area (outside window or in secure * label area. Don't allow any mouse button press. * Release any pressed button. /* disabled on customers request */ * Prevent negative coordinates. * We just entered the valid guest area. Restore the guest mouse * Button was pressed but that press is not reflected in the button state? * It can happen that a mouse up event follows a mouse down event immediately * and we see the events when the bit in the button state is already cleared * again. In that case we simulate the mouse down event. * PutMouseEventAbsolute() expects x and y starting from 1,1. * should we do the increment internally in PutMouseEventAbsolute() * or state it in PutMouseEventAbsolute() docs? // now send the mouse event * PutMouseEventAbsolute() expects x and y starting from 1,1. * should we do the increment internally in PutMouseEventAbsolute() * or state it in PutMouseEventAbsolute() docs? * Initiates a saved state and updates the titlebar with progress information * Wait for the operation to be completed and work * the title bar in the mean while. /// @todo process gui events. #
else /* new loop which processes GUI events while saving. */ /* start regular timer so we don't starve in the event loop */ * Wait for and process GUI a event. * This is necessary for XPCOM IPC and for updating the * Timer event preventing us from getting stuck. * User specific XPCOM event queue event LogFlow((
"SDL_USER_EVENT_XPCOM_EVENTQUEUE: processing XPCOM event queue...\n"));
#
endif /* USE_XPCOM_QUEUE_THREAD */ * Ignore all other events. #
endif /* RT_OS_DARWIN */ * What's the result of the operation? RTPrintf(
"Saved the state successfully.\n");
* Build the titlebar string /* back up current title */ /* which mode are we in? */ // do we have a debugger interface // query the machine state " [STEP=%d CS=%d PAT=%d RR0=%d RR3=%d LOG=%d HWVirt=%d",
/* ignore other states, we could already be in running or aborted state */ " - Taking snapshot %d%%...",
u32User);
* Don't update if it didn't change. printf (
"show_shape %dx%d pitch %d size mask %d\n",
for (x = 0; x < w; ++x) {
if (
mask[x /
8] & (
1 << (
7 - (x %
8))))
* Sets the pointer shape according to parameters. * Must be called only from the main SDL thread. * don't allow to change the pointer shape if we are outside the valid * guest area. In that case set standard mouse pointer is set and should /* pointer debugging code */ // vbox_show_shape(data->width, data->height, 0, data->shape); printf(
"uint8_t pointerdata[] = { ");
// specifiy a supported 32 BPP alpha format for Windows XP // create the DIB section with an alpha channel // create an empty mask bitmap /* Word aligned AND mask. Will be allocated and created if necessary. */ /* Width in bytes of the original AND mask scan line. */ /* Original AND mask is not word aligned. */ /* Allocate memory for aligned AND mask. */ /* According to MSDN the padding bits must be 0. * Compute the bit mask to set padding bits to 0 in the last byte of original AND mask. Log((
"u8LastBytesPaddingMask = %02X, aligned w = %d, width = %d, cbAndMaskScan = %d\n",
// create the AND mask bitmap // here we do a dirty trick by substituting a Window Manager's // cursor handle with the handle we created // convert AND mask to the alpha channel // Linux doesn't support inverted pixels (XOR ops, // to be exact) in cursor shapes, so we detect such // pixels and always replace them with black ones to // make them visible at least over light colors // here we do a dirty trick by substituting a Window Manager's // cursor handle with the handle we created /* Don't disable the cursor if the guest additions are not active (anymore) */ * Handle changed mouse capabilities // Cursor could be overwritten by the guest tools // Actually switch to absolute coordinates * Handles a host key down event * Revalidate the host key modifier * Fullscreen / Windowed toggle. * process because there might be a short moment * without a valid framebuffer * We have switched from/to fullscreen, so request a full * screen repaint, just to be sure. * Save the machine's state and exit * Perform an online snapshot. Continue operation. RTPrintf(
"Error taking snapshot! rc = 0x%x\n",
rc);
* Wait for the operation to be completed and work * the title bar in the mean while. /// @todo process gui events. // /* send Ctrl-Alt-Fx to guest */ keys[0] =
0x1d;
// Ctrl down keys[
1] =
0x38;
// Alt down keys[
4] =
0xb8;
// Alt up keys[
5] =
0x9d;
// Ctrl up * Not a host key combination. * Indicate this by returning false. * Timer callback function for startup processing /* post message so we can do something in the startup loop */ * Timer callback function to check if resizing is finished /* post message so the window is actually resized */ * Timer callback function to check if an ACPI power button event was handled by the guest. /* event was not handled, power down the guest */ * Wait for the next SDL event. Don't use SDL_WaitEvent since this function * calls SDL_Delay(10) if the event queue is empty. /* Immediately wake up if new SDL events are available. This does not * work for internal SDL events. Don't wait more than 10ms. */ * Ensure that an SDL event is really enqueued. Try multiple times if necessary. Log((
"PushSDLEventForSure: waiting for 2ms\n"));
LogRel((
"WARNING: Failed to enqueue SDL event %d.%d!\n",
* Special SDL_PushEvent function for NotifyUpdate events. These events may occur in bursts * so make sure they don't flood the SDL event queue. AssertMsg(!
rc, (
"SDL_PushEvent returned SDL error\n"));
/* A global counter is faster than SDL_PeepEvents() */ /* In order to not flood the SDL event queue, yield the CPU or (if there are already many * events queued) even sleep */ /* Too many NotifyUpdate events, sleep for a small amount to give the main thread time * to handle these events. The SDL queue can hold up to 128 events. */ Log((
"PushNotifyUpdateEvent: Sleep 1ms\n"));
#
endif /* VBOXSDL_WITH_X11 */ * The old/default way: SDL will resize the host to fit the guest screen resolution. * The alternate way: Switch to fullscreen with the host screen resolution and adapt * the guest screen resolution to the host window geometry. /* switch to fullscreen */ /* switch back to saved geometry */