int MFDisplay_CreateDisplay(int width, int height, int bpp, int rate, bool vsync, bool triplebuffer, bool wide, bool progressive) { MFCALLSTACK; FujiModule *pModule = (FujiModule*)pp::Module::Get(); pNaClGLContext = new OpenGLContext(pModule->GetInstance()); pNaClGLContext->MakeContextCurrent(); gDisplay.fullscreenWidth = gDisplay.width = width; gDisplay.fullscreenHeight = gDisplay.height = height; gDisplay.refreshRate = rate; gDisplay.colourDepth = 32; gDisplay.windowed = true; gDisplay.wide = false; gDisplay.progressive = true; MFRenderer_CreateDisplay(); initialised = true; return 0; }
int MFDisplay_CreateDisplay(int width, int height, int bpp, int rate, bool vsync, bool triplebuffer, bool wide, bool progressive) { MFCALLSTACK; MFZeroMemory(gXKeys, sizeof(gXKeys)); MFZeroMemory(&gXMouse, sizeof(gXMouse)); gXMouse.x = -1; gDisplay.fullscreenWidth = gDisplay.width = width; gDisplay.fullscreenHeight = gDisplay.height = height; gDisplay.refreshRate = 0; gDisplay.colourDepth = 0; /* Use default. Chances are, it's something sane */ gDisplay.windowed = true; gDisplay.wide = false; gDisplay.progressive = true; if(!(xdisplay = XOpenDisplay(NULL))) { MFDebug_Error("Unable to open display"); MFDisplay_DestroyDisplay(); return 1; } screen = DefaultScreen(xdisplay); rootWindow = RootWindow(xdisplay, screen); // build our internal list of available video modes GetModes(&modes, !gDisplay.windowed); while(!FindMode(modes, width, height)) { if(!gDisplay.windowed) { // no fullscreen mode, try windowed mode instead MFDebug_Warn(1, "No suitable modes for fullscreen mode, trying windowed mode"); gDisplay.windowed = true; FreeModes(); GetModes(&modes, false); } else { // default is some sort of custom mode that doesn't appear in the windowed mode list // HACK: we'll add it to the end.. modes[numModes].width = width; modes[numModes].height = height; currentMode = numModes; ++numModes; break; } } DebugMenu_AddItem("Resolution", "Display Options", &resSelect, ChangeResCallback); DebugMenu_AddItem("Apply", "Display Options", &applyDisplayMode, ApplyDisplayModeCallback); // Set full screen mode, if necessary if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to switch screenmodes, defaulting to windowed mode"); MFDisplay_DestroyDisplay(); return 1; } } XVisualInfo *MFRenderer_GetVisualInfo(); XVisualInfo *visualInfo = MFRenderer_GetVisualInfo(); if(!visualInfo) return 1; if(!(colorMap = XCreateColormap(xdisplay, rootWindow, visualInfo->visual, AllocNone))) { MFDebug_Error("Unable to create colourmap"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } XSetWindowAttributes windowAttrs; windowAttrs.colormap = colorMap; windowAttrs.cursor = None; windowAttrs.event_mask = StructureNotifyMask; windowAttrs.border_pixel = BlackPixel(xdisplay, screen); windowAttrs.background_pixel = BlackPixel(xdisplay, screen); if(!(window = XCreateWindow(xdisplay, rootWindow, 0, 0, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, CWBackPixel | CWBorderPixel | CWCursor | CWColormap | CWEventMask, &windowAttrs))) { MFDebug_Error("Unable to create X Window"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } // Tell the window manager not to allow our window to be resized. But some window managers can ignore me and do it anyway. Typical X-Windows. if((sizeHints = XAllocSizeHints()) == NULL) { MFDebug_Error("Unable to alloc XSizeHints structure, out of memory?"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } sizeHints->flags = PSize | PMinSize | PMaxSize; sizeHints->min_width = sizeHints->max_width = sizeHints->base_width = width; sizeHints->min_height = sizeHints->max_height = sizeHints->base_height = height; XSetWMNormalHints(xdisplay, window, sizeHints); // Window title XStoreName(xdisplay, window, gDefaults.display.pWindowTitle); XWMHints *wmHints; if((wmHints = XAllocWMHints()) == NULL) { MFDebug_Error("Unable to alloc XWMHints structure, out of memory?"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } wmHints->flags = InputHint | StateHint; wmHints->input = true; wmHints->initial_state = NormalState; if(!XSetWMHints(xdisplay, window, wmHints)) { MFDebug_Error("Unable to set WM hints for window"); XFree(visualInfo); MFDisplay_DestroyDisplay(); return 1; } XFree(wmHints); XFree(visualInfo); // Tell the window manager that I want to be notified if the window's closed wm_delete_window = XInternAtom(xdisplay, "WM_DELETE_WINDOW", false); if(!XSetWMProtocols(xdisplay, window, &wm_delete_window, 1)) { MFDebug_Error("Unable to set Window Manager protocols"); MFDisplay_DestroyDisplay(); return 1; } XSelectInput(xdisplay, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ExposureMask); if(!XMapRaised(xdisplay, window)) { MFDebug_Error("Unable to map new window"); MFDisplay_DestroyDisplay(); return 1; } // Wait for the window to be mapped, etc. The documentation doesn't indicate that this is necessary, but every GLX program I've ever seen does it, so I assume it is. XEvent event; XIfEvent(xdisplay, &event, WaitForNotify, (char *)window); MFRenderer_CreateDisplay(); if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to set screen mode"); MFDisplay_DestroyDisplay(); return 1; } XGrabPointer(xdisplay, window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); XFlush(xdisplay); // A little trick to make sure the entire window is on the screen XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, width - 1, height - 1); XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, 0, 0); XFlush(xdisplay); } return 0; }
MF_API MFDisplay *MFDisplay_Create(const char *pName, const MFDisplaySettings *pDisplaySettings) { bool bDidCreateWindow = false; /* // Set full screen mode, if necessary if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to switch screenmodes, defaulting to windowed mode"); MFDisplay_DestroyDisplay(); return 1; } } */ MFWindow *pWindow = pDisplaySettings->pWindow; if(!pWindow) { MFWindowParams params; params.x = (int)gInitParams.display.displayRect.x; params.y = (int)gInitParams.display.displayRect.y; params.width = pDisplaySettings->width; params.height = pDisplaySettings->height; params.pWindowTitle = gInitParams.pAppTitle; params.monitor = pDisplaySettings->monitor; params.bFullscreen = pDisplaySettings->bFullscreen; params.flags = MFWF_WindowFrame | ((pDisplaySettings->flags & MFDF_CanResizeWindow) ? MFWF_CanResize : 0); pWindow = MFWindow_Create(¶ms); if(!pWindow) { MFDebug_Warn(1, "Couldn't create default Fuji window!"); return NULL; } bDidCreateWindow = true; } MFDisplay *pDisplay = (MFDisplay*)MFHeap_Alloc(sizeof(MFDisplay)); pDisplay->settings = *pDisplaySettings; pDisplay->settings.pWindow = pWindow; pDisplay->fullscreenWidth = pDisplay->windowWidth = pDisplay->settings.width; pDisplay->fullscreenHeight = pDisplay->windowHeight = pDisplay->settings.height; pDisplay->aspectRatio = (float)pDisplay->settings.width / (float)pDisplay->settings.height; pDisplay->bHasFocus = pWindow->bHasFocus; pDisplay->bIsVisible = true; pDisplay->orientation = MFDO_Normal; if(MFRenderer_CreateDisplay(pDisplay)) { MFDebug_Warn(2, "Couldn't create display!"); MFHeap_Free(pDisplay); if(bDidCreateWindow) MFWindow_Destroy(pWindow); return NULL; } MFWindow_AssociateDisplay(pWindow, pDisplay); /* if(!gDisplay.windowed && numModes > 1) { if(!XF86VidModeSwitchToMode(xdisplay, screen, vidModes[currentMode])) { MFDebug_Error("Unable to set screen mode"); MFDisplay_DestroyDisplay(); return 1; } XGrabPointer(xdisplay, window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); XFlush(xdisplay); // A little trick to make sure the entire window is on the screen XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, width - 1, height - 1); XWarpPointer(xdisplay, None, window, 0, 0, 0, 0, 0, 0); XFlush(xdisplay); } */ return pDisplay; }
int MFDisplay_CreateDisplay(int width, int height, int bpp, int rate, bool vsync, bool triplebuffer, bool wide, bool progressive) { MFCALLSTACK; DWORD avPack = XGetAVPack(); DWORD vidMode = XGetVideoStandard(); DWORD vidFlags = XGetVideoFlags(); // log the AV pack (just an FYI) switch(avPack) { case XC_AV_PACK_SCART: MFDebug_Log(2, "MFDisplay: Video output using Scart AV Pack"); break; case XC_AV_PACK_HDTV: MFDebug_Log(2, "MFDisplay: Video output using High Def Pack"); break; case XC_AV_PACK_RFU: MFDebug_Log(2, "MFDisplay: Video output using RF Unit"); break; case XC_AV_PACK_SVIDEO: MFDebug_Log(2, "MFDisplay: Video output using Advanced AV Pack"); break; case XC_AV_PACK_STANDARD: MFDebug_Log(2, "MFDisplay: Video output using Standard AV Pack"); break; default: MFDebug_Log(2, "MFDisplay: Video output using Unknown AV Pack"); break; } // calculate the frame buffer size and display mode from the dashboard info gbWidescreen = !!(vidFlags & (XC_VIDEO_FLAGS_WIDESCREEN)); gbLetterBox = !!(vidFlags & (XC_VIDEO_FLAGS_LETTERBOX)); wide = gbWidescreen; if(vidMode == XC_VIDEO_STANDARD_PAL_I) { // PAL modes (poor PAL users dont get high def) :( if(vidFlags & XC_VIDEO_FLAGS_PAL_60Hz) { width = 720; height = 480; rate = 60; progressive = false; MFDebug_Log(2, MFStr("MFDisplay: Video Mode set to PAL60%s", wide ? " (Widescreen)" : (gbLetterBox ? " (Letterbox)" : ""))); } else { width = 720; height = 576; rate = 50; progressive = false; MFDebug_Log(2, MFStr("MFDisplay: Video Mode set to PAL (576i)%s", wide ? " (Widescreen)" : (gbLetterBox ? " (Letterbox)" : ""))); } } else { // NTSC modes if(vidFlags & XC_VIDEO_FLAGS_HDTV_1080i) { width = 1920; height = 1080; rate = 60; progressive = false; MFDebug_Log(2, "MFDisplay: Video Mode set to 1080i"); } else if(vidFlags & XC_VIDEO_FLAGS_HDTV_720p) { width = 1280; height = 720; rate = 60; progressive = true; MFDebug_Log(2, "MFDisplay: Video Mode set to 720p"); } else if(vidFlags & XC_VIDEO_FLAGS_HDTV_480p) { width = 720; height = 480; rate = 60; progressive = true; MFDebug_Log(2, MFStr("MFDisplay: Video Mode set to 480p%s", wide ? " (Widescreen)" : (gbLetterBox ? " (Letterbox)" : ""))); } else { width = 720; height = 480; rate = 60; progressive = false; MFDebug_Log(2, MFStr("MFDisplay: Video Mode set to NTSC (480i)%s", wide ? " (Widescreen)" : (gbLetterBox ? " (Letterbox)" : ""))); } } // update display parameters gDisplay.fullscreenWidth = gDisplay.width = width; gDisplay.fullscreenHeight = gDisplay.height = height; gDisplay.progressive = progressive; gDisplay.refreshRate = rate; gDisplay.wide = wide; gDisplay.colourDepth = bpp; gDisplay.windowed = false; MFRenderer_CreateDisplay(); // setup the initial viewport (letterbox) MFRenderer_ResetViewport(); return 0; }