summaryrefslogtreecommitdiffstats
path: root/client/Wayland/wlf_pointer.c
diff options
context:
space:
mode:
Diffstat (limited to 'client/Wayland/wlf_pointer.c')
-rw-r--r--client/Wayland/wlf_pointer.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/client/Wayland/wlf_pointer.c b/client/Wayland/wlf_pointer.c
new file mode 100644
index 0000000..6fba40b
--- /dev/null
+++ b/client/Wayland/wlf_pointer.c
@@ -0,0 +1,167 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Wayland Mouse Pointer
+ *
+ * Copyright 2019 Armin Novak <armin.novak@thincast.com>
+ * Copyright 2019 Thincast Technologies GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <freerdp/config.h>
+
+#include "wlf_pointer.h"
+#include "wlfreerdp.h"
+
+#define TAG CLIENT_TAG("wayland.pointer")
+
+typedef struct
+{
+ rdpPointer pointer;
+ size_t size;
+ void* data;
+} wlfPointer;
+
+static BOOL wlf_Pointer_New(rdpContext* context, rdpPointer* pointer)
+{
+ wlfPointer* ptr = (wlfPointer*)pointer;
+
+ if (!ptr)
+ return FALSE;
+
+ ptr->size = pointer->width * pointer->height * 4ULL;
+ ptr->data = winpr_aligned_malloc(ptr->size, 16);
+
+ if (!ptr->data)
+ return FALSE;
+
+ if (!freerdp_image_copy_from_pointer_data(
+ ptr->data, PIXEL_FORMAT_BGRA32, 0, 0, 0, pointer->width, pointer->height,
+ pointer->xorMaskData, pointer->lengthXorMask, pointer->andMaskData,
+ pointer->lengthAndMask, pointer->xorBpp, &context->gdi->palette))
+ {
+ winpr_aligned_free(ptr->data);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void wlf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
+{
+ wlfPointer* ptr = (wlfPointer*)pointer;
+ WINPR_UNUSED(context);
+
+ if (ptr)
+ winpr_aligned_free(ptr->data);
+}
+
+static BOOL wlf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
+{
+ wlfContext* wlf = (wlfContext*)context;
+ wlfPointer* ptr = (wlfPointer*)pointer;
+ void* data = NULL;
+ UINT32 w = 0;
+ UINT32 h = 0;
+ UINT32 x = 0;
+ UINT32 y = 0;
+ size_t size = 0;
+ UwacReturnCode rc = UWAC_ERROR_INTERNAL;
+ BOOL res = FALSE;
+ RECTANGLE_16 area;
+
+ if (!wlf || !wlf->seat)
+ return FALSE;
+
+ x = pointer->xPos;
+ y = pointer->yPos;
+ w = pointer->width;
+ h = pointer->height;
+
+ if (!wlf_scale_coordinates(context, &x, &y, FALSE) ||
+ !wlf_scale_coordinates(context, &w, &h, FALSE))
+ return FALSE;
+
+ size = w * h * 4ULL;
+ data = malloc(size);
+
+ if (!data)
+ return FALSE;
+
+ area.top = 0;
+ area.left = 0;
+ area.right = (UINT16)pointer->width;
+ area.bottom = (UINT16)pointer->height;
+
+ if (!wlf_copy_image(ptr->data, pointer->width * 4, pointer->width, pointer->height, data, w * 4,
+ w, h, &area,
+ freerdp_settings_get_bool(context->settings, FreeRDP_SmartSizing)))
+ goto fail;
+
+ rc = UwacSeatSetMouseCursor(wlf->seat, data, size, w, h, x, y);
+
+ if (rc == UWAC_SUCCESS)
+ res = TRUE;
+
+fail:
+ free(data);
+ return res;
+}
+
+static BOOL wlf_Pointer_SetNull(rdpContext* context)
+{
+ wlfContext* wlf = (wlfContext*)context;
+
+ if (!wlf || !wlf->seat)
+ return FALSE;
+
+ if (UwacSeatSetMouseCursor(wlf->seat, NULL, 0, 0, 0, 0, 0) != UWAC_SUCCESS)
+ return FALSE;
+
+ return TRUE;
+}
+
+static BOOL wlf_Pointer_SetDefault(rdpContext* context)
+{
+ wlfContext* wlf = (wlfContext*)context;
+
+ if (!wlf || !wlf->seat)
+ return FALSE;
+
+ if (UwacSeatSetMouseCursor(wlf->seat, NULL, 1, 0, 0, 0, 0) != UWAC_SUCCESS)
+ return FALSE;
+
+ return TRUE;
+}
+
+static BOOL wlf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
+{
+ // TODO
+ WLog_WARN(TAG, "not implemented");
+ return TRUE;
+}
+
+BOOL wlf_register_pointer(rdpGraphics* graphics)
+{
+ rdpPointer pointer = { 0 };
+
+ pointer.size = sizeof(wlfPointer);
+ pointer.New = wlf_Pointer_New;
+ pointer.Free = wlf_Pointer_Free;
+ pointer.Set = wlf_Pointer_Set;
+ pointer.SetNull = wlf_Pointer_SetNull;
+ pointer.SetDefault = wlf_Pointer_SetDefault;
+ pointer.SetPosition = wlf_Pointer_SetPosition;
+ graphics_register_pointer(graphics, &pointer);
+ return TRUE;
+}