summaryrefslogtreecommitdiffstats
path: root/client/windows/platform_utils.cpp
diff options
context:
space:
mode:
authorYaniv Kamay <ykamay@redhat.com>2009-09-19 21:25:46 +0300
committerYaniv Kamay <ykamay@redhat.com>2009-10-14 15:06:41 +0200
commitc1b79eb035fa158fb2ac3bc8e559809611070016 (patch)
tree3348dd749a700dedf87c9b16fe8be77c62928df8 /client/windows/platform_utils.cpp
downloadspice-c1b79eb035fa158fb2ac3bc8e559809611070016.tar.gz
spice-c1b79eb035fa158fb2ac3bc8e559809611070016.tar.xz
spice-c1b79eb035fa158fb2ac3bc8e559809611070016.zip
fresh start
Diffstat (limited to 'client/windows/platform_utils.cpp')
-rw-r--r--client/windows/platform_utils.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/client/windows/platform_utils.cpp b/client/windows/platform_utils.cpp
new file mode 100644
index 00000000..6b9049a0
--- /dev/null
+++ b/client/windows/platform_utils.cpp
@@ -0,0 +1,151 @@
+/*
+ Copyright (C) 2009 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 "common.h"
+#include <map>
+#include "platform_utils.h"
+#include "utils.h"
+#include "threads.h"
+
+void string_vprintf(std::string& str, const char* format, va_list ap)
+{
+ int buf_size = 256;
+ for (;;) {
+ AutoArray<char> buf(new char[buf_size]);
+ int r = vsnprintf_s(buf.get(), buf_size, buf_size - 1, format, ap);
+ if (r != -1) {
+ str = buf.get();
+ return;
+ }
+ buf_size *= 2;
+ }
+}
+
+void wstring_vprintf(std::wstring& str, const wchar_t* format, va_list ap)
+{
+ int buf_size = 256;
+ for (;;) {
+ AutoArray<wchar_t> buf(new wchar_t[buf_size]);
+ int r = vswprintf(buf.get(), buf_size, format, ap);
+ if (r != -1) {
+ str = buf.get();
+ return;
+ }
+ buf_size *= 2;
+ }
+}
+
+HDC create_compatible_dc()
+{
+ HDC dc = CreateCompatibleDC(NULL);
+ if (!dc) {
+ THROW("create compatible DC failed");
+ }
+ return dc;
+}
+
+HBITMAP get_bitmap_res(int id)
+{
+ HBITMAP bitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(id));
+ if (!bitmap) {
+ THROW("get bitmpa #%d failed", id);
+ }
+ return bitmap;
+}
+
+HBITMAP get_alpha_bitmap_res(int id)
+{
+ AutoGDIObject bitmap(LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0,
+ LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_SHARED));
+ if (!bitmap.valid()) {
+ THROW("get bitmpa #%d failed", id);
+ }
+
+ BITMAP src_info;
+ GetObject(bitmap.get(), sizeof(src_info), &src_info);
+ if (src_info.bmBitsPixel != 32 || src_info.bmPlanes != 1) {
+ THROW("invalid format #%d ", id);
+ }
+
+ LONG src_size = src_info.bmHeight * src_info.bmWidthBytes;
+ AutoArray<uint8_t> src_pixels(new uint8_t[src_size]);
+ LONG ncopy = GetBitmapBits((HBITMAP)bitmap.get(), src_size, src_pixels.get());
+ if (ncopy != src_size) {
+ THROW("get vitmap bits failed, %u", GetLastError());
+ }
+
+ AutoDC auto_dc(create_compatible_dc());
+ BITMAPINFO dest_info;
+ uint8_t *dest;
+ dest_info.bmiHeader.biSize = sizeof(dest_info.bmiHeader);
+ dest_info.bmiHeader.biWidth = src_info.bmWidth;
+ dest_info.bmiHeader.biHeight = -src_info.bmHeight;
+ dest_info.bmiHeader.biPlanes = 1;
+ dest_info.bmiHeader.biBitCount = 32;
+ dest_info.bmiHeader.biCompression = BI_RGB;
+ dest_info.bmiHeader.biSizeImage = 0;
+ dest_info.bmiHeader.biXPelsPerMeter = dest_info.bmiHeader.biYPelsPerMeter = 0;
+ dest_info.bmiHeader.biClrUsed = 0;
+ dest_info.bmiHeader.biClrImportant = 0;
+
+ HBITMAP ret = CreateDIBSection(auto_dc.get(), &dest_info, 0, (VOID **)&dest, NULL, 0);
+ if (!ret) {
+ THROW("create bitmap failed, %u", GetLastError());
+ }
+
+ uint8_t* src_line = src_pixels.get();
+ for (int i = 0; i < src_info.bmHeight; i++, src_line += src_info.bmWidthBytes) {
+ uint8_t* src = src_line;
+ for (int j = 0; j < src_info.bmWidth; j++) {
+ dest[3] = src[3];
+ double alpha = (double)dest[3] / 0xff;
+ dest[2] = (uint8_t)(alpha * src[2]);
+ dest[1] = (uint8_t)(alpha * src[1]);
+ dest[0] = (uint8_t)(alpha * src[0]);
+ src += 4;
+ dest += 4;
+ }
+ }
+ return ret;
+}
+
+static std::map<int, const char*> errors_map;
+static Mutex errors_map_mutex;
+
+const char* sys_err_to_str(int error)
+{
+ Lock lock(errors_map_mutex);
+ if (errors_map.find(error) == errors_map.end()) {
+ LPSTR msg;
+ if (!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&msg, 0, NULL)) {
+ const int BUF_SIZE = 20;
+ msg = new char[BUF_SIZE];
+ _snprintf(msg, BUF_SIZE, "errno %d", error);
+ } else {
+ char *new_line;
+ if ((new_line = strrchr(msg, '\r'))) {
+ *new_line = 0;
+ }
+ }
+ errors_map[error] = msg;
+ }
+ return errors_map[error];
+}
+