home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
-
- #include "stdafx.h"
- #include "gridedge.h"
- #include "netsvw.h"
- #include "template.h"
-
- #define VIEW_SOURCE_TARGET_WINDOW_NAME "%ViewSourceWindow" /* from ns/lib/libnet/cvcolor.c */
-
- MWContext *FE_MakeGridWindow(MWContext *pOldContext, void *hist_list, void *pHistory,
- int32 lX, int32 lY,
- int32 lWidth, int32 lHeight, char *pUrlStr, char *pWindowName, int8 iScrollType,
- NET_ReloadMethod eReloadThis, Bool no_edge) {
-
- // First, ensure that the context we're going into is of an appropriate type.
- if(pOldContext == NULL || ABSTRACTCX(pOldContext)->IsFrameContext() == FALSE) {
- // Only let this happen to window contexts for now.
- return(NULL);
- }
- else {
- // The goal here is to create a new, fabulous, grid that is a child of the
- // other window context's frame.
- CWinCX *pParentCX = VOID2CX(pOldContext->fe.cx, CWinCX);
-
- // Safety dance.
- if(pParentCX->GetPane() == NULL) {
- return(NULL);
- }
-
- HWND hParentWnd = pParentCX->GetPane();
-
- // Bring up a create context, so that the Create call won't complain on
- // 16 bit windows.
- // Since we create the context here, and the document, along with the view,
- // the view takes care of destroying the docuemnt on close, so we don't
- // need to worry about it.
- CCreateContext cccGrid;
- cccGrid.m_pNewViewClass = RUNTIME_CLASS(CNetscapeView);
- cccGrid.m_pCurrentDoc = new CGenericDoc();
-
- // Create the view.
- DWORD dwGridStyle = WS_HSCROLL | WS_VSCROLL;
- CNetscapeView *pNewView = new CNetscapeView();
- pNewView->Create(NULL,
- pWindowName,
- dwGridStyle,
- CRect(0, 0, 1, 1),
- CWnd::FromHandle(hParentWnd),
- 0,
- &cccGrid);
-
- CWinCX *pWinCX = new CWinCX((CGenericDoc *)cccGrid.m_pCurrentDoc, pParentCX->GetFrame(), pNewView);
-
- // Set the context's name.
- // Set its parent.
- pWinCX->SetContextName(pWindowName);
- pWinCX->SetParentContext(pOldContext);
-
- RECT rect;
- rect.left = CASTINT(pParentCX->Twips2PixX(lX));
- rect.top = CASTINT(pParentCX->Twips2PixY(lY));
- rect.right = CASTINT(pParentCX->Twips2PixX(lX) + pParentCX->Twips2PixX(lWidth));
- rect.bottom = CASTINT(pParentCX->Twips2PixY(lY) + pParentCX->Twips2PixY(lHeight));
- // Initialize the context.
- pWinCX->Initialize(pWinCX->CDCCX::IsOwnDC(), &rect);
-
- // Tell it wether or not it will have an edge (border in the
- // non client area).
- pWinCX->SetBorder(!no_edge);
-
- // Size the window to final coords.
- // This causes the non client calc to happen which is needed
- // now that it knows it's a grid cell.
- pNewView->MoveWindow(
- CRect(CASTINT(pParentCX->Twips2PixX(lX)),
- CASTINT(pParentCX->Twips2PixY(lY)),
- CASTINT(pParentCX->Twips2PixX(lX) + pParentCX->Twips2PixX(lWidth)),
- CASTINT(pParentCX->Twips2PixY(lY) + pParentCX->Twips2PixY(lHeight))),
- FALSE);
-
- // Decide what we're doing about scroll bars.
- switch(iScrollType) {
- case LO_SCROLL_NO:
- // Shouldn't ever have scrollbars.
- // Get rid of them.
- pWinCX->SetDynamicScrollBars(FALSE);
- pWinCX->ShowScrollBars(SB_BOTH, FALSE);
- pWinCX->SetAlwaysShowScrollBars(FALSE);
- break;
- case LO_SCROLL_AUTO:
- // Aha, the hard case.
- // Set a flag so that when the load is complete in the context, such
- // that we will hide the scroll bars if there is already enough room.
- // This means that the entire document fits on the screen (not much data),
- // and that doing a load from resize at that point will be minimal
- // overhead.
- pWinCX->SetDynamicScrollBars(TRUE);
- pWinCX->SetAlwaysShowScrollBars(FALSE);
- break;
- case LO_SCROLL_YES:
- // Have the scroll bars show.
- pWinCX->SetDynamicScrollBars(FALSE);
- pWinCX->SetAlwaysShowScrollBars(TRUE);
- pWinCX->ShowScrollBars(SB_BOTH, TRUE);
- break;
- default:
- ASSERT(0); // user mush pass in invalid value.
- }
-
- // If we have a history list, we need to stick it in the context.
- History_entry *pHistEnt = (History_entry *)pHistory;
- XP_List *pHistList = (XP_List *)hist_list;
- if(pHistList != NULL) {
- pWinCX->GetContext()->hist.list_ptr = pHistList;
- }
- else {
- // If we have a history entry, we need to add it to the session.
- if(pHistEnt != NULL) {
- SHIST_AddDocument(pWinCX->GetContext(), pHistEnt);
- }
- }
-
- // Have it load the url in question.
- // This could be from the history entry.
- if(pHistEnt == NULL) {
- URL_Struct *pUrl = NET_CreateURLStruct(pUrlStr, NET_DONT_RELOAD);
- pUrl->force_reload = eReloadThis;
-
- // Be sure to add the referrer field of the top level context.
- MWContext *mwRefer = pOldContext;
- while(mwRefer->grid_parent) {
- mwRefer = mwRefer->grid_parent;
- }
- History_entry *he = SHIST_GetCurrent (&mwRefer->hist);
- if(he && he->referer) {
- pUrl->referer = XP_STRDUP(he->referer);
- }
-
- pWinCX->GetUrl(pUrl, FO_CACHE_AND_PRESENT);
- }
- else {
- URL_Struct *pUrl = SHIST_CreateURLStructFromHistoryEntry(pWinCX->GetContext(), pHistEnt);
- pUrl->force_reload = eReloadThis;
- pWinCX->GetUrl(pUrl, FO_CACHE_AND_PRESENT);
- }
-
- // Grid parents have WS_CLIPCHILDREN turned on. This allows them
- // to draw (backgrounds for example) into their windows without
- // worrying about their children.
- CFrameGlue *pGlue = pWinCX->GetFrame();
- if(pGlue) {
- pGlue->ClipChildren(pNewView, TRUE);
- }
-
- // Show the window, but don't activate it.
- pNewView->ShowWindow(SW_SHOWNA);
-
- return(pWinCX->GetContext());
- }
- }
-
- void FE_LoadGridCellFromHistory(MWContext *pContext, void *hist, NET_ReloadMethod netReloadMethod) {
- History_entry *pHist = (History_entry *)hist;
-
- if (pHist != NULL) {
- URL_Struct *pUrl = SHIST_CreateURLStructFromHistoryEntry(pContext, pHist);
- if(pUrl) {
- pUrl->force_reload = netReloadMethod;
- ABSTRACTCX(pContext)->GetUrl(pUrl, FO_CACHE_AND_PRESENT, TRUE);
- }
- }
- }
-
- void *FE_FreeGridWindow(MWContext *pContext, XP_Bool bSaveHistory) {
- ASSERT(ABSTRACTCX(pContext)->IsWindowContext());
-
- void *pRetval = NULL;
-
- // Destroy the view then the doc/it in turn destroys the context.
- // We have to clean up the doc, since we passed it in....
- CWinCX *pWinCX = VOID2CX(pContext->fe.cx, CWinCX);
- CWinCX *pParentCX = WINCX(pWinCX->GetParentContext());
-
- // We may want to return the history entry.
- if(bSaveHistory == TRUE) {
- // Reset to top of document
- SHIST_SetPositionOfCurrentDoc(&(pWinCX->GetContext()->hist), 0);
- if(pWinCX->GetOriginX() || pWinCX->GetOriginY()) {
- #ifdef LAYERS
- LO_Any *pAny = (LO_Any *)LO_XYToNearestElement(pWinCX->GetContext(), pWinCX->GetOriginX(), pWinCX->GetOriginY(), NULL);
- #else
- LO_Any *pAny = (LO_Any *)LO_XYToNearestElement(pWinCX->GetContext(), pWinCX->GetOriginX(), pWinCX->GetOriginY());
- #endif
-
- // Save the location of the current document.
- if(pAny != NULL) {
- SHIST_SetPositionOfCurrentDoc(&(pWinCX->GetContext()->hist), pAny->ele_id);
- }
- }
-
- LO_DiscardDocument(pWinCX->GetContext());
- XP_List *hist_list = pWinCX->GetContext()->hist.list_ptr;
- pWinCX->GetContext()->hist.list_ptr = NULL;
-
- pRetval = (void *)hist_list;
- }
-
- CFrameGlue *frame = pWinCX->GetFrame();
-
- // Make sure child grid cell going away doesn't hold onto frame
- // which may also be going down.
- pWinCX->ClearFrame();
-
- ASSERT(pWinCX->GetPane());
- if(pWinCX->GetPane()) {
- CGenericView *pView = pWinCX->GetView();
-
- ASSERT(pView);
- if(pView) {
- // Tell our parent(s) that they don't need to clip children
- // anymore just for our sake.
- if(frame) {
- frame->ClipChildren(pView, FALSE);
- }
- pView->FrameClosing();
- pView->SendMessage(WM_CLOSE);
- }
- }
-
- return(pRetval);
- }
-
- void FE_GetFullWindowSize(MWContext *pContext, int32 *plWidth, int32 *plHeight) {
-
- // Only do this on windows.
- if(ABSTRACTCX(pContext)->IsWindowContext() == TRUE && ABSTRACTCX(pContext)->IsDestroyed() == FALSE) {
- CPaneCX *pWindow = PANECX(pContext);
-
- RECT crDimensions;
-
- // Get the full size of the window.
- ::GetClientRect(pWindow->GetPane(), &crDimensions);
-
- // Convert the dimensions to twips.
- HDC hDC = pWindow->GetContextDC();
- ::DPtoLP(hDC, (POINT *)&crDimensions, 2);
- pWindow->ReleaseContextDC(hDC);
-
- *plWidth = crDimensions.right - crDimensions.left;
- *plHeight = crDimensions.bottom - crDimensions.top;
-
- // Adjust to not include scroll bars.
- if(pWindow->IsVScrollBarOn()) {
- *plWidth += sysInfo.m_iScrollWidth;
- }
- if(pWindow->IsHScrollBarOn()) {
- *plHeight += sysInfo.m_iScrollHeight;
- }
- }
- else {
- // No window here....
- // Set to 1 to avoid divide by zero errors in Back end.
- *plHeight = *plWidth = 1;
- }
- }
-
- void FE_RestructureGridWindow(MWContext *pContext, int32 lX, int32 lY, int32 lWidth, int32 lHeight) {
- TRACE("FE_RestructureGridWindow(%p, %ld, %ld, %ld, %ld)\n", pContext, lX, lY, lWidth, lHeight);
-
- // Safety dance.
- if(pContext == NULL) {
- return;
- }
-
- // We're under the immediate assumption that the context is a window.
- ASSERT(ABSTRACTCX(pContext)->IsWindowContext());
-
- CWinCX *pWinCX = WINCX(pContext);
-
- // We need to move the window.
- // It will automagically redraw itself.
- ::MoveWindow(pWinCX->GetPane(), CASTINT(pWinCX->Twips2PixX(lX)),
- CASTINT(pWinCX->Twips2PixY(lY)),
- CASTINT(pWinCX->Twips2PixX(lWidth)),
- CASTINT(pWinCX->Twips2PixY(lHeight)),
- TRUE);
-
- // Dynamic scroll bars are handled internally, as is resize.
- }
-
- void FE_SetWindowLoading(MWContext *pContext, URL_Struct *pUrl, Net_GetUrlExitFunc **ppExitRoutine) {
-
- // A url load is changing context.
- // Telling the exit routine that we'd like to be called.
- *ppExitRoutine = CFE_GetUrlExitRoutine;
-
- // Now, call the GetUrl routine, but don't really load.
- // This bootstraps the normal loading procedure.
- // DON'T REALLY CARE WHAT WE PASS IN AS THE PRESENTATION TYPE, yet.
- ABSTRACTCX(pContext)->GetUrl(pUrl, FO_CACHE_AND_PRESENT, FALSE);
- }
-
- void FE_GetEdgeMinSize(MWContext *pContext, int32 *pSize, Bool no_edge) {
- TRACE("FE_GetEdgeMinSize(%p, %p)\n", pContext, pSize);
-
- // Don't care anymore.
- *pSize = 5;
-
- if(!no_edge) {
- *pSize = 5;
- }
- }
-
- MWContext *FE_MakeBlankWindow(MWContext *pOldContext, URL_Struct *pUrl, char *pContextName) {
- // TRACE("FE_MakeBlankWindow(%p, %p, %s)\n", pOldContext, pUrl, pContextName);
-
- // Create a new top level blank window.
- // Only don't load anything. Leave it blank.
- // HACK ALERT:
- // In order to better do this, we need to have the CreateNewDocWindow
- // function not load what's in the history. It only does this with
- // other browser windows. Anyhow, switch our context type temporarily
- // in order to get the effect.
- MWContextType OldType = pOldContext->type;
- pOldContext->type = (MWContextType)-1;
- MWContext *pRetval = pOldContext->funcs->CreateNewDocWindow(pOldContext, NULL);
- pOldContext->type = OldType;
-
- if(pRetval != NULL) {
- ABSTRACTCX(pRetval)->SetContextName(pContextName);
- }
-
- return(pRetval);
- }
-
- // Create a new window.
- // If pChrome is NULL, do a FE_MakeBlankWindow....
- // pChrome specifies the attributes of a window.
- // If you use this call, Toolbar information will not be saved in the preferences.
- MWContext *FE_MakeNewWindow(MWContext *pOldContext, URL_Struct *pUrl, char *pContextName, Chrome *pChrome)
- {
-
- BOOL bNetHelpWnd = FALSE;
-
-
- // Decide which type of context this will be (we use this to possible access some templates).
- MWContextType cxType = MWContextAny;
- if(pChrome != NULL) {
- switch(pChrome->type) {
- case MWContextHTMLHelp:
- pChrome->type = MWContextBrowser;
- #ifndef _WIN32
- pChrome->allow_resize = FALSE;
- #endif
- bNetHelpWnd = TRUE;
- // Fall through...
- case MWContextBrowser:
- cxType = MWContextBrowser;
- break;
- case MWContextDialog:
- cxType = MWContextDialog;
- break;
- }
- }
- else {
- // Default to MWContextBrowser;
- cxType = MWContextBrowser;
- }
-
- // A type came in that we're not ready to handle.
- // Seems more code needs to be written....
- ASSERT(cxType != MWContextAny);
- if(cxType == MWContextAny) {
- return(NULL);
- }
-
- // Decide now wether or not to make the window initially visible.
- // We decide by detecting wether or not we'll be enforcing a resize.
- // We'll make the window visible after we're done sizing.
- // Only works with 32 bits right now.
- BOOL bMakeVisible = TRUE;
- if(pChrome && ((pChrome->outw_hint && pChrome->outh_hint) ||
- (pChrome->w_hint && pChrome->h_hint) ||
- pChrome->location_is_chrome ||
- pChrome->topmost || pChrome->bottommost)) {
- bMakeVisible = FALSE;
- }
-
- // Must check if user wants a titlebar now since it affects the type of
- // window used during window creation. If no titlebar, use popup type.
- BOOL bHideTitlebar = FALSE;
- BOOL bBorder = TRUE;
- if (pChrome && pChrome->hide_title_bar){
- bHideTitlebar = TRUE;
- }
-
- BOOL bDependent = FALSE;
- if (pOldContext && pChrome && pChrome->dependent) {
- bDependent = TRUE;
- }
-
- // Take the template of the appropriate window type, and pull it up.
- CAbstractCX *pCX = NULL;
-
- // If there is a parent, get its hwnd
- CWinCX *pOldWinCX = NULL;
- if(pOldContext)
- pOldWinCX = WINCX(pOldContext);
-
- HWND hParentHwnd = NULL;
- if(pOldWinCX && pOldWinCX->GetFrame() && pOldWinCX->GetFrame()->GetFrameWnd())
- hParentHwnd = pOldWinCX->GetFrame()->GetFrameWnd()->GetSafeHwnd();
-
-
- switch(cxType) {
- case MWContextBrowser:
- case MWContextDialog: {
- BOOL bPopup = FALSE;
- HWND hPopupParent = NULL;
-
- // if we are creating a modal window then we need to become a child of
- // the calling frame and of type WS_POPUP. The values below are set to
- // tell the frame to create itself this way.
- if(hParentHwnd && pChrome && pChrome->is_modal)
- {
- bPopup = TRUE;
- hPopupParent = ::GetLastActivePopup(hParentHwnd);
- }
-
- CGenericDoc *pDoc =
- (CGenericDoc *)theApp.m_ViewTmplate->OpenDocumentFile(NULL, bMakeVisible,
- bHideTitlebar, bDependent, bPopup, hPopupParent);
- if(pDoc != NULL) {
- pCX = pDoc->GetContext();
- }
- }
-
-
- break;
- default:
- // Please add your case statement.
- ASSERT(0);
- break;
- }
-
- // If the context wasn't created, we can not continue.
- if(pCX == NULL) {
- return(NULL);
- }
-
- // Hack to identify a NetHelp window
- pCX->m_bNetHelpWnd = bNetHelpWnd;
-
- // JavaScript can create windows which are lifetime-linked to their parent.
- // This is set here instead of in JS to avoid threading problems.
-
- if (bDependent) {
- if (pOldContext->js_dependent_list == NULL)
- pOldContext->js_dependent_list = XP_ListNew();
- if (pOldContext->js_dependent_list == NULL)
- return(NULL);
- XP_ListAddObject(pOldContext->js_dependent_list, pCX->GetContext());
- pCX->GetContext()->js_parent = pOldContext;
- }
-
-
- // Get the context, and manually assign its type.
- // The XP context that is.
- pCX->GetContext()->type = cxType;
-
- // Assign the context name, if provided.
- if(pContextName != NULL) {
- pCX->SetContextName(pContextName);
- }
-
- // Copy over the same char set ID as the old context if we're a window.
- if(pCX->IsFrameContext() == TRUE && pOldContext != NULL) {
- CWinCX *pWinCX = VOID2CX(pCX, CWinCX);
- if(cxType != MWContextDialog && !bNetHelpWnd) {
- pWinCX->GetFrame()->m_iCSID = INTL_DefaultDocCharSetID(pOldContext);
- } else {
- // use the client's default encoding for HTML dialogs (fix for #78838)
- pWinCX->GetFrame()->m_iCSID = INTL_CharSetNameToID(INTL_ResourceCharSet());
- if (pContextName != NULL) {
- if(strncmp(pContextName, VIEW_SOURCE_TARGET_WINDOW_NAME,
- strlen(VIEW_SOURCE_TARGET_WINDOW_NAME)) == 0) {
- // but not for View Source which gets the old context char set ID
- // (fix for #79072)
- pWinCX->GetFrame()->m_iCSID = INTL_DefaultDocCharSetID(pOldContext);
- }
- if(strncmp(pContextName, "%DocInfoWindow", 14) == 0) {
- // %DocInfoWindow is from ns/lib/libnet/mkgeturl.c net_output_about_url()
- // Document Info gets the user-selectable default encoding
- pWinCX->GetFrame()->m_iCSID = INTL_DefaultWinCharSetID(NULL);
- }
- }
- }
- }
-
- #ifdef _WIN32
- if(sysInfo.m_bWin4 && bNetHelpWnd && pCX->IsFrameContext()) {
-
- CWinCX *pWinCX = VOID2CX(pCX, CWinCX);
- CFrameWnd *pFrame = pWinCX->GetFrame()->GetFrameWnd();
-
- if( pFrame ) {
- HICON hIcon = theApp.LoadIcon( "IDR_NETHELP_ICON" );
- pFrame->SetIcon( hIcon, TRUE );
-
- hIcon = (HICON)::LoadImage( AfxFindResourceHandle( "IDR_NETHELP_ICON", RT_GROUP_ICON ), "IDR_NETHELP_ICON", IMAGE_ICON,
- GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), LR_SHARED );
- pFrame->SetIcon( hIcon, FALSE );
- }
- }
- #endif // _WIN32
-
- // Pay special attention to the chrome attributes specified, if specified.
- // If they aren't, attempt to use attributes from the old context passed in.
- if(pChrome != NULL && pCX->IsFrameContext() == TRUE) {
- CWinCX *pWinCX = VOID2CX(pCX, CWinCX);
-
- LPCHROME pIChrome = pWinCX->GetFrame()->GetChrome();
- if(pIChrome) {
- // Url bar and directory buttons.
- // make it so that we don't save toolbar information
- pIChrome->SetSaveToolbarInfo(FALSE);
- pIChrome->ShowToolbar(ID_LOCATION_TOOLBAR, pChrome->show_url_bar);
- pIChrome->ShowToolbar(ID_PERSONAL_TOOLBAR, pChrome->show_directory_buttons);
- pIChrome->ShowToolbar(ID_NAVIGATION_TOOLBAR, pChrome->show_button_bar);
-
- // Status bar!
- LPNSSTATUSBAR pIStatusBar = NULL;
- pIChrome->QueryInterface( IID_INSStatusBar, (LPVOID *) &pIStatusBar );
- if ( pIStatusBar ) {
- pIStatusBar->Show( pChrome->show_bottom_status_bar );
- pIStatusBar->Release();
- }
- }
-
- // Show the menu?
- if(pChrome->show_menu == FALSE) {
- CMenu *pMenu = pWinCX->GetFrame()->GetFrameWnd()->GetMenu();
- HMENU hMenu = pMenu ? pMenu->m_hMenu : NULL;
- pWinCX->GetFrame()->GetFrameWnd()->SetMenu(NULL);
- if( hMenu && (theApp.m_ViewTmplate->m_hMenuShared != hMenu) )
- {
- pMenu->DestroyMenu();
- }
- }
-
- // Need to recalc.
- pWinCX->GetFrame()->GetFrameWnd()->RecalcLayout();
-
- // Size, of all things, of the viewing area only....
- // Doesn't account for menu wrap or unwrap when getting smaller/bigger.
- if((pChrome->outw_hint && pChrome->outh_hint) ||
- (pChrome->w_hint &&pChrome->h_hint) ||
- pChrome->location_is_chrome ||
- pChrome->topmost || pChrome->bottommost) {
-
- int32 lLeft=0;
- int32 lTop=0;
- int32 lWidth=0;
- int32 lHeight=0;
-
- CRect crFrame;
- pWinCX->GetFrame()->GetFrameWnd()->GetWindowRect(crFrame);
- CRect crView;
- ::GetWindowRect(pWinCX->GetPane(), crView);
-
- // Acount for the view border style.
- crView.InflateRect(-1 * sysInfo.m_iBorderWidth, -1 * sysInfo.m_iBorderHeight);
-
- int32 lWAdjust = pChrome->w_hint - (int32)crView.Width();
- int32 lHAdjust = pChrome->h_hint - (int32)crView.Height();
-
- if (pChrome->outw_hint>0 && pChrome->outh_hint>0) {
- lWidth = pChrome->outw_hint;
- lHeight = pChrome->outh_hint;
- }
- else if (pChrome->w_hint>0 && pChrome->h_hint>0) {
- lWidth = (int32)crFrame.Width() + lWAdjust;
- lHeight = (int32)crFrame.Height() + lHAdjust;
- }
- else {
- lWidth = (int32)crFrame.Width();
- lHeight = (int32)crFrame.Height();
- }
-
- if (pChrome->location_is_chrome) {
- lLeft = pChrome->l_hint;
- lTop = pChrome->t_hint;
- }
- else {
- lLeft = (int32)crFrame.left;
- lTop = (int32)crFrame.top;
- }
-
- //There is a security problem where the window size buffer can be
- //overridden on Win95. Using arbitrary max window size of 10000
- lWidth = lWidth > 10000 ? 10000 : lWidth;
- lHeight = lHeight > 10000 ? 10000 : lHeight;
-
- if (pChrome->topmost)
- pWinCX->GetFrame()->GetFrameWnd()->SetWindowPos(&CWnd::wndTopMost, CASTINT(lLeft), CASTINT(lTop), CASTINT(lWidth), CASTINT(lHeight), NULL);
- else if (pChrome->bottommost)
- pWinCX->GetFrame()->GetFrameWnd()->SetWindowPos(&CWnd::wndBottom, CASTINT(lLeft), CASTINT(lTop), CASTINT(lWidth), CASTINT(lHeight), NULL);
- else
- pWinCX->GetFrame()->GetFrameWnd()->MoveWindow(CASTINT(lLeft), CASTINT(lTop), CASTINT(lWidth), CASTINT(lHeight));
-
- // Specific width and height information means that we should not save the sizes when closing down, regardless of context type.
- pWinCX->m_bSizeIsChrome = TRUE;
- }
-
- // Set windows always on bottom.
- pWinCX->SetZOrder(pChrome->z_lock, pChrome->bottommost);
-
- // Modality.
- if(pChrome->is_modal) {
- // Inform the context of its special status.
- pWinCX->GoModal(pOldContext);
- }
-
- // Scroll bars.
- if(pChrome->show_scrollbar == FALSE) {
- // Turn them off.
- pWinCX->SetDynamicScrollBars(FALSE);
- pWinCX->ShowScrollBars(SB_BOTH, FALSE);
- pWinCX->SetAlwaysShowScrollBars(FALSE);
- }
-
- // Resize.
- if(pChrome->allow_resize == FALSE) {
- // Disable resize....
- // This is a truly gross and unholy option.
- pWinCX->EnableResize(FALSE);
- }
-
- // Hotkeys
- if (pChrome->disable_commands) {
- // Disable hotkeys
-
- pWinCX->DisableHotkeys(TRUE);
- }
-
- // Close.
- if(pChrome->allow_close == FALSE) {
- // Disable closing....
- // This is a truly gross and unholy option.
- // This is reenabled in FE_DestroyContext regardless (i.e.
- // can't be closed unless someone calls that API).
- pWinCX->EnableClose(FALSE);
- }
-
- // Don't allow restricted target windows to be targeted
- // by mail links and other functions which just grab
- // the nearest Browser context.
- if(pChrome->restricted_target)
- pCX->GetContext()->restricted_target = TRUE;
-
- // Close callback.
- // Callback when the context is destroyed.
- pWinCX->CloseCallback(pChrome->close_callback, pChrome->close_arg);
-
- // History copy.
- if(pChrome->copy_history && pOldContext != NULL) {
- // Copy the old context's history.
- SHIST_CopySession(pWinCX->GetContext(), pOldContext);
- }
- }
- else if(cxType == MWContextBrowser && pCX->IsFrameContext() == TRUE) {
- CWinCX *pWinCX = VOID2CX(pCX, CWinCX);
-
- // See if the calling context is a window context, and if so, emulate its
- // settings.
- // Otherwise, just take what we have up....
- if(pOldContext != NULL && pOldContext->type == MWContextBrowser) {
- CWinCX *pOldCX = WINCX(pOldContext);
-
- LPCHROME pIChrome = pWinCX->GetFrame()->GetChrome();
- if(pIChrome) {
- // Directory buttons, location box and all
- // make it so that we don't save toolbar information
- pIChrome->SetSaveToolbarInfo(FALSE);
- pIChrome->SetToolbarStyle( theApp.m_pToolbarStyle );
-
- pIChrome->ShowToolbar( ID_LOCATION_TOOLBAR, pOldCX->GetFrame()->m_bLocationBar );
- pIChrome->ShowToolbar(ID_PERSONAL_TOOLBAR, pOldCX->GetFrame()->m_bStarter);
- pIChrome->ShowToolbar(ID_NAVIGATION_TOOLBAR, pOldCX->GetFrame()->m_bShowToolbar);
- }
- }
- }
-
- // If a URL struct was passed in, load it as the last thing to do.
- if(pUrl != NULL) {
- int iFormatOut = FO_CACHE_AND_PRESENT;
- switch(cxType) {
- case MWContextBrowser:
- case MWContextDialog:
- iFormatOut = FO_CACHE_AND_PRESENT;
- break;
- default:
- // May be a different format out depending on context type.
- // Please set as appropriate!
- ASSERT(0);
- break;
- }
- pCX->GetUrl(pUrl, iFormatOut);
- }
-
- // If we hid the window earlier due to sizing information, time to make it come back.
- if(pCX->IsFrameContext() == TRUE && !bMakeVisible) {
- VOID2CX(pCX, CWinCX)->GetFrame()->GetFrameWnd()->ShowWindow(SW_SHOW);
- }
-
- // Return the XP context.
- return(pCX->GetContext());
- }
-
- // Update current chrome in a context.
- void FE_UpdateChrome(MWContext *pContext, Chrome *pChrome)
- {
- TRACE("FE_UpdateChrome(%p, %p)\n", pContext, pChrome);
-
- // API fulfillments.
- if(!pContext || !pChrome || !ABSTRACTCX(pContext) || !ABSTRACTCX(pContext)->IsFrameContext()) {
- return;
- }
-
- CWinCX *pWinCX = WINCX(pContext);
- if(!pWinCX->GetPane() || !pWinCX->GetFrame() || !pWinCX->GetFrame()->GetFrameWnd()) {
- // Context isn't anatomically correct.
- return;
- }
-
- LPCHROME pIChrome = pWinCX->GetFrame()->GetChrome();
- if(pIChrome) {
- // Url bar and directory buttons.
- pIChrome->SetSaveToolbarInfo(FALSE);
- pIChrome->ShowToolbar(ID_LOCATION_TOOLBAR, pChrome->show_url_bar );
- pIChrome->ShowToolbar(ID_PERSONAL_TOOLBAR, pChrome->show_directory_buttons );
- pIChrome->ShowToolbar(ID_NAVIGATION_TOOLBAR, pChrome->show_button_bar);
-
- // Status bar!
- LPNSSTATUSBAR pIStatusBar = NULL;
- pIChrome->QueryInterface( IID_INSStatusBar, (LPVOID *) &pIStatusBar );
- if ( pIStatusBar ) {
- pIStatusBar->Show( pChrome->show_bottom_status_bar );
- pIStatusBar->Release();
- }
- }
-
- // Show the menu?
- if(pChrome->show_menu == FALSE) {
- CMenu *pMenu = pWinCX->GetFrame()->GetFrameWnd()->GetMenu();
- HMENU hMenu = pMenu ? pMenu->m_hMenu : NULL;
- pWinCX->GetFrame()->GetFrameWnd()->SetMenu(NULL);
- if( hMenu && (theApp.m_ViewTmplate->m_hMenuShared != hMenu) )
- {
- pMenu->DestroyMenu();
- }
- }
- else {
- // Get the menu back out of the template.
- CMenu *pMenu = pWinCX->GetFrame()->GetFrameWnd()->GetMenu();
- HMENU hMenu = pMenu ? pMenu->m_hMenu : NULL;
- ::SetMenu(pWinCX->GetFrame()->GetFrameWnd()->GetSafeHwnd(), theApp.m_ViewTmplate->m_hMenuShared);
- if( hMenu && (theApp.m_ViewTmplate->m_hMenuShared != hMenu) )
- {
- pMenu->DestroyMenu();
- }
- }
-
- // Need to recalc.
- pWinCX->GetFrame()->GetFrameWnd()->RecalcLayout();
-
- // Size, of all things, of the viewing area only....
- // Doesn't account for menu wrap or unwrap when getting smaller/bigger.
- if((pChrome->outw_hint && pChrome->outh_hint) ||
- (pChrome->w_hint &&pChrome->h_hint) ||
- pChrome->location_is_chrome ||
- pChrome->topmost || pChrome->bottommost) {
-
- int32 lLeft=0;
- int32 lTop=0;
- int32 lWidth=0;
- int32 lHeight=0;
-
- CRect crFrame;
- pWinCX->GetFrame()->GetFrameWnd()->GetWindowRect(crFrame);
- CRect crView;
- ::GetWindowRect(pWinCX->GetPane(), crView);
-
- // Acount for the view border style.
- crView.InflateRect(-1 * sysInfo.m_iBorderWidth, -1 * sysInfo.m_iBorderHeight);
-
- int32 lWAdjust = pChrome->w_hint - (int32)crView.Width();
- int32 lHAdjust = pChrome->h_hint - (int32)crView.Height();
-
- if (pChrome->outw_hint>0 && pChrome->outh_hint>0) {
- lWidth = pChrome->outw_hint;
- lHeight = pChrome->outh_hint;
- }
- else if (pChrome->w_hint>0 && pChrome->h_hint>0) {
- lWidth = (int32)crFrame.Width() + lWAdjust;
- lHeight = (int32)crFrame.Height() + lHAdjust;
- }
- else {
- lWidth = (int32)crFrame.Width();
- lHeight = (int32)crFrame.Height();
- }
-
- if (pChrome->location_is_chrome) {
- lLeft = pChrome->l_hint;
- lTop = pChrome->t_hint;
- }
- else {
- lLeft = (int32)crFrame.left;
- lTop = (int32)crFrame.top;
- }
-
- //There is a security problem where the window size buffer can be
- //overridden on Win95. Using arbitrary max window size of 10000
- lWidth = lWidth > 10000 ? 10000 : lWidth;
- lHeight = lHeight > 10000 ? 10000 : lHeight;
-
- if (pChrome->topmost)
- pWinCX->GetFrame()->GetFrameWnd()->SetWindowPos(&CWnd::wndTopMost, CASTINT(lLeft), CASTINT(lTop), CASTINT(lWidth), CASTINT(lHeight), NULL);
- else if (pChrome->bottommost)
- pWinCX->GetFrame()->GetFrameWnd()->SetWindowPos(&CWnd::wndBottom, CASTINT(lLeft), CASTINT(lTop), CASTINT(lWidth), CASTINT(lHeight), NULL);
- else
- pWinCX->GetFrame()->GetFrameWnd()->MoveWindow(CASTINT(lLeft), CASTINT(lTop), CASTINT(lWidth), CASTINT(lHeight));
-
- // Specific width and height information means that we should not save the sizes when closing down, regardless of context type.
- pWinCX->m_bSizeIsChrome = TRUE;
- }
-
- // Set windows always on bottom.
- pWinCX->SetZOrder(pChrome->z_lock, pChrome->bottommost);
-
- // Hotkeys
- pWinCX->DisableHotkeys(pChrome->disable_commands);
-
- // Scroll bars.
- if(pChrome->show_scrollbar == FALSE) {
- // Turn them off.
- pWinCX->SetDynamicScrollBars(FALSE);
- pWinCX->ShowScrollBars(SB_BOTH, FALSE);
- pWinCX->SetAlwaysShowScrollBars(FALSE);
- }
- else {
- pWinCX->SetDynamicScrollBars(TRUE);
- pWinCX->RealizeScrollBars();
- }
-
- // Resize.
- // This is a truly gross and unholy option.
- pWinCX->EnableResize(pChrome->allow_resize);
-
- // Close.
- // This is a truly gross and unholy option.
- // This is reenabled in FE_DestroyContext regardless (i.e.
- // can't be closed unless someone calls that API).
- // This also sets the closing attributes of all child contexts.
- pWinCX->EnableClose(pChrome->allow_close);
-
- // Close callback.
- // Callback when the context is destroyed.
- pWinCX->CloseCallback(pChrome->close_callback, pChrome->close_arg);
-
- // We don't handle modality, as there is no parent context passed in.
- }
-
- // Query current chrome in a context.
- void FE_QueryChrome(MWContext *pContext, Chrome *pChrome)
- {
- TRACE("FE_QueryChrome(%p, %p)\n", pContext, pChrome);
-
- // API fulfillments.
- if(!pContext || !pChrome || !ABSTRACTCX(pContext) || !ABSTRACTCX(pContext)->IsFrameContext()) {
- return;
- }
-
- CWinCX *pWinCX = WINCX(pContext);
- if(!pWinCX->GetPane() || !pWinCX->GetDocument() || !pWinCX->GetFrame() || !pWinCX->GetFrame()->GetFrameWnd()) {
- // Context isn't anatomically correct.
- return;
- }
-
- // Clear the chrome struct, we'll refill in the relevant parts.
- memset((void *)pChrome, 0, sizeof(Chrome));
-
- LPCHROME pIChrome = pWinCX->GetFrame()->GetChrome();
- if(pIChrome) {
- // Toolbar on or off?
- pChrome->show_button_bar = pIChrome->GetToolbarVisible(ID_NAVIGATION_TOOLBAR);
-
- // Url bar and directory buttons.
- pChrome->show_url_bar = pIChrome->GetToolbarVisible(ID_LOCATION_TOOLBAR);
- pChrome->show_directory_buttons = pIChrome->GetToolbarVisible(ID_PERSONAL_TOOLBAR);
-
- // The security bar?
- // TODO: Fix me!
- pChrome->show_security_bar = TRUE;
-
- // Status bar!
- LPNSSTATUSBAR pIStatusBar = NULL;
- pIChrome->QueryInterface( IID_INSStatusBar, (LPVOID *) &pIStatusBar );
- if ( pIStatusBar ) {
- HWND hWnd = pIStatusBar->GetHWnd();
- pIStatusBar->Release();
- pChrome->show_bottom_status_bar = IsWindowVisible( hWnd );
- }
- }
-
- // Show the menu?
- pChrome->show_menu = pWinCX->GetFrame()->GetFrameWnd()->GetMenu() == NULL ? FALSE : TRUE;
-
- // Size, of all things, of the viewing area only....
- // Acount for the view border style, too.
- CRect crView;
- ::GetWindowRect(pWinCX->GetPane(), crView);
- CRect crFrame;
- pWinCX->GetFrame()->GetFrameWnd()->GetWindowRect(crFrame);
- crView.InflateRect(-1 * sysInfo.m_iBorderWidth, -1 * sysInfo.m_iBorderHeight);
- pChrome->outw_hint = (int32)crFrame.Width();
- pChrome->outh_hint = (int32)crFrame.Height();
- pChrome->w_hint = (int32)crView.Width();
- pChrome->h_hint = (int32)crView.Height();
- pChrome->l_hint = (int32)crFrame.left;
- pChrome->t_hint = (int32)crFrame.top;
-
- //Set to make sure the coords given are used.
- pChrome->location_is_chrome= TRUE;
-
- // Scroll bars.
- pChrome->show_scrollbar = pWinCX->DynamicScrollBars();
-
- // Resize.
- // This is a truly gross and unholy option.
- pChrome->allow_resize = ((CGenericFrame *)pWinCX->GetFrame()->GetFrameWnd())->CanResize();
-
- // Hotkeys.
- pChrome->disable_commands = ((CGenericFrame *)pWinCX->GetFrame()->GetFrameWnd())->HotkeysDisabled();
-
- // ZLocked.
- pChrome->z_lock = ((CGenericFrame *)pWinCX->GetFrame()->GetFrameWnd())->IsZOrderLocked();
-
- // Bottommost.
- pChrome->bottommost = ((CGenericFrame *)pWinCX->GetFrame()->GetFrameWnd())->IsBottommost();
-
- // Close.
- // This is a truly gross and unholy option.
- // This will only report if the current context and its children can close, not if
- // the actual frame can close if this context has a parent.
- pChrome->allow_close = pWinCX->GetDocument()->CanClose();
-
- // Close callback is not handled correctly, as there may be multiples.
-
- // We don't handle modality, as there is no parent context passed in to check against.
- }
-
- // Destroy a window/context.
- void FE_DestroyWindow(MWContext *pContext)
- {
- TRACE("FE_DestroyWindow(%p)\n", pContext);
-
- ASSERT(pContext);
- if(pContext != NULL) {
- // Make sure that this is a CWinCX.
- ASSERT(ABSTRACTCX(pContext)->IsFrameContext());
- if(ABSTRACTCX(pContext)->IsWindowContext()) {
- CWinCX *pCX = WINCX(pContext);
-
- // Make sure there's a frame to close.
- if(pCX->GetFrame()->GetFrameWnd()) {
- // Reenable closing.
- pCX->EnableClose(TRUE);
-
- // Send it a close message.
- pCX->GetFrame()->GetFrameWnd()->SendMessage(WM_CLOSE);
- }
- }
- }
- }
-
- // Fill in left top position of frame.
- // Breaks down on the minimized maximized scenario.
- void FE_GetWindowPosition(MWContext *pContext, int32 *pX, int32 *pY)
- {
- TRACE("FE_GetWindowPosition(%p, %p, %p)\n", pContext, pX, pY);
-
- // Initialize.
- if(pX) {
- *pX = 0;
- }
- if(pY) {
- *pY = 0;
- }
-
- if(pContext && ABSTRACTCX(pContext) && ABSTRACTCX(pContext)->IsFrameContext() && (pX || pY)) {
- // Make sure there's a frame.
- CWinCX *pCX = WINCX(pContext);
- if(pCX->GetFrame() && pCX->GetFrame()->GetFrameWnd()) {
- CRect cr;
- pCX->GetFrame()->GetFrameWnd()->GetWindowRect(cr);
-
- if(pX) {
- *pX = cr.left;
- }
- if(pY) {
- *pY = cr.top;
- }
- }
- }
- }
-
- // Set left top position of frame.
- // Breaks down on the minimized maximized scenario.
- void FE_SetWindowPosition(MWContext *pContext, int32 lX, int32 lY)
- {
- TRACE("FE_SetWindowPosition(%p, %ld, %ld)\n", pContext, lX, lY);
-
- if(pContext && ABSTRACTCX(pContext) &&
- ABSTRACTCX(pContext)->IsFrameContext()) {
- // Make sure there's a frame.
- CWinCX *pCX = WINCX(pContext);
- if(pCX->GetFrame() && pCX->GetFrame()->GetFrameWnd()) {
- pCX->GetFrame()->GetFrameWnd()->SetWindowPos(NULL, CASTINT(lX),
- CASTINT(lY), 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
- }
- }
- }
-
- // Return screen dimensions.
- void FE_GetScreenSize(MWContext *pContext, int32 *pX, int32 *pY)
- {
- // Initialize
- if(pX) {
- *pX = sysInfo.m_iScreenWidth;
- }
- if(pY) {
- *pY = sysInfo.m_iScreenHeight;
- }
- }
-
- // Return available screen rectangle.
- void FE_GetAvailScreenRect(MWContext *pContext, int32 *pX, int32 *pY,
- int32 *pLeft, int32 *pTop)
- {
- RECT *pRect = NULL;
- #ifdef WIN32
- APPBARDATA abd;
- UINT state;
-
- XP_BZERO(&abd, sizeof abd);
- abd.cbSize = sizeof(abd);
- abd.hWnd = NULL;
-
- state = SHAppBarMessage(ABM_GETSTATE, &abd);
-
- if ((state & ABS_ALWAYSONTOP) && !(state & ABS_AUTOHIDE))
- if (!SHAppBarMessage(ABM_GETTASKBARPOS, &abd))
- ASSERT(0);
- pRect = &abd.rc;
- #endif
- // Initialize
- if(pX) {
- *pX = sysInfo.m_iScreenWidth;
- if (pRect != NULL) {
- if (pRect->top < 0 && pRect->bottom > sysInfo.m_iScreenHeight) {
- //Docked left
- if (pRect->left < 0)
- *pX -= pRect->right;
- //Docked right
- if (pRect->right > sysInfo.m_iScreenWidth)
- *pX = pRect->left;
- }
- }
- }
- if(pY) {
- *pY = sysInfo.m_iScreenHeight;
- if (pRect != NULL) {
- if (pRect->left < 0 && pRect->right > sysInfo.m_iScreenWidth) {
- //Docked top
- if (pRect->top < 0);
- *pY -= pRect->bottom;
- //Docked bottom
- if (pRect->bottom > sysInfo.m_iScreenHeight)
- *pY = pRect->top;
- }
- }
- }
- if(pLeft) {
- *pLeft = 0;
- if (pRect != NULL) {
- if (pRect->top < 0 && pRect->left < 0) {
- //Docked left
- if (pRect->bottom > sysInfo.m_iScreenHeight)
- *pLeft = pRect->right;
- }
- }
- }
- if(pTop) {
- *pTop = 0;
- if (pRect != NULL) {
- if (pRect->top < 0 && pRect->left < 0) {
- //Docked top
- if (pRect->right > sysInfo.m_iScreenWidth)
- *pTop = pRect->bottom;
- }
- }
- }
- }
-
- // Return color depth.
- void FE_GetPixelAndColorDepth(MWContext *pContext, int32 *pixel, int32 *pallette)
- {
- TRACE("FE_GetPixelAndColorDepth(%p, %p)\n", pixel, pallette);
-
- *pixel = *pallette = 0;
-
- if(ABSTRACTCX(pContext)->IsDestroyed() == FALSE) {
-
- CWinCX *pWinCX = WINCX(pContext);
-
- HDC pDC = pWinCX->GetContextDC();
-
- // Figure out the depth of the CDC.
- *pixel = ::GetDeviceCaps(pDC, BITSPIXEL);
-
- // Check for pallette existence
- if ((::GetDeviceCaps(pDC, RASTERCAPS) & RC_PALETTE) != 0)
- *pallette = ::GetDeviceCaps(pDC, COLORRES);
- else
- *pallette = *pixel;
-
- pWinCX->ReleaseContextDC(pDC);
- }
-
- }
-
-
-
-
-
-
-
-
- BOOL GetIntelCPUSpeed(int32 &processorSpeed );
- BOOL GetIntelCPUInfoViaCPUID(char *systemArchitecture,
- int32 &processorType, int32 &processorFamily,
- int32 &processorModel, int32 &processorStepping, int32 &processorFeatures,
- CString &vendor);
- #ifndef _WIN32
- unsigned short GetBaseMemC();
- unsigned short GetExpMemC();
- #endif
- CString csUNKNOWN = "Unknown";
- CString csINTEL = "Intel";
- CString csMIPS = "Mips";
- CString csALPHA = "Alpha";
- CString csPPC = "PowerPC";
-
- CString csARCHITECTURE = "ARCHITECTURE";
- CString csFAMILY = "FAMILY";
- CString csMODEL = "MODEL";
- CString csSTEPPING = "STEPPING";
- CString csTYPE = "TYPE";
- CString csFEATURES = "FEATURES";
- CString csPASS = "PASS";
- CString csREVISION = "REVISION";
- CString csVERSION = "VERSION";
- CString csVENDOR = "VENDOR";
-
- // VARIABLE STRUCTURE DEFINITIONS //////////////////////////////
- struct FREQ_INFO
- {
- unsigned long in_cycles; // Internal clock cycles during
- // test
-
- unsigned long ex_ticks; // Microseconds elapsed during
- // test
-
- unsigned long raw_freq; // Raw frequency of CPU in MHz
-
- unsigned long norm_freq; // Normalized frequency of CPU
- // in MHz.
- };
-
- struct FREQ_INFO cpuspeed(int clocks);
- // Function Prototypes /////////////////////////////////////////
-
- /***************************************************************
- * WORD wincpuidsupport()
- * =================================
- * Wincpuidsupport() tells the caller whether the host processor
- * supports the CPUID opcode or not.
- *
- * Inputs: none
- *
- * Returns:
- * 1 = CPUID opcode is supported
- * 0 = CPUID opcode is not supported
- ***************************************************************/
-
- WORD wincpuidsupport();
-
-
- /***************************************************************
- * WORD wincpuid()
- * ===============
- * This routine uses the standard Intel assembly code to
- * determine what type of processor is in the computer, as
- * described in application note AP-485 (Intel Order #241618).
- * Wincpuid() returns the CPU type as an integer (that is,
- * 2 bytes, a WORD) in the AX register.
- *
- * Returns:
- * 0 = 8086/88
- * 2 = 80286
- * 3 = 80386
- * 4 = 80486
- * 5 = Pentium(R) Processor
- * 6 = PentiumPro(R) Processor
- * 7 or higher = Processor beyond the PentiumPro6(R) Processor
- *
- * Note: This function also sets the global variable clone_flag
- ***************************************************************/
- WORD wincpuid();
-
-
- /***************************************************************
- * WORD wincpuidext()
- * ==================
- * Similar to wincpuid(), but returns more data, in the order
- * reflecting the actual output of a CPUID instruction execution:
- *
- * Returns:
- * AX(15:14) = Reserved (mask these off in the calling code
- * before using)
- * AX(13:12) = Processor type (00=Standard OEM CPU, 01=OverDrive,
- * 10=Dual CPU, 11=Reserved)
- * AX(11:8) = CPU Family (the same 4-bit quantity as wincpuid())
- * AX(7:4) = CPU Model, if the processor supports the CPUID
- * opcode; zero otherwise
- * AX(3:0) = Stepping #, if the processor supports the CPUID
- * opcode; zero otherwise
- *
- * Note: This function also sets the global variable clone_flag
- ***************************************************************/
- WORD wincpuidext(CString &vendorName);
-
-
- /***************************************************************
- * DWORD wincpufeatures()
- * ======================
- * Wincpufeatures() returns the CPU features flags as a DWORD
- * (that is, 32 bits).
- *
- * Inputs: none
- *
- * Returns:
- * 0 = Processor which does not execute the CPUID instruction.
- * This includes 8086, 8088, 80286, 80386, and some
- * older 80486 processors.
- *
- * Else
- * Feature Flags (refer to App Note AP-485 for description).
- * This DWORD was put into EDX by the CPUID instruction.
- *
- * Current flag assignment is as follows:
- *
- * bit31..10 reserved (=0)
- * bit9=1 CPU contains a local APIC (iPentium-3V)
- * bit8=1 CMPXCHG8B instruction supported
- * bit7=1 machine check exception supported
- * bit6=0 reserved (36bit-addressing & 2MB-paging)
- * bit5=1 iPentium-style MSRs supported
- * bit4=1 time stamp counter TSC supported
- * bit3=1 page size extensions supported
- * bit2=1 I/O breakpoints supported
- * bit1=1 enhanced virtual 8086 mode supported
- * bit0=1 CPU contains a floating-point unit (FPU)
- *
- * Note: New bits will be assigned on future processors... see
- * processor data books for updated information
- *
- * Note: This function also sets the global variable clone_flag
- ***************************************************************/
- DWORD wincpufeatures(CString &vendorName);
-
-
-
- #ifndef _WIN32
- unsigned short GetBaseMemC()
- {
- // get memory below 1-MB boundary
- // using run-time library functions
- unsigned short base;
- outp( 0x70, 0x15 );
- base = inp( 0x71 ); //retrieve low byte
- outp( 0x70, 0x16 );
- base += inp(0x71) << 8; //retieve high byte,
- //shift and add to base
- return base; // return K's of base memory
- }
-
- unsigned short GetExpMemC()
- {
- // get memory above 1-MB boundary
- // using run-time library functions
- unsigned short extend;
- outp( 0x70, 0x17 );
- base = inp( 0x71 ); //retrieve low byte
- outp( 0x70, 0x18 );
- base += inp(0x71) << 8; //retieve high byte,
- //shift and add to extend
- return extend; // return K's of expansion memory
- }
- #endif
-
- int32 FE_SystemRAM( void )
- {
- int32 systemRAM = -1;
- #ifdef _WIN32
- MEMORYSTATUS MemoryStatus;
-
- memset( &MemoryStatus, 0, sizeof(MEMORYSTATUS));
- MemoryStatus.dwLength = sizeof(MEMORYSTATUS);
-
- GlobalMemoryStatus( &MemoryStatus );
- //return physical memory size in K
- systemRAM = MemoryStatus.dwTotalPhys / 1024 ;
- #else
- //return physical memory size in K
- int32 expansionMem = GetExpMemC();
- int32 baseMem = GetBaseMemC();
- systemRAM = expansionMem + baseMem;
- #endif
- return systemRAM;
- }
-
- int32 FE_SystemClockSpeed( void )
- {
- int32 clockSpeed = -1;
- #ifdef _WIN32
- OSVERSIONINFO OSVersionInfo;
- memset( &OSVersionInfo, 0, sizeof(OSVERSIONINFO));
- OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if(GetVersionEx( &OSVersionInfo ))
- {
- if(OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ||
- OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) //Windows 9x
- {
- SYSTEM_INFO SystemInfo;
- GetSystemInfo( &SystemInfo );
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
- {
- if(!GetIntelCPUSpeed(clockSpeed))
- clockSpeed = -1;
- }
- else
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA )
- {
- return -1;
- }
- else
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_MIPS )
- {
- return -1;
- }
- else
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_PPC )
- {
- return -1;
- }
- else
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_UNKNOWN )
- return -1;
- else
- {
- ASSERT(FALSE);
- return -1;
- }
- }
- else //if Win32s we must be running on Win3.x so Intel architecture
- if( OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32s )
- {
- if(!GetIntelCPUSpeed(clockSpeed))
- clockSpeed = -1;
- }
- else
- {
- ASSERT(FALSE);
- return -1;
- }
- }
- #else
- if(!GetIntelCPUSpeed(clockSpeed))
- clockSpeed = -1;
- #endif
- return clockSpeed;
- }
-
- BOOL GetIntelCPUSpeed(int32 &processorSpeed )
- {
- BOOL bRet = FALSE;
- // VARIABLE STRUCTURE DEFINITIONS //////////////////////////////
- struct FREQ_INFO cpu_speed; // Return variable
- // structure for
- // cpuspeed
- // routine
-
-
- cpu_speed = cpuspeed(0);
-
- if ( cpu_speed.in_cycles == 0 && cpu_speed.ex_ticks == 0 )
- {
- /*
- sprintf(buf,
- "This processor cannot be accurately "
- "timed with this program.\n The "
- "processor could be"
- "below 80386 level.");
- MessageBox(NULL,buf,"error", MB_ICONINFORMATION );
- */
- bRet = FALSE;
- }
- else
- {
- /*
- sprintf(buf,
- "Clock Cycles: %lu cycles\n"
- "Elapsed Time: %luus\n"
- "Raw Clock Frequency: %luMHz\n"
- "Normalized Frequency: %luMHz",
- cpu_speed.in_cycles,
- cpu_speed.ex_ticks,
- cpu_speed.raw_freq,
- cpu_speed.norm_freq);
-
- MessageBox(NULL,buf,"32-bit cpuspeed",
- MB_ICONINFORMATION );
- */
- processorSpeed = cpu_speed.norm_freq;
- bRet = TRUE;
- }
- return bRet;
- }
-
-
- BOOL GetIntelCPUInfoViaCPUID(CString &systemArchitecture,
- int32 &processorType, int32 &processorFamily,
- int32 &processorModel, int32 &processorStepping, int32 &processorFeatures,
- CString &vendor)
- {
- //Intel Only!!!
- systemArchitecture = csINTEL;
- int32 processorExtensions = 0;
- processorExtensions = wincpuidext(vendor);
-
- processorStepping = processorExtensions & 0x0f;
- processorModel = (processorExtensions & 0x0f0) >> 4;
- processorFamily = (processorExtensions & 0x0f00) >> 8;
- processorType = (processorExtensions & 0x03000) >> 12;
-
- processorFeatures = wincpufeatures(vendor);
-
- return TRUE;
- }
-
- char *CreateNonIntelCPUInfoString(CString &systemArchitecture,
- int32 &processorModel, int32 &processorStepping)
- {
- CString tmpStr;
- CString CPUInfoString;
- ASSERT( !systemArchitecture.IsEmpty() );
-
- if( !systemArchitecture.IsEmpty() )
- {
- CPUInfoString = csARCHITECTURE + "=";
- CPUInfoString += systemArchitecture;
- }
-
- if( systemArchitecture == csALPHA )
- {
- if( processorModel > -1 )
- {
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csMODEL + "=A";
- tmpStr.Format("%.2X", processorModel );
- CPUInfoString += tmpStr;
- }
- if( processorStepping > -1 )
- {
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csPASS + "=";
- tmpStr.Format("%.2X", processorStepping);
- CPUInfoString += tmpStr;
- }
- }
- else
- if( systemArchitecture == csMIPS )
- {
- if( processorModel > -1 )
- {
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csREVISION + "=";
- tmpStr.Format("%.2X", processorModel);
- CPUInfoString += tmpStr;
- }
- }
- else
- if( systemArchitecture == csPPC )
- {
- if( processorModel > -1 )
- {
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csVERSION + "=";
- tmpStr.Format("%.2X", processorModel);
- CPUInfoString += tmpStr;
- }
-
- if( processorStepping > -1 )
- {
- CPUInfoString += ".";
- tmpStr.Format("%.2X", processorStepping);
- CPUInfoString += tmpStr;
- }
- }
- char * pstr = NULL;
- int len = CPUInfoString.GetLength();
- if(len > 0 )
- {
- pstr = new char[ len + 1];
- if( pstr != NULL )
- strcpy( pstr, CPUInfoString );
- }
- return pstr;
- }
-
-
- char *CreateIntelCPUInfoString(CString &systemArchitecture,
- int32 processorType, int32 processorFamily,
- int32 processorModel, int32 processorStepping, int32 processorFeatures,
- CString &vendor)
- {
- CString tmpStr;
- CString CPUInfoString;
- ASSERT( !systemArchitecture.IsEmpty() );
-
- if( !systemArchitecture.IsEmpty() )
- {
- CPUInfoString = csARCHITECTURE + "=";
- CPUInfoString += systemArchitecture;
- }
- if( processorType > -1 )
- {
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csTYPE + "=";
- tmpStr.Format("%d", processorType);
- CPUInfoString += tmpStr;
- }
- if( processorFamily > -1 )
- {
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csFAMILY + "=";
- tmpStr.Format("%d", processorFamily);
- CPUInfoString += tmpStr;
- }
- if( processorModel > -1 )
- {
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csMODEL + "=";
- tmpStr.Format("%d", processorModel);
- CPUInfoString += tmpStr;
- }
- if( processorStepping > -1 )
- {
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csSTEPPING + "=";
- tmpStr.Format("%d", processorStepping);
- CPUInfoString += tmpStr;
- }
- if( processorFeatures > -1 )
- {
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csFEATURES + "=";
- tmpStr.Format("0x%x", processorFeatures);
- CPUInfoString += tmpStr;
- }
-
- if( !CPUInfoString.IsEmpty() )
- CPUInfoString += ";";
- CPUInfoString += csVENDOR + "=";
- if( !vendor.IsEmpty() )
- CPUInfoString += vendor;
- else
- CPUInfoString += csUNKNOWN;
-
- char * pstr = NULL;
- int len = CPUInfoString.GetLength();
- if(len > 0 )
- {
- pstr = new char[ len + 1];
- if( pstr != NULL )
- strcpy( pstr, CPUInfoString );
- }
-
- return pstr;
- }
-
- char *FE_SystemCPUInfo(void)
- {
- CString systemArchitecture;
- int32 processorType = -1;
- int32 processorFamily = -1;
- int32 processorModel = -1;
- int32 processorStepping = -1;
- int32 processorFeatures = -1;
- CString vendor;
-
- #ifdef _WIN32
- OSVERSIONINFO OSVersionInfo;
- memset( &OSVersionInfo, 0, sizeof(OSVERSIONINFO));
- OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if(GetVersionEx( &OSVersionInfo ))
- {
- //if Win32s is the platform
- if( OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32s )
- {
- if(GetIntelCPUInfoViaCPUID(systemArchitecture,
- processorType, processorFamily, processorModel,
- processorStepping, processorFeatures, vendor ))
- return CreateIntelCPUInfoString(systemArchitecture,
- processorType, processorFamily, processorModel,
- processorStepping, processorFeatures, vendor );
- else
- return NULL;
- }
- else
- if(OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ||
- OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) //Windows 9x
- {
- SYSTEM_INFO SystemInfo;
- GetSystemInfo( &SystemInfo );
- processorFamily = SystemInfo.wProcessorLevel;
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
- {
- if(OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
- { //Windows 9x
- if(GetIntelCPUInfoViaCPUID(systemArchitecture,
- processorType, processorFamily, processorModel,
- processorStepping, processorFeatures, vendor ))
- return CreateIntelCPUInfoString(systemArchitecture,
- processorType, processorFamily, processorModel,
- processorStepping, processorFeatures, vendor );
- else
- return NULL;
- }
- else //Windows NT on Intel
- {
- //Might as well use CPUID; it provides a little more information
- if(GetIntelCPUInfoViaCPUID(systemArchitecture,
- processorType, processorFamily, processorModel,
- processorStepping, processorFeatures, vendor ))
- return CreateIntelCPUInfoString(systemArchitecture,
- processorType, processorFamily, processorModel,
- processorStepping, processorFeatures, vendor );
- else
- return NULL;
-
- // strcpy(systemArchitecture, INTEL);
- // if( SystemInfo.dwProcessorType == PROCESSOR_INTEL_386 ||
- // SystemInfo.dwProcessorType == PROCESSOR_INTEL_486 )
- // {
- // //wProcessor type of form xxyz; if xx != 0xFF
- // if( ((SystemInfo.wProcessorRevision >> 8) & 0xff ) != 0xff )
- // {
- // //then xx + 'A' is the stepping letter
- // processorStepping = ((SystemInfo.wProcessorRevision >> 8) & 0xff) + 'A';
- // //this is actually the minor stepping
- // processorModel = (SystemInfo.wProcessorRevision & 0x0ff);
- // }
- // else
- // if( ((SystemInfo.wProcessorRevision >> 8) & 0xff ) == 0xff )
- // {
- // processorModel = (SystemInfo.wProcessorRevision & 0x0f0) >> 4;
- // processorStepping = (SystemInfo.wProcessorRevision & 0x0f);
- // }
- // }
- // else //processor must be > x486
- // {
- // processorModel = (SystemInfo.wProcessorRevision & 0x0ff00) >> 8;
- // processorStepping = (SystemInfo.wProcessorRevision & 0x0ff);
- // }
- }
- }
- else
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA )
- {
- systemArchitecture = csALPHA;
- processorModel = (SystemInfo.wProcessorRevision & 0x0ff00) >> 8;
- //"Pass" on Alpha; display as "Model 'A'+xx, Pass yy"
- processorStepping = (SystemInfo.wProcessorRevision & 0x0ff);
- return CreateNonIntelCPUInfoString(systemArchitecture,
- processorModel, processorStepping);
- }
- else
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_MIPS )
- {
- systemArchitecture = csMIPS;
- //"Revision Number" on MIPS
- processorModel = (SystemInfo.wProcessorRevision & 0x0ff);
- return CreateNonIntelCPUInfoString(systemArchitecture,
- processorModel, processorStepping);
- }
- else
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_PPC )
- {
- systemArchitecture = csPPC;
- //display as xx.yy on PPC
- processorModel = (SystemInfo.wProcessorRevision & 0x0ff00) >> 8;
- processorStepping = (SystemInfo.wProcessorRevision & 0x0ff);
- return CreateNonIntelCPUInfoString(systemArchitecture,
- processorModel, processorStepping);
- }
- else
- if( SystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_UNKNOWN )
- {
- systemArchitecture = csUNKNOWN;
- return CreateNonIntelCPUInfoString(systemArchitecture,
- processorModel, processorStepping);
- }
- else
- {
- ASSERT(FALSE);
- systemArchitecture = csUNKNOWN;
- return CreateNonIntelCPUInfoString(systemArchitecture,
- processorModel, processorStepping);
- }
- }
- ASSERT(FALSE); //Unknown operating system
- }
- return NULL;
- #else //WIN16
- if(GetIntelCPUInfoViaCPUID(systemArchitecture, processorType,
- processorFamily, processorModel, processorStepping,
- processorFeatures, vendor ))
- return CreateIntelCPUInfoString(systemArchitecture,
- processorType, processorFamily, processorModel,
- processorStepping, processorFeatures, vendor );
- else
- return NULL;
- #endif
- }
-
-
-
-
-
-
-
-
- // CONSTANT DEFINITIONS ////////////////////////////////////////
- #define CLONE_MASK 0x8000 // Mask to be 'OR'ed with proc-
- #define MAXCLOCKS 150 // Maximum number of cycles per
- // BSF instruction
- // ACCURACY AFFECTING CONSTANTS ////////////////////////////
- #define ITERATIONS 4000 // Number of times to repeat BSF
- // instruction in samplings.
- // Initially set to 4000.
-
- #define MAX_TRIES 20 // Maximum number of samplings
- // to allow before giving up
- // and returning current
- // average. Initially set to
- // 20.
-
- #define TOLERANCE 1 // Number of MHz to allow
- // samplings to deviate from
- // average of samplings.
- // Initially set to 2.
-
- #define SAMPLINGS 10 // Number of BSF sequence
- // samplings to make.
- // Initially set to 10.
-
-
- typedef unsigned short ushort;
- typedef unsigned long ulong;
-
- // Global Variable /////////////////////////////////////////////
- int clone_flag; // Flag to show whether processor
- // is non-Intel
-
-
-
-
- // OPCODE DEFINITIONS //////////////////////////////////////////
- #define CPU_ID _asm _emit 0x0f _asm _emit 0xa2
- // CPUID instruction
-
- #define RDTSC _asm _emit 0x0f _asm _emit 0x31
- // RDTSC instruction
-
- // Private Function Declarations ///////////////////////////////
-
- /***************************************************************
- * static WORD check_clone()
- *
- * Inputs: none
- *
- * Returns:
- * 1 if processor is clone (limited detection ability)
- * 0 otherwise
- ***************************************************************/
- static WORD check_clone();
-
-
- /***************************************************************
- * static WORD check_8086()
- *
- * Inputs: none
- *
- * Returns:
- * 0 if processor 8086
- * 0xffff otherwise
- ***************************************************************/
- static WORD check_8086();
-
-
- /***************************************************************
- * static WORD check_80286()
- *
- * Inputs: none
- *
- * Returns:
- * 2 if processor 80286
- * 0xffff otherwise
- ***************************************************************/
- static WORD check_80286();
-
-
- /***************************************************************
- * static WORD check_80386()
- *
- * Inputs: none
- *
- * Returns:
- * 3 if processor 80386
- * 0xffff otherwise
- ***************************************************************/
- static WORD check_80386();
-
-
- /***************************************************************
- * static WORD check_IDProc()
- * ==========================
- * Check_IDProc() uses the CPUID opcode to find the family type
- * of the host processor.
- *
- * Inputs: none
- *
- * Returns:
- * CPU Family (i.e. 4 if Intel 486, 5 if Pentium(R) Processor)
- *
- * Note: This function also sets the global variable clone_flag
- ***************************************************************/
- static WORD check_IDProc();
-
- //end of prototypes //////////////////////////////////////////////
-
-
- #define ROUND_THRESHOLD 6
-
- // Tabs set at 4
- static struct FREQ_INFO GetRDTSCCpuSpeed();
- static struct FREQ_INFO GetBSFCpuSpeed(ulong cycles);
-
- // Number of cycles needed to execute a single BSF instruction.
- // Note that processors below i386(tm) are not supported.
- static ulong processor_cycles[] = {
- 00, 00, 00, 115, 47, 43,
- 38, 38, 38, 38, 38, 38,
- };
-
- /***************************************************************
- * wincpuidsupport()
- *
- * Inputs: none
- *
- * Returns:
- * 1 = CPUID opcode is supported
- * 0 = CPUID opcode is not supported
- ***************************************************************/
-
- WORD wincpuidsupport() {
- int cpuid_support = 1;
-
- _asm {
- pushfd // Get original EFLAGS
- pop eax
- mov ecx, eax
- xor eax, 200000h // Flip ID bit in EFLAGS
- push eax // Save new EFLAGS value on
- // stack
- popfd // Replace current EFLAGS value
- pushfd // Get new EFLAGS
- pop eax // Store new EFLAGS in EAX
- xor eax, ecx // Can not toggle ID bit,
- jnz support // Processor=80486
-
- mov cpuid_support,0 // Clear support flag
- support:
- }
-
- return cpuid_support;
-
- } // wincpuidsupport()
-
-
- /***************************************************************
- * wincpuid()
- *
- * Inputs: none
- *
- * Returns:
- * 0 = 8086/88
- * 2 = 80286
- * 3 = 80386
- * 4 = 80486
- * 5 = Pentium(R) Processor
- * 6 = PentiumPro(R) Processor
- * 7 or higher = Processor beyond the PentiumPro6(R) Processor
- *
- * Note: This function also sets the global variable clone_flag
- ***************************************************************/
-
- WORD wincpuid() {
-
- WORD cpuid;
-
- if ( wincpuidsupport() ) // Determine whether CPUID
- // opcode is supported
- cpuid=check_IDProc();
-
- else {
-
- clone_flag=check_clone();
-
- cpuid=check_8086(); // Will return FFFFh or 0
- if (cpuid == 0) goto end;
-
- cpuid=check_80286(); // Will return FFFFh or 2
- if (cpuid == 2) goto end;
-
- cpuid=check_80386(); // Will return FFFFh or 3
- if (cpuid == 3) goto end; // temporarily commented out.
-
- cpuid=4; // If the processor does not support CPUID,
- // is not an 8086, 80286, or 80386, assign
- // processor to be an 80486
- }
-
- end:
- if (clone_flag)
- cpuid = cpuid | CLONE_MASK; // Signify that a clone has been
- // detected by setting MSB high
-
- return cpuid;
-
- } // wincpuid ()
-
-
- /***************************************************************
- * wincpufeatures()
- *
- * Inputs: none
- *
- * Returns:
- * 0 = Processor which does not execute the CPUID instruction.
- * This includes 8086, 8088, 80286, 80386, and some
- * older 80486 processors.
- *
- * Else
- * Feature Flags (refer to App Note AP-485 for description).
- * This DWORD was put into EDX by the CPUID instruction.
- *
- * Current flag assignment is as follows:
- *
- * bit31..10 reserved (=0)
- * bit9=1 CPU contains a local APIC (iPentium-3V)
- * bit8=1 CMPXCHG8B instruction supported
- * bit7=1 machine check exception supported
- * bit6=0 reserved (36bit-addressing & 2MB-paging)
- * bit5=1 iPentium-style MSRs supported
- * bit4=1 time stamp counter TSC supported
- * bit3=1 page size extensions supported
- * bit2=1 I/O breakpoints supported
- * bit1=1 enhanced virtual 8086 mode supported
- * bit0=1 CPU contains a floating-point unit (FPU)
- *
- * Note: New bits will be assigned on future processors... see
- * processor data books for updated information
- *
- * Note: This function also sets the global variable clone_flag
- ***************************************************************/
-
- DWORD wincpufeatures(CString &vendorName) {
-
- int i=0;
- DWORD cpuff=0x00000000;
- BYTE vendor_id[]="------------";
- BYTE intel_id[]="GenuineIntel";
-
- if ( wincpuidsupport() ) {
-
- _asm {
-
- xor eax, eax // Set up for CPUID instruction
-
- CPU_ID // Get and save vendor ID
-
- mov dword ptr vendor_id, ebx
- mov dword ptr vendor_id[+4], edx
- mov dword ptr vendor_id[+8], ecx
- }
- vendorName = vendor_id;
-
- for (i=0;i<12;i++)
- {
- if (!(vendor_id[i]==intel_id[i]))
- clone_flag = 1;
- }
-
- _asm {
-
- cmp eax, 1 // Make sure 1 is valid input
- // for CPUID
-
- jl end_cpuff // If not, jump to end
- xor eax, eax
- inc eax
- CPU_ID // Get family/model/stepping/
- // features
-
- mov cpuff, edx
-
- end_cpuff:
- mov eax, cpuff
- }
- }
-
- return cpuff;
-
- } // wincpufeatures()
-
-
- /***************************************************************
- * wincpuidext()
- *
- * Inputs: none
- *
- * Returns:
- * AX(15:14) = Reserved (mask these off in the calling code
- * before using)
- * AX(13:12) = Processor type (00=Standard OEM CPU, 01=OverDrive,
- * 10=Dual CPU, 11=Reserved)
- * AX(11:8) = CPU Family (the same 4-bit quantity as wincpuid())
- * AX(7:4) = CPU Model, if the processor supports the CPUID
- * opcode; zero otherwise
- * AX(3:0) = Stepping #, if the processor supports the CPUID
- * opcode; zero otherwise
- *
- * Note: This function also sets the global variable clone_flag
- ***************************************************************/
-
- WORD wincpuidext(CString &vendorName) {
-
- int i=0;
- WORD cpu_type=0x0000;
- WORD cpuidext=0x0000;
- BYTE vendor_id[]="------------";
- BYTE intel_id[]="GenuineIntel";
-
- if ( wincpuidsupport() ) {
-
- _asm {
-
- xor eax, eax // Set up for CPUID instruction
-
- CPU_ID // Get and save vendor ID
-
- mov dword ptr vendor_id, ebx
- mov dword ptr vendor_id[+4], edx
- mov dword ptr vendor_id[+8], ecx
- }
- vendorName = vendor_id;
-
- for (i=0;i<12;i++)
- {
- if (!(vendor_id[i]==intel_id[i]))
- clone_flag = 1;
- }
-
- _asm {
-
- cmp eax, 1 // Make sure 1 is valid input
- // for CPUID
-
- jl end_cpuidext // If not, jump to end
- xor eax, eax
- inc eax
- CPU_ID // Get family/model/stepping/
- // features
-
- mov cpuidext, ax
-
- end_cpuidext:
- mov ax, cpuidext
- }
- }
- else {
-
- cpu_type = wincpuid(); // If CPUID opcode is not
- cpuidext = cpu_type << 8; // supported, put family
- // value in extensions and
- } // return
-
- return cpuidext;
-
- } // wincpuidext()
-
-
- static struct FREQ_INFO GetBSFCpuSpeed(ulong cycles)
- {
- // If processor does not support time
- // stamp reading, but is at least a
- // 386 or above, utilize method of
- // timing a loop of BSF instructions
- // which take a known number of cycles
- // to run on i386(tm), i486(tm), and
- // Pentium(R) processors.
- LARGE_INTEGER t0,t1; // Variables for High-
- // Resolution Performance
- // Counter reads
-
- ulong freq =0; // Most current frequ. calculation
-
- ulong ticks; // Microseconds elapsed
- // during test
-
- LARGE_INTEGER count_freq; // High Resolution
- // Performance Counter
- // frequency
-
- int i; // Temporary Variable
-
- ulong current = 0; // Variable to store time
- // elapsed during loop of
- // of BSF instructions
-
- ulong lowest = ULONG_MAX; // Since algorithm finds
- // the lowest value out of
- // a set of samplings,
- // this variable is set
- // intially to the max
- // unsigned long value).
- // This guarantees that
- // the initialized value
- // is not later used as
- // the least time through
- // the loop.
-
- struct FREQ_INFO cpu_speed;
-
- memset(&cpu_speed, 0x00, sizeof(cpu_speed));
-
- if ( !QueryPerformanceFrequency ( &count_freq ) )
- return cpu_speed;
-
- for ( i = 0; i < SAMPLINGS; i++ ) { // Sample Ten times. Can
- // be increased or
- // decreased depending
- // on accuracy vs. time
- // requirements
-
- QueryPerformanceCounter(&t0); // Get start time
-
- _asm
- {
-
- mov eax, 80000000h
- mov bx, ITERATIONS
- // Number of consecutive BSF
- // instructions to execute.
- // Set identical to
- // nIterations constant in
- // speed.h
-
- loop1: bsf ecx,eax
-
- dec bx
- jnz loop1
- }
-
- QueryPerformanceCounter(&t1); // Get end time
- current = (ulong) t1.LowPart - (ulong) t0.LowPart;
- // Number of external ticks is
- // difference between two
- // hi-res counter reads.
-
- if ( current < lowest ) // Take lowest elapsed
- lowest = current; // time to account
- } // for some samplings
- // being interrupted
- // by other operations
-
- ticks = lowest;
-
- // Note that some seemingly arbitrary mulitplies and
- // divides are done below. This is to maintain a
- // high level of precision without truncating the
- // most significant data. According to what value
- // ITERATIIONS is set to, these multiplies and
- // divides might need to be shifted for optimal
- // precision.
-
- ticks = ticks * 100000;
- // Convert ticks to hundred
- // thousandths of a tick
-
- ticks = ticks / ( count_freq.LowPart/10 );
- // Hundred Thousandths of a
- // Ticks / ( 10 ticks/second )
- // = microseconds (us)
-
- if ( ticks%count_freq.LowPart > count_freq.LowPart/2 )
- ticks++; // Round up if necessary
-
- freq = cycles/ticks; // Cycles / us = MHz
-
- cpu_speed.raw_freq = freq;
- if ( cycles%ticks > ticks/2 )
- freq++; // Round up if necessary
-
- cpu_speed.in_cycles = cycles; // Return variable structure
- cpu_speed.ex_ticks = ticks; // determined by one of
- cpu_speed.norm_freq = freq;
-
- return cpu_speed;
- }
-
- static struct FREQ_INFO GetRDTSCCpuSpeed()
- {
- struct FREQ_INFO cpu_speed;
- LARGE_INTEGER t0,t1; // Variables for High-
- // Resolution Performance
- // Counter reads
-
- ulong freq =0; // Most current frequ. calculation
- ulong freq2 =0; // 2nd most current frequ. calc.
- ulong freq3 =0; // 3rd most current frequ. calc.
-
- ulong total; // Sum of previous three frequency
- // calculations
-
- int tries=0; // Number of times a calculation has
- // been made on this call to
- // cpuspeed
-
- ulong total_cycles=0, cycles; // Clock cycles elapsed
- // during test
-
- ulong stamp0, stamp1; // Time Stamp Variable
- // for beginning and end
- // of test
-
- ulong total_ticks=0, ticks; // Microseconds elapsed
- // during test
-
- LARGE_INTEGER count_freq; // High Resolution
- // Performance Counter
- // frequency
-
- #ifdef WIN32
- int iPriority;
- HANDLE hThread = GetCurrentThread();
- #endif // WIN32;
-
- memset(&cpu_speed, 0x00, sizeof(cpu_speed));
-
- if ( !QueryPerformanceFrequency ( &count_freq ) )
- return cpu_speed;
-
- // On processors supporting the Read
- // Time Stamp opcode, compare elapsed
- // time on the High-Resolution Counter
- // with elapsed cycles on the Time
- // Stamp Register.
-
- do { // This do loop runs up to 20 times or
- // until the average of the previous
- // three calculated frequencies is
- // within 1 MHz of each of the
- // individual calculated frequencies.
- // This resampling increases the
- // accuracy of the results since
- // outside factors could affect this
- // calculation
-
- tries++; // Increment number of times sampled
- // on this call to cpuspeed
-
- freq3 = freq2; // Shift frequencies back to make
- freq2 = freq; // room for new frequency
- // measurement
-
- QueryPerformanceCounter(&t0);
- // Get high-resolution performance
- // counter time
-
- t1.LowPart = t0.LowPart; // Set Initial time
- t1.HighPart = t0.HighPart;
-
- #ifdef WIN32
- iPriority = GetThreadPriority(hThread);
- if ( iPriority != THREAD_PRIORITY_ERROR_RETURN )
- {
- SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
- }
- #endif // WIN32
-
- while ( (ulong)t1.LowPart - (ulong)t0.LowPart<50) {
- // Loop until 50 ticks have
- // passed since last read of hi-
- // res counter. This accounts for
- // overhead later.
-
- QueryPerformanceCounter(&t1);
-
- RDTSC; // Read Time Stamp
- _asm {
- MOV stamp0, EAX
- }
- }
-
-
- t0.LowPart = t1.LowPart; // Reset Initial
- t0.HighPart = t1.HighPart; // Time
-
- while ((ulong)t1.LowPart-(ulong)t0.LowPart<1000 ) {
- // Loop until 1000 ticks have
- // passed since last read of hi-
- // res counter. This allows for
- // elapsed time for sampling.
-
-
- QueryPerformanceCounter(&t1);
-
-
- RDTSC; // Read Time Stamp
- __asm {
- MOV stamp1, EAX
- }
- }
-
-
-
- #ifdef WIN32
- // Reset priority
- if ( iPriority != THREAD_PRIORITY_ERROR_RETURN )
- {
- SetThreadPriority(hThread, iPriority);
- }
- #endif // WIN32
-
- cycles = stamp1 - stamp0; // Number of internal
- // clock cycles is
- // difference between
- // two time stamp
- // readings.
-
- ticks = (ulong) t1.LowPart - (ulong) t0.LowPart;
- // Number of external ticks is
- // difference between two
- // hi-res counter reads.
-
-
- // Note that some seemingly arbitrary multiplies and
- // divides are done below. This is to maintain a
- // high level of precision without truncating the
- // most significant data. According to what value
- // ITERATIONS is set to, these multiplies and
- // divides might need to be shifted for optimal
- // precision.
-
- ticks = ticks * 100000;
- // Convert ticks to hundred
- // thousandths of a tick
-
- ticks = ticks / ( count_freq.LowPart/10 );
- // Hundred Thousandths of a
- // Ticks / ( 10 ticks/second )
- // = microseconds (us)
-
- total_ticks += ticks;
- total_cycles += cycles;
-
- if ( ticks%count_freq.LowPart > count_freq.LowPart/2 )
- ticks++; // Round up if necessary
-
- freq = cycles/ticks; // Cycles / us = MHz
-
- if ( cycles%ticks > ticks/2 )
- freq++; // Round up if necessary
-
- total = ( freq + freq2 + freq3 );
- // Total last three frequency
- // calculations
-
- } while ( (tries < 3 ) ||
- (tries < 20)&&
- ((abs(int(3 * freq -total)) > 3*TOLERANCE )||
- (abs(int(3 * freq2-total)) > 3*TOLERANCE )||
- (abs(int(3 * freq3-total)) > 3*TOLERANCE )));
- // Compare last three calculations to
- // average of last three calculations.
-
- // Try one more significant digit.
- freq3 = ( total_cycles * 10 ) / total_ticks;
- freq2 = ( total_cycles * 100 ) / total_ticks;
-
-
- if ( freq2 - (freq3 * 10) >= ROUND_THRESHOLD )
- freq3++;
-
- cpu_speed.raw_freq = total_cycles / total_ticks;
- cpu_speed.norm_freq = cpu_speed.raw_freq;
-
- freq = cpu_speed.raw_freq * 10;
- if( (freq3 - freq) >= ROUND_THRESHOLD )
- cpu_speed.norm_freq++;
-
- cpu_speed.ex_ticks = total_ticks;
- cpu_speed.in_cycles = total_cycles;
-
- return cpu_speed;
- }
-
-
- //CPU Speed functions
- /***************************************************************
- * CpuSpeed() -- Return the raw clock rate of the host CPU.
- *
- * Inputs:
- * clocks: 0: Use default value for number of cycles
- * per BSF instruction.
- * -1: Use CMos timer to get cpu speed.
- * Positive Integer: Use clocks value for number
- * of cycles per BSF instruction.
- *
- * Returns:
- * If error then return all zeroes in FREQ_INFO structure
- * Else return FREQ_INFO structure containing calculated
- * clock frequency, normalized clock frequency, number of
- * clock cycles during test sampling, and the number of
- * microseconds elapsed during the sampling.
- ***************************************************************/
-
- struct FREQ_INFO cpuspeed(int clocks)
- {
- ulong cycles; // Clock cycles elapsed
- // during test
-
- ushort processor = wincpuid(); // Family of processor
-
-
- CString vendor;
- DWORD features = wincpufeatures(vendor); // Features of Processor
-
- int manual=0; // Specifies whether the user
- // manually entered the number of
- // cycles for the BSF instruction.
-
- struct FREQ_INFO cpu_speed; // Return structure for
- // cpuspeed
-
- memset(&cpu_speed, 0x00, sizeof(cpu_speed));
-
- // Check for manual BSF instruction clock count
- if (clocks <= 0) {
- cycles = ITERATIONS * processor_cycles[processor];
- }
- else if (0 < clocks && clocks <= MAXCLOCKS) {
- cycles = ITERATIONS * clocks;
- manual = 1; // Toggle manual control flag.
- // Note that this mode will not
- // work properly with processors
- // which can process multiple
- // BSF instructions at a time.
- // For example, manual mode
- // will not work on a
- // PentiumPro(R)
- }
-
- if ( ( features&0x00000010 ) && !(manual) ) {
- // On processors supporting the Read
- // Time Stamp opcode, compare elapsed
- // time on the High-Resolution Counter
- // with elapsed cycles on the Time
- // Stamp Register.
- if ( clocks == 0 )
- return GetRDTSCCpuSpeed();
- else
- return cpu_speed;
- }
- else if ( processor >= 3 ) {
- return GetBSFCpuSpeed(cycles);
- }
-
- return cpu_speed;
-
- } // cpuspeed()
-
-
- // Internal Private Functions //////////////////////////////////
-
- /***************************************************************
- * check_clone()
- *
- * Inputs: none
- *
- * Returns:
- * 1 if processor is clone (limited detection ability)
- * 0 otherwise
- ***************************************************************/
-
- static WORD check_clone()
- {
- short cpu_type=0;
-
- _asm
- {
- MOV AX,5555h // Check to make sure this
- XOR DX,DX // is a 32-bit processor
- MOV CX,2h
- DIV CX // Perform Division
- CLC
- JNZ no_clone
- JMP clone
- no_clone: STC
- clone: PUSHF
- POP AX // Get the flags
- AND AL,1
- XOR AL,1 // AL=0 is probably Intel,
- // AL=1 is a Clone
-
- MOV cpu_type, ax
- }
-
- cpu_type = cpu_type & 0x0001;
-
- return cpu_type;
-
- } // check_clone()
-
- /***************************************************************
- * check_8086()
- *
- * Inputs: none
- *
- * Returns:
- * 0 if processor 8086
- * 0xffff otherwise
- ***************************************************************/
-
- static WORD check_8086()
- {
-
- WORD cpu_type=0xffff;
-
- _asm {
- pushf // Push original FLAGS
- pop ax // Get original FLAGS
- mov cx, ax // Save original FLAGS
- and ax, 0fffh // Clear bits 12-15 in FLAGS
- push ax // Save new FLAGS value on stack
- popf // Replace current FLAGS value
- pushf // Get new FLAGS
- pop ax // Store new FLAGS in AX
- and ax, 0f000h // If bits 12-15 are set, then
- cmp ax, 0f000h // processor is an 8086/8088
- mov cpu_type, 0 // Turn on 8086/8088 flag
- je end_8086 // Jump if processor is 8086/
- // 8088
- mov cpu_type, 0ffffh
- end_8086:
- push cx
- popf
- mov ax, cpu_type
-
- }
-
- return cpu_type;
-
- } // check_8086()
-
-
-
- /***************************************************************
- * check_80286()
- *
- * Inputs: none
- *
- * Returns:
- * 2 if processor 80286
- * 0xffff otherwise
- ***************************************************************/
-
- static WORD check_80286()
- {
-
- WORD cpu_type=0xffff;
-
- _asm {
- pushf
- pop cx
- mov bx, cx
- or cx, 0f000h // Try to set bits 12-15
- push cx // Save new FLAGS value on stack
- popf // Replace current FLAGS value
- pushf // Get new FLAGS
- pop ax // Store new FLAGS in AX
- and ax, 0f000h // If bits 12-15 are clear
-
- mov cpu_type, 2 // Processor=80286, turn on
- // 80286 flag
-
- jz end_80286 // If no bits set, processor is
- // 80286
-
- mov cpu_type, 0ffffh
- end_80286:
- push bx
- popf
- mov ax, cpu_type
-
- }
-
- return cpu_type;
-
- } // check_80286()
-
-
-
- /***************************************************************
- * check_80386()
- *
- * Inputs: none
- *
- * Returns:
- * 3 if processor 80386
- * 0xffff otherwise
- ***************************************************************/
-
- static WORD check_80386()
- {
-
- WORD cpu_type=0xffff;
-
- _asm {
- mov bx, sp
- and sp, not 3
- pushfd // Push original EFLAGS
- pop eax // Get original EFLAGS
- mov ecx, eax // Save original EFLAGS
- xor eax, 40000h // Flip AC bit in EFLAGS
-
- push eax // Save new EFLAGS value on
- // stack
-
- popfd // Replace current EFLAGS value
- pushfd // Get new EFLAGS
- pop eax // Store new EFLAGS in EAX
-
- xor eax, ecx // Can't toggle AC bit,
- // processor=80386
-
- mov cpu_type, 3 // Turn on 80386 processor flag
- jz end_80386 // Jump if 80386 processor
- mov cpu_type, 0ffffh
- end_80386:
- push ecx
- popfd
- mov sp, bx
- mov ax, cpu_type
- and eax, 0000ffffh
- }
-
- return cpu_type;
-
- } // check_80386()
-
-
-
- /***************************************************************
- * check_IDProc()
- *
- * Inputs: none
- *
- * Returns:
- * CPU Family (i.e. 4 if Intel 486, 5 if Pentium(R) Processor)
- *
- * Note: This function also sets the global variable clone_flag
- ***************************************************************/
-
- static WORD check_IDProc() {
-
- int i=0;
- WORD cpu_type=0xffff;
- BYTE stepping=0;
- BYTE model=0;
- BYTE vendor_id[]="------------";
- BYTE intel_id[]="GenuineIntel";
-
- _asm {
-
- xor eax, eax // Set up for CPUID instruction
-
- CPU_ID // Get and save vendor ID
-
- mov dword ptr vendor_id, ebx
- mov dword ptr vendor_id[+4], edx
- mov dword ptr vendor_id[+8], ecx
- }
-
- for (i=0;i<12;i++)
- {
- if (!(vendor_id[i]==intel_id[i]))
- clone_flag = 1;
- }
-
- _asm {
-
- cmp eax, 1 // Make sure 1 is valid input
- // for CPUID
-
- jl end_IDProc // If not, jump to end
- xor eax, eax
- inc eax
- CPU_ID // Get family/model/stepping/
- // features
-
- mov stepping, al
- and stepping, 0x0f //0fh
-
- and al, 0f0h
- shr al, 4
- mov model, al
-
- and eax, 0f00h
- shr eax, 8 // Isolate family
- and eax, 0fh
- mov cpu_type, ax // Set _cpu_type with family
-
- end_IDProc:
- mov ax, cpu_type
- }
-
- return cpu_type;
-
- } // Check_IDProc()
-
-
-