void MapWindow::Initialize() { #ifndef ENABLE_OPENGL ScopeLock Lock(Surface_Mutex); #endif // Reset common topology and waypoint label declutter, first init. Done also in other places. ResetLabelDeclutter(); // Default draw area is full screen, no opacity MapRect = MainWindow.GetClientRect(); DrawRect = MapRect; UpdateActiveScreenZone(MapRect); UpdateTimeStats(true); #ifndef ENABLE_OPENGL // paint draw window black to start DrawSurface.SetBackgroundTransparent(); DrawSurface.Blackness(MapRect.left, MapRect.top,MapRect.right-MapRect.left, MapRect.bottom-MapRect.top); hdcMask.SetBackgroundOpaque(); BackBufferSurface.Blackness(MapRect.left, MapRect.top,MapRect.right-MapRect.left, MapRect.bottom-MapRect.top); #endif // This is just here to give fully rendered start screen UpdateInfo(&GPS_INFO, &CALCULATED_INFO); MapDirty = true; FillScaleListForEngineeringUnits(); zoom.RequestedScale(zoom.Scale()); zoom.ModifyMapScale(); LKUnloadFixedBitmaps(); LKUnloadProfileBitmaps(); LKLoadFixedBitmaps(); LKLoadProfileBitmaps(); // This will reset the function for the new ScreenScale PolygonRotateShift((POINT*)NULL,0,0,0,DisplayAngle+1); // Restart from moving map if (MapSpaceMode!=MSM_WELCOME) SetModeType(LKMODE_MAP, MP_MOVING); // These should be better checked. first_run is forcing also cache update for topo. ForceRenderMap=true; first_run=true; // Signal that draw thread can run now Initialised = TRUE; #ifndef ENABLE_OPENGL drawTriggerEvent.set(); #endif }
// // FUNCTION: InitInstance() // // PURPOSE: creates main window // // COMMENTS: // // In this function, we create and display the main program window. // BOOL InitInstance() { extern bool CommandResolution; if(!IsEmbedded() && !CommandResolution) { ScreenSizeX = 800; ScreenSizeY = 480; } #if defined(ENABLE_SDL) && defined(USE_FULLSCREEN) #if (SDL_MAJOR_VERSION >= 2) SDL_DisplayMode mode = {}; if(SDL_GetCurrentDisplayMode(0, &mode) == 0) { ScreenSizeX = mode.w; ScreenSizeY = mode.h; } else { fprintf(stderr, "SDL_GetCurrentDisplayMode() has failed: %s\n", ::SDL_GetError()); } #else ScreenSizeX = 0; ScreenSizeY = 0; #endif #endif PreloadInitialisation(true); RECT WindowSize; #ifdef __linux__ WindowSize=WindowResize(ScreenSizeX, ScreenSizeY); #endif #ifdef WIN32 #ifdef UNDER_CE WindowSize=WindowResize( GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); #else WindowSize=WindowResize(ScreenSizeX, ScreenSizeY); #endif #endif if (!goInstallSystem) Poco::Thread::sleep(50); // 091119 #if TESTBENCH StartupStore(TEXT(". Create main window%s"),NEWLINE); #endif if(!MainWindow.Create(WindowSize)) { StartupStore(TEXT(". FAILURE: Create main window%s"),NEWLINE); return FALSE; } const PixelRect rc(MainWindow.GetClientRect()); ScreenSizeX = rc.GetSize().cx; ScreenSizeY = rc.GetSize().cy; InitLKScreen(); InitLKFonts(); // causing problems with CreateButtonLabels? LKLoadFixedBitmaps(); LKLoadProfileBitmaps(); LKObjects_Create(); ButtonLabel::CreateButtonLabels(rc); ButtonLabel::SetLabelText(0,TEXT("MODE")); extern void InitLKFonts(); // reload updating LK fonts after loading profile for fontquality InitLKFonts(); ButtonLabel::SetFont(MapWindowBoldFont); Message::Initialize(rc); // creates window, sets fonts MainWindow.SetVisible(true); return TRUE; }
DWORD MapWindow::DrawThread (LPVOID lpvoid) { FILETIME CreationTime, ExitTime, StartKernelTime, EndKernelTime, StartUserTime, EndUserTime ; while ((!ProgramStarted) || (!Initialised)) { Sleep(100); } #if TRACETHREAD StartupStore(_T("############## DRAW threadid=%d\n"),GetCurrentThreadId()); #endif // THREADRUNNING = FALSE; THREADEXIT = FALSE; // Reset common topology and waypoint label declutter, first init. Done also in other places. ResetLabelDeclutter(); GetClientRect(hWndMapWindow, &MapRect); // Default draw area is full screen, no opacity DrawRect=MapRect; UpdateTimeStats(true); SetBkMode(hdcDrawWindow,TRANSPARENT); SetBkMode(hDCTemp,OPAQUE); SetBkMode(hDCMask,OPAQUE); // paint draw window black to start SelectObject(hdcDrawWindow, GetStockObject(BLACK_PEN)); Rectangle(hdcDrawWindow,MapRect.left,MapRect.top, MapRect.right,MapRect.bottom); BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left, MapRect.bottom-MapRect.top, hdcDrawWindow, 0, 0, SRCCOPY); // This is just here to give fully rendered start screen UpdateInfo(&GPS_INFO, &CALCULATED_INFO); MapDirty = true; UpdateTimeStats(true); zoom.RequestedScale(zoom.Scale()); zoom.ModifyMapScale(); FillScaleListForEngineeringUnits(); bool lastdrawwasbitblitted=false; bool first_run=true; // // Big LOOP // while (!CLOSETHREAD) { WaitForSingleObject(drawTriggerEvent, 5000); ResetEvent(drawTriggerEvent); if (CLOSETHREAD) break; // drop out without drawing if ((!THREADRUNNING) || (!GlobalRunning)) { Sleep(100); continue; } // This is also occuring on resolution change if (LKSW_ReloadProfileBitmaps) { #if TESTBENCH StartupStore(_T(".... SWITCH: ReloadProfileBitmaps detected\n")); #endif // This is needed to update resolution change GetClientRect(hWndMapWindow, &MapRect); DrawRect=MapRect; FillScaleListForEngineeringUnits(); LKUnloadProfileBitmaps(); LKLoadProfileBitmaps(); LKUnloadFixedBitmaps(); LKLoadFixedBitmaps(); MapWindow::zoom.Reset(); // This will reset the function for the new ScreenScale PolygonRotateShift((POINT*)NULL,0,0,0,DisplayAngle+1); // Restart from moving map if (MapSpaceMode!=MSM_WELCOME) SetModeType(LKMODE_MAP, MP_MOVING); LKSW_ReloadProfileBitmaps=false; // These should be better checked. first_run is forcing also cache update for topo. ForceRenderMap=true; first_run=true; } GetThreadTimes( hDrawThread, &CreationTime, &ExitTime,&StartKernelTime,&StartUserTime); // Until MapDirty is set true again, we shall only repaint the screen. No Render, no calculations, no updates. // This is intended for very fast immediate screen refresh. // // MapDirty is set true by: // - TriggerRedraws() in calculations thread // - RefreshMap() in drawthread generally // extern int XstartScreen, YstartScreen, XtargetScreen, YtargetScreen; extern bool OnFastPanning; // While we are moving in bitblt mode, ignore RefreshMap requests from LK // unless a timeout was triggered by MapWndProc itself. if (OnFastPanning) { MapDirty=false; } // We must check if we are on FastPanning, because we may be in pan mode even while // the menu buttons are active and we are using them, accessing other functions. // In that case, without checking OnFastPanning, we would fall back here and repaint // with bitblt everytime, while instead we were asked a simple fastrefresh! // // Notice: we could be !MapDirty without OnFastPanning, of course! // if (!MapDirty && !ForceRenderMap && OnFastPanning && !first_run) { if (!mode.Is(Mode::MODE_TARGET_PAN) && mode.Is(Mode::MODE_PAN)) { int fromX=0, fromY=0; fromX=XstartScreen-XtargetScreen; fromY=YstartScreen-YtargetScreen; BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left, MapRect.bottom-MapRect.top, hdcDrawWindow, 0, 0, WHITENESS); BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left, MapRect.bottom-MapRect.top, hdcDrawWindow, fromX,fromY, // source SRCCOPY); POINT centerscreen; centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2; DrawMapScale(hdcScreen,MapRect,false); DrawCrossHairs(hdcScreen, centerscreen, MapRect); lastdrawwasbitblitted=true; } else { // THIS IS NOT GOING TO HAPPEN! // // The map was not dirty, and we are not in fastpanning mode. // FastRefresh! We simply redraw old bitmap. // BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left, MapRect.bottom-MapRect.top, hdcDrawWindow, 0, 0, SRCCOPY); lastdrawwasbitblitted=true; } // Now we can clear the flag. If it was off already, no problems. OnFastPanning=false; continue; } else { // // Else the map wasy dirty, and we must render it.. // Notice: if we were fastpanning, than the map could not be dirty. // #if 1 // --------------------- EXPERIMENTAL, CHECK ZOOM IS WORKING IN PNA static double lasthere=0; // Only for special case: PAN mode, map not dirty (including requests for zooms!) // not in the ForceRenderMap run and last time was a real rendering. THEN, at these conditions, // we simply redraw old bitmap, for the scope of accelerating touch response. // In fact, if we are panning the map while rendering, there would be an annoying delay. // This is using lastdrawwasbitblitted if (INPAN && !MapDirty && !lastdrawwasbitblitted && !ForceRenderMap && !first_run) { // In any case, after 5 seconds redraw all if ( (LKHearthBeats-8) >lasthere ) { lasthere=LKHearthBeats; goto _dontbitblt; } BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left, MapRect.bottom-MapRect.top, hdcDrawWindow, 0, 0, SRCCOPY); POINT centerscreen; centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2; DrawMapScale(hdcScreen,MapRect,false); DrawCrossHairs(hdcScreen, centerscreen, MapRect); continue; } #endif // -------------------------- _dontbitblt: MapDirty = false; PanRefreshed=true; } // MapDirty lastdrawwasbitblitted=false; MapWindow::UpdateInfo(&GPS_INFO, &CALCULATED_INFO); RenderMapWindow(MapRect); if (!ForceRenderMap && !first_run) { BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left, MapRect.bottom-MapRect.top, hdcDrawWindow, 0, 0, SRCCOPY); InvalidateRect(hWndMapWindow, &MapRect, false); } // Draw cross sight for pan mode, in the screen center, // after a full repaint while not fastpanning if (mode.AnyPan() && !mode.Is(Mode::MODE_TARGET_PAN) && !OnFastPanning) { POINT centerscreen; centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2; DrawMapScale(hdcScreen,MapRect,false); DrawCompass(hdcScreen, MapRect, DisplayAngle); DrawCrossHairs(hdcScreen, centerscreen, MapRect); } UpdateTimeStats(false); // we do caching after screen update, to minimise perceived delay // UpdateCaches is updating topology bounds when either forced (only here) // or because MapWindow::ForceVisibilityScan is set true. UpdateCaches(first_run); first_run=false; ForceRenderMap = false; if (ProgramStarted==psInitDone) { ProgramStarted = psFirstDrawDone; } if ( (GetThreadTimes( hDrawThread, &CreationTime, &ExitTime,&EndKernelTime,&EndUserTime)) == 0) { Cpu_Draw=9999; } else { Cpustats(&Cpu_Draw,&StartKernelTime, &EndKernelTime, &StartUserTime, &EndUserTime); } } // Big LOOP #if TESTBENCH StartupStore(_T("... Thread_Draw terminated\n")); #endif THREADEXIT = TRUE; return 0; }
// // FUNCTION: InitInstance() // // PURPOSE: creates main window // // COMMENTS: // // In this function, we create and display the main program window. // BOOL InitInstance() { extern bool CommandResolution; if(!IsEmbedded() && !CommandResolution) { ScreenSizeX = 800; ScreenSizeY = 480; } #if defined(ENABLE_SDL) && defined(USE_FULLSCREEN) #if (SDL_MAJOR_VERSION >= 2) SDL_DisplayMode mode = {}; if(SDL_GetCurrentDisplayMode(0, &mode) == 0) { ScreenSizeX = mode.w; ScreenSizeY = mode.h; } else { fprintf(stderr, "SDL_GetCurrentDisplayMode() has failed: %s\n", ::SDL_GetError()); } #else ScreenSizeX = 0; ScreenSizeY = 0; #endif #endif PreloadInitialisation(true); RECT WindowSize; #ifdef __linux__ #ifdef USE_VIDEOCORE uint32_t iWidth, iHeight; if(graphics_get_display_size(0, &iWidth, &iHeight) >= 0) { ScreenSizeX=iWidth; ScreenSizeY=iHeight; } #endif #ifdef ANDROID const PixelSize Size = native_view->GetSize(); ScreenSizeX=Size.cx; ScreenSizeY=Size.cy; #endif WindowSize=WindowResize(ScreenSizeX, ScreenSizeY); #endif #ifdef WIN32 #if defined(UNDER_CE) || defined(USE_FULLSCREEN) WindowSize=WindowResize( GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); #else WindowSize=WindowResize(ScreenSizeX, ScreenSizeY); #endif #endif #if TESTBENCH StartupStore(TEXT(". Create main window%s"),NEWLINE); #endif if(!MainWindow.Create(WindowSize)) { StartupStore(TEXT(". FAILURE: Create main window%s"),NEWLINE); return FALSE; } const PixelRect rc(MainWindow.GetClientRect()); ScreenSizeX = rc.GetSize().cx; ScreenSizeY = rc.GetSize().cy; ScreenHasChanged(); InitLKScreen(); InitLKFonts(); // causing problems with CreateButtonLabels? LKLoadFixedBitmaps(); LKLoadProfileBitmaps(); LKObjects_Create(); ButtonLabel::CreateButtonLabels(rc); ButtonLabel::SetFont(MapWindowBoldFont); Message::Initialize(rc); // creates window, sets fonts MainWindow.SetVisible(true); return TRUE; }
// // FUNCTION: InitInstance(HANDLE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // The window class name RECT rc; hInst = hInstance; // Store instance handle in our global variable LoadString(hInstance, IDC_LK8000, szWindowClass, MAX_LOADSTRING); LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); // If it is already running, then focus on the window // problem was that if two instances are started within a few seconds, both will survive! // We enforceed this with mutex at the beginning of WinMain hWndMainWindow = FindWindow(szWindowClass, szTitle); if (hWndMainWindow) { SetForegroundWindow((HWND)((ULONG) hWndMainWindow | 0x00000001)); return 0; } InitLKScreen(); InitLKFonts(); // causing problems with CreateButtonLabels? PreloadInitialisation(true); MyRegisterClass(hInst, szWindowClass); RECT WindowSize; WindowSize.left = 0; WindowSize.top = 0; WindowSize.right = GetSystemMetrics(SM_CXSCREEN); WindowSize.bottom = GetSystemMetrics(SM_CYSCREEN); #if (WINDOWSPC>0) WindowSize.right = SCREENWIDTH + 2*GetSystemMetrics( SM_CXFIXEDFRAME); WindowSize.left = (GetSystemMetrics(SM_CXSCREEN) - WindowSize.right) / 2; WindowSize.bottom = SCREENHEIGHT + 2*GetSystemMetrics( SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION); WindowSize.top = (GetSystemMetrics(SM_CYSCREEN) - WindowSize.bottom) / 2; /* // // Custom setup for positioning the window , ready to be used // WindowSize.top=768; // top and left corner coords WindowSize.left=1024; WindowSize.right = SCREENWIDTH + 2*GetSystemMetrics( SM_CXFIXEDFRAME); WindowSize.bottom = SCREENHEIGHT + 2*GetSystemMetrics( SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION); */ #endif if (!goInstallSystem) Sleep(50); // 091119 #if TESTBENCH StartupStore(TEXT(". Create main window%s"),NEWLINE); #endif hWndMainWindow = CreateWindow(szWindowClass, szTitle, WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WindowSize.left, WindowSize.top, WindowSize.right, WindowSize.bottom, NULL, NULL, hInstance, NULL); if (!hWndMainWindow) { return FALSE; } hBrushSelected = (HBRUSH)CreateSolidBrush(ColorSelected); hBrushUnselected = (HBRUSH)CreateSolidBrush(ColorUnselected); hBrushButton = (HBRUSH)CreateSolidBrush(ColorButton); #ifdef LXMINIMAP hBrushButtonHasFocus = (HBRUSH)CreateSolidBrush(ColorButtonHasFocus); #endif GetClientRect(hWndMainWindow, &rc); #if (WINDOWSPC>0) rc.left = 0; rc.right = SCREENWIDTH; rc.top = 0; rc.bottom = SCREENHEIGHT; #endif LKLoadFixedBitmaps(); LKLoadProfileBitmaps(); LKObjects_Create(); ButtonLabel::CreateButtonLabels(rc); ButtonLabel::SetLabelText(0,TEXT("MODE")); extern void InitialiseFonts(RECT rc); InitialiseFonts(rc); InitLKFonts(); // reload updating LK fonts after loading profile for fontquality ButtonLabel::SetFont(MapWindowBoldFont); Message::Initialize(rc); // creates window, sets fonts ShowWindow(hWndMainWindow, SW_SHOW); #if TESTBENCH StartupStore(TEXT(". Create map window%s"),NEWLINE); #endif hWndMapWindow = CreateWindow(TEXT("MapWindowClass"),NULL, WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, (rc.right - rc.left), (rc.bottom-rc.top) , hWndMainWindow, NULL ,hInstance,NULL); ShowWindow(hWndMainWindow, nCmdShow); UpdateWindow(hWndMainWindow); // Since MapWndProc is doing static inits, we want them to be recalculated at the end of // initializations, since some values in use might have been not available yet, for example BottomSize. Reset_Single_DoInits(MDI_MAPWNDPROC); return TRUE; }