<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://cegui.org.uk/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Black</id>
		<title>CEGUI Wiki - Crazy Eddie's GUI System (Open Source) - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://cegui.org.uk/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Black"/>
		<link rel="alternate" type="text/html" href="http://cegui.org.uk/wiki/Special:Contributions/Black"/>
		<updated>2026-04-12T08:49:00Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.24.1</generator>

	<entry>
		<id>http://cegui.org.uk/wiki/index.php?title=Using_CEGUI_with_GLUT&amp;diff=3205</id>
		<title>Using CEGUI with GLUT</title>
		<link rel="alternate" type="text/html" href="http://cegui.org.uk/wiki/index.php?title=Using_CEGUI_with_GLUT&amp;diff=3205"/>
				<updated>2008-07-17T21:26:23Z</updated>
		
		<summary type="html">&lt;p&gt;Black: /* Creating a Renderer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GLUT is the OpenGL Utility Toolkit.  It was designed to make it easy to create&lt;br /&gt;
simple OpenGL application across different platforms. One reason to use GLUT is&lt;br /&gt;
you may want a basic life support system while you design your CEGUI code.&lt;br /&gt;
GLUT lets you get up and running with minimal code and dependencies.&lt;br /&gt;
&lt;br /&gt;
On the other hand, GLUT has a wonky input system that you may find inadequate,&lt;br /&gt;
especially if your GUI needs exotic keypress combinations or unicode support.&lt;br /&gt;
&lt;br /&gt;
The information presented here is the result of a couple days of tinkering with&lt;br /&gt;
CEGUI and FreeGLUT on Linux.  Let me clearly state that I am an not an expert&lt;br /&gt;
on CEGUI, GLUT, C++, or Linux and the things I say may not be the optimum&lt;br /&gt;
approaches.  This information is presented with the simple hope that some may&lt;br /&gt;
find it useful.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The Loop==&lt;br /&gt;
&lt;br /&gt;
We're going to specify FreeGLUT instead of GLUT because we need one of the new&lt;br /&gt;
functions added.  In GLUT you call glutMainLoop() and it never comes back.&lt;br /&gt;
FreeGLUT gives us glutMainLoopEvent which invokes one loop and then returns&lt;br /&gt;
control.  We need this arrangement so we can call CEGUI's renderer later.&lt;br /&gt;
&lt;br /&gt;
This is a simple teapot drawing app which should compile and run provided you&lt;br /&gt;
have an OpenGL capable display and freeglut + freeglut-devel packages&lt;br /&gt;
installed.&lt;br /&gt;
&lt;br /&gt;
Note the while(keep_running){} loop.&lt;br /&gt;
&lt;br /&gt;
 //glut_loop.cpp&lt;br /&gt;
 //&lt;br /&gt;
 #include &amp;lt;GL/freeglut.h&amp;gt;&lt;br /&gt;
 //&lt;br /&gt;
 void render(void);&lt;br /&gt;
 void keyFunc(unsigned char, int, int);&lt;br /&gt;
 int window_id;&lt;br /&gt;
 bool keep_running = true;&lt;br /&gt;
 //&lt;br /&gt;
 // A barebones GLUT application&lt;br /&gt;
 //&lt;br /&gt;
 int main()&lt;br /&gt;
     {&lt;br /&gt;
     // Create our OpenGL Window&lt;br /&gt;
     int fake_argc = 1;&lt;br /&gt;
     char* fake_argv;&lt;br /&gt;
     glutInit(&amp;amp;fake_argc, &amp;amp;fake_argv);&lt;br /&gt;
     glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);&lt;br /&gt;
     glutInitWindowSize(640, 480);&lt;br /&gt;
     window_id = glutCreateWindow(&amp;quot;GLUT Loop&amp;quot;);&lt;br /&gt;
     // Set the function to handle normal key presses&lt;br /&gt;
     glutKeyboardFunc(keyFunc);&lt;br /&gt;
     // Begin the loop&lt;br /&gt;
     while(keep_running)&lt;br /&gt;
         {&lt;br /&gt;
         glutMainLoopEvent();&lt;br /&gt;
         render();&lt;br /&gt;
         glutSwapBuffers();&lt;br /&gt;
         }&lt;br /&gt;
     // Exit gracefully&lt;br /&gt;
     glutDestroyWindow(window_id);&lt;br /&gt;
     return 0;&lt;br /&gt;
     }&lt;br /&gt;
 //&lt;br /&gt;
 // This is where you'd draw a frame of your 3D application&lt;br /&gt;
 //&lt;br /&gt;
 void render()&lt;br /&gt;
     {&lt;br /&gt;
     glLoadIdentity();&lt;br /&gt;
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
     // Look on my works, ye Mighty, and despair!&lt;br /&gt;
     glutWireTeapot( 0.5 );&lt;br /&gt;
     }&lt;br /&gt;
 //&lt;br /&gt;
 //  Handler for normal keypressed&lt;br /&gt;
 //&lt;br /&gt;
 void keyFunc(unsigned char key, int x, int y)&lt;br /&gt;
     {&lt;br /&gt;
     switch (key)&lt;br /&gt;
         {&lt;br /&gt;
         case 113:   // 'q',&lt;br /&gt;
         case 81:    // 'Q',&lt;br /&gt;
         case 27:    // 'ESC'&lt;br /&gt;
            keep_running = false;&lt;br /&gt;
            break;&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
==Makefile for GLUT Only==&lt;br /&gt;
&lt;br /&gt;
Remember, 'make' expects tabs not spaces when indenting compiler commands.&lt;br /&gt;
&lt;br /&gt;
 # Makefile to compile glut_loop&lt;br /&gt;
 glut_loop: glut_loop.o&lt;br /&gt;
     g++ glut_loop.o -lglut -o glut_loop&lt;br /&gt;
 #&lt;br /&gt;
 glut_loop.o: glut_loop.cpp&lt;br /&gt;
     g++ -c glut_loop.cpp&lt;br /&gt;
 #&lt;br /&gt;
 .PHONY: clean&lt;br /&gt;
 clean:&lt;br /&gt;
     rm -rf *.o glut_loop&lt;br /&gt;
&lt;br /&gt;
==GLUT's Keyboard Callbacks==&lt;br /&gt;
&lt;br /&gt;
A note on GLUT's keyboard functions:&lt;br /&gt;
&lt;br /&gt;
Keys that don't generate an ASCII value or aren't in the short list for&lt;br /&gt;
glutSpecialFunc generate ... nothing.  There are no events triggered when&lt;br /&gt;
pressing the CTRL, ALT, or Shift keys.  There is no way to tell if '5' was&lt;br /&gt;
pressed on the keypad instead of the number keys.  Later, I will show you a way&lt;br /&gt;
to fake CTRL, ALT, and Shift for CEGUI but it wont be in real time.&lt;br /&gt;
&lt;br /&gt;
Despite this, there should be enough utility in them to support a GUI. You can&lt;br /&gt;
enter text, tab, arrow key about, etc. But if your app needs RIGHT-CRTL for&lt;br /&gt;
'fire missles' and Keypad-Slash for 'shields' you'll want another input&lt;br /&gt;
library.&lt;br /&gt;
&lt;br /&gt;
These are the Set-Handler and the What-a-Handler-Should-Look-Like functions:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''void glutKeyboardFunc(myKeyboardFunc)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the handler for a normal keypress.  These would be keys that generate&lt;br /&gt;
normal ASCII characters.  'Delete' (ASCII 127) is a normal key. 'Insert' is&lt;br /&gt;
not. The special keys are handled by glutSpecialFunc (see below).&lt;br /&gt;
&lt;br /&gt;
Example Handler:&lt;br /&gt;
* void myKeyboardFunc(unsigned char key, int x, int y);&lt;br /&gt;
You get the ASCII value of the key pressed and the current mouse x and y.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''void glutKeyboardUpFunc(myKeyboardUpFunc)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the handler for a normal key release.&lt;br /&gt;
&lt;br /&gt;
Example Handler:&lt;br /&gt;
* void myKeyboardUpFunc(unsigned char key, int x, int y)&lt;br /&gt;
You get the ASCII value of the key released and the current mouse x and y.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''glutSpecialFunc(mySpecialFunc)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the handler for a special keypress.  &lt;br /&gt;
&lt;br /&gt;
Example Handler:&lt;br /&gt;
* void mySpecialFunc(int key, int x, int y)&lt;br /&gt;
You get an int with the special key value and the current mouse x and y. The possible values are:&lt;br /&gt;
* GLUT_KEY_F1 through GLUT_KEY_F12&lt;br /&gt;
* GLUT_KEY_UP, GLUT_KEY_RIGHT, and GLUT_KEY_DOWN, and GLUT_KEY_LEFT&lt;br /&gt;
* GLUT_KEY_PAGE_UP and GLUT_KEY_PAGE_DOWN,&lt;br /&gt;
* GLUT_KEY_HOME, GLUT_KEY_END, and GLUT_KEY_INSERT&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''glutSpecialUpFunc(mySpecialupFunc)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sets the handler for a special key release.&lt;br /&gt;
&lt;br /&gt;
Example Handler:&lt;br /&gt;
* void mySpecialUpFunc(int key, int x, int y)&lt;br /&gt;
You get an int with the special key value and the current mouse x and y.&lt;br /&gt;
&lt;br /&gt;
==Connecting GLUT's Keyboard Callbacks to CEGUI==&lt;br /&gt;
&lt;br /&gt;
As you probably know, CEGUI does not capture any input.  You need to feed it in&lt;br /&gt;
it with the various .inject_Something_() functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Faking CTRL, ALT, and Shift'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As mentioned, GLUT does not generate an event when the user presses or releases&lt;br /&gt;
these keys.  If does have a function called glutGetModifiers() that lets you&lt;br /&gt;
poll their state.  It returns an INT with certain bits set.&lt;br /&gt;
&lt;br /&gt;
First we need to add some global flags to our program:&lt;br /&gt;
&lt;br /&gt;
 // Track the status of modifiers&lt;br /&gt;
 bool ctrl_held = false;&lt;br /&gt;
 bool alt_held = false;&lt;br /&gt;
 bool shift_held = false;&lt;br /&gt;
&lt;br /&gt;
Then a function to track the state of these keys:&lt;br /&gt;
&lt;br /&gt;
 void fakeCtrlAltShift()&lt;br /&gt;
    {&lt;br /&gt;
    int status = glutGetModifiers();&lt;br /&gt;
    if (status &amp;amp; GLUT_ACTIVE_CTRL)&lt;br /&gt;
        {&lt;br /&gt;
        if (!ctrl_held)&lt;br /&gt;
            {&lt;br /&gt;
            ctrl_held = true;&lt;br /&gt;
            CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::LeftControl);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    else&lt;br /&gt;
        {&lt;br /&gt;
        if (ctrl_held)&lt;br /&gt;
            {&lt;br /&gt;
            ctrl_held = false;&lt;br /&gt;
            CEGUI::System::getSingleton().injectKeyUp(CEGUI::Key::LeftControl);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    //&lt;br /&gt;
    if (status &amp;amp; GLUT_ACTIVE_ALT)&lt;br /&gt;
        {&lt;br /&gt;
        if (!alt_held)&lt;br /&gt;
            {&lt;br /&gt;
            alt_held = true;&lt;br /&gt;
            CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::LeftAlt);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    else&lt;br /&gt;
        {&lt;br /&gt;
        if (alt_held)&lt;br /&gt;
            {&lt;br /&gt;
            alt_held = false;&lt;br /&gt;
            CEGUI::System::getSingleton().injectKeyUp(CEGUI::Key::LeftAlt);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    //&lt;br /&gt;
    if (status &amp;amp; GLUT_ACTIVE_SHIFT)&lt;br /&gt;
        {&lt;br /&gt;
        if (!shift_held)&lt;br /&gt;
            {&lt;br /&gt;
            shift_held = true;&lt;br /&gt;
            CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::LeftShift);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    else&lt;br /&gt;
        {&lt;br /&gt;
        if (shift_held)&lt;br /&gt;
            {&lt;br /&gt;
            shift_held = false;&lt;br /&gt;
            CEGUI::System::getSingleton().injectKeyUp(CEGUI::Key::LeftShift);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
We'll call this in every keyboard handler.  It's not pretty but it should keep&lt;br /&gt;
CEGUI informed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Scan Codes'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For key presses, CEGUI wants to be told the ASCII value of the key pressed and&lt;br /&gt;
the system scan code generated. For key releases, CEGUI wants the scan code&lt;br /&gt;
only. Our problem is GLUT has no idea what a scan code is.&lt;br /&gt;
&lt;br /&gt;
Here's two functions to create some fake scan codes, one for normal input and&lt;br /&gt;
one for the special keys:&lt;br /&gt;
&lt;br /&gt;
 // Map ASCII to Scan Codes&lt;br /&gt;
 int mapNormal(unsigned char c)&lt;br /&gt;
    {&lt;br /&gt;
    int scancode;&lt;br /&gt;
    switch(c)&lt;br /&gt;
        {&lt;br /&gt;
        case 97:&lt;br /&gt;
        case 65:&lt;br /&gt;
            scancode = CEGUI::Key::A;&lt;br /&gt;
            break;&lt;br /&gt;
        case 98:&lt;br /&gt;
        case 66:&lt;br /&gt;
            scancode = CEGUI::Key::B;&lt;br /&gt;
            break;&lt;br /&gt;
        case 99:&lt;br /&gt;
        case 67:&lt;br /&gt;
            scancode = CEGUI::Key::C;&lt;br /&gt;
            break;&lt;br /&gt;
        case 100:&lt;br /&gt;
        case 68:&lt;br /&gt;
            scancode = CEGUI::Key::D;&lt;br /&gt;
            break;&lt;br /&gt;
        case 101:&lt;br /&gt;
        case 69:&lt;br /&gt;
            scancode = CEGUI::Key::E;&lt;br /&gt;
            break;&lt;br /&gt;
        case 102:&lt;br /&gt;
        case 70:&lt;br /&gt;
            scancode = CEGUI::Key::F;&lt;br /&gt;
            break;&lt;br /&gt;
        case 103:&lt;br /&gt;
        case 71:&lt;br /&gt;
            scancode = CEGUI::Key::G;&lt;br /&gt;
            break;&lt;br /&gt;
        case 104:&lt;br /&gt;
        case 72:&lt;br /&gt;
            scancode = CEGUI::Key::H;&lt;br /&gt;
            break;&lt;br /&gt;
        case 105:&lt;br /&gt;
        case 73:&lt;br /&gt;
            scancode = CEGUI::Key::I;&lt;br /&gt;
            break;&lt;br /&gt;
        case 106:&lt;br /&gt;
        case 74:&lt;br /&gt;
            scancode = CEGUI::Key::J;&lt;br /&gt;
            break;&lt;br /&gt;
        case 107:&lt;br /&gt;
        case 75:&lt;br /&gt;
            scancode = CEGUI::Key::K;&lt;br /&gt;
            break;&lt;br /&gt;
        case 108:&lt;br /&gt;
        case 76:&lt;br /&gt;
            scancode = CEGUI::Key::L;&lt;br /&gt;
            break;&lt;br /&gt;
        case 109:&lt;br /&gt;
        case 77:&lt;br /&gt;
            scancode = CEGUI::Key::M;&lt;br /&gt;
            break;&lt;br /&gt;
        case 110:&lt;br /&gt;
        case 78:&lt;br /&gt;
            scancode = CEGUI::Key::N;&lt;br /&gt;
            break;&lt;br /&gt;
        case 111:&lt;br /&gt;
        case 79:&lt;br /&gt;
            scancode = CEGUI::Key::O;&lt;br /&gt;
            break;&lt;br /&gt;
        case 112:&lt;br /&gt;
        case 80:&lt;br /&gt;
            scancode = CEGUI::Key::P;&lt;br /&gt;
            break;&lt;br /&gt;
        case 113:&lt;br /&gt;
        case 81:&lt;br /&gt;
            scancode = CEGUI::Key::Q;&lt;br /&gt;
            break;&lt;br /&gt;
        case 114:&lt;br /&gt;
        case 82:&lt;br /&gt;
            scancode = CEGUI::Key::R;&lt;br /&gt;
            break;&lt;br /&gt;
        case 115:&lt;br /&gt;
        case 83:&lt;br /&gt;
            scancode = CEGUI::Key::S;&lt;br /&gt;
            break;&lt;br /&gt;
        case 116:&lt;br /&gt;
        case 84:&lt;br /&gt;
            scancode = CEGUI::Key::T;&lt;br /&gt;
            break;&lt;br /&gt;
        case 117:&lt;br /&gt;
        case 85:&lt;br /&gt;
            scancode = CEGUI::Key::U;&lt;br /&gt;
            break;&lt;br /&gt;
        case 118:&lt;br /&gt;
        case 86:&lt;br /&gt;
            scancode = CEGUI::Key::V;&lt;br /&gt;
            break;&lt;br /&gt;
        case 119:&lt;br /&gt;
        case 87:&lt;br /&gt;
            scancode = CEGUI::Key::W;&lt;br /&gt;
            break;&lt;br /&gt;
        case 120:&lt;br /&gt;
        case 88:&lt;br /&gt;
            scancode = CEGUI::Key::X;&lt;br /&gt;
            break;&lt;br /&gt;
        case 121:&lt;br /&gt;
        case 89:&lt;br /&gt;
            scancode = CEGUI::Key::Y;&lt;br /&gt;
            break;&lt;br /&gt;
        case 122:&lt;br /&gt;
        case 90:&lt;br /&gt;
            scancode = CEGUI::Key::Z;&lt;br /&gt;
            break;&lt;br /&gt;
        case 27:&lt;br /&gt;
            scancode = CEGUI::Key::Escape;&lt;br /&gt;
            break;&lt;br /&gt;
        case 49:&lt;br /&gt;
            scancode = CEGUI::Key::One;&lt;br /&gt;
            break;&lt;br /&gt;
        case 50:&lt;br /&gt;
            scancode = CEGUI::Key::Two;&lt;br /&gt;
            break;&lt;br /&gt;
        case 51:&lt;br /&gt;
            scancode = CEGUI::Key::Three;&lt;br /&gt;
            break;&lt;br /&gt;
        case 52:&lt;br /&gt;
            scancode = CEGUI::Key::Four;&lt;br /&gt;
            break;&lt;br /&gt;
        case 53:&lt;br /&gt;
            scancode = CEGUI::Key::Five;&lt;br /&gt;
            break;&lt;br /&gt;
        case 54:&lt;br /&gt;
            scancode = CEGUI::Key::Six;&lt;br /&gt;
            break;&lt;br /&gt;
        case 55:&lt;br /&gt;
            scancode = CEGUI::Key::Seven;&lt;br /&gt;
            break;&lt;br /&gt;
        case 56:&lt;br /&gt;
            scancode = CEGUI::Key::Eight;&lt;br /&gt;
            break;&lt;br /&gt;
        case 57:&lt;br /&gt;
            scancode = CEGUI::Key::Nine;&lt;br /&gt;
            break;&lt;br /&gt;
        case 48:&lt;br /&gt;
            scancode = CEGUI::Key::Zero;&lt;br /&gt;
            break;&lt;br /&gt;
        case 45:&lt;br /&gt;
            scancode = CEGUI::Key::Minus;&lt;br /&gt;
            break;&lt;br /&gt;
        case 61:&lt;br /&gt;
            scancode = CEGUI::Key::Equals;&lt;br /&gt;
            break;&lt;br /&gt;
        case 8:&lt;br /&gt;
            scancode = CEGUI::Key::Backspace;&lt;br /&gt;
            break;&lt;br /&gt;
        case 9:&lt;br /&gt;
            scancode = CEGUI::Key::Tab;&lt;br /&gt;
            break;&lt;br /&gt;
        case 91:&lt;br /&gt;
            scancode = CEGUI::Key::LeftBracket;&lt;br /&gt;
            break;&lt;br /&gt;
        case 93:&lt;br /&gt;
            scancode = CEGUI::Key::RightBracket;&lt;br /&gt;
            break;&lt;br /&gt;
        case 13:&lt;br /&gt;
            scancode = CEGUI::Key::Return;&lt;br /&gt;
            break;&lt;br /&gt;
        case 59:&lt;br /&gt;
            scancode = CEGUI::Key::Semicolon;&lt;br /&gt;
            break;&lt;br /&gt;
        case 39:&lt;br /&gt;
            scancode = CEGUI::Key::Apostrophe;&lt;br /&gt;
            break;&lt;br /&gt;
        case 96:&lt;br /&gt;
            scancode = CEGUI::Key::Grave;&lt;br /&gt;
            break;&lt;br /&gt;
        case 92:&lt;br /&gt;
            scancode = CEGUI::Key::Backslash;&lt;br /&gt;
            break;&lt;br /&gt;
        case 44:&lt;br /&gt;
            scancode = CEGUI::Key::Comma;&lt;br /&gt;
            break;&lt;br /&gt;
        case 46:&lt;br /&gt;
            scancode = CEGUI::Key::Period;&lt;br /&gt;
            break;&lt;br /&gt;
        case 47:&lt;br /&gt;
            scancode = CEGUI::Key::Slash;&lt;br /&gt;
            break;&lt;br /&gt;
        case 42:&lt;br /&gt;
            scancode = CEGUI::Key::Multiply;&lt;br /&gt;
            break;&lt;br /&gt;
        case 32:&lt;br /&gt;
            scancode = CEGUI::Key::Space;&lt;br /&gt;
            break;&lt;br /&gt;
         case 64:&lt;br /&gt;
            scancode = CEGUI::Key::At;&lt;br /&gt;
            break;&lt;br /&gt;
        case 58:&lt;br /&gt;
            scancode = CEGUI::Key::Colon;&lt;br /&gt;
            break;&lt;br /&gt;
        case 95:&lt;br /&gt;
            scancode = CEGUI::Key::Underline;&lt;br /&gt;
            break;&lt;br /&gt;
        case 127:&lt;br /&gt;
            scancode = CEGUI::Key::Delete;&lt;br /&gt;
            break;&lt;br /&gt;
        default:&lt;br /&gt;
            scancode = 0;&lt;br /&gt;
        }&lt;br /&gt;
    return scancode;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 // Map Special GLUT Keys to Scan Codes&lt;br /&gt;
 int mapSpecial(int c)&lt;br /&gt;
    {&lt;br /&gt;
    int scancode;&lt;br /&gt;
    switch(c)&lt;br /&gt;
        {&lt;br /&gt;
        case 1:&lt;br /&gt;
            scancode = CEGUI::Key::F1;&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            scancode = CEGUI::Key::F2;&lt;br /&gt;
            break;&lt;br /&gt;
        case 3:&lt;br /&gt;
            scancode = CEGUI::Key::F3;&lt;br /&gt;
            break;&lt;br /&gt;
        case 4:&lt;br /&gt;
            scancode = CEGUI::Key::F4;&lt;br /&gt;
            break;&lt;br /&gt;
        case 5:&lt;br /&gt;
            scancode = CEGUI::Key::F5;&lt;br /&gt;
            break;&lt;br /&gt;
        case 6:&lt;br /&gt;
            scancode = CEGUI::Key::F6;&lt;br /&gt;
            break;&lt;br /&gt;
        case 7:&lt;br /&gt;
            scancode = CEGUI::Key::F7;&lt;br /&gt;
            break;&lt;br /&gt;
        case 8:&lt;br /&gt;
            scancode = CEGUI::Key::F8;&lt;br /&gt;
            break;&lt;br /&gt;
        case 9:&lt;br /&gt;
            scancode = CEGUI::Key::F9;&lt;br /&gt;
            break;&lt;br /&gt;
        case 10:&lt;br /&gt;
            scancode = CEGUI::Key::F10;&lt;br /&gt;
            break;&lt;br /&gt;
         case 11:&lt;br /&gt;
            scancode = CEGUI::Key::F11;&lt;br /&gt;
            break;&lt;br /&gt;
        case 12:&lt;br /&gt;
            scancode = CEGUI::Key::F12;&lt;br /&gt;
            break;&lt;br /&gt;
        case 104:&lt;br /&gt;
            scancode = CEGUI::Key::PageUp;&lt;br /&gt;
            break;&lt;br /&gt;
        case 105:&lt;br /&gt;
            scancode = CEGUI::Key::PageDown;&lt;br /&gt;
            break;&lt;br /&gt;
        case 106:&lt;br /&gt;
            scancode = CEGUI::Key::Home;&lt;br /&gt;
            break;&lt;br /&gt;
        case 107:&lt;br /&gt;
            scancode = CEGUI::Key::End;&lt;br /&gt;
            break;&lt;br /&gt;
        case 100:&lt;br /&gt;
            scancode = CEGUI::Key::ArrowLeft;&lt;br /&gt;
            break;&lt;br /&gt;
        case 101:&lt;br /&gt;
            scancode = CEGUI::Key::ArrowUp;&lt;br /&gt;
            break;&lt;br /&gt;
        case 102:&lt;br /&gt;
            scancode = CEGUI::Key::ArrowRight;&lt;br /&gt;
            break;&lt;br /&gt;
        case 103:&lt;br /&gt;
            scancode = CEGUI::Key::ArrowDown;&lt;br /&gt;
            break;&lt;br /&gt;
        case 108:&lt;br /&gt;
            scancode = CEGUI::Key::Insert;&lt;br /&gt;
            break;&lt;br /&gt;
        default:&lt;br /&gt;
            scancode = 0;&lt;br /&gt;
        }&lt;br /&gt;
    return scancode;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Normal Keypresses'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 void myKeyboardFunc(unsigned char key, int x, int y)&lt;br /&gt;
    {&lt;br /&gt;
    fakeCtrlAltShift();&lt;br /&gt;
    CEGUI::System::getSingleton().injectChar(key);&lt;br /&gt;
    int scancode = mapNormal(key);&lt;br /&gt;
    if (scancode)&lt;br /&gt;
        {&lt;br /&gt;
        CEGUI::System::getSingleton().injectKeyUp(scancode);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 void myKeyboardUpFunc(unsigned char key, int x, int y)&lt;br /&gt;
    {&lt;br /&gt;
    fakeCtrlAltShift();&lt;br /&gt;
    int scancode = mapNormal(key);&lt;br /&gt;
    if (scancode)&lt;br /&gt;
        {&lt;br /&gt;
        CEGUI::System::getSingleton().injectKeyUp(scancode);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Special Keypresses'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 void mySpecialFunc(int key, int x, int y)&lt;br /&gt;
    {&lt;br /&gt;
    fakeCtrlAltShift();&lt;br /&gt;
    int scancode = mapSpecial(key);&lt;br /&gt;
    if (scancode)&lt;br /&gt;
        {&lt;br /&gt;
        CEGUI::System::getSingleton().injectKeyDown(scancode);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 void mySpecialUpFunc(int key, int x, int y)&lt;br /&gt;
    {&lt;br /&gt;
    fakeCtrlAltShift();&lt;br /&gt;
    int scancode = mapSpecial(key);&lt;br /&gt;
    if (scancode)&lt;br /&gt;
        {&lt;br /&gt;
        CEGUI::System::getSingleton().injectKeyUp(scancode);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GLUT's Mouse Callbacks==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''glutMouseFunc(myMouseFunc)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sets the handler for any mouse button function.  This includes presses and&lt;br /&gt;
releases.  Scrolling a mouse wheels generates a press and a release for each&lt;br /&gt;
tick.&lt;br /&gt;
&lt;br /&gt;
Example Handler:&lt;br /&gt;
* void myMouseFunc(int button, int state, int x, int y)&lt;br /&gt;
The button numbering looks like this (depending on your mouse):&lt;br /&gt;
* 0 = Left&lt;br /&gt;
* 1 = Middle&lt;br /&gt;
* 2 = Right&lt;br /&gt;
* 3 = MouseWheel Up&lt;br /&gt;
* 4 = MouseWheel Down&lt;br /&gt;
&lt;br /&gt;
You may notice that the middle and right buttons are swapped from what Windows&lt;br /&gt;
programmers would expect.&lt;br /&gt;
&lt;br /&gt;
If state == 0, the event is a button press. If state == 1, the event is a&lt;br /&gt;
button release. X and Y are the current mouse co-ordinates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' glutPassiveMotionFunc(myPassiveMotionFunc)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set the handler for mouse movement with NO buttons held -- ie not dragging.&lt;br /&gt;
&lt;br /&gt;
Example Handler:&lt;br /&gt;
&lt;br /&gt;
* void myPassiveMotionFunc(int x, int y)&lt;br /&gt;
Pretty simple, x == x, y == y.  You will not receive callbacks when the mouse&lt;br /&gt;
pointer leaves the GLUT window.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''glutMotionFunc(myMotionFunc)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sets the handler for mouse movent with ANY button held -- ie dragging.&lt;br /&gt;
&lt;br /&gt;
Example Handler:&lt;br /&gt;
&lt;br /&gt;
* void myMotionFunc(int x, int y)&lt;br /&gt;
Again x==x, y==y.  The behavoir is a little different in that you will get&lt;br /&gt;
callbacks with a button held and the mouse point dragged out of the GLUT window.&lt;br /&gt;
&lt;br /&gt;
For more exotic callbacks, please see:&lt;br /&gt;
http://www.opengl.org/resources/libraries/glut/spec3/node45.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Connecting GLUT's Mouse Callbacks to CEGUI==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Handling Buttons'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 void myMouseFunc(int button, int state, int x, int y)&lt;br /&gt;
     {&lt;br /&gt;
     if (state == 0)     // State 0 = Button Pressed&lt;br /&gt;
         {&lt;br /&gt;
         switch (button)&lt;br /&gt;
             {&lt;br /&gt;
             case 0:     // glut's left mouse button&lt;br /&gt;
                 CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);&lt;br /&gt;
                 break;&lt;br /&gt;
             case 1:     // glut's middle mouse button&lt;br /&gt;
                 CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);&lt;br /&gt;
                 break;&lt;br /&gt;
             case 2:     // glut's right mouse button&lt;br /&gt;
                 CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);&lt;br /&gt;
                 break;&lt;br /&gt;
             case 3:     // glut's mouse wheel up&lt;br /&gt;
                 CEGUI::System::getSingleton().injectMouseWheelChange(2.0);&lt;br /&gt;
                 break;&lt;br /&gt;
             case 4:     // glut's mouse wheen down&lt;br /&gt;
                 CEGUI::System::getSingleton().injectMouseWheelChange(-2.0);&lt;br /&gt;
                 break;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
     else if (state == 1)    // State 1 = Button Released&lt;br /&gt;
         {&lt;br /&gt;
         switch (button)&lt;br /&gt;
             {&lt;br /&gt;
             case 0:     // glut's left mouse button&lt;br /&gt;
                 CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);&lt;br /&gt;
                 break;&lt;br /&gt;
             case 1:     // glut's middle mouse button&lt;br /&gt;
                 CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);&lt;br /&gt;
                 break;&lt;br /&gt;
             case 2:     // glut's right mouse button&lt;br /&gt;
                 CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);&lt;br /&gt;
                 break;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Handling Movement'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You need both of these, since GLUT uses separate callbacks for normal movement&lt;br /&gt;
and dragging (or register one function to both callbacks):&lt;br /&gt;
&lt;br /&gt;
 void myPassiveMotionFunc(int x, int y)&lt;br /&gt;
     {&lt;br /&gt;
     CEGUI::System::getSingleton().injectMousePosition(x,y);&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
 void myMotionFunc(int x, int y)&lt;br /&gt;
     {&lt;br /&gt;
     CEGUI::System::getSingleton().injectMousePosition(x,y);&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
==Registering the Callbacks==&lt;br /&gt;
&lt;br /&gt;
In the initialization code of your GLUT program you'll want to add:&lt;br /&gt;
&lt;br /&gt;
 // Set some input handlers&lt;br /&gt;
 glutKeyboardFunc(myKeyboardFunc);              // key pressed&lt;br /&gt;
 glutKeyboardUpFunc(myKeyboardUpFunc);          // key released&lt;br /&gt;
 glutSpecialFunc(mySpecialFunc);                // special key pressed&lt;br /&gt;
 glutSpecialUpFunc(mySpecialUpFunc);            // special key released&lt;br /&gt;
 glutMouseFunc(myMouseFunc);                    // any mouse button press or release&lt;br /&gt;
 glutPassiveMotionFunc(myPassiveMotionFunc);    // mouse movement with no buttons held&lt;br /&gt;
 glutMotionFunc(myMotionFunc);                  // mouse movement with any button held&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating a Renderer==&lt;br /&gt;
&lt;br /&gt;
Naturally, GLUT will use the OpenGLRenderer.  So in your CEGUI initialization&lt;br /&gt;
you'll want:&lt;br /&gt;
&lt;br /&gt;
 CEGUI::OpenGLRenderer* myRenderer = new CEGUI::OpenGLRenderer(0);&lt;br /&gt;
 new CEGUI::System(myRenderer);&lt;br /&gt;
&lt;br /&gt;
==The New Loop==&lt;br /&gt;
&lt;br /&gt;
 while( keep_running )&lt;br /&gt;
     {&lt;br /&gt;
     glutMainLoopEvent();&lt;br /&gt;
     render();&lt;br /&gt;
     CEGUI::System::getSingleton().renderGUI();&lt;br /&gt;
     glutSwapBuffers();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
==Makefile for GLUT + CEGUI==&lt;br /&gt;
&lt;br /&gt;
 # Makefile&lt;br /&gt;
 # compile gui_loop&lt;br /&gt;
 #&lt;br /&gt;
 gui_loop: gui_loop.o&lt;br /&gt;
    g++ gui_loop.o -lglut -L/usr/local/lib -lCEGUIBase -lCEGUIOpenGLRenderer -o gui_loop&lt;br /&gt;
 #&lt;br /&gt;
 gui_loop.o: gui_loop.cpp&lt;br /&gt;
    g++ -c gui_loop.cpp -I/usr/local/include/CEGUI&lt;br /&gt;
 #&lt;br /&gt;
 .PHONY: clean&lt;br /&gt;
 clean:&lt;br /&gt;
    rm -rf *.o gui_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==License for the Code Samples==&lt;br /&gt;
&lt;br /&gt;
Copyright (C) 2006 Jim Storch&lt;br /&gt;
&lt;br /&gt;
This software is provided 'as-is', without any express or implied&lt;br /&gt;
warranty.  In no event will the authors be held liable for any damages&lt;br /&gt;
arising from the use of this software.&lt;br /&gt;
&lt;br /&gt;
Permission is granted to anyone to use this software for any purpose,&lt;br /&gt;
including commercial applications, and to alter it and redistribute it&lt;br /&gt;
freely.  Attribution is not required.&lt;/div&gt;</summary>
		<author><name>Black</name></author>	</entry>

	</feed>