[Spice-devel] [vdagent-win PATCH v11 1/6] Move image handling to a separate file
Frediano Ziglio
fziglio at redhat.com
Mon Jul 24 12:10:21 UTC 2017
This will make easier to change code that handle images.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
Acked-by: Christophe Fergeau <cfergeau at redhat.com>
---
Makefile.am | 2 ++
vdagent/image.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++
vdagent/image.h | 48 +++++++++++++++++++++++++++++
vdagent/vdagent.cpp | 57 +++++-----------------------------
4 files changed, 146 insertions(+), 49 deletions(-)
create mode 100644 vdagent/image.cpp
create mode 100644 vdagent/image.h
diff --git a/Makefile.am b/Makefile.am
index b60a718..868199e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,8 @@ vdagent_SOURCES = \
vdagent/vdagent.cpp \
vdagent/as_user.cpp \
vdagent/as_user.h \
+ vdagent/image.cpp \
+ vdagent/image.h \
$(NULL)
vdagent_rc.$(OBJEXT): vdagent/vdagent.rc
diff --git a/vdagent/image.cpp b/vdagent/image.cpp
new file mode 100644
index 0000000..960058d
--- /dev/null
+++ b/vdagent/image.cpp
@@ -0,0 +1,88 @@
+/*
+ Copyright (C) 2013-2017 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <spice/macros.h>
+
+#include "vdcommon.h"
+#include "image.h"
+
+#include "ximage.h"
+
+typedef struct ImageType {
+ uint32_t type;
+ DWORD cximage_format;
+} ImageType;
+
+static const ImageType image_types[] = {
+ {VD_AGENT_CLIPBOARD_IMAGE_PNG, CXIMAGE_FORMAT_PNG},
+ {VD_AGENT_CLIPBOARD_IMAGE_BMP, CXIMAGE_FORMAT_BMP},
+};
+
+static DWORD get_cximage_format(uint32_t type)
+{
+ for (unsigned int i = 0; i < SPICE_N_ELEMENTS(image_types); i++) {
+ if (image_types[i].type == type) {
+ return image_types[i].cximage_format;
+ }
+ }
+ return 0;
+}
+
+HANDLE get_image_handle(const VDAgentClipboard& clipboard, uint32_t size, UINT&)
+{
+ HANDLE clip_data;
+ DWORD cximage_format = get_cximage_format(clipboard.type);
+ ASSERT(cximage_format);
+ CxImage image((BYTE*)clipboard.data, size, cximage_format);
+ clip_data = image.CopyToHandle();
+ return clip_data;
+}
+
+uint8_t* get_raw_clipboard_image(const VDAgentClipboardRequest& clipboard_request,
+ HANDLE clip_data, long& new_size)
+{
+ new_size = 0;
+
+ CxImage image;
+ uint8_t *new_data = NULL;
+ DWORD cximage_format = get_cximage_format(clipboard_request.type);
+ HPALETTE pal = 0;
+
+ ASSERT(cximage_format);
+ if (IsClipboardFormatAvailable(CF_PALETTE)) {
+ pal = (HPALETTE)GetClipboardData(CF_PALETTE);
+ }
+ if (!image.CreateFromHBITMAP((HBITMAP)clip_data, pal)) {
+ vd_printf("Image create from handle failed");
+ return NULL;
+ }
+ if (!image.Encode(new_data, new_size, cximage_format)) {
+ vd_printf("Image encode to type %u failed", clipboard_request.type);
+ return NULL;
+ }
+ vd_printf("Image encoded to %lu bytes", new_size);
+ return new_data;
+}
+
+void free_raw_clipboard_image(uint8_t *data)
+{
+ // this is really just a free however is better to make
+ // the free from CxImage code as on Windows the free
+ // can be different between libraries
+ CxImage image;
+ image.FreeMemory(data);
+}
diff --git a/vdagent/image.h b/vdagent/image.h
new file mode 100644
index 0000000..b70f53a
--- /dev/null
+++ b/vdagent/image.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 2013-2017 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VDAGENT_IMAGE_H_
+#define VDAGENT_IMAGE_H_
+
+/**
+ * Returns image to put in the clipboard.
+ *
+ * @param clipboard data to write in the clipboard
+ * @param size size of data
+ * @param[in,out] format suggested clipboard format. This can be changed by
+ * the function to reflect a better format
+ */
+HANDLE get_image_handle(const VDAgentClipboard& clipboard, uint32_t size, UINT& format);
+
+/**
+ * Return raw data got from the clipboard.
+ *
+ * Function could use clip_data or get new data from the clipboard.
+ * You should free data returned with free_raw_clipboard_image.
+ * @param clipboard_request request
+ * @param clip_data clipboard data
+ * @param[out] new_size size of returned data
+ */
+uint8_t* get_raw_clipboard_image(const VDAgentClipboardRequest& clipboard_request,
+ HANDLE clip_data, long& new_size);
+
+/**
+ * Free data returned by get_raw_clipboard_image
+ */
+void free_raw_clipboard_image(uint8_t *data);
+
+#endif
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index bb07e1d..f00fbf5 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -19,7 +19,7 @@
#include "desktop_layout.h"
#include "display_setting.h"
#include "file_xfer.h"
-#include "ximage.h"
+#include "image.h"
#undef max
#undef min
#include <spice/macros.h>
@@ -55,16 +55,6 @@ static const VDClipboardFormat clipboard_formats[] = {
#define clipboard_formats_count SPICE_N_ELEMENTS(clipboard_formats)
-typedef struct ImageType {
- uint32_t type;
- DWORD cximage_format;
-} ImageType;
-
-static const ImageType image_types[] = {
- {VD_AGENT_CLIPBOARD_IMAGE_PNG, CXIMAGE_FORMAT_PNG},
- {VD_AGENT_CLIPBOARD_IMAGE_BMP, CXIMAGE_FORMAT_BMP},
-};
-
typedef struct ALIGN_VC VDIChunk {
VDIChunkHeader hdr;
uint8_t data[0];
@@ -725,23 +715,19 @@ bool VDAgent::handle_clipboard(VDAgentClipboard* clipboard, uint32_t size)
if (clipboard->type == VD_AGENT_CLIPBOARD_NONE) {
goto fin;
}
+ format = get_clipboard_format(clipboard->type);
switch (clipboard->type) {
case VD_AGENT_CLIPBOARD_UTF8_TEXT:
clip_data = utf8_alloc((LPCSTR)clipboard->data, size);
break;
case VD_AGENT_CLIPBOARD_IMAGE_PNG:
- case VD_AGENT_CLIPBOARD_IMAGE_BMP: {
- DWORD cximage_format = get_cximage_format(clipboard->type);
- ASSERT(cximage_format);
- CxImage image(clipboard->data, size, cximage_format);
- clip_data = image.CopyToHandle();
+ case VD_AGENT_CLIPBOARD_IMAGE_BMP:
+ clip_data = get_image_handle(*clipboard, size, format);
break;
- }
default:
vd_printf("Unsupported clipboard type %u", clipboard->type);
goto fin;
}
- format = get_clipboard_format(clipboard->type);
if (format == 0) {
vd_printf("Unknown clipboard format, type %u", clipboard->type);
goto fin;
@@ -1104,7 +1090,6 @@ bool VDAgent::handle_clipboard_request(VDAgentClipboardRequest* clipboard_reques
uint8_t* new_data = NULL;
long new_size = 0;
size_t len = 0;
- CxImage image;
VDAgentClipboard* clipboard = NULL;
if (_clipboard_owner != owner_guest) {
@@ -1135,28 +1120,12 @@ bool VDAgent::handle_clipboard_request(VDAgentClipboardRequest* clipboard_reques
new_size = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)new_data, (int)len, NULL, 0, NULL, NULL);
break;
case VD_AGENT_CLIPBOARD_IMAGE_PNG:
- case VD_AGENT_CLIPBOARD_IMAGE_BMP: {
- DWORD cximage_format = get_cximage_format(clipboard_request->type);
- HPALETTE pal = 0;
-
- ASSERT(cximage_format);
- if (IsClipboardFormatAvailable(CF_PALETTE)) {
- pal = (HPALETTE)GetClipboardData(CF_PALETTE);
- }
- if (!image.CreateFromHBITMAP((HBITMAP)clip_data, pal)) {
- vd_printf("Image create from handle failed");
- break;
- }
- if (!image.Encode(new_data, new_size, cximage_format)) {
- vd_printf("Image encode to type %u failed", clipboard_request->type);
- break;
- }
- vd_printf("Image encoded to %lu bytes", new_size);
+ case VD_AGENT_CLIPBOARD_IMAGE_BMP:
+ new_data = get_raw_clipboard_image(*clipboard_request, clip_data, new_size);
break;
}
- }
- if (!new_size) {
+ if (!new_size || !new_data) {
vd_printf("clipboard is empty");
goto handle_clipboard_request_fail;
}
@@ -1184,7 +1153,7 @@ bool VDAgent::handle_clipboard_request(VDAgentClipboardRequest* clipboard_reques
case VD_AGENT_CLIPBOARD_IMAGE_PNG:
case VD_AGENT_CLIPBOARD_IMAGE_BMP:
memcpy(clipboard->data, new_data, new_size);
- image.FreeMemory(new_data);
+ free_raw_clipboard_image(new_data);
break;
}
CloseClipboard();
@@ -1242,16 +1211,6 @@ uint32_t VDAgent::get_clipboard_type(uint32_t format) const
return 0;
}
-DWORD VDAgent::get_cximage_format(uint32_t type) const
-{
- for (unsigned int i = 0; i < SPICE_N_ELEMENTS(image_types); i++) {
- if (image_types[i].type == type) {
- return image_types[i].cximage_format;
- }
- }
- return 0;
-}
-
void VDAgent::set_clipboard_owner(int new_owner)
{
// FIXME: Clear requests, clipboard data and state
--
2.13.3
More information about the Spice-devel
mailing list