This commit is contained in:
linkmauve 2015-12-25 19:55:53 +00:00
commit 5ce835a726
4 changed files with 104 additions and 3 deletions

View File

@ -381,7 +381,8 @@ static void registryHandleGlobal(void* data,
if (strcmp(interface, "wl_compositor") == 0) if (strcmp(interface, "wl_compositor") == 0)
{ {
_glfw.wl.compositor = _glfw.wl.compositor =
wl_registry_bind(registry, name, &wl_compositor_interface, 1); wl_registry_bind(registry, name, &wl_compositor_interface,
min(3, version));
} }
else if (strcmp(interface, "wl_shm") == 0) else if (strcmp(interface, "wl_shm") == 0)
{ {

View File

@ -97,6 +97,9 @@ static void scale(void* data,
struct wl_output* output, struct wl_output* output,
int32_t factor) int32_t factor)
{ {
struct _GLFWmonitor *monitor = data;
monitor->wl.scale = factor;
} }
static const struct wl_output_listener output_listener = { static const struct wl_output_listener output_listener = {

View File

@ -65,8 +65,16 @@ typedef struct _GLFWwindowWayland
struct wl_egl_window* native; struct wl_egl_window* native;
struct wl_shell_surface* shell_surface; struct wl_shell_surface* shell_surface;
struct wl_callback* callback; struct wl_callback* callback;
_GLFWcursor* currentCursor; _GLFWcursor* currentCursor;
double cursorPosX, cursorPosY; double cursorPosX, cursorPosY;
// We need to track the monitors the window spans on to calculate the
// optimal scaling factor.
int scale;
_GLFWmonitor** monitors;
int monitorsCount;
int monitorsSize;
} _GLFWwindowWayland; } _GLFWwindowWayland;
@ -123,7 +131,7 @@ typedef struct _GLFWmonitorWayland
int x; int x;
int y; int y;
int scale;
} _GLFWmonitorWayland; } _GLFWmonitorWayland;

View File

@ -72,6 +72,79 @@ static const struct wl_shell_surface_listener shellSurfaceListener = {
handlePopupDone handlePopupDone
}; };
static void checkScaleChange(_GLFWwindow* window)
{
int scaledWidth, scaledHeight;
int scale = 1;
int i;
int monitorScale;
// Get the scale factor from the highest scale monitor.
for (i = 0; i < window->wl.monitorsCount; ++i)
{
monitorScale = window->wl.monitors[i]->wl.scale;
if (scale < monitorScale)
scale = monitorScale;
}
// Only change the framebuffer size if the scale changed.
if (scale != window->wl.scale)
{
window->wl.scale = scale;
scaledWidth = window->wl.width * scale;
scaledHeight = window->wl.height * scale;
wl_surface_set_buffer_scale(window->wl.surface, scale);
wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
}
}
static void handleEnter(void *data,
struct wl_surface *surface,
struct wl_output *output)
{
_GLFWwindow* window = data;
_GLFWmonitor* monitor = wl_output_get_user_data(output);
if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)
{
++window->wl.monitorsSize;
window->wl.monitors =
realloc(window->wl.monitors,
window->wl.monitorsSize * sizeof(_GLFWmonitor*));
}
window->wl.monitors[window->wl.monitorsCount++] = monitor;
checkScaleChange(window);
}
static void handleLeave(void *data,
struct wl_surface *surface,
struct wl_output *output)
{
_GLFWwindow* window = data;
_GLFWmonitor* monitor = wl_output_get_user_data(output);
GLFWbool found;
int i;
for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
{
if (monitor == window->wl.monitors[i])
found = GLFW_TRUE;
if (found)
window->wl.monitors[i] = window->wl.monitors[i + 1];
}
window->wl.monitors[--window->wl.monitorsCount] = NULL;
checkScaleChange(window);
}
static const struct wl_surface_listener surfaceListener = {
handleEnter,
handleLeave
};
static GLFWbool createSurface(_GLFWwindow* window, static GLFWbool createSurface(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig) const _GLFWwndconfig* wndconfig)
{ {
@ -79,6 +152,10 @@ static GLFWbool createSurface(_GLFWwindow* window,
if (!window->wl.surface) if (!window->wl.surface)
return GLFW_FALSE; return GLFW_FALSE;
wl_surface_add_listener(window->wl.surface,
&surfaceListener,
window);
wl_surface_set_user_data(window->wl.surface, window); wl_surface_set_user_data(window->wl.surface, window);
window->wl.native = wl_egl_window_create(window->wl.surface, window->wl.native = wl_egl_window_create(window->wl.surface,
@ -98,6 +175,7 @@ static GLFWbool createSurface(_GLFWwindow* window,
window->wl.width = wndconfig->width; window->wl.width = wndconfig->width;
window->wl.height = wndconfig->height; window->wl.height = wndconfig->height;
window->wl.scale = 1;
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -262,6 +340,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
window->wl.currentCursor = NULL; window->wl.currentCursor = NULL;
window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*));
window->wl.monitorsCount = 0;
window->wl.monitorsSize = 1;
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -288,6 +370,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window->wl.surface) if (window->wl.surface)
wl_surface_destroy(window->wl.surface); wl_surface_destroy(window->wl.surface);
free(window->wl.monitors);
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
@ -322,9 +406,12 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{ {
wl_egl_window_resize(window->wl.native, width, height, 0, 0); int scaledWidth = width * window->wl.scale;
int scaledHeight = height * window->wl.scale;
window->wl.width = width; window->wl.width = width;
window->wl.height = height; window->wl.height = height;
wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
} }
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
@ -344,6 +431,8 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
{ {
_glfwPlatformGetWindowSize(window, width, height); _glfwPlatformGetWindowSize(window, width, height);
*width *= window->wl.scale;
*height *= window->wl.scale;
} }
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,