dc_hw.c 9.4 KB
Newer Older
B
bernard.xiong 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * File      : dc_hw.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2009-10-16     Bernard      first version
 */
#include <rtgui/dc.h>
15
#include <rtgui/dc_hw.h>
B
bernard.xiong 已提交
16
#include <rtgui/driver.h>
B
bernard.xiong 已提交
17
#include <rtgui/rtgui_system.h>
B
bernard.xiong 已提交
18 19 20 21 22 23
#include <rtgui/widgets/view.h>
#include <rtgui/widgets/window.h>
#include <rtgui/widgets/workbench.h>
#include <rtgui/widgets/title.h>

static void rtgui_dc_hw_draw_point(struct rtgui_dc* dc, int x, int y);
24
static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* dc, int x, int y, rtgui_color_t color);
B
bernard.xiong 已提交
25 26 27 28
static void rtgui_dc_hw_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
static void rtgui_dc_hw_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
static void rtgui_dc_hw_fill_rect (struct rtgui_dc* dc, rtgui_rect_t* rect);
static void rtgui_dc_hw_blit	  (struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
29 30
static void rtgui_dc_hw_set_gc (struct rtgui_dc* dc, rtgui_gc_t *gc);
static rtgui_gc_t *rtgui_dc_hw_get_gc (struct rtgui_dc* dc);
B
bernard.xiong 已提交
31 32 33 34
static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc);
static rt_bool_t rtgui_dc_hw_get_visible(struct rtgui_dc* dc);
static void rtgui_dc_hw_get_rect(struct rtgui_dc* dc, rtgui_rect_t* rect);

35 36 37 38 39
#define hw_driver				(rtgui_graphic_driver_get_default())
#define dc_set_foreground(c) 	dc->gc.foreground = c
#define dc_set_background(c) 	dc->gc.background = c

const struct rtgui_dc_engine dc_hw_engine = 
B
bernard.xiong 已提交
40
{
41 42 43 44 45 46
	rtgui_dc_hw_draw_point,
	rtgui_dc_hw_draw_color_point,
	rtgui_dc_hw_draw_vline,
	rtgui_dc_hw_draw_hline,
	rtgui_dc_hw_fill_rect,
	rtgui_dc_hw_blit,
B
bernard.xiong 已提交
47

48 49
	rtgui_dc_hw_set_gc,
	rtgui_dc_hw_get_gc,
B
bernard.xiong 已提交
50

51 52
	rtgui_dc_hw_get_visible,
	rtgui_dc_hw_get_rect,
B
bernard.xiong 已提交
53

54 55
	rtgui_dc_hw_fini,
};
B
bernard.xiong 已提交
56 57 58 59 60 61

extern struct rt_mutex cursor_mutex;
extern void rtgui_mouse_show_cursor(void);
extern void rtgui_mouse_hide_cursor(void);
struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
{
62
	struct rtgui_dc* dc;
B
bernard.xiong 已提交
63 64 65 66 67 68
	rtgui_widget_t* widget;

	/* adjudge owner */
	if (owner == RT_NULL || owner->toplevel == RT_NULL) return RT_NULL;
	if (!RTGUI_IS_TOPLEVEL(owner->toplevel)) return RT_NULL;

69 70 71
	dc = RTGUI_WIDGET_DC(owner);
	/* set init visible as true */
	RTGUI_WIDGET_DC_SET_VISIBLE(owner);
B
bernard.xiong 已提交
72

73
	/* check widget visible */
B
bernard.xiong 已提交
74 75 76 77 78
	widget = owner;
	while (widget != RT_NULL)
	{
		if (RTGUI_WIDGET_IS_HIDE(widget))
		{
79
			RTGUI_WIDGET_DC_SET_UNVISIBLE(owner);
B
bernard.xiong 已提交
80 81 82 83 84 85
			break;
		}

		widget = widget->parent;
	}

86
	if (RTGUI_IS_WINTITLE(owner->toplevel))
B
bernard.xiong 已提交
87
	{
88
		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
B
bernard.xiong 已提交
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
		top->drawing ++;

		if (top->drawing == 1)
		{
#ifdef RTGUI_USING_MOUSE_CURSOR
#ifdef __WIN32__
			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
			rt_kprintf("hide cursor\n");
			rtgui_mouse_hide_cursor();
#else
			/* hide cursor */
			rtgui_mouse_hide_cursor();
#endif
#endif
		}
	}
105 106
	else if (RTGUI_IS_WORKBENCH(owner->toplevel) ||
		RTGUI_IS_WIN(owner->toplevel))
B
bernard.xiong 已提交
107
	{
108
		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
B
bernard.xiong 已提交
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
		top->drawing ++;

		if (top->drawing == 1)
		{
#ifdef __WIN32__
#ifdef RTGUI_USING_MOUSE_CURSOR
			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
			rt_kprintf("hide cursor\n");
			rtgui_mouse_hide_cursor();
#endif
#else
			/* send draw begin to server */
			struct rtgui_event_update_begin eupdate;
			RTGUI_EVENT_UPDATE_BEGIN_INIT(&(eupdate));
			eupdate.rect = RTGUI_WIDGET(top)->extent;

			rtgui_thread_send(top->server, (struct rtgui_event*)&eupdate, sizeof(eupdate));
#endif
		}
	}

130
	return dc;
B
bernard.xiong 已提交
131 132 133 134
}

