From c1b79eb035fa158fb2ac3bc8e559809611070016 Mon Sep 17 00:00:00 2001 From: Yaniv Kamay Date: Sat, 19 Sep 2009 21:25:46 +0300 Subject: fresh start --- client/windows/platform_utils.cpp | 151 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 client/windows/platform_utils.cpp (limited to 'client/windows/platform_utils.cpp') 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 . +*/ + +#include "common.h" +#include +#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 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 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 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 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]; +} + -- cgit