diff options
Diffstat (limited to 'client/windows/red_drawable.cpp')
-rw-r--r-- | client/windows/red_drawable.cpp | 151 |
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); +} + |