mirror of
https://github.com/glfw/glfw.git
synced 2024-11-10 00:51:47 +00:00
Added a conservative set of key modifiers.
This commit is contained in:
parent
7f2eb7b15b
commit
2d1b835711
@ -309,6 +309,7 @@ GLFW.
|
||||
* Added `GLFW_VISIBLE` window hint and parameter for controlling and polling
|
||||
window visibility
|
||||
* Added `GLFW_REPEAT` key action for repeated keys
|
||||
* Added key modifier parameter to key and mouse button callbacks
|
||||
* Added `windows` simple multi-window test program
|
||||
* Added `sharing` simple OpenGL object sharing test program
|
||||
* Added `modes` video mode enumeration and setting test program
|
||||
|
@ -43,7 +43,7 @@
|
||||
void init( void );
|
||||
void display( void );
|
||||
void reshape( GLFWwindow* window, int w, int h );
|
||||
void key_callback( GLFWwindow* window, int key, int action );
|
||||
void key_callback( GLFWwindow* window, int key, int action, int mods );
|
||||
void DrawBoingBall( void );
|
||||
void BounceBall( double dt );
|
||||
void DrawBoingBallBand( GLfloat long_lo, GLfloat long_hi );
|
||||
@ -245,7 +245,7 @@ void reshape( GLFWwindow* window, int w, int h )
|
||||
0.0, -1.0, 0.0 ); /* up vector */
|
||||
}
|
||||
|
||||
void key_callback( GLFWwindow* window, int key, int action )
|
||||
void key_callback( GLFWwindow* window, int key, int action, int mods )
|
||||
{
|
||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||
|
@ -211,13 +211,13 @@ static void animate(void)
|
||||
|
||||
|
||||
/* change view angle, exit upon ESC */
|
||||
void key( GLFWwindow* window, int k, int action )
|
||||
void key( GLFWwindow* window, int k, int action, int mods )
|
||||
{
|
||||
if( action != GLFW_PRESS ) return;
|
||||
|
||||
switch (k) {
|
||||
case GLFW_KEY_Z:
|
||||
if( glfwGetKey( window, GLFW_KEY_LEFT_SHIFT ) )
|
||||
if( mods & GLFW_MOD_SHIFT )
|
||||
view_rotz -= 5.0;
|
||||
else
|
||||
view_rotz += 5.0;
|
||||
|
@ -477,7 +477,7 @@ static void update_mesh(void)
|
||||
* GLFW callback functions
|
||||
*********************************************************************/
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
|
@ -414,7 +414,7 @@ static void cursorPosFun(GLFWwindow* window, double x, double y)
|
||||
// Mouse button callback function
|
||||
//========================================================================
|
||||
|
||||
static void mouseButtonFun(GLFWwindow* window, int button, int action)
|
||||
static void mouseButtonFun(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
if ((button == GLFW_MOUSE_BUTTON_LEFT) && action == GLFW_PRESS)
|
||||
{
|
||||
@ -434,7 +434,7 @@ static void mouseButtonFun(GLFWwindow* window, int button, int action)
|
||||
do_redraw = 1;
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||
|
@ -270,7 +270,7 @@ static void error_callback(int error, const char* description)
|
||||
// Handle key strokes
|
||||
//========================================================================
|
||||
|
||||
void key_callback(GLFWwindow* window, int key, int action)
|
||||
void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
@ -313,7 +313,7 @@ void key_callback(GLFWwindow* window, int key, int action)
|
||||
// Callback function for mouse button events
|
||||
//========================================================================
|
||||
|
||||
void mouse_button_callback(GLFWwindow* window, int button, int action)
|
||||
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT)
|
||||
return;
|
||||
|
@ -407,6 +407,21 @@ extern "C" {
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*! @name keys Modifier key flags
|
||||
* @{ */
|
||||
|
||||
/*! @ingroup input
|
||||
*/
|
||||
#define GLFW_MOD_SHIFT 0x0001
|
||||
/*! @ingroup input
|
||||
*/
|
||||
#define GLFW_MOD_CTRL 0x0002
|
||||
/*! @ingroup input
|
||||
*/
|
||||
#define GLFW_MOD_ALT 0x0004
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup buttons Mouse buttons
|
||||
* @ingroup input
|
||||
* @{ */
|
||||
@ -669,12 +684,13 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
|
||||
* @param[in] button The [mouse button](@ref buttons) that was pressed or
|
||||
* released.
|
||||
* @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.
|
||||
* @param[in] mods Bit field describing which modifier keys were held down.
|
||||
*
|
||||
* @sa glfwSetMouseButtonCallback
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int);
|
||||
typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
|
||||
|
||||
/*! @brief The function signature for cursor position callbacks.
|
||||
*
|
||||
@ -725,12 +741,13 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
|
||||
* @param[in] window The window that received the event.
|
||||
* @param[in] key The [keyboard key](@ref keys) that was pressed or released.
|
||||
* @param[in] action @ref GLFW_PRESS, @ref GLFW_RELEASE or @ref GLFW_REPEAT.
|
||||
* @param[in] mods Bit field describing which modifier keys were held down.
|
||||
*
|
||||
* @sa glfwSetKeyCallback
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
typedef void (* GLFWkeyfun)(GLFWwindow*,int,int);
|
||||
typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int);
|
||||
|
||||
/*! @brief The function signature for Unicode character callbacks.
|
||||
*
|
||||
|
@ -201,6 +201,22 @@ static void centerCursor(_GLFWwindow *window)
|
||||
|
||||
@end
|
||||
|
||||
// Converts Mac OS X key modifiers into GLFW ones
|
||||
//
|
||||
static int convertKeyMods(NSUInteger flags)
|
||||
{
|
||||
int mods = 0;
|
||||
|
||||
if (flags & NSShiftKeyMask)
|
||||
mods |= GLFW_MOD_SHIFT;
|
||||
if (flags & NSControlKeyMask)
|
||||
mods |= GLFW_MOD_CTRL;
|
||||
if (flags & NSAlternateKeyMask)
|
||||
mods |= GLFW_MOD_ALT;
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
// Converts a Mac OS X keycode to a GLFW keycode
|
||||
//
|
||||
static int convertMacKeyCode(unsigned int macKeyCode)
|
||||
@ -413,7 +429,10 @@ static int convertMacKeyCode(unsigned int macKeyCode)
|
||||
|
||||
- (void)mouseDown:(NSEvent *)event
|
||||
{
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_LEFT,
|
||||
GLFW_PRESS,
|
||||
convertKeyMods([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(NSEvent *)event
|
||||
@ -423,7 +442,10 @@ static int convertMacKeyCode(unsigned int macKeyCode)
|
||||
|
||||
- (void)mouseUp:(NSEvent *)event
|
||||
{
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE);
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_LEFT,
|
||||
GLFW_RELEASE,
|
||||
convertKeyMods([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)event
|
||||
@ -442,7 +464,10 @@ static int convertMacKeyCode(unsigned int macKeyCode)
|
||||
|
||||
- (void)rightMouseDown:(NSEvent *)event
|
||||
{
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_RIGHT,
|
||||
GLFW_PRESS,
|
||||
convertKeyMods([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)rightMouseDragged:(NSEvent *)event
|
||||
@ -452,12 +477,18 @@ static int convertMacKeyCode(unsigned int macKeyCode)
|
||||
|
||||
- (void)rightMouseUp:(NSEvent *)event
|
||||
{
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE);
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_RIGHT,
|
||||
GLFW_RELEASE,
|
||||
convertKeyMods([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)otherMouseDown:(NSEvent *)event
|
||||
{
|
||||
_glfwInputMouseClick(window, [event buttonNumber], GLFW_PRESS);
|
||||
_glfwInputMouseClick(window,
|
||||
[event buttonNumber],
|
||||
GLFW_PRESS,
|
||||
convertKeyMods([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)otherMouseDragged:(NSEvent *)event
|
||||
@ -467,7 +498,10 @@ static int convertMacKeyCode(unsigned int macKeyCode)
|
||||
|
||||
- (void)otherMouseUp:(NSEvent *)event
|
||||
{
|
||||
_glfwInputMouseClick(window, [event buttonNumber], GLFW_RELEASE);
|
||||
_glfwInputMouseClick(window,
|
||||
[event buttonNumber],
|
||||
GLFW_RELEASE,
|
||||
convertKeyMods([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent *)event
|
||||
@ -503,7 +537,12 @@ static int convertMacKeyCode(unsigned int macKeyCode)
|
||||
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
_glfwInputKey(window, convertMacKeyCode([event keyCode]), GLFW_PRESS);
|
||||
const NSUInteger mods = [event modifierFlags];
|
||||
|
||||
_glfwInputKey(window,
|
||||
convertMacKeyCode([event keyCode]),
|
||||
GLFW_PRESS,
|
||||
convertKeyMods(mods));
|
||||
|
||||
if ([event modifierFlags] & NSCommandKeyMask)
|
||||
return;
|
||||
@ -530,12 +569,15 @@ static int convertMacKeyCode(unsigned int macKeyCode)
|
||||
|
||||
key = convertMacKeyCode([event keyCode]);
|
||||
if (key != -1)
|
||||
_glfwInputKey(window, key, action);
|
||||
_glfwInputKey(window, key, action, convertKeyMods([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)keyUp:(NSEvent *)event
|
||||
{
|
||||
_glfwInputKey(window, convertMacKeyCode([event keyCode]), GLFW_RELEASE);
|
||||
_glfwInputKey(window,
|
||||
convertMacKeyCode([event keyCode]),
|
||||
GLFW_RELEASE,
|
||||
convertKeyMods([event modifierFlags]));
|
||||
}
|
||||
|
||||
- (void)scrollWheel:(NSEvent *)event
|
||||
|
@ -122,7 +122,7 @@ static void setStickyMouseButtons(_GLFWwindow* window, int enabled)
|
||||
////// GLFW event API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwInputKey(_GLFWwindow* window, int key, int action)
|
||||
void _glfwInputKey(_GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
GLboolean repeated = GL_FALSE;
|
||||
|
||||
@ -141,7 +141,7 @@ void _glfwInputKey(_GLFWwindow* window, int key, int action)
|
||||
action = GLFW_REPEAT;
|
||||
|
||||
if (window->callbacks.key)
|
||||
window->callbacks.key((GLFWwindow*) window, key, action);
|
||||
window->callbacks.key((GLFWwindow*) window, key, action, mods);
|
||||
}
|
||||
|
||||
void _glfwInputChar(_GLFWwindow* window, unsigned int character)
|
||||
@ -162,7 +162,7 @@ void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
|
||||
window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset);
|
||||
}
|
||||
|
||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action)
|
||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
|
||||
return;
|
||||
@ -174,7 +174,7 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action)
|
||||
window->mouseButton[button] = (char) action;
|
||||
|
||||
if (window->callbacks.mouseButton)
|
||||
window->callbacks.mouseButton((GLFWwindow*) window, button, action);
|
||||
window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
|
||||
}
|
||||
|
||||
void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y)
|
||||
|
@ -591,9 +591,10 @@ void _glfwInputWindowCloseRequest(_GLFWwindow* window);
|
||||
* @param[in] window The window that received the event.
|
||||
* @param[in] key The key that was pressed or released.
|
||||
* @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE.
|
||||
* @param[in] mods The modifiers pressed when the event was generated.
|
||||
* @ingroup event
|
||||
*/
|
||||
void _glfwInputKey(_GLFWwindow* window, int key, int action);
|
||||
void _glfwInputKey(_GLFWwindow* window, int key, int action, int mods);
|
||||
|
||||
/*! @brief Notifies shared code of a Unicode character input event.
|
||||
* @param[in] window The window that received the event.
|
||||
@ -616,7 +617,7 @@ void _glfwInputScroll(_GLFWwindow* window, double x, double y);
|
||||
* @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE.
|
||||
* @ingroup event
|
||||
*/
|
||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action);
|
||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||
|
||||
/*! @brief Notifies shared code of a cursor motion event.
|
||||
* @param[in] window The window that received the event.
|
||||
|
@ -104,6 +104,38 @@ static void showCursor(_GLFWwindow* window)
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieves and translates modifier keys
|
||||
//
|
||||
static int getKeyMods(void)
|
||||
{
|
||||
int mods = 0;
|
||||
|
||||
if (GetKeyState(VK_SHIFT) & (1 << 31))
|
||||
mods |= GLFW_MOD_SHIFT;
|
||||
if (GetKeyState(VK_CONTROL) & (1 << 31))
|
||||
mods |= GLFW_MOD_CTRL;
|
||||
if (GetKeyState(VK_MENU) & (1 << 31))
|
||||
mods |= GLFW_MOD_ALT;
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
// Retrieves and translates modifier keys
|
||||
//
|
||||
static int getAsyncKeyMods(void)
|
||||
{
|
||||
int mods = 0;
|
||||
|
||||
if (GetAsyncKeyState(VK_SHIFT) & (1 << 31))
|
||||
mods |= GLFW_MOD_SHIFT;
|
||||
if (GetAsyncKeyState(VK_CONTROL) & (1 << 31))
|
||||
mods |= GLFW_MOD_CTRL;
|
||||
if (GetAsyncKeyState(VK_MENU) & (1 << 31))
|
||||
mods |= GLFW_MOD_ALT;
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
// Translates a Windows key to the corresponding GLFW key
|
||||
//
|
||||
static int translateKey(WPARAM wParam, LPARAM lParam)
|
||||
@ -433,7 +465,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
{
|
||||
_glfwInputKey(window, translateKey(wParam, lParam), GLFW_PRESS);
|
||||
_glfwInputKey(window, translateKey(wParam, lParam), GLFW_PRESS, getKeyMods());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -461,20 +493,22 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
const int mods = getKeyMods();
|
||||
|
||||
if (wParam == VK_SHIFT)
|
||||
{
|
||||
// Special trick: release both shift keys on SHIFT up event
|
||||
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, GLFW_RELEASE);
|
||||
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, GLFW_RELEASE);
|
||||
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, GLFW_RELEASE, mods);
|
||||
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, GLFW_RELEASE, mods);
|
||||
}
|
||||
else if (wParam == VK_SNAPSHOT)
|
||||
{
|
||||
// Key down is not reported for the print screen key
|
||||
_glfwInputKey(window, GLFW_KEY_PRINT_SCREEN, GLFW_PRESS);
|
||||
_glfwInputKey(window, GLFW_KEY_PRINT_SCREEN, GLFW_RELEASE);
|
||||
_glfwInputKey(window, GLFW_KEY_PRINT_SCREEN, GLFW_PRESS, mods);
|
||||
_glfwInputKey(window, GLFW_KEY_PRINT_SCREEN, GLFW_RELEASE, mods);
|
||||
}
|
||||
else
|
||||
_glfwInputKey(window, translateKey(wParam, lParam), GLFW_RELEASE);
|
||||
_glfwInputKey(window, translateKey(wParam, lParam), GLFW_RELEASE, getKeyMods());
|
||||
|
||||
break;
|
||||
}
|
||||
@ -484,20 +518,22 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_XBUTTONDOWN:
|
||||
{
|
||||
const int mods = getKeyMods();
|
||||
|
||||
SetCapture(hWnd);
|
||||
|
||||
if (uMsg == WM_LBUTTONDOWN)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
|
||||
else if (uMsg == WM_RBUTTONDOWN)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);
|
||||
else if (uMsg == WM_MBUTTONDOWN)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);
|
||||
else
|
||||
{
|
||||
if (HIWORD(wParam) == XBUTTON1)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_PRESS, mods);
|
||||
else if (HIWORD(wParam) == XBUTTON2)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_PRESS, mods);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -510,20 +546,22 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
{
|
||||
const int mods = getKeyMods();
|
||||
|
||||
ReleaseCapture();
|
||||
|
||||
if (uMsg == WM_LBUTTONUP)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods);
|
||||
else if (uMsg == WM_RBUTTONUP)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods);
|
||||
else if (uMsg == WM_MBUTTONUP)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods);
|
||||
else
|
||||
{
|
||||
if (HIWORD(wParam) == XBUTTON1)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_RELEASE);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_4, GLFW_RELEASE, mods);
|
||||
else if (HIWORD(wParam) == XBUTTON2)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_RELEASE);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_5, GLFW_RELEASE, mods);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1017,19 +1055,19 @@ void _glfwPlatformPollEvents(void)
|
||||
// This is the only async event handling in GLFW, but it solves some
|
||||
// nasty problems
|
||||
{
|
||||
int lshiftDown, rshiftDown;
|
||||
const int mods = getAsyncKeyMods();
|
||||
|
||||
// Get current state of left and right shift keys
|
||||
lshiftDown = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;
|
||||
rshiftDown = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;
|
||||
const int lshiftDown = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;
|
||||
const int rshiftDown = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;
|
||||
|
||||
// See if this differs from our belief of what has happened
|
||||
// (we only have to check for lost key up events)
|
||||
if (!lshiftDown && window->key[GLFW_KEY_LEFT_SHIFT] == 1)
|
||||
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, GLFW_RELEASE);
|
||||
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, GLFW_RELEASE, mods);
|
||||
|
||||
if (!rshiftDown && window->key[GLFW_KEY_RIGHT_SHIFT] == 1)
|
||||
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, GLFW_RELEASE);
|
||||
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, GLFW_RELEASE, mods);
|
||||
}
|
||||
|
||||
// Did the cursor move in an focused window that has captured the cursor
|
||||
|
@ -77,14 +77,14 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean focused)
|
||||
for (i = 0; i <= GLFW_KEY_LAST; i++)
|
||||
{
|
||||
if (window->key[i] == GLFW_PRESS)
|
||||
_glfwInputKey(window, i, GLFW_RELEASE);
|
||||
_glfwInputKey(window, i, GLFW_RELEASE, 0);
|
||||
}
|
||||
|
||||
// Release all pressed mouse buttons
|
||||
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
|
||||
{
|
||||
if (window->mouseButton[i] == GLFW_PRESS)
|
||||
_glfwInputMouseClick(window, i, GLFW_RELEASE);
|
||||
_glfwInputMouseClick(window, i, GLFW_RELEASE, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,22 @@ typedef struct
|
||||
#define MWM_HINTS_DECORATIONS (1L << 1)
|
||||
|
||||
|
||||
// Translates an X event modifier state mask
|
||||
//
|
||||
int translateState(int state)
|
||||
{
|
||||
int mods = 0;
|
||||
|
||||
if (state & ShiftMask)
|
||||
mods |= GLFW_MOD_SHIFT;
|
||||
if (state & ControlMask)
|
||||
mods |= GLFW_MOD_CTRL;
|
||||
if (state & Mod1Mask)
|
||||
mods |= GLFW_MOD_ALT;
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
// Translates an X Window key to internal coding
|
||||
//
|
||||
static int translateKey(int keycode)
|
||||
@ -511,31 +527,36 @@ static void processEvent(XEvent *event)
|
||||
{
|
||||
case KeyPress:
|
||||
{
|
||||
_glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_PRESS);
|
||||
const int key = translateKey(event->xkey.keycode);
|
||||
const int mods = translateState(event->xkey.state);
|
||||
|
||||
if (!(event->xkey.state & ControlMask) &&
|
||||
!(event->xkey.state & Mod1Mask /*Alt*/))
|
||||
{
|
||||
_glfwInputChar(window, translateChar(&event->xkey));
|
||||
}
|
||||
_glfwInputKey(window, key, GLFW_PRESS, mods);
|
||||
|
||||
if (!(mods & GLFW_MOD_CTRL) && !(mods & GLFW_MOD_ALT))
|
||||
_glfwInputChar(window, translateChar(&event->xkey));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyRelease:
|
||||
{
|
||||
_glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_RELEASE);
|
||||
const int key = translateKey(event->xkey.keycode);
|
||||
const int mods = translateState(event->xkey.state);
|
||||
|
||||
_glfwInputKey(window, key, GLFW_RELEASE, mods);
|
||||
break;
|
||||
}
|
||||
|
||||
case ButtonPress:
|
||||
{
|
||||
const int mods = translateState(event->xbutton.state);
|
||||
|
||||
if (event->xbutton.button == Button1)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
|
||||
else if (event->xbutton.button == Button2)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);
|
||||
else if (event->xbutton.button == Button3)
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS);
|
||||
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);
|
||||
|
||||
// Modern X provides scroll events as mouse button presses
|
||||
else if (event->xbutton.button == Button4)
|
||||
@ -552,23 +573,28 @@ static void processEvent(XEvent *event)
|
||||
|
||||
case ButtonRelease:
|
||||
{
|
||||
const int mods = translateState(event->xbutton.state);
|
||||
|
||||
if (event->xbutton.button == Button1)
|
||||
{
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_LEFT,
|
||||
GLFW_RELEASE);
|
||||
GLFW_RELEASE,
|
||||
mods);
|
||||
}
|
||||
else if (event->xbutton.button == Button2)
|
||||
{
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_MIDDLE,
|
||||
GLFW_RELEASE);
|
||||
GLFW_RELEASE,
|
||||
mods);
|
||||
}
|
||||
else if (event->xbutton.button == Button3)
|
||||
{
|
||||
_glfwInputMouseClick(window,
|
||||
GLFW_MOUSE_BUTTON_RIGHT,
|
||||
GLFW_RELEASE);
|
||||
GLFW_RELEASE,
|
||||
mods);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ static void cursor_position_callback(GLFWwindow* window, double x, double y)
|
||||
cursor_y = y;
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
|
||||
set_swap_interval(window, 1 - swap_interval);
|
||||
|
@ -39,18 +39,12 @@ static void usage(void)
|
||||
printf("Usage: clipboard [-h]\n");
|
||||
}
|
||||
|
||||
static GLboolean control_is_down(GLFWwindow* window)
|
||||
{
|
||||
return glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) ||
|
||||
glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL);
|
||||
}
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
@ -62,7 +56,7 @@ static void key_callback(GLFWwindow* window, int key, int action)
|
||||
break;
|
||||
|
||||
case GLFW_KEY_V:
|
||||
if (control_is_down(window))
|
||||
if (mods == GLFW_MOD_CTRL)
|
||||
{
|
||||
const char* string;
|
||||
|
||||
@ -75,7 +69,7 @@ static void key_callback(GLFWwindow* window, int key, int action)
|
||||
break;
|
||||
|
||||
case GLFW_KEY_C:
|
||||
if (control_is_down(window))
|
||||
if (mods == GLFW_MOD_CTRL)
|
||||
{
|
||||
const char* string = "Hello GLFW World!";
|
||||
glfwSetClipboardString(window, string);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
|
||||
// These must match the input mode defaults
|
||||
@ -206,6 +207,22 @@ static const char* get_button_name(int button)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* get_mods_name(int mods)
|
||||
{
|
||||
static char name[512];
|
||||
|
||||
name[0] = '\0';
|
||||
|
||||
if (mods & GLFW_MOD_SHIFT)
|
||||
strcat(name, " shift");
|
||||
if (mods & GLFW_MOD_CTRL)
|
||||
strcat(name, " control");
|
||||
if (mods & GLFW_MOD_ALT)
|
||||
strcat(name, " alt");
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static const char* get_character_string(int character)
|
||||
{
|
||||
// This assumes UTF-8, which is stupid
|
||||
@ -278,16 +295,19 @@ static void window_iconify_callback(GLFWwindow* window, int iconified)
|
||||
iconified ? "iconified" : "restored");
|
||||
}
|
||||
|
||||
static void mouse_button_callback(GLFWwindow* window, int button, int action)
|
||||
static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
const char* name = get_button_name(button);
|
||||
|
||||
printf("%08x at %0.3f: Mouse button %i", counter++, glfwGetTime(), button);
|
||||
|
||||
if (name)
|
||||
printf(" (%s) was %s\n", name, get_action_name(action));
|
||||
else
|
||||
printf(" was %s\n", get_action_name(action));
|
||||
printf(" (%s)", name);
|
||||
|
||||
if (mods)
|
||||
printf(" (with%s)", get_mods_name(mods));
|
||||
|
||||
printf(" was %s\n", get_action_name(action));
|
||||
}
|
||||
|
||||
static void cursor_position_callback(GLFWwindow* window, double x, double y)
|
||||
@ -308,16 +328,19 @@ static void scroll_callback(GLFWwindow* window, double x, double y)
|
||||
printf("%08x at %0.3f: Scroll: %0.3f %0.3f\n", counter++, glfwGetTime(), x, y);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
const char* name = get_key_name(key);
|
||||
|
||||
printf("%08x at %0.3f: Key 0x%04x", counter++, glfwGetTime(), key);
|
||||
|
||||
if (name)
|
||||
printf(" (%s) was %s\n", name, get_action_name(action));
|
||||
else
|
||||
printf(" was %s\n", get_action_name(action));
|
||||
printf(" (%s)", name);
|
||||
|
||||
if (mods)
|
||||
printf(" (with%s)", get_mods_name(mods));
|
||||
|
||||
printf(" was %s\n", get_action_name(action));
|
||||
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
|
18
tests/fsaa.c
18
tests/fsaa.c
@ -48,17 +48,17 @@ static void window_size_callback(GLFWwindow* window, int width, int height)
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_SPACE:
|
||||
glfwSetTime(0.0);
|
||||
break;
|
||||
}
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_SPACE:
|
||||
glfwSetTime(0.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
|
@ -60,7 +60,7 @@ static void error_callback(int error, const char* description)
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
|
@ -45,7 +45,7 @@ static void error_callback(int error, const char* description)
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
printf("%0.2f Key %s\n",
|
||||
glfwGetTime(),
|
||||
|
@ -73,7 +73,7 @@ static void window_size_callback(GLFWwindow* window, int width, int height)
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (key == GLFW_KEY_ESCAPE)
|
||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||
|
@ -65,7 +65,7 @@ static void cursor_position_callback(GLFWwindow* window, double x, double y)
|
||||
cursor_y = y;
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ static void window_close_callback(GLFWwindow* window)
|
||||
printf("Close callback triggered\n");
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
|
@ -44,7 +44,7 @@ static void error_callback(int error, const char* description)
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE)
|
||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||
|
@ -64,7 +64,7 @@ static void window_size_callback(GLFWwindow* window, int width, int height)
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int action)
|
||||
static void key_callback(GLFWwindow* window, int key, int action, int mods)
|
||||
{
|
||||
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
|
||||
set_swap_interval(window, 1 - swap_interval);
|
||||
|
Loading…
Reference in New Issue
Block a user