File: keymousepoll.c

/*
  keymousepoll.c

  A basic test of key and mouse callbacks, and 
  mouse state polling.

*/

#define CPWDLL_EXTERN
#include <cpw.h>

/* handy window characteristics holder */

static CpwWindowInfo windowInfo = { 0,100,100,400,200 }; /* id,posx,posy,w,h */
static CpwMouseCapabilities mcaps;
static CpwMouseInfo minfo;
static CpwFontFace font;

static char buf[1000];

static int_32 mouse_x;
static int_32 mouse_y;

static bool   click = false;
static int_32 clickdn_x;
static int_32 clickdn_y;
static int_32 clickup_x;
static int_32 clickup_y;

static char asciikey;
static bool asciistate;

static char systemkey[10];
static bool systemstate;

/****************************************************/
/*  OpenGL 2D Matrix Setup                          */
/****************************************************/

void set2DMatrix( void ) 
{
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluOrtho2D( 0, windowInfo.width, 0, windowInfo.height );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
}

/****************************************************/
/*  OpenGL 3D Matrix Setup                          */
/****************************************************/

void set3DMatrix( void ) 
{
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 60, windowInfo.width / windowInfo.height, 1, 100 );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
}

/****************************************************/
/*  Draw Window One                                 */
/****************************************************/

void drawWindowOne( pCpw cpw ) 
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    set2DMatrix();

    /* draw something in the window with OpenGL */

    glPushMatrix();

    if ( click )
      glColor3f( 0.0, 1.0, 0.0 );
    else
      glColor3f( 1.0, 1.0, 1.0 );

    glRasterPos2d( mouse_x, windowInfo.height - mouse_y );

    sprintf( buf, "%dx%d", mouse_x, mouse_y );

    cpwFontMode( cpw, CPW_FONTOPT_PIXELMAP_GLFORMAT, GL_RGB );
    cpwDrawFont( cpw, font, buf, 1 );

    glRasterPos2d( 3, 1 );

    sprintf( buf, "mouse: down:%dx%d up:%dx%d", clickdn_x, clickdn_y, clickup_x, clickup_y );

    cpwFontMode( cpw, CPW_FONTOPT_PIXELMAP_GLFORMAT, GL_LUMINANCE );
    cpwDrawFont( cpw, font, buf, 1 );

    glRasterPos2d( 3, 20 );

    sprintf( buf, "key: %c state:%d", asciikey, asciistate );

    cpwDrawFont( cpw, font, buf, 1 );

    glRasterPos2d( 3, 40 );

    sprintf( buf, "system key: %s state:%d", systemkey, systemstate );

    cpwDrawFont( cpw, font, buf, 1 );

    glPopMatrix();
}

/****************************************************/
/*  Window Draw Event callback                      */
/****************************************************/

void draw( pCpw cpw, uint_32 winid )
{
    drawWindowOne( cpw );
    cpwSwapWindowBuffers( cpw, winid );
}

/****************************************************/
/*  Mouse Click Event Callback                      */
/****************************************************/

void mouseclick( pCpw cpw, uint_32 id, uint_32 state, uint_32 button, uint_32 x, uint_32 y )
{
    if ( state == CPW_BUTTON_DOWN ) {
        click = true;
        clickdn_x = x;
        clickdn_y = y;
    }

    if ( state == CPW_BUTTON_UP ) {
        click = false;
        clickup_x = x;
        clickup_y = y;
    }

    /* wheel support on win32 */

    if ( state == CPW_BUTTON_ROLL ) {
        clickdn_x = x;
        clickdn_y = 0;
        clickup_x = 0;
        clickup_y = 0;
    }

    /*
    cpwMouseState( cpw, &minfo );
    printf( "%d,%d,%d b1:%d b2:%d b3:%d\n", 
        minfo.x, minfo.y, minfo.z,
        minfo.buttons[0], 
        minfo.buttons[1], 
        minfo.buttons[2] );
    */

    cpwPostWindowRedisplay( cpw, 1 );
}

/****************************************************/
/*  Mouse Drag Event Callback                       */
/****************************************************/

void mousedrag( pCpw cpw, uint_32 id, uint_32 button, int_32 x, int_32 y )
{
    mouse_x = x;
    mouse_y = y;
    cpwPostWindowRedisplay( cpw, 1 );
}

/****************************************************/
/*  Mouse Move Event Callback                       */
/****************************************************/

void mousemove( pCpw cpw, uint_32 id, uint_32 x, uint_32 y )
{
    mouse_x = x;
    mouse_y = y;
    cpwPostWindowRedisplay( cpw, 1 );
}

/****************************************************/
/*  System Key Event Callback                       */
/****************************************************/

void keyboard( pCpw cpw, uint_32 id, uint_32 key, uint_32 state, uint_32 x, uint_32 y )
{
    asciikey = (char)key;

    if ( state == CPW_KEYMOD_UP ) 
      asciistate = false;
    else 
      asciistate = true;

    cpwPostWindowRedisplay( cpw, 1 );
}

void syskey( pCpw cpw, uint_32 id, uint_32 key, uint_32 state, uint_32 x, uint_32 y )
{
    if ( state == CPW_KEYMOD_UP ) 
      systemstate = false;
    else 
      systemstate = true;

    switch ( key ) {

        case CPW_KEY_F1:
        strcpy( systemkey, "F1" );
        break;
        case CPW_KEY_F2:
        strcpy( systemkey, "F2" );
        break;
        case CPW_KEY_F3:
        strcpy( systemkey, "F3" );
        break;
        case CPW_KEY_F4:
        strcpy( systemkey, "F4" );
        break;
        case CPW_KEY_F5:
        strcpy( systemkey, "F5" );
        break;
        case CPW_KEY_F6:
        strcpy( systemkey, "F6" );
        break;
        case CPW_KEY_F7:
        strcpy( systemkey, "F7" );
        break;
        case CPW_KEY_F8:
        strcpy( systemkey, "F8" );
        break;
        case CPW_KEY_F9:
        strcpy( systemkey, "F9" );
        break;
        case CPW_KEY_F10:
        strcpy( systemkey, "F10" );
        break;
        case CPW_KEY_F11:
        strcpy( systemkey, "F11" );
        break;
        case CPW_KEY_F12:
        strcpy( systemkey, "F12" );
        break;

          /* arrow keys */

        case CPW_KEY_LEFT:
        strcpy( systemkey, "LArrow" );
        break;
        case CPW_KEY_UP:
        strcpy( systemkey, "UArrow" );
        break;
        case CPW_KEY_RIGHT:
        strcpy( systemkey, "RArrow" );
        break;
        case CPW_KEY_DOWN:
        strcpy( systemkey, "DArrow" );
        break;

          /* cursor control keys */

        case CPW_KEY_PAGEUP:
        strcpy( systemkey, "PageUp" );
        break;
        case CPW_KEY_PAGEDOWN:
        strcpy( systemkey, "PageDn" );
        break;
        case CPW_KEY_HOME:
        strcpy( systemkey, "Home" );
        break;
        case CPW_KEY_END:
        strcpy( systemkey, "End" );
        break;
        case CPW_KEY_INSERT:
        strcpy( systemkey, "Ins" );
        break;
        case CPW_KEY_DELETE:
        strcpy( systemkey, "Del" );
        break;

          /* system keys */

        case CPW_KEY_CAPSLOCK:
        strcpy( systemkey, "CapsLock" );
        break;

        case CPW_KEY_SHIFT:
        if ( cpwKeyState( cpw, CPW_KEY_LSHIFT ) )
          strcpy( systemkey, "LShift" );
        else if ( cpwKeyState( cpw, CPW_KEY_RSHIFT ) )
          strcpy( systemkey, "RShift" );
        else
          strcpy( systemkey, "Shift" );
        break;

        case CPW_KEY_CONTROL:
        if ( cpwKeyState( cpw, CPW_KEY_LCONTROL ) )
          strcpy( systemkey, "LControl" );
        else if ( cpwKeyState( cpw, CPW_KEY_RCONTROL ) )
          strcpy( systemkey, "RControl" );
        else
          strcpy( systemkey, "Control" );
        break;

        case CPW_KEY_ALT:
        if ( cpwKeyState( cpw, CPW_KEY_LALT ) )
          strcpy( systemkey, "LCommand" );
        else if ( cpwKeyState( cpw, CPW_KEY_RALT ) )
          strcpy( systemkey, "RCommand" );
        else
          strcpy( systemkey, "Command" );
        break;

        case CPW_KEY_ESCAPE:
        strcpy( systemkey, "Esc" );
        break;
        case CPW_KEY_TAB:
        strcpy( systemkey, "Tab" );
        break;
        case CPW_KEY_BACKSPACE:
        strcpy( systemkey, "Back" );
        break;
        case CPW_KEY_ENTER:
        strcpy( systemkey, "Enter" );
        break;

          /* number pad keys */

        case CPW_KEY_MULTIPLY:
        strcpy( systemkey, "Mult" );
        break;
        case CPW_KEY_ADD:
        strcpy( systemkey, "Add" );
        break;
        case CPW_KEY_SEPERATOR:
        strcpy( systemkey, "Sep" );
        break;
        case CPW_KEY_SUBTRACT:
        strcpy( systemkey, "Sub" );
        break;
        case CPW_KEY_DECIMAL:
        strcpy( systemkey, "Dec" );
        break;
        case CPW_KEY_DIVIDE:
        strcpy( systemkey, "Div" );
        break;
        case CPW_KEY_NUMLOCK:
        strcpy( systemkey, "NumLock" );
        break;

          /* sys request key */

        case CPW_KEY_PRINT:
        strcpy( systemkey, "Print" );
        break;
        case CPW_KEY_SCROLLLOCK:
        strcpy( systemkey, "ScLock" );
        break;
        case CPW_KEY_PAUSE:
        strcpy( systemkey, "Pause" );
        break;
    }
    cpwPostWindowRedisplay( cpw, 1 );
}

/****************************************************/
/*  Window Create / Destroy Event Callback          */
/****************************************************/

void window( pCpw cpw, uint_32 winid, bool flag )
{
    /* creation event */

    if ( flag == true ) {

        glShadeModel( GL_SMOOTH );
        glDepthFunc( GL_LEQUAL );
        glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
        glEnable( GL_LINE_SMOOTH );
        glEnable( GL_POLYGON_SMOOTH );
        glClearColor( 0.0, 0.0, 0.0, 1.0 );
        return;
    }

    /* window close event */

    if ( flag == false ) {
        cpwDestroyWindow( cpw, winid );
        return;
    }
}

/****************************************************/
/*  Window Resize Event Callback                    */
/****************************************************/

void reshape( pCpw cpw, uint_32 winid, uint_32 width, uint_32 height )
{
    if ( height == 0 ) { height = 1; }
    if ( width == 0 )  { width = 1; }

    windowInfo.width = width;
    windowInfo.height = height;

    set2DMatrix();

    glViewport( 0, 0, width, height );
}


/****************************************************/
/*  Main                                            */
/****************************************************/

int main(int argc, char* argv[])
{
    pCpw cpw = null;

    /****************************************************/
    /*  Init                                            */
    /****************************************************/

    cpwInitContext( &cpw );

    /****************************************************/
    /*  Creaing Windows                                 */
    /****************************************************/
    
    windowInfo.id = 
    cpwCreateWindowEx( cpw, "Key Mouse Demo", windowInfo.x, windowInfo.y, 
                             windowInfo.width, windowInfo.height );

    /****************************************************/
    /*  Event Callbacks                                 */
    /****************************************************/

    cpwCreateCallback( cpw, window );
    cpwDisplayCallback( cpw, draw );
    cpwReshapeCallback( cpw, reshape );
    cpwMouseClickCallback( cpw, mouseclick );
    cpwMouseDragCallback( cpw, mousedrag );
    cpwMouseMoveCallback( cpw, mousemove );
    cpwReshapeCallback( cpw, reshape );
    cpwKeyboardCallback( cpw, keyboard );
    cpwSystemKeyboardCallback( cpw, syskey );

    /****************************************************/
    /*  Fonts                                           */
    /****************************************************/

    glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE );
    glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

    cpwFontMode( cpw, CPW_FONTOPT_PIXELMAP, 0 );
    cpwFontMode( cpw, CPW_FONTOPT_ALIGNLEFT, 0 );
    cpwFontMode( cpw, CPW_FONTOPT_SIZE, 18 );
    cpwFontMode( cpw, CPW_FONTOPT_PIXELMAP_GLFORMAT, GL_RGB );
    cpwFontMode( cpw, CPW_FONTOPT_LAYOUTDEBUG, 0 );
    cpwFontMode( cpw, CPW_FONTOPT_SPACING, 1 );

    glColor3f( 0.0, 1.0, 0.0 );

    font = cpwLoadFont( cpw, "arial.ttf", CPW_FONTLOC_HOST, "", "" );

    cpwMouseCapabilities( cpw, &mcaps );

    if ( mcaps.xy == false )
        printf( "Mouse not supported?\n" );

    if ( mcaps.z == true )
        printf( "Mouse supports a wheel.\n" );

    printf( "Mouse supports %d buttons.\n", mcaps.buttons );

    /****************************************************/
    /*  MainLoop                                        */
    /****************************************************/

    cpwMainLoop( cpw );

    /****************************************************/
    /*  Exit and Free                                   */
    /****************************************************/

    cpwFreeContext( &cpw );

    return 0;
}