VirtualBox

Changeset 98357 in vbox for trunk/src


Ignore:
Timestamp:
Jan 31, 2023 10:53:46 AM (2 years ago)
Author:
vboxsync
Message:

FE/SDL: Fixed and simplified the host key detection ("--detecthostkey") on Windows; we need a window for that in order to receive any keypress events. Factored out that functionality into an own function, as the main function is waaaaaay too long. See @todo. ​bugref:9449

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp

    r98345 r98357  
    689689#endif /* VBOXSDL_WITH_X11 */
    690690
     691/**
     692 * Returns a stringified version of a keyboard modifier.
     693 *
     694 * @returns Stringified version of the keyboard modifier.
     695 * @param   mod                 Modifier code to return a stringified version for.
     696 */
     697static const char *keyModToStr(unsigned mod)
     698{
     699    switch (mod)
     700    {
     701        RT_CASE_RET_STR(KMOD_NONE);
     702        RT_CASE_RET_STR(KMOD_LSHIFT);
     703        RT_CASE_RET_STR(KMOD_RSHIFT);
     704        RT_CASE_RET_STR(KMOD_LCTRL);
     705        RT_CASE_RET_STR(KMOD_RCTRL);
     706        RT_CASE_RET_STR(KMOD_LALT);
     707        RT_CASE_RET_STR(KMOD_RALT);
     708        RT_CASE_RET_STR(KMOD_LGUI);
     709        RT_CASE_RET_STR(KMOD_RGUI);
     710        RT_CASE_RET_STR(KMOD_NUM);
     711        RT_CASE_RET_STR(KMOD_CAPS);
     712        RT_CASE_RET_STR(KMOD_MODE);
     713        RT_CASE_RET_STR(KMOD_SCROLL);
     714        default:
     715            break;
     716    }
     717
     718    return "<Unknown>";
     719}
     720
     721/**
     722 * Handles detecting a host key by printing its values to stdout.
     723 *
     724 * @returns RTEXITCODE
     725 */
     726static RTEXITCODE handleDetectHostKey(void)
     727{
     728    RTEXITCODE rcExit  = RTEXITCODE_SUCCESS;
     729
     730    int rc = SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER);
     731    if (rc == 0)
     732    {
     733        /* We need a window, otherwise we won't get any keypress events. */
     734        SDL_Window *pWnd = SDL_CreateWindow("VBoxSDL",
     735                                            SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
     736        RTPrintf("Please hit one or two function key(s) to get the --hostkey value. ..\n");
     737        RTPrintf("Press CTRL+C to quit.\n");
     738        SDL_Event e1;
     739        while (SDL_WaitEvent(&e1))
     740        {
     741            if (    e1.key.keysym.sym == SDLK_c
     742                && (e1.key.keysym.mod & KMOD_CTRL) != 0)
     743                break;
     744            if (e1.type == SDL_QUIT)
     745                break;
     746            if (e1.type == SDL_KEYDOWN)
     747            {
     748                unsigned const mod = SDL_GetModState() & ~(KMOD_MODE | KMOD_NUM | KMOD_RESERVED);
     749                RTPrintf("--hostkey %d", e1.key.keysym.sym);
     750                if (mod)
     751                    RTPrintf(" %d\n", mod);
     752                else
     753                    RTPrintf("\n");
     754
     755                if (mod)
     756                    RTPrintf("Host key is '%s' + '%s'\n", keyModToStr(mod), SDL_GetKeyName(e1.key.keysym.sym));
     757                else
     758                    RTPrintf("Host key is '%s'\n", SDL_GetKeyName(e1.key.keysym.sym));
     759            }
     760        }
     761        SDL_DestroyWindow(pWnd);
     762        SDL_Quit();
     763    }
     764    else
     765    {
     766        RTPrintf("Error: SDL_InitSubSystem failed with message '%s'\n", SDL_GetError());
     767        rcExit = RTEXITCODE_FAILURE;
     768    }
     769
     770    return rcExit;
     771}
    691772
    692773/** entry point */
     
    696777    RT_NOREF(envp);
    697778#ifdef RT_OS_WINDOWS
     779    /* As we run with the WINDOWS subsystem, we need to either attach to or create an own console
     780     * to get any stdout / stderr output. */
     781    bool fAllocConsole = IsDebuggerPresent();
     782    if (!fAllocConsole)
     783    {
     784        if (!AttachConsole(ATTACH_PARENT_PROCESS))
     785            fAllocConsole = true;
     786    }
     787
     788    if (fAllocConsole)
     789    {
     790        if (!AllocConsole())
     791            MessageBox(GetDesktopWindow(), L"Unable to attach to or allocate a console!", L"VBoxSDL", MB_OK | MB_ICONERROR);
     792        /* Continue running. */
     793    }
     794
     795    RTFILE hStdIn;
     796    RTFileFromNative(&hStdIn,  (RTHCINTPTR)GetStdHandle(STD_INPUT_HANDLE));
     797    /** @todo Closing of standard handles not support via IPRT (yet). */
     798    RTStrmOpenFileHandle(hStdIn, "r", 0, &g_pStdIn);
     799
     800    RTFILE hStdOut;
     801    RTFileFromNative(&hStdOut,  (RTHCINTPTR)GetStdHandle(STD_OUTPUT_HANDLE));
     802    /** @todo Closing of standard handles not support via IPRT (yet). */
     803    RTStrmOpenFileHandle(hStdOut, "wt", 0, &g_pStdOut);
     804
     805    RTFILE hStdErr;
     806    RTFileFromNative(&hStdErr,  (RTHCINTPTR)GetStdHandle(STD_ERROR_HANDLE));
     807    RTStrmOpenFileHandle(hStdErr, "wt", 0, &g_pStdErr);
     808
     809    if (!fAllocConsole) /* When attaching to the parent console, make sure we start on a fresh line. */
     810        RTPrintf("\n");
     811
    698812    ATL::CComModule _Module; /* Required internally by ATL (constructor records instance in global variable). */
    699 #endif
     813#endif /* RT_OS_WINDOWS */
    700814
    701815#ifdef Q_WS_X11
     
    731845#endif
    732846
     847    RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
     848
    733849    /*
    734850     * the hostkey detection mode is unrelated to VM processing, so handle it before
     
    738854                      || !strcmp(argv[1], "--detecthostkey")))
    739855    {
    740         Uint32 fInitSubSystem = SDL_INIT_VIDEO | SDL_INIT_TIMER;
    741         int rc = SDL_InitSubSystem(fInitSubSystem);
    742         if (rc != 0)
    743         {
    744             RTPrintf("Error: SDL_InitSubSystem failed with message '%s'\n", SDL_GetError());
    745             return 1;
    746         }
    747         RTPrintf("Please hit one or two function key(s) to get the --hostkey value...\n");
    748         SDL_Event event1;
    749         while (SDL_WaitEvent(&event1))
    750         {
    751             if (event1.type == SDL_KEYDOWN)
    752             {
    753                 SDL_Event event2;
    754                 unsigned  mod = SDL_GetModState() & ~(KMOD_MODE | KMOD_NUM | KMOD_RESERVED);
    755                 while (SDL_WaitEvent(&event2))
    756                 {
    757                     if (event2.type == SDL_KEYDOWN || event2.type == SDL_KEYUP)
    758                     {
    759                         /* pressed additional host key */
    760                         RTPrintf("--hostkey %d", event1.key.keysym.sym);
    761                         if (event2.type == SDL_KEYDOWN)
    762                         {
    763                             RTPrintf(" %d", event2.key.keysym.sym);
    764                             RTPrintf(" %d\n", SDL_GetModState() & ~(KMOD_MODE | KMOD_NUM | KMOD_RESERVED));
    765                         }
    766                         else
    767                         {
    768                             RTPrintf(" %d\n", mod);
    769                         }
    770                         /* we're done */
    771                         break;
    772                     }
    773                 }
    774                 /* we're down */
    775                 break;
    776             }
    777         }
    778         SDL_Quit();
    779         return 1;
    780     }
     856        rcExit = handleDetectHostKey();
     857#ifdef RT_OS_WINDOWS
     858        FreeConsole(); /* Detach or destroy (from) console. */
     859#endif
     860        return rcExit;
     861    }
     862
     863    /** @todo r=andy This function is waaaaaay to long, uses goto's and leaks stuff. Use RTGetOpt handling. */
    781864
    782865    HRESULT hrc;
     
    12951378    else if (pcszSettingsPwFile)
    12961379    {
    1297         int rcExit = settingsPasswordFile(pVirtualBox, pcszSettingsPwFile);
     1380        rcExit = settingsPasswordFile(pVirtualBox, pcszSettingsPwFile);
    12981381        if (rcExit != RTEXITCODE_SUCCESS)
    12991382            goto leave;
     
    27822865    LogFlow(("Returning from main()!\n"));
    27832866    RTLogFlush(NULL);
     2867
     2868#ifdef RT_OS_WINDOWS
     2869    FreeConsole(); /* Detach or destroy (from) console. */
     2870#endif
     2871
    27842872    return FAILED(hrc) ? 1 : 0;
    27852873}
     
    28022890        return RTMsgInitFailure(rc);
    28032891
    2804 #ifdef RT_OS_WINDOWS
    2805     /* As we run with the WINDOWS subsystem, we need to either attach to or create an own console
    2806      * to get any stdout / stderr output. */
    2807     bool fAllocConsole = ::IsDebuggerPresent();
    2808     if (!fAllocConsole)
    2809     {
    2810         if (!AttachConsole(ATTACH_PARENT_PROCESS))
    2811             fAllocConsole = true;
    2812     }
    2813 
    2814     if (fAllocConsole)
    2815     {
    2816         if (!AllocConsole())
    2817             MessageBox(GetDesktopWindow(), L"Unable to attach to or allocate a console!", L"VBoxSDL", MB_OK | MB_ICONERROR);
    2818         /* Continue running. */
    2819     }
    2820 
    2821     RTFILE hStdOut;
    2822     RTFileFromNative(&hStdOut,  (RTHCINTPTR)GetStdHandle(STD_OUTPUT_HANDLE));
    2823     /** @todo Closing of standard handles not support via IPRT (yet). */
    2824     RTStrmOpenFileHandle(hStdOut, "wt", 0, &g_pStdOut);
    2825 
    2826     RTFILE hStdErr;
    2827     RTFileFromNative(&hStdErr,  (RTHCINTPTR)GetStdHandle(STD_ERROR_HANDLE));
    2828     RTStrmOpenFileHandle(hStdErr, "wt", 0, &g_pStdErr);
    2829 
    2830     if (!fAllocConsole) /* When attaching to the parent console, make sure we start on a fresh line. */
    2831         RTPrintf("\n");
    2832 #endif /* RT_OS_WINDOWS */
    2833 
    2834     int rcExit = TrustedMain(argc, argv, NULL);
    2835 
    2836 #ifdef RT_OS_WINDOWS
    2837     FreeConsole(); /* Detach or destroy (from) console. */
    2838 #endif
    2839 
    2840     return rcExit;
     2892    return TrustedMain(argc, argv, NULL);
    28412893}
    28422894#endif /* !VBOX_WITH_HARDENING */
Note: See TracChangeset for help on using the changeset viewer.

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