static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
{
135 136 137 138 139 140
	rtgui_widget_t* owner;
	
	if (dc == RT_NULL || dc->type != RTGUI_DC_HW) return RT_FALSE;

	/* get owner */
	owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
B
bernard.xiong 已提交
141

142
	if (RTGUI_IS_WINTITLE(owner->toplevel))
B
bernard.xiong 已提交
143 144
	{
		/* update title extent */
145
		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
B
bernard.xiong 已提交
146 147

		top->drawing --;
148
		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
B
bernard.xiong 已提交
149 150 151 152 153 154 155 156 157
		{
#ifdef __WIN32__
#ifdef RTGUI_USING_MOUSE_CURSOR
			rt_mutex_release(&cursor_mutex);
			/* show cursor */
			rtgui_mouse_show_cursor();
			rt_kprintf("show cursor\n");
#endif
			/* update screen */
158
			hw_driver->screen_update(&(owner->extent));
B
bernard.xiong 已提交
159 160 161 162 163 164 165
#else
#ifdef RTGUI_USING_MOUSE_CURSOR
			/* show cursor */
			rtgui_mouse_show_cursor();
#endif

			/* update screen */
166
			hw_driver->screen_update(&(owner->extent));
B
bernard.xiong 已提交
167 168 169
#endif
		}
	}
170 171
	else if (RTGUI_IS_WORKBENCH(owner->toplevel) ||
		RTGUI_IS_WIN(owner->toplevel))
B
bernard.xiong 已提交
172
	{
173
		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
B
bernard.xiong 已提交
174 175
		top->drawing --;

176
		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
B
bernard.xiong 已提交
177 178 179 180 181 182 183 184 185
		{
#ifdef __WIN32__
#ifdef RTGUI_USING_MOUSE_CURSOR
			rt_mutex_release(&cursor_mutex);
			/* show cursor */
			rtgui_mouse_show_cursor();
			rt_kprintf("show cursor\n");
#endif
			/* update screen */
186
			hw_driver->screen_update(&(owner->extent));
B
bernard.xiong 已提交
187 188 189 190
#else
			/* send to server to end drawing */
			struct rtgui_event_update_end eupdate;
			RTGUI_EVENT_UPDATE_END_INIT(&(eupdate));
191
			eupdate.rect = owner->extent;
B
bernard.xiong 已提交
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206

			rtgui_thread_send(top->server, (struct rtgui_event*)&eupdate, sizeof(eupdate));
#endif
		}
	}

	return RT_TRUE;
}

/*
 * draw a logic point on device
 */
static void rtgui_dc_hw_draw_point(struct rtgui_dc* self, int x, int y)
{
	rtgui_rect_t rect;
207
	rtgui_widget_t *owner;
B
bernard.xiong 已提交
208

209 210 211 212 213
	if (self == RT_NULL) return;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;
B
bernard.xiong 已提交
214

215 216 217
	x = x + owner->extent.x1;
	y = y + owner->extent.y1;

218 219
	/* draw this point */
	hw_driver->set_pixel(&(owner->gc.foreground), x, y);
B
bernard.xiong 已提交
220 221
}

222 223 224
static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* self, int x, int y, rtgui_color_t color)
{
	rtgui_rect_t rect;
225
	rtgui_widget_t *owner;
226

227 228 229 230 231
	if (self == RT_NULL) return;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;
232

233 234
	x = x + owner->extent.x1;
	y = y + owner->extent.y1;
235

236 237
	/* draw this point */
	hw_driver->set_pixel(&color, x, y);
238 239
}

B
bernard.xiong 已提交
240 241 242 243 244 245
/*
 * draw a logic vertical line on device
 */
