Window Management
(updated in 30/08/2001)

Previous | Index | Next

The only two things you know about "window management" by now are how to create a window (via createWindow) and how to tell your program that you wish your window to be redisplayed (via postRedisplay). As you may have guessed, there are a lot of other things that you can do with a window.

Before we start, it is important to keep two things in mind:

  • What is a window in HOpenGL? Here comes the answer:
    		newtype Window = Window Int deriving (Eq,Ord)
    	
    In other words, each window is associated to an identifier (Int). The range of allocated identifiers starts at one. The function createWindow returns a IO Window, so it is always possible to keep the identifier of a created window using:
    		w1 <- createWindow ...
    	
  • The callback procedures (keyboardFunc, mouseFunc, etc.) are associated to a specific window. These procedures are part of the window context (let's think of this as being the collection of all window properties). Each created window has a unique associated context. State changes to a window's associated context can be done immediately after the window is created.

For example, you must declare a keyboardFunc twice if you pretend to read keyboard inputs in two different windows. Notice that the function declared can be the same for both windows. Watch carefully the following code:

	main :: IO ()
	main = do
		GLUT.init Nothing
		w1 <- createWindow "Hello World" (return ()) [ Single, GLUT.Rgb ]
				(Just (WindowPosition 100 100))
				(Just (WindowSize     300 250))
		keyboardFunc (Just keyboard)
		mouseFunc (Just mouse1)
		w2 <- createWindow "Hello World, again!" (return ()) [ Single, GLUT.Rgb ]
				(Just (WindowPosition 100 100))
				(Just (WindowSize     300 250))
		keyboardFunc (Just keyboard)
		mouseFunc (Just mouse2)
		myInit
		mainLoop

In this example, two windows were created. When a keyboard key is pressed and the first window (w1) is active, the function keyboard is going to deal with this input. The same happens when the active window is w2. But when a mouse button is pressed, the function that is going to deal with this input will be mouse1, if the active window is w1, or mouse2, if the active window is w2. As you noticed, each window needs its own declaration of callback procedures, but the function indicated by them can be the same.


Once you understood this introduction, let's take a look on what you can do with windows:


Create a Window

Function:

		createWindow :: String -> DisplayAction -> [DisplayMode]
				-> Maybe WindowPosition -> Maybe WindowSize -> IO Window

Usage and Comments: The current window is set to the newly created window. All you need to know about this function was already described in the Your First (and Simple) Program lesson. Check out it if you still have any doubts. Perhaps the only thing you don't know by now is the values of a DisplayMode. They are:

  • Rgb
  • Rgba
  • Index
  • Single
  • Double
  • Accum
  • Alpha
  • Depth
  • Stencil
  • Multisample
  • Stereo
  • Luminance
back!

Create a subwindow

Function: createSubWindow :: Window -> WindowPosition -> WindowSize -> IO Window

Usage: createSubWindow (parent window) (WindowPosition posX posY) (WindowSize width height)

Comments: All values of WindowPosition and WindowSize are related to pixels. The current window is set to the newly created subwindow. Subwindows can be nested arbitrarily deep.

back!

Set the current window

Function: setWindow :: Window -> IO ()

Usage: setWindow (identifier of GLUT window to make the current window)

Comments: You can create a lot of windows first, then declare their callback procedures one by one, usging setWindow to set the current window. Perhaps this will generate a "cleaner" code.

back!

Get the identifier of the current window

Function: getWindow :: IO Window

Usage: getWindow

Comments: If no windows exist or the previously current window was destroyed, getWindow returns zero.

back!

Destroy a window

Function: destroyWindow :: Window -> IO ()

Usage: destroyWindow (identifier of GLUT window to destroy)

Comments: Any subwindows of destroyed windows are also destroyed. If the [identifier of GLUT window to destroy] was the current window, the current window becomes invalid (getWindow will return zero).

back!

Force a window to be redisplayed

Function: postWindowRedisplay :: Window -> IO ()

Usage: postWindowRedisplay (identifier of GLUT window to redisplay)

Comments: The postRedisplay function you already know forces the current window to be redisplayed.

back!

Swap the front and back buffers of a window

Function: swapBuffers :: IO ()

Usage: swapBuffers

Comments: The contents of the back buffer of the layer in use of the current window to become the contents of the front buffer. The contents of the back buffer then become undefined. The update typically takes place during the vertical retrace of the monitor, rather than immediately after glutSwapBuffers is called. Subsequent HOpenGL commands can be issued immediately after calling swapBuffers, but are not executed until the buffer exchange is completed. If the layer in use is not double buffered, swapBuffers has no effect.

back!

Change the position of a window

Function: positionWindow :: WindowPosition -> IO ()

Usage: positionWindow (WindowPosition posX posY)

Comments: For top-level windows, the posX and posY parameters are pixel offsets from the screen origin. For subwindows, the posX and posY parameters are pixel offsets from the window's parent window origin. This function disables the full screen status of a window if previously enabled.

back!

Reshape a window

Function: reshapeWindow :: WindowSize -> IO ()

Usage: reshapeWindow (WindowSize width height)

Comments: reshapeWindow requests a change in the size of the current window. Whether a reshape actually takes effect and, if so, the reshaped dimensions are reported to the program by a reshape callback (reshapeFunc). This function disables the full screen status of a window if previously enabled.

back!

Set the window with full-screen mode

Function: fullScreen :: IO ()

Usage: fullScreen

Comments: fullScreen requests that the current window be made full screen. The exact semantics of what full screen means may vary by window system. The intent is to make the window as large as possible and disable any window decorations or borders added the window system. The window width and height are not guaranteed to be the same as the screen width and height, but that is the intent of making a window full screen. Subsequent reshapeWindow and positionWindow requests on the window will disable the full screen status of the window. This funtion is defined to work only on top-level windows

back!

Change the stacking order of a window relative to its siblings

Functions:

		popWindow :: IO ()
		pushWindow :: IO ()

Usage:

		popWindow
		pushWindow

Comments: Both of these functions work on top-level windows and subwindows. The effect of pushing and popping windows does not take place immediately. Instead the push or pop is saved for execution upon return to the GLUT event loop. Subsequent push or pop requests on a window replace the previously saved request for that window. The effect of pushing and popping top-level windows is subject to the window system's policy for restacking windows.

back!

Hide a window

Function: hideWindow :: IO ()

Usage: hideWindow

Comments: hideWindow will hide the current window. The effect of showing, hiding, and iconifying windows does not take place immediately. Instead the requests are saved for execution upon return to the GLUT event loop. Subsequent show, hide, or iconification requests on a window replace the previously saved request for that window.

back!

Iconify a window

Function: iconifyWindow :: IO ()

Usage: iconifyWindow

Comments: iconifyWindow will iconify a top-level window, but GLUT prohibits iconification of a subwindow. The effect of showing, hiding, and iconifying windows does not take place immediately. Instead the requests are saved for execution upon return to the GLUT event loop. Subsequent show, hide, or iconification requests on a window replace the previously saved request for that window.

back!

Show a window

Function: showWindow :: IO ()

Usage: showWindow

Comments: showWindow will show the current window (though it may still not be visible if obscured by other shown windows). The effect of showing, hiding, and iconifying windows does not take place immediately. Instead the requests are saved for execution upon return to the GLUT event loop. Subsequent show, hide, or iconification requests on a window replace the previously saved request for that window.

back!

Set the window/icon title of a window

Functions:

		setWindowTitle :: String -> IO ()
		setIconTitle :: String -> IO ()

Usage:

		setWindowTitle (ASCII character string for the window name to be set for the window)
		setIconTitle (ASCII character string for the icon name to be set for the window)

Comments: These routines should be called only when the current window is a top-level window. Upon creation of a top-level window, the window and icon names are determined by the name parameter to createWindow. Once created, setWindowTitle and setIconTitle can change the window and icon names respectively of top-level windows. Each call requests the window system change the title appropriately. Requests are not buffered or coalesced. The policy by which the window and icon name are displayed is window system dependent. Both function have the same effect under Windows 95/98/NT.

back!

Set the cursor image of a window

Function: setCursor :: Cursor -> IO ()

Usage: setCursor (name of cursor image to change to)

Comments: The options for the [name of cursor image to change to] are:

  • CursorRightArrow - arrow pointing up and to the right.
  • CursorLeftArrow - arrow pointing up and to the left.
  • CursorInfo - pointing hand.
  • CursorDestroy - skull & cross bones.
  • CursorHelp - question mark.
  • CursorCycle - arrows rotating in a circle.
  • CursorSpray - spray can.
  • CursorWait - wrist watch.
  • CursorText - insertion point cursor for text.
  • CursorCrosshair - simple cross-hair.
  • CursorUpDown - bi-directional pointing up & down.
  • CursorLeftRight - bi-directional pointing left & right.
  • CursorTopSide - arrow pointing to top side.
  • CursorBottomSide - arrow pointing to bottom side.
  • CursorLeftSide - arrow pointing to left side.
  • CursorRightSide - arrow pointing to right side.
  • CursorTopLeftCorner - arrow pointing to top-left corner.
  • CursorTopRightCorner - arrow pointing to top-right corner.
  • CursorBottomRightCorner - arrow pointing to bottom-left corner.
  • CursorBottomLeftCorner - arrow pointing to bottom-right corner.
  • CursorInherit - use parent's cursor.
  • CursorNone - invisible cursor.
  • CursorFullCrosshair - full-screen cross-hair cursor (if possible, otherwise CursorCrosshair).

Comments (continuation): This function changes the cursor image of the current window. Each call requests the window system change the cursor appropriately. The cursor image when a window is created is CursorInherit. The exact cursor images used are implementation dependent. The intent is for the image to convey the meaning of the cursor name. For a top-level window, CursorInherit uses the default window system cursor.

back!

Warp the pointer's location in a window

Function: warpPointer :: WindowPosition -> IO ()

Usage: warpPointer (WindowPosition posX posY)

Comments: This function warps the window system's pointer to a new location relative to the origin of the current window. The new location will be offset posX pixels on the X axis and posY pixels on the Y axis. These parameters may be negative. The warp is done immediately. If the pointer would be warped outside the screen's frame buffer region, the location will be clamped to the nearest screen edge.

back!

The function createWindow is defined in module GLUT_Init. The other ones, in module GLUT_Window. Both of them are imported with you program already imports module GLUT.

I would like to thank The OpenGL Utility Toolkit (GLUT) Programming Interface API Version 3 Documentation, created by Mark J. Kilgard, Silicon Graphics, Inc. It was very important for the development of this lesson.



HOpenGL Tutorial - Andre W B Furtado
Window Management
www.cin.ufpe.br/~haskell/hopengl/window.html
Last updated in 30/08/2001
Informatics Center (CIn) - UFPE
Recife - PE - Brazil