VirtualBox

Changeset 99546 in vbox


Ignore:
Timestamp:
Apr 27, 2023 12:33:12 PM (19 months ago)
Author:
vboxsync
Message:

FE/VBoxBFE: Some very simple SDL based display output and add more devices, bugref:10397

Location:
trunk/src/VBox/Frontends/VBoxBFE
Files:
4 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxBFE/Makefile.kmk

    r99050 r99546  
    5151endif
    5252VBoxBFE_TEMPLATE := $(if $(VBOX_WITH_HARDENING),VBoxMainClientDll,VBoxMainClientExe)
    53 VBoxHeadless_INCS      = \
     53VBoxBFE_SDKS      = LIBSDL2
     54VBoxBFE_INCS      = \
     55        $(VBoxBFE_0_OUTDIR) \
    5456        $(VBOX_GRAPHICS_INCS) \
    5557        ../Common
    5658VBoxBFE_SOURCES   = \
    57         VBoxBFE.cpp
     59        VBoxBFE.cpp \
     60        Display.cpp \
     61        Framebuffer.cpp
    5862ifdef VBOX_WITH_HARDENING
    5963 VBoxBFE_LDFLAGS.darwin += -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxBFE.dylib
    6064endif
     65
     66VBoxBFE_CLEAN = $(VBoxBFE_0_OUTDIR)/Ico64x01.h
     67VBoxBFE_INTERMEDIATES = $(VBoxBFE_0_OUTDIR)/Ico64x01.h
     68
     69 # Convert the pnm-file to a byte array.
     70 $$(VBoxBFE_0_OUTDIR)/Ico64x01.h: $(PATH_ROOT)/src/VBox/Frontends/VBoxSDL/ico64x01.pnm $(VBOX_BIN2C) | $$(dir $$@)
     71        $(call MSG_TOOL,bin2c,VBoxSDL,$<,$@)
     72        $(QUIET)$(VBOX_BIN2C) Ico64x01 $< $@
     73
    6174ifdef VBOX_WITH_HARDENING
    6275 $(call VBOX_SET_VER_INFO_DLL,VBoxBFE,VirtualBox Basic Frontend (dll),$(VBOX_WINDOWS_ICON_FILE)) # Version info / description.
  • trunk/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp

    r99493 r99546  
    4747#include <iprt/stream.h>
    4848#include <iprt/ldr.h>
     49#include <iprt/mem.h>
    4950#include <iprt/getopt.h>
    5051#include <iprt/env.h>
    5152#include <iprt/errcore.h>
    5253#include <iprt/thread.h>
     54#include <iprt/uuid.h>
     55
     56#include <SDL.h>
     57
     58#include "Display.h"
     59#include "Framebuffer.h"
    5360
    5461
     
    8390static VMSTATE          g_enmVmState        = VMSTATE_CREATING;
    8491static const char       *g_pszLoadMem       = NULL;
     92static const char       *g_pszLoadFlash     = NULL;
    8593static const char       *g_pszLoadDtb       = NULL;
    8694static const char       *g_pszSerialLog     = NULL;
     95static const char       *g_pszLoadKernel    = NULL;
     96static const char       *g_pszLoadInitrd    = NULL;
     97static const char       *g_pszCmdLine       = NULL;
     98static VMM2USERMETHODS  g_Vmm2UserMethods;
     99static Display          *g_pDisplay         = NULL;
     100static Framebuffer      *g_pFramebuffer     = NULL;
     101static bool gfIgnoreNextResize = false;
     102static SDL_TimerID gSdlResizeTimer = 0;
    87103
    88104/** @todo currently this is only set but never read. */
    89105static char szError[512];
    90106
     107extern DECL_HIDDEN_DATA(RTSEMEVENT) g_EventSemSDLEvents;
     108extern DECL_HIDDEN_DATA(volatile int32_t) g_cNotifyUpdateEventsPending;
    91109
    92110/*********************************************************************************************************************************
    93111*   Internal Functions                                                                                                           *
    94112*********************************************************************************************************************************/
     113
     114/**
     115 * Wait for the next SDL event. Don't use SDL_WaitEvent since this function
     116 * calls SDL_Delay(10) if the event queue is empty.
     117 */
     118static int WaitSDLEvent(SDL_Event *event)
     119{
     120    for (;;)
     121    {
     122        int rc = SDL_PollEvent(event);
     123        if (rc == 1)
     124            return 1;
     125        /* Immediately wake up if new SDL events are available. This does not
     126         * work for internal SDL events. Don't wait more than 10ms. */
     127        RTSemEventWait(g_EventSemSDLEvents, 10);
     128    }
     129}
     130
     131
     132/**
     133 * Timer callback function to check if resizing is finished
     134 */
     135static Uint32 ResizeTimer(Uint32 interval, void *param) RT_NOTHROW_DEF
     136{
     137    RT_NOREF(interval, param);
     138
     139    /* post message so the window is actually resized */
     140    SDL_Event event = {0};
     141    event.type      = SDL_USEREVENT;
     142    event.user.type = SDL_USER_EVENT_WINDOW_RESIZE_DONE;
     143    PushSDLEventForSure(&event);
     144    /* one-shot */
     145    return 0;
     146}
     147
    95148
    96149/**
     
    200253
    201254
    202 #if 0
    203255/**
    204256 * Register the main drivers.
     
    213265    AssertReleaseMsg(u32Version == VBOX_VERSION, ("u32Version=%#x VBOX_VERSION=%#x\n", u32Version, VBOX_VERSION));
    214266
    215     /** @todo */
    216     RT_NOREF(pCallbacks);
     267    int vrc = pCallbacks->pfnRegister(pCallbacks, &Display::DrvReg);
     268    if (RT_FAILURE(vrc))
     269        return vrc;
    217270
    218271    return VINF_SUCCESS;
    219272}
    220 #endif
    221273
    222274
     
    254306    rc = pVMM->pfnCFGMR3InsertNode(pMem, "Flash", &pMemRegion);                                 UPDATE_RC();
    255307    rc = pVMM->pfnCFGMR3InsertInteger(pMemRegion, "GCPhysStart",   0);                          UPDATE_RC();
    256     rc = pVMM->pfnCFGMR3InsertInteger(pMemRegion, "Size", 128 * _1M);                           UPDATE_RC();
     308    rc = pVMM->pfnCFGMR3InsertInteger(pMemRegion, "Size", 64 * _1M);                            UPDATE_RC();
    257309
    258310    rc = pVMM->pfnCFGMR3InsertNode(pMem, "Conventional", &pMemRegion);                          UPDATE_RC();
     
    264316     * PDM.
    265317     */
    266     //rc = pVMM->pfnPDMR3DrvStaticRegistration(pVM, VBoxDriversRegister);                      UPDATE_RC();
     318    rc = pVMM->pfnPDMR3DrvStaticRegistration(pVM, VBoxDriversRegister);                         UPDATE_RC();
    267319
    268320    /*
     
    293345    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "MmioSize",       4096);                        UPDATE_RC();
    294346    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "MmioBase", 0x09020000);                        UPDATE_RC();
     347    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "DmaEnabled",        1);                        UPDATE_RC();
     348    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "QemuRamfbSupport",  1);                        UPDATE_RC();
     349    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "LUN#0",           &pLunL0);                    UPDATE_RC();
     350    rc = pVMM->pfnCFGMR3InsertString(pLunL0, "Driver",          "MainDisplay");              UPDATE_RC();
     351    if (g_pszLoadKernel)
     352    {
     353        rc = pVMM->pfnCFGMR3InsertString(pCfg,  "KernelImage",  g_pszLoadKernel);            UPDATE_RC();
     354    }
     355    if (g_pszLoadInitrd)
     356    {
     357        rc = pVMM->pfnCFGMR3InsertString(pCfg,  "InitrdImage",  g_pszLoadInitrd);            UPDATE_RC();
     358    }
     359    if (g_pszCmdLine)
     360    {
     361        rc = pVMM->pfnCFGMR3InsertString(pCfg,  "CmdLine",  g_pszCmdLine);                   UPDATE_RC();
     362    }
     363
     364
     365    rc = pVMM->pfnCFGMR3InsertNode(pDevices, "flash-cfi",         &pDev);                    UPDATE_RC();
     366    rc = pVMM->pfnCFGMR3InsertNode(pDev,     "0",            &pInst);                        UPDATE_RC();
     367    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "Config",        &pCfg);                        UPDATE_RC();
     368    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "BaseAddress", 64 * _1M);                       UPDATE_RC();
     369    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "Size",        64 * _1M);                       UPDATE_RC();
     370    if (g_pszLoadFlash)
     371    {
     372        rc = pVMM->pfnCFGMR3InsertString(pCfg, "FlashFile", g_pszLoadFlash);                 UPDATE_RC();
     373    }
    295374
    296375    rc = pVMM->pfnCFGMR3InsertNode(pDevices, "arm-pl011",     &pDev);                        UPDATE_RC();
     
    310389    }
    311390
     391    rc = pVMM->pfnCFGMR3InsertNode(pDevices, "arm-pl031-rtc", &pDev);                        UPDATE_RC();
     392    rc = pVMM->pfnCFGMR3InsertNode(pDev,     "0",            &pInst);                        UPDATE_RC();
     393    rc = pVMM->pfnCFGMR3InsertNode(pInst,    "Config",        &pCfg);                        UPDATE_RC();
     394    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "Irq",               2);                        UPDATE_RC();
     395    rc = pVMM->pfnCFGMR3InsertInteger(pCfg,  "MmioBase", 0x09010000);                        UPDATE_RC();
    312396
    313397#undef UPDATE_RC
     
    410494
    411495    return rc;
     496}
     497
     498
     499/**
     500 * @interface_method_impl{VMM2USERMETHODS,pfnQueryGenericObject}
     501 */
     502static DECLCALLBACK(void *) vboxbfeVmm2User_QueryGenericObject(PCVMM2USERMETHODS pThis, PUVM pUVM, PCRTUUID pUuid)
     503{
     504    RT_NOREF(pThis, pUVM);
     505
     506    if (!RTUuidCompareStr(pUuid, DISPLAY_OID))
     507        return g_pDisplay;
     508
     509    return NULL;
    412510}
    413511
     
    459557    LogFlow(("VMPowerUp\n"));
    460558
     559    g_Vmm2UserMethods.u32Magic                         = VMM2USERMETHODS_MAGIC;
     560    g_Vmm2UserMethods.u32Version                       = VMM2USERMETHODS_VERSION;
     561    g_Vmm2UserMethods.pfnSaveState                     = NULL;
     562    g_Vmm2UserMethods.pfnNotifyEmtInit                 = NULL;
     563    g_Vmm2UserMethods.pfnNotifyEmtTerm                 = NULL;
     564    g_Vmm2UserMethods.pfnNotifyPdmtInit                = NULL;
     565    g_Vmm2UserMethods.pfnNotifyPdmtTerm                = NULL;
     566    g_Vmm2UserMethods.pfnNotifyResetTurnedIntoPowerOff = NULL;
     567    g_Vmm2UserMethods.pfnQueryGenericObject            = vboxbfeVmm2User_QueryGenericObject;
     568    g_Vmm2UserMethods.u32EndMagic                      = VMM2USERMETHODS_MAGIC;
     569
    461570    /*
    462571     * Create empty VM.
    463572     */
    464     rc = g_pVMM->pfnVMR3Create(1, NULL, 0 /*fFlags*/, vboxbfeSetVMErrorCallback, NULL, vboxbfeConfigConstructor, NULL, &g_pVM, NULL);
     573    rc = g_pVMM->pfnVMR3Create(1, &g_Vmm2UserMethods, 0 /*fFlags*/, vboxbfeSetVMErrorCallback, NULL, vboxbfeConfigConstructor, NULL, &g_pVM, NULL);
    465574    if (RT_FAILURE(rc))
    466575    {
     
    573682        { "--memory-size-mib",    'm', RTGETOPT_REQ_UINT32 },
    574683        { "--load-file-into-ram", 'l', RTGETOPT_REQ_STRING },
     684        { "--load-flash",         'f', RTGETOPT_REQ_STRING },
    575685        { "--load-dtb",           'd', RTGETOPT_REQ_STRING },
    576686        { "--load-vmm",           'v', RTGETOPT_REQ_STRING },
     687        { "--load-kernel",        'k', RTGETOPT_REQ_STRING },
     688        { "--load-initrd",        'i', RTGETOPT_REQ_STRING },
     689        { "--cmd-line",           'c', RTGETOPT_REQ_STRING },
    577690        { "--serial-log",         's', RTGETOPT_REQ_STRING },
    578691    };
     
    598711                g_pszLoadMem = ValueUnion.psz;
    599712                break;
     713            case 'f':
     714                g_pszLoadFlash = ValueUnion.psz;
     715                break;
    600716            case 'd':
    601717                g_pszLoadDtb = ValueUnion.psz;
     
    603719            case 'v':
    604720                pszVmmMod = ValueUnion.psz;
     721                break;
     722            case 'k':
     723                g_pszLoadKernel = ValueUnion.psz;
     724                break;
     725            case 'i':
     726                g_pszLoadInitrd = ValueUnion.psz;
     727                break;
     728            case 'c':
     729                g_pszCmdLine = ValueUnion.psz;
    605730                break;
    606731            case 's':
     
    620745    }
    621746
     747    /* static initialization of the SDL stuff */
     748    if (!Framebuffer::init(true /*fShowSDLConfig*/))
     749        return RTEXITCODE_FAILURE;
     750
     751    g_pDisplay = new Display();
     752    g_pFramebuffer = new Framebuffer(g_pDisplay, 0, false /*fFullscreen*/, false /*fResizable*/, true /*fShowSDLConfig*/, false,
     753                                     ~0, ~0, ~0, false /*fSeparate*/);
     754    g_pDisplay->SetFramebuffer(0, g_pFramebuffer);
     755
    622756    int vrc = vboxbfeLoadVMM(pszVmmMod);
    623757    if (RT_FAILURE(vrc))
     
    648782           || g_enmVmState == VMSTATE_LOADING);
    649783
    650     /** @todo Mainloop. */
    651     for (;;)
    652         RTThreadSleep(1000);
     784    LogFlow(("VBoxSDL: Entering big event loop\n"));
     785    SDL_Event event;
     786    uint32_t uResizeWidth  = ~(uint32_t)0;
     787    uint32_t uResizeHeight = ~(uint32_t)0;
     788
     789    while (WaitSDLEvent(&event))
     790    {
     791        switch (event.type)
     792        {
     793            /*
     794             * The screen needs to be repainted.
     795             */
     796            case SDL_WINDOWEVENT:
     797            {
     798                switch (event.window.event)
     799                {
     800                    case SDL_WINDOWEVENT_EXPOSED:
     801                    {
     802                        g_pFramebuffer->repaint();
     803                        break;
     804                    }
     805                    case SDL_WINDOWEVENT_FOCUS_GAINED:
     806                    {
     807                        break;
     808                    }
     809                    case SDL_WINDOWEVENT_FOCUS_LOST:
     810                    {
     811                        break;
     812                    }
     813                    case SDL_WINDOWEVENT_RESIZED:
     814                    {
     815                        if (g_pDisplay)
     816                        {
     817                            if (gfIgnoreNextResize)
     818                            {
     819                                gfIgnoreNextResize = FALSE;
     820                                break;
     821                            }
     822                            uResizeWidth  = event.window.data1;
     823                            uResizeHeight = event.window.data2;
     824                            if (gSdlResizeTimer)
     825                                SDL_RemoveTimer(gSdlResizeTimer);
     826                            gSdlResizeTimer = SDL_AddTimer(300, ResizeTimer, NULL);
     827                        }
     828                        break;
     829                    }
     830                    default:
     831                        break;
     832                }
     833                break;
     834            }
     835
     836            /*
     837             * The window was closed.
     838             */
     839            case SDL_QUIT:
     840            {
     841                /** @todo */
     842                break;
     843            }
     844
     845            /*
     846             * User specific update event.
     847             */
     848            /** @todo use a common user event handler so that SDL_PeepEvents() won't
     849             * possibly remove other events in the queue!
     850             */
     851            case SDL_USER_EVENT_UPDATERECT:
     852            {
     853                /*
     854                 * Decode event parameters.
     855                 */
     856                ASMAtomicDecS32(&g_cNotifyUpdateEventsPending);
     857
     858                SDL_Rect *pUpdateRect = (SDL_Rect *)event.user.data1;
     859                AssertPtrBreak(pUpdateRect);
     860
     861                int const x = pUpdateRect->x;
     862                int const y = pUpdateRect->y;
     863                int const w = pUpdateRect->w;
     864                int const h = pUpdateRect->h;
     865
     866                RTMemFree(event.user.data1);
     867
     868                Log3Func(("SDL_USER_EVENT_UPDATERECT: x=%d y=%d, w=%d, h=%d\n", x, y, w, h));
     869
     870                Assert(g_pFramebuffer);
     871                g_pFramebuffer->update(x, y, w, h, true /* fGuestRelative */);
     872                break;
     873            }
     874
     875            /*
     876             * User event: Window resize done
     877             */
     878            case SDL_USER_EVENT_WINDOW_RESIZE_DONE:
     879            {
     880                /* communicate the resize event to the guest */
     881                //g_pDisplay->SetVideoModeHint(0 /*=display*/, true /*=enabled*/, false /*=changeOrigin*/,
     882                //                             0 /*=originX*/, 0 /*=originY*/,
     883                //                             uResizeWidth, uResizeHeight, 0 /*=don't change bpp*/, true /*=notify*/);
     884                break;
     885
     886            }
     887
     888            /*
     889             * User specific framebuffer change event.
     890             */
     891            case SDL_USER_EVENT_NOTIFYCHANGE:
     892            {
     893                LogFlow(("SDL_USER_EVENT_NOTIFYCHANGE\n"));
     894                g_pFramebuffer->notifyChange(event.user.code);
     895                break;
     896            }
     897
     898            /*
     899             * User specific termination event
     900             */
     901            case SDL_USER_EVENT_TERMINATE:
     902            {
     903                if (event.user.code != VBOXSDL_TERM_NORMAL)
     904                    RTPrintf("Error: VM terminated abnormally!\n");
     905                break;
     906            }
     907
     908            default:
     909            {
     910                Log8(("unknown SDL event %d\n", event.type));
     911                break;
     912            }
     913        }
     914    }
    653915
    654916    LogRel(("VBoxBFE: exiting\n"));
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