Portability | portable |
---|---|
Stability | stable |
Maintainer | sven.panne@aedion.de |
GLUT supports two types of windows: top-level windows and subwindows. Both types support OpenGL rendering and GLUT callbacks. There is a single identifier space for both types of windows.
- data Window
- createWindow :: String -> IO Window
- createSubWindow :: Window -> Position -> Size -> IO Window
- destroyWindow :: Window -> IO ()
- parentWindow :: GettableStateVar (Maybe Window)
- numSubWindows :: GettableStateVar Int
- currentWindow :: StateVar (Maybe Window)
- postRedisplay :: Maybe Window -> IO ()
- swapBuffers :: IO ()
- windowPosition :: StateVar Position
- windowSize :: StateVar Size
- fullScreen :: IO ()
- fullScreenToggle :: IO ()
- pushWindow :: IO ()
- popWindow :: IO ()
- data WindowStatus
- windowStatus :: SettableStateVar WindowStatus
- windowTitle :: SettableStateVar String
- iconTitle :: SettableStateVar String
- data Cursor
- = RightArrow
- | LeftArrow
- | Info
- | Destroy
- | Help
- | Cycle
- | Spray
- | Wait
- | Text
- | Crosshair
- | UpDown
- | LeftRight
- | TopSide
- | BottomSide
- | LeftSide
- | RightSide
- | TopLeftCorner
- | TopRightCorner
- | BottomRightCorner
- | BottomLeftCorner
- | Inherit
- | None
- | FullCrosshair
- cursor :: StateVar Cursor
- pointerPosition :: SettableStateVar Position
Window identifiers
An opaque identifier for a top-level window or a subwindow.
Creating and destroying (sub-)windows
Each created window has a unique associated OpenGL context. State changes to a window's associated OpenGL context can be done immediately after the window is created.
The display state of a window is initially for the window to be shown. But
the window's display state is not actually acted upon until
Graphics.UI.GLUT.Begin.mainLoop
is entered. This means until
Graphics.UI.GLUT.Begin.mainLoop
is called, rendering to a created window is
ineffective because the window can not yet be displayed.
The value returned by createWindow
and createSubWindow
is a unique
identifier for the window, which can be used with currentWindow
.
Create a top-level window. The given name will be provided to the window system as the window's name. The intent is that the window system will label the window with the name.Implicitly, the current window is set to the newly created window.
X Implementation Notes: The proper X Inter-Client Communication Conventions
Manual (ICCCM) top-level properties are established. The WM_COMMAND
property that lists the command line used to invoke the GLUT program is only
established for the first window created.
:: Window | Identifier of the subwindow's parent window. |
-> Position | Window position in pixels relative to parent window's origin. |
-> Size | Window size in pixels |
-> IO Window | The identifier for the newly created subwindow |
Create a subwindow of the identified window with the given relative position and size. Implicitly, the current window is set to the newly created subwindow. Subwindows can be nested arbitrarily deep.
destroyWindow :: Window -> IO ()Source
Destroy the specified window and the window's associated OpenGL context,
logical colormap (if the window is color index), and overlay and related
state (if an overlay has been established). Any subwindows of the destroyed
window are also destroyed by destroyWindow
. If the specified window was the
current window, the current window becomes invalid (currentWindow
will
contain Nothing
).
parentWindow :: GettableStateVar (Maybe Window)Source
Contains the current window\'s parent. If the current window is a
top-level window, Nothing
is returned.
numSubWindows :: GettableStateVar IntSource
Contains the number of subwindows the current window has, not counting children of children.
Manipulating the current window
Re-displaying and double buffer management
postRedisplay :: Maybe Window -> IO ()Source
Mark the normal plane of given window (or the current window, if none
is supplied) as needing to be redisplayed. The next iteration through
Graphics.UI.GLUT.Begin.mainLoop
, the window's display callback will be
called to redisplay the window's normal plane. Multiple calls to
postRedisplay
before the next display callback opportunity generates only a
single redisplay callback. postRedisplay
may be called within a window's
display or overlay display callback to re-mark that window for redisplay.
Logically, normal plane damage notification for a window is treated as a
postRedisplay
on the damaged window. Unlike damage reported by the window
system, postRedisplay
will not set to true the normal plane's damaged
status (see Graphics.UI.GLUT.State.damaged
).
Also, see Graphics.UI.GLUT.Overlay.postOverlayRedisplay
.
Mark the normal plane of the given window as needing to be redisplayed,
otherwise the same as postRedisplay
.
The advantage of this routine is that it saves the cost of using
currentWindow
(entailing an expensive OpenGL context switch), which is
particularly useful when multiple windows need redisplays posted at the same
time.
Perform a buffer swap on the layer in use for the current window.
Specifically, swapBuffers
promotes 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 swapBuffers
is called.
An implicit Graphics.Rendering.OpenGL.GL.FlushFinish.flush
is done by
swapBuffers
before it returns. Subsequent OpenGL 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.
Changing the window geometry
Note that the requests by windowPosition
, windowSize
, and fullScreen
are not processed immediately. A request is executed after returning to the
main event loop. This allows multiple requests to the same window to be
coalesced.
windowPosition
and windowSize
requests on a window will disable the full
screen status of the window.
windowPosition :: StateVar PositionSource
Controls the position of the current window. For top-level windows,
parameters of Position
are pixel offsets from the screen origin. For
subwindows, the parameters are pixel offsets from the window's parent window
origin.
In the case of top-level windows, setting windowPosition
is considered only
a request for positioning the window. The window system is free to apply its
own policies to top-level window placement. The intent is that top-level
windows should be repositioned according to the value of windowPosition
.
windowSize :: StateVar SizeSource
Controls the size of the current window. The parameters of Size
are
size extents in pixels. The width and height must be positive values.
In the case of top-level windows, setting windowSize
is considered only a
request for sizing the window. The window system is free to apply its own
policies to top-level window sizing. The intent is that top-level windows
should be reshaped according to the value of windowSize
. Whether a reshape
actually takes effect and, if so, the reshaped dimensions are reported to the
program by a reshape callback.
fullScreen :: IO ()Source
Request 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.
fullScreen
is defined to work only on top-level windows.
X Implementation Notes: In the X implementation of GLUT, full screen is
implemented by sizing and positioning the window to cover the entire screen
and posting the _MOTIF_WM_HINTS
property on the window requesting
absolutely no decorations. Non-Motif window managers may not respond to
_MOTIF_WM_HINTS
.
fullScreenToggle :: IO ()Source
(freeglut only) Toggle between windowed and full screen mode.
Manipulating the stacking order
pushWindow
and popWindow
work on both 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 pop or push 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.
pushWindow :: IO ()Source
Change the stacking order of the current window relative to its siblings (lowering it).
Change the stacking order of the current window relative to its siblings, bringing the current window closer to the top.
Managing a window's display status
data WindowStatus Source
The display status of a window.
windowStatus :: SettableStateVar WindowStatusSource
Controls the display status of the current window.
Note that 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. The effect of hiding, showing, or iconifying top-level windows is subject to the window system's policy for displaying windows. Subwindows can't be iconified.
Changing the window/icon title
windowTitle
and iconTitle
should be set 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 given to createWindow
.
Once created, setting windowTitle
and iconTitle
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.
windowTitle :: SettableStateVar StringSource
Controls the window title of the current top-level window.
iconTitle :: SettableStateVar StringSource
Controls the icon title of the current top-level window.
Cursor management
The different cursor images GLUT supports.
RightArrow | Arrow pointing up and to the right. |
LeftArrow | Arrow pointing up and to the left. |
Info | Pointing hand. |
Destroy | Skull & cross bones. |
Help | Question mark. |
Cycle | Arrows rotating in a circle. |
Spray | Spray can. |
Wait | Wrist watch. |
Text | Insertion point cursor for text. |
Crosshair | Simple cross-hair. |
UpDown | Bi-directional pointing up & down. |
LeftRight | Bi-directional pointing left & right. |
TopSide | Arrow pointing to top side. |
BottomSide | Arrow pointing to bottom side. |
LeftSide | Arrow pointing to left side. |
RightSide | Arrow pointing to right side. |
TopLeftCorner | Arrow pointing to top-left corner. |
TopRightCorner | Arrow pointing to top-right corner. |
BottomRightCorner | Arrow pointing to bottom-left corner. |
BottomLeftCorner | Arrow pointing to bottom-right corner. |
Inherit | Use parent's cursor. |
None | Invisible cursor. |
FullCrosshair | Full-screen cross-hair cursor (if possible, otherwise |
cursor :: StateVar CursorSource
Change 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 Inherit
. 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, Inherit
uses the default window system
cursor.
X Implementation Notes: GLUT for X uses SGI's _SGI_CROSSHAIR_CURSOR
convention to access a full-screen cross-hair cursor if possible.
pointerPosition :: SettableStateVar PositionSource
Setting pointerPosition
warps the window system's pointer to a new
location relative to the origin of the current window by the specified
pixel offset, which 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. The window system is allowed to further constrain the pointer's location in window system dependent ways.
Good advice from Xlib's XWarpPointer
man page: "There is seldom any
reason for calling this function. The pointer should normally be left to the
user."