static void rtgui_dc_hw_draw_vline(struct rtgui_dc* self, int x, int y1, int y2)
{
	register rt_base_t index;
246
	rtgui_widget_t *owner;
B
bernard.xiong 已提交
247

248 249 250 251 252
	if (self == RT_NULL) return;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;
B
bernard.xiong 已提交
253

254 255 256
	x  = x + owner->extent.x1;
	y1 = y1 + owner->extent.y1;
	y2 = y2 + owner->extent.y1;
B
bernard.xiong 已提交
257

258 259
	/* draw vline */
	hw_driver->draw_vline(&(owner->gc.foreground), x, y1, y2);
B
bernard.xiong 已提交
260 261 262 263 264 265 266 267
}

/*
 * draw a logic horizontal line on device
 */
static void rtgui_dc_hw_draw_hline(struct rtgui_dc* self, int x1, int x2, int y)
{
	register rt_base_t index;
268
	rtgui_widget_t *owner;
B
bernard.xiong 已提交
269

270 271 272 273 274
	if (self == RT_NULL) return;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;
B
bernard.xiong 已提交
275 276

	/* convert logic to device */
277 278 279
	x1 = x1 + owner->extent.x1;
	x2 = x2 + owner->extent.x1;
	y  = y + owner->extent.y1;
B
bernard.xiong 已提交
280

281 282
	/* draw hline */
	hw_driver->draw_hline(&(owner->gc.foreground), x1, x2, y);
B
bernard.xiong 已提交
283 284 285 286
}

static void rtgui_dc_hw_fill_rect (struct rtgui_dc* self, struct rtgui_rect* rect)
{
287 288
	rtgui_color_t color;
	register rt_base_t index, x1, x2;
289
	rtgui_widget_t *owner;
B
bernard.xiong 已提交
290

291
	if (self == RT_NULL) return;
292

293 294 295
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;
B
bernard.xiong 已提交
296

297 298 299 300 301
	/* get background color */
	color = owner->gc.background;
	/* convert logic to device */
	x1 = rect->x1 + owner->extent.x1;
	x2 = rect->x2 + owner->extent.x1;
B
bernard.xiong 已提交
302 303

	/* fill rect */
304
	for (index = owner->extent.y1 + rect->y1; index < owner->extent.y1 + rect->y2; index ++)
B
bernard.xiong 已提交
305
	{
306
		hw_driver->draw_hline(&color, x1, x2, index);
B
bernard.xiong 已提交
307 308 309 310 311 312 313 314 315
	}
}

static void rtgui_dc_hw_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
{
	/* not blit in hardware dc */
	return ;
}

316
static void rtgui_dc_hw_set_gc(struct rtgui_dc* self, rtgui_gc_t *gc)
B
bernard.xiong 已提交
317
{
318
	rtgui_widget_t *owner;
B
bernard.xiong 已提交
319

320 321 322 323 324
	if (self == RT_NULL) return;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	owner->gc = *gc;
B
bernard.xiong 已提交
325 326
}

327
static rtgui_gc_t* rtgui_dc_hw_get_gc(struct rtgui_dc* self)
B
bernard.xiong 已提交
328
{
329
	rtgui_widget_t *owner;
B
bernard.xiong 已提交
330

331 332 333 334 335 336 337 338 339 340
	if (self == RT_NULL) 
	{
	rt_kprintf("why!!\n");
	return RT_NULL;
	}
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);

	return &(owner->gc);
B
bernard.xiong 已提交
341 342
}

343
static rt_bool_t rtgui_dc_hw_get_visible(struct rtgui_dc* self)
B
bernard.xiong 已提交
344
{
345 346 347 348 349 350 351
	rtgui_widget_t *owner;

	if (self == RT_NULL) return RT_FALSE;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return RT_FALSE;
352

353
	return RT_TRUE;
B
bernard.xiong 已提交
354 355 356 357
}

static void rtgui_dc_hw_get_rect(struct rtgui_dc* self, rtgui_rect_t* rect)
{
358
	rtgui_widget_t *owner;
B
bernard.xiong 已提交
359

360 361 362 363 364
	if (self == RT_NULL) return;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	rtgui_widget_get_rect(owner, rect);
B
bernard.xiong 已提交
365
}
366

367
void rtgui_dc_hw_draw_raw_hline(struct rtgui_dc* self, rt_uint8_t* raw_ptr, int x1, int x2, int y)
368 369
{
	register rt_base_t index;
370
	rtgui_widget_t *owner;
371

372 373 374 375 376
	if (self == RT_NULL) return;
	
	/* get owner */
	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;
377 378

	/* convert logic to device */
379 380 381
	x1 = x1 + owner->extent.x1;
	x2 = x2 + owner->extent.x1;
	y  = y + owner->extent.y1;
382

383 384
	/* draw raw hline */
	hw_driver->draw_raw_hline(raw_ptr, x1, x2, y);
385
}
386