Mir: Add cursor mode support

Implements a few other missing functions. Cleaning up naming convention
as well.

Fix FindMir.cmake was not finding the correct mirclient.so when
you wanted something other then the system library.

Closes #839.
This commit is contained in:
Brandon Schaefer
2016-08-16 15:26:07 -07:00
committed by Camilla Berglund
parent fbb2d5e10d
commit acce7ec9cf
5 changed files with 167 additions and 77 deletions
+118 -53
View File
@@ -54,37 +54,37 @@ static GLFWbool emptyEventQueue(EventQueue* queue)
// for single threaded event handling.
static EventNode* newEventNode(const MirEvent* event, _GLFWwindow* context)
{
EventNode* new_node = calloc(1, sizeof(EventNode));
new_node->event = mir_event_ref(event);
new_node->window = context;
EventNode* newNode = calloc(1, sizeof(EventNode));
newNode->event = mir_event_ref(event);
newNode->window = context;
return new_node;
return newNode;
}
static void enqueueEvent(const MirEvent* event, _GLFWwindow* context)
{
pthread_mutex_lock(&_glfw.mir.event_mutex);
pthread_mutex_lock(&_glfw.mir.eventMutex);
EventNode* new_node = newEventNode(event, context);
TAILQ_INSERT_TAIL(&_glfw.mir.event_queue->head, new_node, entries);
EventNode* newNode = newEventNode(event, context);
TAILQ_INSERT_TAIL(&_glfw.mir.eventQueue->head, newNode, entries);
pthread_cond_signal(&_glfw.mir.event_cond);
pthread_cond_signal(&_glfw.mir.eventCond);
pthread_mutex_unlock(&_glfw.mir.event_mutex);
pthread_mutex_unlock(&_glfw.mir.eventMutex);
}
static EventNode* dequeueEvent(EventQueue* queue)
{
EventNode* node = NULL;
pthread_mutex_lock(&_glfw.mir.event_mutex);
pthread_mutex_lock(&_glfw.mir.eventMutex);
node = queue->head.tqh_first;
if (node)
TAILQ_REMOVE(&queue->head, node, entries);
pthread_mutex_unlock(&_glfw.mir.event_mutex);
pthread_mutex_unlock(&_glfw.mir.eventMutex);
return node;
}
@@ -201,16 +201,31 @@ static void handlePointerButton(_GLFWwindow* window,
static void handlePointerMotion(_GLFWwindow* window,
const MirPointerEvent* pointer_event)
{
int current_x = window->virtualCursorPosX;
int current_y = window->virtualCursorPosY;
int x = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x);
int y = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y);
int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll);
int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll);
const int hscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll);
const int vscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll);
_glfwInputCursorPos(window, x, y);
if (dx != 0 || dy != 0)
_glfwInputScroll(window, dx, dy);
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (_glfw.mir.disabledCursorWindow != window)
return;
const int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_relative_x);
const int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_relative_y);
const int current_x = window->virtualCursorPosX;
const int current_y = window->virtualCursorPosY;
_glfwInputCursorPos(window, dx + current_x, dy + current_y);
}
else
{
const int x = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x);
const int y = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y);
_glfwInputCursorPos(window, x, y);
}
if (hscroll != 0 || vscroll != 0)
_glfwInputScroll(window, hscroll, vscroll);
}
static void handlePointerEvent(const MirPointerEvent* pointer_event,
@@ -234,7 +249,6 @@ static void handlePointerEvent(const MirPointerEvent* pointer_event,
break;
default:
break;
}
}
@@ -286,7 +300,7 @@ static GLFWbool createSurface(_GLFWwindow* window)
"Mir: Unable to find a correct pixel format");
return GLFW_FALSE;
}
spec = mir_connection_create_spec_for_normal_surface(_glfw.mir.connection,
window->mir.width,
window->mir.height,
@@ -312,6 +326,17 @@ static GLFWbool createSurface(_GLFWwindow* window)
return GLFW_TRUE;
}
static void setSurfaceConfinement(_GLFWwindow* window, MirPointerConfinementState state)
{
MirSurfaceSpec* spec;
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_pointer_confinement(spec, state);
mir_surface_apply_spec(window->mir.surface, spec);
mir_surface_spec_release(spec);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
@@ -370,6 +395,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
window->mir.width = wndconfig->width;
window->mir.height = wndconfig->height;
window->mir.currentCursor = NULL;
if (!createSurface(window))
return GLFW_FALSE;
@@ -390,6 +416,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
if (_glfw.mir.disabledCursorWindow == window)
_glfw.mir.disabledCursorWindow = NULL;
if (mir_surface_is_valid(window->mir.surface))
{
mir_surface_release_sync(window->mir.surface);
@@ -475,18 +504,35 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
mir_surface_set_state(window->mir.surface, mir_surface_state_minimized);
MirSurfaceSpec* spec;
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_state(spec, mir_surface_state_minimized);
mir_surface_apply_spec(window->mir.surface, spec);
mir_surface_spec_release(spec);
}
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
mir_surface_set_state(window->mir.surface, mir_surface_state_restored);
MirSurfaceSpec* spec;
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_state(spec, mir_surface_state_restored);
mir_surface_apply_spec(window->mir.surface, spec);
mir_surface_spec_release(spec);
}
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
MirSurfaceSpec* spec;
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_state(spec, mir_surface_state_maximized);
mir_surface_apply_spec(window->mir.surface, spec);
mir_surface_spec_release(spec);
}
void _glfwPlatformHideWindow(_GLFWwindow* window)
@@ -529,9 +575,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
return GLFW_FALSE;
return mir_surface_get_focus(window->mir.surface) == mir_surface_focused;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
@@ -548,48 +592,46 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window)
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
return GLFW_FALSE;
return mir_surface_get_state(window->mir.surface) == mir_surface_state_maximized;
}
void _glfwPlatformPollEvents(void)
{
EventNode* node = NULL;
while ((node = dequeueEvent(_glfw.mir.event_queue)))
while ((node = dequeueEvent(_glfw.mir.eventQueue)))
{
handleEvent(node->event, node->window);
deleteNode(_glfw.mir.event_queue, node);
deleteNode(_glfw.mir.eventQueue, node);
}
}
void _glfwPlatformWaitEvents(void)
{
pthread_mutex_lock(&_glfw.mir.event_mutex);
pthread_mutex_lock(&_glfw.mir.eventMutex);
if (emptyEventQueue(_glfw.mir.event_queue))
pthread_cond_wait(&_glfw.mir.event_cond, &_glfw.mir.event_mutex);
if (emptyEventQueue(_glfw.mir.eventQueue))
pthread_cond_wait(&_glfw.mir.eventCond, &_glfw.mir.eventMutex);
pthread_mutex_unlock(&_glfw.mir.event_mutex);
pthread_mutex_unlock(&_glfw.mir.eventMutex);
_glfwPlatformPollEvents();
}
void _glfwPlatformWaitEventsTimeout(double timeout)
{
pthread_mutex_lock(&_glfw.mir.event_mutex);
pthread_mutex_lock(&_glfw.mir.eventMutex);
if (emptyEventQueue(_glfw.mir.event_queue))
if (emptyEventQueue(_glfw.mir.eventQueue))
{
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
time.tv_sec += (long) timeout;
time.tv_nsec += (long) ((timeout - (long) timeout) * 1e9);
pthread_cond_timedwait(&_glfw.mir.event_cond, &_glfw.mir.event_mutex, &time);
pthread_cond_timedwait(&_glfw.mir.eventCond, &_glfw.mir.eventMutex, &time);
}
pthread_mutex_unlock(&_glfw.mir.event_mutex);
pthread_mutex_unlock(&_glfw.mir.eventMutex);
_glfwPlatformPollEvents();
}
@@ -606,7 +648,6 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* heigh
*height = window->mir.height;
}
// FIXME implement
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
@@ -654,7 +695,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
pixels += r_stride;
}
cursor->mir.custom_cursor = stream;
cursor->mir.customCursor = stream;
return GLFW_TRUE;
}
@@ -686,8 +727,8 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
if (cursor_name)
{
cursor->mir.conf = mir_cursor_configuration_from_name(cursor_name);
cursor->mir.custom_cursor = NULL;
cursor->mir.conf = mir_cursor_configuration_from_name(cursor_name);
cursor->mir.customCursor = NULL;
return GLFW_TRUE;
}
@@ -699,23 +740,25 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
{
if (cursor->mir.conf)
mir_cursor_configuration_destroy(cursor->mir.conf);
if (cursor->mir.custom_cursor)
mir_buffer_stream_release_sync(cursor->mir.custom_cursor);
if (cursor->mir.customCursor)
mir_buffer_stream_release_sync(cursor->mir.customCursor);
}
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
if (cursor && cursor->mir.conf)
{
window->mir.currentCursor = cursor;
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, cursor->mir.conf));
if (cursor->mir.custom_cursor)
if (cursor->mir.customCursor)
{
mir_buffer_stream_swap_buffers_sync(cursor->mir.custom_cursor);
mir_buffer_stream_swap_buffers_sync(cursor->mir.customCursor);
}
}
else
{
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.default_conf));
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.defaultConf));
}
}
@@ -733,8 +776,30 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
if (mode == GLFW_CURSOR_DISABLED)
{
_glfw.mir.disabledCursorWindow = window;
setSurfaceConfinement(window, mir_pointer_confined_to_surface);
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.disabledConf));
}
else
{
// If we were disabled before lets undo that!
if (_glfw.mir.disabledCursorWindow == window)
{
_glfw.mir.disabledCursorWindow = NULL;
setSurfaceConfinement(window, mir_pointer_unconfined);
}
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
_glfwPlatformSetCursor(window, window->mir.currentCursor);
}
else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
{
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.disabledConf));
}
}
}
const char* _glfwPlatformGetKeyName(int key, int scancode)