VBoxSDL.cpp revision c0accab8b00e781ab7cf12ab60044643ec2290b4
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * VBox frontends: VBoxSDL (simple frontend based on SDL):
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * Main code
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2006-2007 innotek GmbH
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * available from http://www.virtualbox.org. This file is free software;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * General Public License as published by the Free Software Foundation,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/*******************************************************************************
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync* Header Files *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync*******************************************************************************/
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsyncusing namespace com;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/* Xlib would re-define our enums */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/*******************************************************************************
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync* Defined Constants And Macros *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync*******************************************************************************/
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** extra data key for the secure label */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#define VBOXSDL_SECURELABEL_EXTRADATA "VBoxSDL/SecureLabel"
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** label area height in pixels */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** Enables the rawr[0|3], patm, and casm options. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/*******************************************************************************
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync* Structures and Typedefs *
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync*******************************************************************************/
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** Pointer shape change event data strucure */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync PointerShapeChangeData (BOOL aVisible, BOOL aAlpha, ULONG aXHot, ULONG aYHot,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync ULONG aWidth, ULONG aHeight, const uint8_t *aShape)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync : visible (aVisible), alpha (aAlpha), xHot (aXHot), yHot (aYHot),
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync // make a copy of the shape
0c4004948fca34f2db87e7b38013137e9472c306vboxsync uint32_t shapeSize = ((((aWidth + 7) / 8) * aHeight + 3) & ~3) + aWidth * 4 * aHeight;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync memcpy ((void *) shape, (void *) aShape, shapeSize);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/*******************************************************************************
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync* Internal Functions *
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync*******************************************************************************/
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsyncstatic bool UseAbsoluteMouse(void);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncstatic void ResetKeys(void);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncstatic void InputGrabStart(void);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsyncstatic void InputGrabEnd(void);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncstatic void SendMouseEvent(int dz, int button, int down);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsyncstatic void UpdateTitlebar(TitlebarMode mode, uint32_t u32User = 0);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsyncstatic void SetPointerShape(const PointerShapeChangeData *data);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsyncstatic void HandleGuestCapsChanged(void);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncstatic int HandleHostKey(const SDL_KeyboardEvent *pEv);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsyncstatic Uint32 StartupTimer(Uint32 interval, void *param);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsyncstatic Uint32 ResizeTimer(Uint32 interval, void *param);
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync/*******************************************************************************
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync* Global Variables *
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync*******************************************************************************/
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync// my mini kbd doesn't have RCTRL...
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** modifier keypress status (scancode as index) */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncstatic volatile int32_t g_cNotifyUpdateEventsPending;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Callback handler for VirtualBox events
64f58e4154eaa20c47782b429eeaff09070369bfvboxsync delete this;
64f58e4154eaa20c47782b429eeaff09070369bfvboxsync STDMETHOD(QueryInterface)(REFIID riid , void **ppObj)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync STDMETHOD(OnMachineStateChange)(INPTR GUIDPARAM machineId, MachineState_T state)
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync STDMETHOD(OnMachineDataChange)(INPTR GUIDPARAM machineId)
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync STDMETHOD(OnExtraDataCanChange)(INPTR GUIDPARAM machineId, INPTR BSTR key, INPTR BSTR value,
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync /* we never disagree */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync STDMETHOD(OnExtraDataChange)(INPTR GUIDPARAM machineId, INPTR BSTR key, INPTR BSTR value)
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * check if we're interested in the message
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync if (keyString && keyString == VBOXSDL_SECURELABEL_EXTRADATA)
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * Notify SDL thread of the string update
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync event.user.type = SDL_USER_EVENT_SECURELABEL_UPDATE;
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync#endif /* VBOX_SECURELABEL */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync STDMETHOD(OnMediaRegistered) (INPTR GUIDPARAM mediaId, DeviceType_T mediaType,
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync STDMETHOD(OnMachineRegistered)(INPTR GUIDPARAM machineId, BOOL registered)
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync STDMETHOD(OnSessionStateChange)(INPTR GUIDPARAM machineId, SessionState_T state)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync STDMETHOD(OnSnapshotTaken) (INPTR GUIDPARAM aMachineId, INPTR GUIDPARAM aSnapshotId)
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync STDMETHOD(OnSnapshotDiscarded) (INPTR GUIDPARAM aMachineId, INPTR GUIDPARAM aSnapshotId)
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync STDMETHOD(OnSnapshotChange) (INPTR GUIDPARAM aMachineId, INPTR GUIDPARAM aSnapshotId)
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync * Callback handler for machine events
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync VBoxSDLConsoleCallback() : m_fIgnorePowerOffEvents(false)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync delete this;
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync STDMETHOD(QueryInterface)(REFIID riid , void **ppObj)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync STDMETHOD(OnMousePointerShapeChange) (BOOL visible, BOOL alpha, ULONG xHot, ULONG yHot,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync data = new PointerShapeChangeData (visible, alpha, xHot, yHot, width, height,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync STDMETHOD(OnMouseCapabilityChange)(BOOL supportsAbsolute, BOOL needsHostCursor)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync LogFlow(("OnMouseCapabilityChange: supportsAbsolute = %d\n", supportsAbsolute));
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync event.user.type = SDL_USER_EVENT_GUEST_CAP_CHANGED;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync STDMETHOD(OnKeyboardLedsChange)(BOOL fNumLock, BOOL fCapsLock, BOOL fScrollLock)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /* Don't bother the guest with NumLock scancodes if he doesn't set the NumLock LED */
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync STDMETHOD(OnStateChange)(MachineState_T machineState)
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync LogFlow(("OnStateChange: machineState = %d (%s)\n", machineState, GetStateName(machineState)));
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync || (machineState == MachineState_Saved && !m_fIgnorePowerOffEvents)
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync || (machineState == MachineState_PoweredOff && !m_fIgnorePowerOffEvents))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * We have to inform the SDL thread that the application has be terminated
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync event.user.code = machineState == MachineState_Aborted
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync * Inform the SDL thread to refresh the titlebar
b0db50948c349fa76655abf252f7946b515e8204vboxsync STDMETHOD(OnNetworkAdapterChange) (INetworkAdapter *aNetworkAdapter)
b0db50948c349fa76655abf252f7946b515e8204vboxsync STDMETHOD(OnSerialPortChange) (ISerialPort *aSerialPort)
b0db50948c349fa76655abf252f7946b515e8204vboxsync STDMETHOD(OnParallelPortChange) (IParallelPort *aParallelPort)
b0db50948c349fa76655abf252f7946b515e8204vboxsync STDMETHOD(OnUSBDeviceStateChange) (IUSBDevice *aDevice, BOOL aAttached,
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync STDMETHOD(OnRuntimeError)(BOOL fFatal, INPTR BSTR id, INPTR BSTR message)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync const char *pszType;
faee255cc48bfbf17cb9f72fca70c8b9d3020ec4vboxsync bool fPaused = machineState == MachineState_Paused;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTPrintf("\n%s: ** %lS **\n%lS\n%s\n", pszType, id, message,
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync fPaused ? "The VM was paused. Continue with HostKey + P after you solved the problem.\n" : "");
0db6a029780d9f9b347500e117320a8d5661efe5vboxsync /* SDL feature not available on Quartz */
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync#endif /* !RT_OS_DARWIN */
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync static const char *GetStateName(MachineState_T machineState)
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync case MachineState_InvalidMachineState: return "InvalidMachineState";
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync default: return "no idea";
0c4004948fca34f2db87e7b38013137e9472c306vboxsyncNS_IMPL_ISUPPORTS1_CI(VBoxSDLCallback, IVirtualBoxCallback)
71f6a34b72f9cc873da208630959de49df1a28a5vboxsyncNS_IMPL_ISUPPORTS1_CI(VBoxSDLConsoleCallback, IConsoleCallback)
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync#endif /* VBOX_WITH_XPCOM */
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync " -vm <id|name> Virtual machine to start, either UUID or name\n"
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync " -hda <file> Set temporary first hard disk to file\n"
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync " -fda <file> Set temporary first floppy disk to file\n"
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync " -cdrom <file> Set temporary CDROM/DVD to file/device ('none' to unmount)\n"
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync " -boot <a|c|d> Set temporary boot device (a = floppy, c = first hard disk, d = DVD)\n"
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync " -m <size> Set temporary memory size in megabytes\n"
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync " -vram <size> Set temporary size of video memory in megabytes\n"
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync " -fullscreen Start VM in fullscreen mode\n"
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync " -fixedmode <w> <h> <bpp> Use a fixed SDL video mode with given width, height and bits per pixel\n"
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync " -nofstoggle Forbid switching to/from fullscreen mode\n"
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync " -noresize Make the SDL frame non resizable\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync " -nohostkey Disable hostkey\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync " -nograbonclick Disable mouse/keyboard grabbing on mouse click w/o additions\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync " -detecthostkey Get the hostkey identifier and modifier state\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync " -hostkey <key> {<key2>} <mod> Set the host key to the values obtained using -detecthostkey\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) /** @todo UNIXISH_TAP stuff out of main and up to Config.kmk! */
0c4004948fca34f2db87e7b38013137e9472c306vboxsync " -tapdev<1-N> <dev> Use existing persistent TAP device with the given name\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync " -tapfd<1-N> <fd> Use existing TAP device, don't allocate\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync " -vrdp <port> Listen for VRDP connections on port (default if not specified)\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync " -discardstate Discard saved state (if present) and revert to last snapshot (if present)\n"
0c4004948fca34f2db87e7b38013137e9472c306vboxsync " -securelabel Display a secure VM label at the top of the screen\n"
0c4004948fca34f2db87e7b38013137e9472c306vboxsync " -seclabelfnt TrueType (.ttf) font file for secure session label\n"
0c4004948fca34f2db87e7b38013137e9472c306vboxsync " -seclabelsiz Font point size for secure session label (default 12)\n"
0c4004948fca34f2db87e7b38013137e9472c306vboxsync " -seclabelfgcol <rgb> Secure label text color RGB value in 6 digit hexadecimal (eg: FFFF00)\n"
0c4004948fca34f2db87e7b38013137e9472c306vboxsync " -seclabelbgcol <rgb> Secure label background color RGB value in 6 digit hexadecimal (eg: FF0000)\n"
0c4004948fca34f2db87e7b38013137e9472c306vboxsync " -[no]rawr0 Enable or disable raw ring 3\n"
0c4004948fca34f2db87e7b38013137e9472c306vboxsync " -[no]rawr3 Enable or disable raw ring 0\n"
0c4004948fca34f2db87e7b38013137e9472c306vboxsync " -[no]patm Enable or disable PATM\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync " -[no]csam Enable or disable CSAM\n"
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync " -[no]hwvirtex Permit or deny the usage of VMX/SVN\n"
71f6a34b72f9cc873da208630959de49df1a28a5vboxsyncstatic void PrintError(const char *pszName, const BSTR pwszDescr, const BSTR pwszComponent=NULL)
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync RTStrPrintf(pszBuffer, sizeof(pszBuffer), "%lS", pwszDescr);
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync && (pszStat = strstr(pszBuffer, "VBox status code: ")))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Custom signal handler. Currently it is only used to release modifier
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * keys when receiving the USR1 signal. When switching VTs, we might not
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * get release events for Ctrl-Alt and in case a savestate is performed
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * on the new VT, the VM will be saved with modifier keys stuck. This is
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * annoying enough for introducing this hack.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncvoid signal_handler(int sig, siginfo_t *info, void *secret)
8cd2f2e64725096acb682f34a5568b7fb816eda7vboxsync /* only SIGUSR1 is interesting */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* just release the modifiers */
26947320577c481b4afefdb0afbb855181e5b2e8vboxsync#endif /* RT_OS_LINUX */
26947320577c481b4afefdb0afbb855181e5b2e8vboxsync/** entry point */
26947320577c481b4afefdb0afbb855181e5b2e8vboxsync * Before we do *anything*, we initialize the runtime.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTPrintf("Error: RTR3Init failed rcRC=%d\n", rcRT);
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync * Lock keys on SDL behave different from normal keys: A KeyPress event is generated
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * if the lock mode gets active and a keyRelease event is genereated if the lock mode
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * gets inactive, that is KeyPress and KeyRelease are sent when pressing the lock key
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync * to change the mode. The current lock mode is reflected in SDL_GetModState().
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Debian patched libSDL to make the lock keys behave like normal keys generating a
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * KeyPress/KeyRelease event if the lock key was pressed/released. But the lock status
a8139954a84d6e9090dd3a8371aa788351d45bc3vboxsync * is not reflected in the mod status anymore. We disable the Debian-specific extension
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * to ensure a defined environment and work around the missing KeyPress/KeyRelease
a8139954a84d6e9090dd3a8371aa788351d45bc3vboxsync * events in ProcessKeys().
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * the hostkey detection mode is unrelated to VM processing, so handle it before
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * we initialize anything COM related
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (argc == 2 && !strcmp(argv[1], "-detecthostkey"))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync int rc = SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTPrintf("Error: SDL_InitSubSystem failed with message '%s'\n", SDL_GetError());
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /* we need a video window for the keyboard stuff to work */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (!SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTPrintf("Please hit one or two function key(s) to get the -hostkey value...\n");
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync unsigned mod = SDL_GetModState() & ~(KMOD_MODE | KMOD_NUM | KMOD_RESERVED);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (event2.type == SDL_KEYDOWN || event2.type == SDL_KEYUP)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /* pressed additional host key */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTPrintf(" %d\n", SDL_GetModState() & ~(KMOD_MODE | KMOD_NUM | KMOD_RESERVED));
da3503c04ce76e653401396fe2795a9bc2427a1dvboxsync /* we're done */
9b789c281103a2489742bf32f6ab500e38b2ecd5vboxsync /* we're down */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync bool fFullscreen = false;
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync unsigned fRawR0 = ~0U;
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync unsigned fRawR3 = ~0U;
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync unsigned fPATM = ~0U;
b0db50948c349fa76655abf252f7946b515e8204vboxsync unsigned fCSAM = ~0U;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync bool fWin32UI = false;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /* The damned GOTOs forces this to be up here - totally out of place. */
5b465a7c1237993faf8bb50120d247f3f0319adavboxsync * Host key handling.
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync * The golden rule is that host-key combinations should not be seen
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync * by the guest. For instance a CAD should not have any extra RCtrl down
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync * and RCtrl up around itself. Nor should a resume be followed by a Ctrl-P
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync * that could encourage applications to start printing.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * We must not confuse the hostkey processing into any release sequences
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * either, the host key is supposed to be explicitly pressing one key.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Quick state diagram:
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * host key down alone
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * (Normal) ---------------
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * | | v host combination key down
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * | | (Host key down) ----------------
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * | | host key up v | |
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * | |-------------- | other key down v host combination key down
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * | | (host key used) -------------
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync * | | | ^ |
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync * | (not host key)-- | |---------------
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * | | | | |
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * | | ---- other |
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * | modifiers = 0 v v
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * -----------------------------------------------
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync /** The initial and most common state, pass keystrokes to the guest.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Next state: HKEYSTATE_DOWN
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Prev state: Any */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** The first host key was pressed down
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** The second host key was pressed down (if gHostKeySym2 != SDLK_UNKNOWN)
cba6719bd64ec749967bbe931230452664109857vboxsync /** The host key has been pressed down.
cba6719bd64ec749967bbe931230452664109857vboxsync * Prev state: HKEYSTATE_NORMAL
cba6719bd64ec749967bbe931230452664109857vboxsync * Next state: HKEYSTATE_NORMAL - host key up, capture toggle.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Next state: HKEYSTATE_USED - host key combination down.
44a2ecaf2d0fc196ab76cab13b3f909299e386d1vboxsync * Next state: HKEYSTATE_NOT_IT - non-host key combination down.
show_usage();
bool sessionOpened = false;
#ifdef USE_XPCOM_QUEUE_THREAD
fFullscreen = true;
fResizable = false;
gHostKeyMod = 0;
gHostKeySym1 = 0;
if (!hdaFile)
RTPrintf("Error: The path to the specified harddisk, '%s', could not be resolved.\n", argv[curArg]);
if (!fdaFile)
RTPrintf("Error: The path to the specified floppy disk, '%s', could not be resolved.\n", argv[curArg]);
if (!cdromFile)
ULONG n = 0;
curArg++;
ULONG n = 0;
curArg++;
#ifdef VBOX_VRDP
portVRDP = 0;
if (port > 0)
curArg++;
fDiscardState = true;
#ifdef VBOX_SECURELABEL
fSecureLabel = true;
#ifdef VBOXSDL_ADVANCED_OPTIONS
fRawR0 = true;
fRawR0 = false;
fRawR3 = true;
fRawR3 = false;
fPATM = true;
fPATM = false;
fCSAM = true;
fCSAM = false;
#ifdef VBOX_WIN32_UI
fWin32UI = true;
fShowSDLConfig = true;
show_usage();
goto leave;
goto leave;
goto leave;
if (!session)
goto leave;
sessionOpened = true;
if (!gMachine)
goto leave;
if (!gConsole)
goto leave;
if (hdaFile)
if (!hardDisk)
if (hardDisk)
if (hardDisk)
goto leave;
if (fdaFile)
bool done = false;
done = true;
if (!done)
goto leave;
if (cdromFile)
bool done = false;
done = true;
if (!done)
goto leave;
if (fDiscardState)
if (cSnapshots)
if (gMachineDebugger)
if (!gDisplay)
goto leave;
if (memorySize)
if (vramSize)
#ifdef VBOX_WIN32_UI
if (fWin32UI)
if (!gpFrameBuffer)
goto leave;
goto leave;
if (fFullscreen)
#ifdef VBOX_SECURELABEL
if (fSecureLabel)
if (!secureLabelFontFile)
goto leave;
int rcVBox;
rcVBox = gpFrameBuffer->initSecureLabel(SECURE_LABEL_HEIGHT, secureLabelFontFile, secureLabelPointSize);
goto leave;
goto leave;
if (networkAdapter)
if (tapdev[i])
#ifdef VBOX_VRDP
if (portVRDP != ~0)
if (gVrdpServer)
if (portVRDP > 0)
goto leave;
goto leave;
#ifdef VBOXSDL_ADVANCED_OPTIONS
if (fRawR0 != ~0U)
if (!gMachineDebugger)
goto leave;
if (fRawR3 != ~0U)
if (!gMachineDebugger)
goto leave;
if (fPATM != ~0U)
if (!gMachineDebugger)
goto leave;
if (fCSAM != ~0U)
if (!gMachineDebugger)
goto leave;
if (u32WarpDrive != 0)
if (!gMachineDebugger)
goto leave;
#ifdef RT_OS_LINUX
goto leave;
#ifdef RT_OS_LINUX
goto leave;
#ifdef USE_XPCOM_QUEUE_THREAD
bool fTerminateDuringStartup;
fTerminateDuringStartup = false;
#ifdef USE_XPCOM_QUEUE_THREAD
fXPCOMEventThreadSignaled = true;
case SDL_USER_EVENT_TIMER:
case SDL_USER_EVENT_RESIZE:
#ifdef USE_XPCOM_QUEUE_THREAD
case SDL_USER_EVENT_TERMINATE:
fTerminateDuringStartup = true;
sdlTimer = 0;
goto leave;
RTPrintf("Error: failed to power up VM! No error text available (rc = 0x%x state = %d)\n", rc, machineState);
goto leave;
if (!gKeyboard)
goto leave;
if (!gMouse)
goto leave;
#ifdef USE_XPCOM_QUEUE_THREAD
case SDL_VIDEOEXPOSE:
case SDL_KEYDOWN:
case SDL_KEYUP:
switch (enmHKeyState)
case HKEYSTATE_NORMAL:
case HKEYSTATE_DOWN_1ST:
case HKEYSTATE_DOWN_2ND:
case HKEYSTATE_DOWN:
goto leave;
if (!gfGrabbed)
InputGrabEnd();
ResetKeys();
case HKEYSTATE_USED:
goto leave;
case HKEYSTATE_NOT_IT:
case SDL_QUIT:
goto leave;
case SDL_MOUSEMOTION:
SendMouseEvent(0, 0, 0);
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
switch (enmHKeyState)
case HKEYSTATE_DOWN_1ST:
case HKEYSTATE_DOWN_2ND:
case HKEYSTATE_DOWN:
case SDL_ACTIVEEVENT:
InputGrabEnd();
case SDL_VIDEORESIZE:
if (gDisplay)
#ifdef VBOX_SECURELABEL
if (gSdlResizeTimer)
case SDL_USER_EVENT_RESIZE:
#ifdef USE_XPCOM_QUEUE_THREAD
case SDL_USER_EVENT_TERMINATE:
goto leave;
#ifdef VBOX_SECURELABEL
delete data;
#ifdef VBOX_VRDP
if (gVrdpServer)
if (gMachine)
if ( gConsole
RTPrintf("Failed to power down virtual machine! No error information available (rc = 0x%x).\n", rc);
if ( gMachine
if (sessionOpened)
if (gpDefaultCursor)
#ifdef RT_OS_LINUX
#ifdef RT_OS_LINUX
if (gpCustomCursor)
if (pCustomTempWMCursor)
#if defined (RT_OS_WINDOWS)
if (gDisplay)
if (gpFrameBuffer)
#ifdef VBOX_SECURELABEL
if (gLibrarySDL_ttf)
if (callback)
if (consoleCallback)
static bool UseAbsoluteMouse(void)
#if defined(RT_OS_DARWIN)
switch (sym)
case SDLK_EXCLAIM:
case SDLK_AT:
case SDLK_HASH:
case SDLK_DOLLAR:
case SDLK_CARET:
case SDLK_AMPERSAND:
case SDLK_ASTERISK:
case SDLK_LEFTPAREN:
case SDLK_RIGHTPAREN:
case SDLK_UNDERSCORE:
case SDLK_EQUALS:
case SDLK_COLON:
case SDLK_QUOTEDBL:
case SDLK_LESS:
case SDLK_GREATER:
case SDLK_QUESTION:
case SDLK_KP_MULTIPLY:
case SDLK_LMETA:
case SDLK_RMETA:
case SDLK_CLEAR: return 0x;
case SDLK_KP_EQUALS: return 0x;
case SDLK_COMPOSE: return 0x;
case SDLK_HELP: return 0x;
case SDLK_BREAK: return 0x;
case SDLK_POWER: return 0x;
case SDLK_EURO: return 0x;
case SDLK_UNDO: return 0x;
#ifdef RT_OS_LINUX
keycode = 0;
// Japanese backslash/underscore and Brazilian backslash/question mark
keycode = 0;
/* This is derived partially from SDL_QuartzKeys.h and partially from testing. */
/* set-1 SDL_QuartzKeys.h */
if (keycode == 0)
case SDLK_RMETA:
case SDLK_LMETA:
keycode = 0;
if (!keycode)
#ifdef DEBUG_bird
#ifdef DEBUG_bird
return keycode;
static void ResetKeys(void)
if (!gKeyboard)
if (gaModifiersState[i])
gaModifiersState[i] = 0;
case SDLK_F12:
case SDLK_F11:
case SDLK_F12:
case SDLK_F11:
case SDLK_F10:
case SDLK_F9:
case SDLK_F8:
#ifdef DEBUG_bird
switch(keycode)
ResetKeys();
#ifdef RT_OS_DARWIN
typedef int CGSConnection;
extern CGError CGSGetGlobalHotKeyOperatingMode(CGSConnection Connection, CGSGlobalHotKeyOperatingMode *enmMode);
extern CGError CGSSetGlobalHotKeyOperatingMode(CGSConnection Connection, CGSGlobalHotKeyOperatingMode enmMode);
static bool g_fHotKeysDisabled = false;
static bool g_fConnectedToCGS = false;
if (!g_fConnectedToCGS)
g_fConnectedToCGS = true;
if (fDisable)
static void InputGrabStart(void)
#ifdef RT_OS_DARWIN
DisableGlobalHotKeys(true);
if (!gfGuestNeedsHostCursor)
static void InputGrabEnd(void)
if (!gfGuestNeedsHostCursor)
#ifdef RT_OS_DARWIN
DisableGlobalHotKeys(false);
bool abs;
buttons = 0;
if (abs)
button = 0;
if (!gpOffCursor)
if (gpOffCursor)
int tmp_button = 0;
switch (button)
if (abs)
if (abs)
void ResetVM(void)
if (gConsole)
void SaveState(void)
ResetKeys();
if (gfGrabbed)
InputGrabEnd();
case SDL_USER_EVENT_TIMER:
#ifdef USE_XPCOM_QUEUE_THREAD
case SDL_USER_EVENT_RESIZE:
case SDL_USER_EVENT_TERMINATE:
sdlTimer = 0;
lrc = ~0;
if (!lrc)
if (name)
switch (mode)
case TITLEBAR_NORMAL:
if (gfGrabbed)
if (gMachineDebugger)
case TITLEBAR_STARTUP:
case TITLEBAR_SAVE:
case TITLEBAR_SNAPSHOT:
#ifdef VBOX_WIN32_UI
static void vbox_show_shape (unsigned short w, unsigned short h,
size_t x, y;
unsigned short pitch;
if (c == bg)
if (gpOffCursor)
bool ok = false;
uint32_t shapeSize = ((((data->width + 7) / 8) * data->height + 3) & ~3) + data->width * 4 * data->height;
#if defined (RT_OS_WINDOWS)
void *lpBits;
if (hAlphaCursor)
// see SDL12/src/video/wincommon/SDL_sysmouse.c
if (pCustomTempWMCursor)
ok = true;
if (hMonoBitmap)
if (hBitmap)
if (img)
if (cur)
// see SDL12/src/video/x11/SDL_x11mouse.c
if (pCustomTempWMCursor)
ok = true;
if (!ok)
else if (gfAbsoluteMouseGuest)
static void HandleGuestCapsChanged(void)
if (!gfAbsoluteMouseGuest)
if (gfGrabbed)
InputGrabEnd();
return VERR_NOT_SUPPORTED;
case SDLK_DELETE:
case SDLK_f:
case SDLK_p:
if (gfGrabbed)
InputGrabEnd();
case SDLK_r:
ResetVM();
case SDLK_q:
return VINF_EM_TERMINATE;
case SDLK_s:
SaveState();
return VINF_EM_TERMINATE;
case SDLK_h:
if (gConsole)
case SDLK_n:
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_NOT_SUPPORTED;
return VINF_SUCCESS;
return interval;
#ifdef USE_XPCOM_QUEUE_THREAD
if (rc == 0)
#ifdef RT_OS_LINUX
if (!rc)