/* * Set the current window's title */ void fgPlatformGlutSetWindowTitle( const char* title ) { #if defined(MIKTEX_WINDOWS) && defined(_UNICODE) wchar_t miktex_wchar_title[1024]; miktex_utf8_to_wide_char(title, 1024, miktex_wchar_title); #endif #ifdef _WIN32_WCE { wchar_t* wstr = fghWstrFromStr(title); SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr ); free(wstr); } #else if (!IsIconic(fgStructure.CurrentWindow->Window.Handle)) #if defined(MIKTEX_WINDOWS) && defined(_UNICODE) SetWindowText(fgStructure.CurrentWindow->Window.Handle, miktex_wchar_title); #else SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); #endif #endif /* Make copy of string to refer to later */ if (fgStructure.CurrentWindow->State.pWState.WindowTitle) free(fgStructure.CurrentWindow->State.pWState.WindowTitle); #if defined(MIKTEX_WINDOWS) && defined(_UNICODE) fgStructure.CurrentWindow->State.pWState.WindowTitle = miktex_uw_strdup(title); #else fgStructure.CurrentWindow->State.pWState.WindowTitle = strdup(title); #endif }
/* * Set the current window's iconified title * There really isn't a way to set the icon name separate from the * windows name in Win32, so, just set the windows name. */ void fgPlatformGlutSetIconTitle( const char* title ) { #ifdef _WIN32_WCE { wchar_t* wstr = fghWstrFromStr(title); SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr ); free(wstr); } #else SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); #endif }
/* * Set the current window's title */ void fgPlatformGlutSetWindowTitle( const char* title ) { #ifdef _WIN32_WCE { wchar_t* wstr = fghWstrFromStr(title); SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr ); free(wstr); } #else if (!IsIconic(fgStructure.CurrentWindow->Window.Handle)) SetWindowText( fgStructure.CurrentWindow->Window.Handle, title ); #endif /* Make copy of string to refer to later */ if (fgStructure.CurrentWindow->State.pWState.WindowTitle) free(fgStructure.CurrentWindow->State.pWState.WindowTitle); fgStructure.CurrentWindow->State.pWState.WindowTitle = strdup(title); }
/* * Set the current window's iconified title */ void FGAPIENTRY glutSetIconTitle( const char* title ) { FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetIconTitle" ); FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetIconTitle" ); if( ! fgStructure.CurrentWindow->Parent ) { #if TARGET_HOST_UNIX_X11 XTextProperty text; text.value = (unsigned char *) title; text.encoding = XA_STRING; text.format = 8; text.nitems = strlen( title ); XSetWMIconName( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle, &text ); XFlush( fgDisplay.Display ); /* XXX Shouldn't need this */ #elif TARGET_HOST_WIN32 SetWindowTextA( fgStructure.CurrentWindow->Window.Handle, title ); #elif TARGET_HOST_WINCE { wchar_t* wstr = fghWstrFromStr(title); SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr ); free(wstr); } #endif } }
/* * Opens a window. Requires a SFG_Window object created and attached * to the freeglut structure. OpenGL context is created here. */ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, GLboolean isSubWindow ) { #if TARGET_HOST_UNIX_X11 XSetWindowAttributes winAttr; XTextProperty textProperty; XSizeHints sizeHints; XWMHints wmHints; unsigned long mask; unsigned int current_DisplayMode = fgState.DisplayMode ; /* Save the display mode if we are creating a menu window */ if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = GLUT_DOUBLE | GLUT_RGB ; window->Window.VisualInfo = fgChooseVisual( ); if( window->IsMenu && ( ! fgStructure.MenuContext ) ) fgState.DisplayMode = current_DisplayMode ; if( ! window->Window.VisualInfo ) { /* * The "fgChooseVisual" returned a null meaning that the visual * context is not available. * Try a couple of variations to see if they will work. */ if( !( fgState.DisplayMode & GLUT_DOUBLE ) ) { fgState.DisplayMode |= GLUT_DOUBLE ; window->Window.VisualInfo = fgChooseVisual( ); fgState.DisplayMode &= ~GLUT_DOUBLE; } /* * GLUT also checks for multi-sampling, but I don't see that * anywhere else in FREEGLUT so I won't bother with it for the moment. */ } FREEGLUT_INTERNAL_ERROR_EXIT( window->Window.VisualInfo != NULL, "Visual with necessary capabilities not found", "fgOpenWindow" ); /* * XXX HINT: the masks should be updated when adding/removing callbacks. * XXX This might speed up message processing. Is that true? * XXX * XXX A: Not appreciably, but it WILL make it easier to debug. * XXX Try tracing old GLUT and try tracing freeglut. Old GLUT * XXX turns off events that it doesn't need and is a whole lot * XXX more pleasant to trace. (Think mouse-motion! Tons of * XXX ``bonus'' GUI events stream in.) */ winAttr.event_mask = StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask; winAttr.background_pixmap = None; winAttr.background_pixel = 0; winAttr.border_pixel = 0; winAttr.colormap = XCreateColormap( fgDisplay.Display, fgDisplay.RootWindow, window->Window.VisualInfo->visual, AllocNone ); mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; if( window->IsMenu || ( gameMode == GL_TRUE ) ) { winAttr.override_redirect = True; mask |= CWOverrideRedirect; } window->Window.Handle = XCreateWindow( fgDisplay.Display, window->Parent == NULL ? fgDisplay.RootWindow : window->Parent->Window.Handle, x, y, w, h, 0, window->Window.VisualInfo->depth, InputOutput, window->Window.VisualInfo->visual, mask, &winAttr ); /* * The GLX context creation, possibly trying the direct context rendering * or else use the current context if the user has so specified */ if( window->IsMenu ) { /* * If there isn't already an OpenGL rendering context for menu * windows, make one */ if( !fgStructure.MenuContext ) { fgStructure.MenuContext = (SFG_MenuContext *)malloc( sizeof(SFG_MenuContext) ); fgStructure.MenuContext->VisualInfo = window->Window.VisualInfo; fgStructure.MenuContext->Context = glXCreateContext( fgDisplay.Display, fgStructure.MenuContext->VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } /* window->Window.Context = fgStructure.MenuContext->Context; */ window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else if( fgState.UseCurrentContext ) { window->Window.Context = glXGetCurrentContext( ); if( ! window->Window.Context ) window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); } else window->Window.Context = glXCreateContext( fgDisplay.Display, window->Window.VisualInfo, NULL, ( fgState.DirectContext != GLUT_FORCE_INDIRECT_CONTEXT ) ); #if !defined( __FreeBSD__ ) && !defined( __NetBSD__ ) if( !glXIsDirect( fgDisplay.Display, window->Window.Context ) ) { if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT ) fgError( "Unable to force direct context rendering for window '%s'", title ); else if( fgState.DirectContext == GLUT_TRY_DIRECT_CONTEXT ) fgWarning( "Unable to create direct context rendering for window '%s'\nThis may hurt performance.", title ); } #endif /* * XXX Assume the new window is visible by default * XXX Is this a safe assumption? */ window->State.Visible = GL_TRUE; sizeHints.flags = 0; if ( fgState.Position.Use ) sizeHints.flags |= USPosition; if ( fgState.Size.Use ) sizeHints.flags |= USSize; /* * Fill in the size hints values now (the x, y, width and height * settings are obsolete, are there any more WMs that support them?) * Unless the X servers actually stop supporting these, we should * continue to fill them in. It is *not* our place to tell the user * that they should replace a window manager that they like, and which * works, just because *we* think that it's not "modern" enough. */ sizeHints.x = x; sizeHints.y = y; sizeHints.width = w; sizeHints.height = h; wmHints.flags = StateHint; wmHints.initial_state = fgState.ForceIconic ? IconicState : NormalState; /* Prepare the window and iconified window names... */ XStringListToTextProperty( (char **) &title, 1, &textProperty ); XSetWMProperties( fgDisplay.Display, window->Window.Handle, &textProperty, &textProperty, 0, 0, &sizeHints, &wmHints, NULL ); XFree( textProperty.value ); XSetWMProtocols( fgDisplay.Display, window->Window.Handle, &fgDisplay.DeleteWindow, 1 ); glXMakeCurrent( fgDisplay.Display, window->Window.Handle, window->Window.Context ); XMapWindow( fgDisplay.Display, window->Window.Handle ); #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE WNDCLASS wc; DWORD flags; DWORD exFlags = 0; ATOM atom; /* Grab the window class we have registered on glutInit(): */ atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc ); FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Info Not Found", "fgOpenWindow" ); if( gameMode ) { FREEGLUT_INTERNAL_ERROR_EXIT ( window->Parent == NULL, "Game mode being invoked on a subwindow", "fgOpenWindow" ); /* * Set the window creation flags appropriately to make the window * entirely visible: */ flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; } else { #if !TARGET_HOST_WINCE if ( ( ! isSubWindow ) && ( ! window->IsMenu ) ) { /* * Update the window dimensions, taking account of window * decorations. "freeglut" is to create the window with the * outside of its border at (x,y) and with dimensions (w,h). */ w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2; h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION ); } #endif /* TARGET_HOST_WINCE */ if( ! fgState.Position.Use ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; } if( ! fgState.Size.Use ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; } /* * There's a small difference between creating the top, child and * game mode windows */ flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; if ( window->IsMenu ) { flags |= WS_POPUP; exFlags |= WS_EX_TOOLWINDOW; } #if !TARGET_HOST_WINCE else if( window->Parent == NULL ) flags |= WS_OVERLAPPEDWINDOW; #endif else flags |= WS_CHILD; } #if TARGET_HOST_WINCE { wchar_t* wstr = fghWstrFromStr(title); window->Window.Handle = CreateWindow( _T("FREEGLUT"), wstr, WS_VISIBLE | WS_POPUP, 0,0, 240,320, NULL, NULL, fgDisplay.Instance, (LPVOID) window ); free(wstr); SHFullScreen(window->Window.Handle, SHFS_HIDESTARTICON); SHFullScreen(window->Window.Handle, SHFS_HIDESIPBUTTON); SHFullScreen(window->Window.Handle, SHFS_HIDETASKBAR); MoveWindow(window->Window.Handle, 0, 0, 240, 320, TRUE); ShowWindow(window->Window.Handle, SW_SHOW); UpdateWindow(window->Window.Handle); } #else window->Window.Handle = CreateWindowExA( exFlags, "FREEGLUT", title, flags, x, y, w, h, (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle, (HMENU) NULL, fgDisplay.Instance, (LPVOID) window ); #endif /* TARGET_HOST_WINCE */ if( !( window->Window.Handle ) ) fgError( "Failed to create a window (%s)!", title ); #if TARGET_HOST_WINCE ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); #endif /* TARGET_HOST_WINCE */ UpdateWindow( window->Window.Handle ); ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */ #endif fgSetWindow( window ); window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0; if ( ! window->Window.DoubleBuffered ) { glDrawBuffer ( GL_FRONT ); glReadBuffer ( GL_FRONT ); } }
/* * Opens a window. Requires a SFG_Window object created and attached * to the freeglut structure. OpenGL context is created here. */ void fgPlatformOpenWindow( SFG_Window* window, const char* title, GLboolean positionUse, int x, int y, GLboolean sizeUse, int w, int h, GLboolean gameMode, GLboolean isSubWindow ) { WNDCLASS wc; DWORD flags = 0; DWORD exFlags = 0; ATOM atom; /* Grab the window class we have registered on glutInit(): */ atom = GetClassInfo( fgDisplay.pDisplay.Instance, _T("FREEGLUT"), &wc ); FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Info Not Found", "fgOpenWindow" ); /* Determine window style flags*/ if( gameMode ) { FREEGLUT_INTERNAL_ERROR_EXIT ( window->Parent == NULL, "Game mode being invoked on a subwindow", "fgOpenWindow" ); /* * Set the window creation flags appropriately to make the window * entirely visible: */ flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; } else { flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; /* * There's a small difference between creating the top, child and * menu windows */ if ( window->IsMenu ) { flags |= WS_POPUP; exFlags |= WS_EX_TOOLWINDOW; } #if defined(_WIN32_WCE) /* no decorations for windows CE */ #else /* if this is not a subwindow (child), set its style based on the requested window decorations */ else if( window->Parent == NULL ) fghGetDefaultWindowStyle(&flags); #endif else /* subwindows always have no decoration, but are marked as a child window to the OS */ flags |= WS_CHILD; } /* determine window size and position */ if( gameMode ) { /* if in gamemode, query the origin of specified by the -display * command line parameter (if any) and offset the upper-left corner * of the window so we create the window on that screen. * The -display argument doesn't do anything if not trying to enter * gamemode. */ int xoff=0, yoff=0; get_display_origin(&xoff,&yoff); x += xoff; y += yoff; } if( !positionUse ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; } if( !sizeUse ) { if( ! window->IsMenu ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; } else /* fail safe - Windows can make a window of size (0, 0) */ w = h = 300; /* default window size */ } /* store requested client area width and height */ window->State.Width = w; window->State.Height = h; #if !defined(_WIN32_WCE) /* no decorations for windows CE */ if( sizeUse ) { RECT windowRect; /* * Update the window dimensions, taking the window decorations * into account. FreeGLUT is to create the window with the * topleft outside corner at (x,y) and with client area * dimensions (w,h). * note: don't need to do this when w=h=CW_USEDEFAULT, so in the * if( sizeUse ) here is convenient. */ windowRect.left = x; windowRect.top = y; windowRect.right = x+w; windowRect.bottom = y+h; fghComputeWindowRectFromClientArea_UseStyle(&windowRect,flags,exFlags,TRUE); /* NB: w and h are now width and height of window including non-client area! */ w = windowRect.right - windowRect.left; h = windowRect.bottom- windowRect.top; } #endif /* !defined(_WIN32_WCE) */ #if defined(_WIN32_WCE) { wchar_t* wstr = fghWstrFromStr(title); window->Window.Handle = CreateWindow( _T("FREEGLUT"), wstr, WS_VISIBLE | WS_POPUP, 0,0, 240,320, NULL, NULL, fgDisplay.pDisplay.Instance, (LPVOID) window ); free(wstr); SHFullScreen(window->Window.Handle, SHFS_HIDESTARTICON); SHFullScreen(window->Window.Handle, SHFS_HIDESIPBUTTON); SHFullScreen(window->Window.Handle, SHFS_HIDETASKBAR); MoveWindow(window->Window.Handle, 0, 0, 240, 320, TRUE); ShowWindow(window->Window.Handle, SW_SHOW); UpdateWindow(window->Window.Handle); } #else window->Window.Handle = CreateWindowEx( exFlags, _T("FREEGLUT"), title, flags, x, y, w, h, (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle, (HMENU) NULL, fgDisplay.pDisplay.Instance, (LPVOID) window ); #endif /* defined(_WIN32_WCE) */ if( !( window->Window.Handle ) ) fgError( "Failed to create a window (%s)!", title ); #if !defined(_WIN32_WCE) /* Need to set requested style again, apparently Windows doesn't listen when requesting windows without title bar or borders */ SetWindowLong(window->Window.Handle, GWL_STYLE, flags); SetWindowPos(window->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); #endif /* defined(_WIN32_WCE) */ /* Make a menu window always on top - fix Feature Request 947118 */ if( window->IsMenu || gameMode ) SetWindowPos( window->Window.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); /* Enable multitouch: additional flag TWF_FINETOUCH, TWF_WANTPALM */ #ifdef WM_TOUCH if (fghRegisterTouchWindow == (pRegisterTouchWindow)0xDEADBEEF) fghRegisterTouchWindow = (pRegisterTouchWindow)GetProcAddress(GetModuleHandle("user32"),"RegisterTouchWindow"); if (fghRegisterTouchWindow) fghRegisterTouchWindow( window->Window.Handle, TWF_FINETOUCH | TWF_WANTPALM ); #endif #if defined(_WIN32_WCE) ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); #endif /* defined(_WIN32_WCE) */ UpdateWindow( window->Window.Handle ); ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */ }