TwEventX11.c 6.46 KB
Newer Older
Philip Trettner's avatar
Philip Trettner committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
//  ---------------------------------------------------------------------------
//
//  @file       TwEventX11.c
//  @brief      Helper: 
//              translate and forward mouse and keyboard events 
//              from X11 to AntTweakBar
//  
//  @contrib    Greg Popovitch
//  @license    This file is part of the AntTweakBar library.
//              For conditions of distribution and use, see License.txt
//
//  ---------------------------------------------------------------------------

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <AntTweakBar.h>

static int s_KMod = 0;
const int buff_sz = 80;

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
/*
static int _XKeyRelease(XEvent *event)
{
    KeySym keysym;
    char buffer[buff_sz];
        
    XLookupString((XKeyEvent *)event, buffer, buff_sz, &keysym, 0);

    switch (keysym)
    {
    case XK_Control_L:
    case XK_Control_R: s_KMod  &= ~TW_KMOD_CTRL;  break;

    case XK_Shift_L:
    case XK_Shift_R:   s_KMod &= ~TW_KMOD_SHIFT;  break;

    case XK_Alt_L:
    case XK_Alt_R:     s_KMod &= ~TW_KMOD_ALT;    break;
    }
    return 0;
}
*/

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
static int _XKeyPress(XEvent *event)
{
    int modifiers = 0;  // modifiers sent to AntTweakBar
    int k = 0;          // key sent to AntTweakBar
    KeySym keysym;
    char buffer[buff_sz];
        
    int num_char = XLookupString((XKeyEvent *)event, buffer, buff_sz, &keysym, 0);

    if (event->xkey.state & ControlMask)
        modifiers |= TW_KMOD_CTRL;
    if (event->xkey.state & ShiftMask)
        modifiers |= TW_KMOD_SHIFT;
    if (event->xkey.state & Mod1Mask)
        modifiers |= TW_KMOD_ALT;

    switch (keysym)
    {
    case XK_Control_L:
    case XK_Control_R: s_KMod |= TW_KMOD_CTRL;  break;

    case XK_Shift_L:
    case XK_Shift_R:   s_KMod |= TW_KMOD_SHIFT; break;

    case XK_Alt_L:
    case XK_Alt_R:     s_KMod |= TW_KMOD_ALT;   break;

    case XK_Escape:    k = TW_KEY_ESCAPE;    break;
    case XK_Help:      k = TW_KEY_F1;        break;
    case XK_F1:        k = TW_KEY_F1;        break;
    case XK_F2:        k = TW_KEY_F2;        break;
    case XK_F3:        k = TW_KEY_F3;        break;
    case XK_F4:        k = TW_KEY_F4;        break;
    case XK_F5:        k = TW_KEY_F5;        break;
    case XK_F6:        k = TW_KEY_F6;        break;
    case XK_F7:        k = TW_KEY_F7;        break;
    case XK_F8:        k = TW_KEY_F8;        break;
    case XK_F9:        k = TW_KEY_F9;        break;
    case XK_F10:       k = TW_KEY_F10;       break;
    case XK_F11:       k = TW_KEY_F11;       break;
    case XK_F12:       k = TW_KEY_F12;       break;
    case XK_Up:        k = TW_KEY_UP;        break;
    case XK_Down:      k = TW_KEY_DOWN;      break;
    case XK_Right:     k = TW_KEY_RIGHT;     break;
    case XK_Left:      k = TW_KEY_LEFT;      break;
    case XK_Return:    k = TW_KEY_RETURN;    break;
    case XK_Insert:    k = TW_KEY_INSERT;    break;
    case XK_Delete:    k = TW_KEY_DELETE;    break;
    case XK_BackSpace: k = TW_KEY_BACKSPACE; break;
    case XK_Home:      k = TW_KEY_HOME;      break;
    case XK_Tab:       k = TW_KEY_TAB;       break;
    case XK_End:       k = TW_KEY_END;       break;

#ifdef XK_Enter
    case XK_Enter:     k = TW_KEY_RETURN;    break;
#endif

#ifdef XK_KP_Home
    case XK_KP_Home:   k = TW_KEY_HOME;      break;
    case XK_KP_End:    k = TW_KEY_END;       break;
    case XK_KP_Delete: k = TW_KEY_DELETE;    break;
#endif

#ifdef XK_KP_Up
    case XK_KP_Up:     k = TW_KEY_UP;        break;
    case XK_KP_Down:   k = TW_KEY_DOWN;      break;
    case XK_KP_Right:  k = TW_KEY_RIGHT;     break;
    case XK_KP_Left:   k = TW_KEY_LEFT;      break;
#endif

#ifdef XK_KP_Page_Up
    case XK_KP_Page_Up:   k = TW_KEY_PAGE_UP;    break;
    case XK_KP_Page_Down: k = TW_KEY_PAGE_DOWN;  break;
#endif

#ifdef XK_KP_Tab
    case XK_KP_Tab:    k = TW_KEY_TAB;       break;
#endif

    default:
        if (0)
        {
            // should we do that, or rely on the buffer (see code below)
            if (keysym > 12 && keysym < 127) 
                k = keysym;
        }
        break;
    }  
        
    if (k == 0 && num_char)
    {
        int i, handled = 0;
        for (i=0; i<num_char; ++i)
            if (TwKeyPressed(buffer[i], modifiers))
                handled = 1;
        return handled;
    }

    // if we have a valid key, send to AntTweakBar
    // -------------------------------------------
    return (k > 0) ? TwKeyPressed(k, modifiers) : 0;
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
static int _XButtonEvent(XEvent *event)
{
    TwMouseAction action = (event->type == ButtonPress) ? TW_MOUSE_PRESSED : TW_MOUSE_RELEASED;
    XButtonEvent *xbe = (XButtonEvent *)event;
    return TwMouseButton(action, xbe->button);
}
    
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
static int _XConfigureEvent(XEvent *event)
{
    XConfigureEvent *xce = (XConfigureEvent *)event;
    TwWindowSize(xce->width, xce->height);
    return 0;
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
static int _XMotionEvent(XEvent *event)
{
    XMotionEvent *xme = (XMotionEvent *)event;
    return TwMouseMotion(xme->x, xme->y);
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
TW_API int TW_CDECL_CALL TwEventX11(void *xevent)
{
    XEvent *event = (XEvent *)xevent;
    
    switch (event->type)
    {
    case KeyPress:    
        return _XKeyPress(xevent);

    case KeyRelease:  
        return 0; // _XKeyRelease(xevent);

    case ButtonPress: 
    case ButtonRelease: 
        return _XButtonEvent(xevent);

    case MotionNotify:
        return _XMotionEvent(xevent);

    case ConfigureNotify:
        return _XConfigureEvent(xevent);

    default:  
        break;
    }
    return 0;
}