summaryrefslogtreecommitdiffstats
path: root/client/windows/red_drawable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'client/windows/red_drawable.cpp')
-rw-r--r--client/windows/red_drawable.cpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/client/windows/red_drawable.cpp b/client/windows/red_drawable.cpp
new file mode 100644
index 00000000..13d4a21e
--- /dev/null
+++ b/client/windows/red_drawable.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 "red_drawable.h"
+#include "pixels_source_p.h"
+#include "utils.h"
+#include "threads.h"
+
+static const uint64_t lock_timout = 1000 * 1000 * 10; /*10ms*/
+
+void RedDrawable::copy_pixels(const PixelsSource& src, int src_x, int src_y, const Rect& dest)
+{
+ PixelsSource_p* dest_p_data = (PixelsSource_p*)get_opaque();
+ PixelsSource_p* src_p_data = (PixelsSource_p*)src.get_opaque();
+
+ for (;;) {
+ Lock lock(*dest_p_data->_mutex);
+ Lock timed_lock(*src_p_data->_mutex, lock_timout);
+ if (!timed_lock.is_locked()) {
+ continue;
+ }
+ BitBlt(dest_p_data->dc, dest.left + _origin.x, dest.top + _origin.y,
+ dest.right - dest.left, dest.bottom - dest.top,
+ src_p_data->dc, src_x + src._origin.x,
+ src_y + src._origin.y, SRCCOPY);
+ return;
+ }
+}
+
+void RedDrawable::blend_pixels(const PixelsSource& src, int src_x, int src_y, const Rect& dest)
+{
+ static BLENDFUNCTION blend_func = { AC_SRC_OVER, 0, 0xff, AC_SRC_ALPHA};
+
+ int width = dest.right - dest.left;
+ int height = dest.bottom - dest.top;
+ PixelsSource_p* dest_p_data = (PixelsSource_p*)get_opaque();
+ PixelsSource_p* src_p_data = (PixelsSource_p*)src.get_opaque();
+ for (;;) {
+ Lock lock(*dest_p_data->_mutex);
+ Lock timed_lock(*src_p_data->_mutex, lock_timout);
+ if (!timed_lock.is_locked()) {
+ continue;
+ }
+ AlphaBlend(dest_p_data->dc, dest.left + _origin.x, dest.top + _origin.y, width, height,
+ src_p_data->dc, src_x + src._origin.x, src_y + src._origin.y, width, height,
+ blend_func);
+ return;
+ }
+}
+
+void RedDrawable::combine_pixels(const PixelsSource& src, int src_x, int src_y, const Rect& dest,
+ CombineOP op)
+{
+ DWORD rop;
+ switch (op) {
+ case OP_COPY:
+ rop = SRCCOPY;
+ break;
+ case OP_AND:
+ rop = SRCAND;
+ break;
+ case OP_XOR:
+ rop = SRCINVERT;
+ break;
+ default:
+ THROW("invalid op %d", op);
+ }
+
+ PixelsSource_p* dest_p_data = (PixelsSource_p*)get_opaque();
+ PixelsSource_p* src_p_data = (PixelsSource_p*)src.get_opaque();
+ for (;;) {
+ Lock lock(*dest_p_data->_mutex);
+ Lock timed_lock(*src_p_data->_mutex, lock_timout);
+ if (!timed_lock.is_locked()) {
+ continue;
+ }
+ BitBlt(dest_p_data->dc, dest.left + _origin.x, dest.top + _origin.y,
+ dest.right - dest.left, dest.bottom - dest.top,
+ src_p_data->dc, src_x + src._origin.x,
+ src_y + src._origin.y, rop);
+ return;
+ }
+}
+
+void RedDrawable::erase_rect(const Rect& rect, rgb32_t color)
+{
+ RECT r;
+ r.left = rect.left + _origin.x;
+ r.right = rect.right + _origin.x;
+ r.top = rect.top + _origin.y;
+ r.bottom = rect.bottom + _origin.y;
+
+ PixelsSource_p* dest_p_data = (PixelsSource_p*)get_opaque();
+ Lock lock(*dest_p_data->_mutex);
+ FillRect(dest_p_data->dc, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));
+}
+
+void RedDrawable::fill_rect(const Rect& rect, rgb32_t color)
+{
+ RECT r;
+ r.left = rect.left + _origin.x;
+ r.right = rect.right + _origin.x;
+ r.top = rect.top + _origin.y;
+ r.bottom = rect.bottom + _origin.y;
+
+ HBRUSH brush = CreateSolidBrush(RGB(rgb32_get_red(color),
+ rgb32_get_green(color),
+ rgb32_get_blue(color)));
+ for (;;) {
+ PixelsSource_p* dest_p_data = (PixelsSource_p*)get_opaque();
+ Lock lock(*dest_p_data->_mutex);
+ FillRect(dest_p_data->dc, &r, brush);
+ break;
+ }
+ DeleteObject(brush);
+}
+
+void RedDrawable::frame_rect(const Rect& rect, rgb32_t color)
+{
+ RECT r;
+ r.left = rect.left + _origin.x;
+ r.right = rect.right + _origin.x;
+ r.top = rect.top + _origin.y;
+ r.bottom = rect.bottom + _origin.y;
+ HBRUSH brush = CreateSolidBrush(RGB(rgb32_get_red(color),
+ rgb32_get_green(color),
+ rgb32_get_blue(color)));
+ for (;;) {
+ PixelsSource_p* dest_p_data = (PixelsSource_p*)get_opaque();
+ Lock lock(*dest_p_data->_mutex);
+ FrameRect(dest_p_data->dc, &r, brush);
+ break;
+ }
+ DeleteObject(brush);
+}
+