window.c 15.0 KB
Newer Older
B
bernard.xiong 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * File      : window.c
 * This file is part of RTGUI in 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-04     Bernard      first version
 */
#include <rtgui/dc.h>
#include <rtgui/color.h>
#include <rtgui/image.h>
#include <rtgui/rtgui_system.h>

#include <rtgui/widgets/window.h>
#include <rtgui/widgets/button.h>
#include <rtgui/widgets/workbench.h>

static void _rtgui_win_constructor(rtgui_win_t *win)
{
	/* init window attribute */
	win->on_activate	= RT_NULL;
	win->on_deactivate	= RT_NULL;
	win->on_close		= RT_NULL;
	win->title			= RT_NULL;
30 31
	win->modal_code		= RTGUI_MODAL_OK;
	win->modal_widget	= RT_NULL;
B
bernard.xiong 已提交
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

	/* set window hide */
	RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));

	/* set window style */
	win->style = RTGUI_WIN_STYLE_DEFAULT;
	rtgui_widget_set_event_handler(RTGUI_WIDGET(win), rtgui_win_event_handler);

	/* init user data */
	win->user_data = 0;
}

static void _rtgui_win_destructor(rtgui_win_t* win)
{
	struct rtgui_event_win_destroy edestroy;

	if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
	{
		/* destroy in server */
		RTGUI_EVENT_WIN_DESTROY_INIT(&edestroy);
		edestroy.wid = win;
		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&edestroy),
			sizeof(struct rtgui_event_win_destroy)) != RT_EOK)
		{
			/* destroy in server failed */
			return;
		}
	}

	/* release field */
	rt_free(win->title);
}

static rt_bool_t _rtgui_win_create_in_server(rtgui_win_t* win)
{
	if (RTGUI_TOPLEVEL(win)->server == RT_NULL)
	{
		rt_thread_t server;
		struct rtgui_event_win_create ecreate;
		RTGUI_EVENT_WIN_CREATE_INIT(&ecreate);

		/* get server thread id */
		server = rtgui_thread_get_server();
		if (server == RT_NULL)
		{
			rt_kprintf("RTGUI server is not running...\n");
			return RT_FALSE;
		}

		/* send win create event to server */
82 83 84 85
		ecreate.wid 		= win;
		ecreate.parent.user	= win->style;
#ifndef RTGUI_USING_SMALL_SIZE
		ecreate.extent 		= RTGUI_WIDGET(win)->extent;
B
bernard.xiong 已提交
86
		rt_strncpy((char*)ecreate.title, (char*)win->title, RTGUI_NAME_MAX);
87
#endif
B
bernard.xiong 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102

		if (rtgui_thread_send_sync(server, RTGUI_EVENT(&ecreate),
			sizeof(struct rtgui_event_win_create)) != RT_EOK)
		{
			rt_kprintf("create win: %s failed\n", win->title);
			return RT_FALSE;
		}

		/* set server */
		RTGUI_TOPLEVEL(win)->server = server;
	}

	return RT_TRUE;
}

103 104 105 106 107
DEFINE_CLASS_TYPE(win, "win", 
	RTGUI_TOPLEVEL_TYPE,
	_rtgui_win_constructor,
	_rtgui_win_destructor,
	sizeof(struct rtgui_win));
B
bernard.xiong 已提交
108

109
rtgui_win_t* rtgui_win_create(rtgui_toplevel_t* parent_toplevel, const char* title, rtgui_rect_t *rect, rt_uint8_t style)
B
bernard.xiong 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
{
	struct rtgui_win* win;

	/* allocate win memory */
	win = (struct rtgui_win*) rtgui_widget_create (RTGUI_WIN_TYPE);
	if (win != RT_NULL)
	{
		/* set parent toplevel */
		win->parent_toplevel = parent_toplevel;

		/* set title, rect and style */
		if (title != RT_NULL) win->title = rt_strdup(title);
		else win->title = RT_NULL;

		rtgui_widget_set_rect(RTGUI_WIDGET(win), rect);
		win->style = style;

		if (_rtgui_win_create_in_server(win) == RT_FALSE)
		{
			rtgui_widget_destroy(RTGUI_WIDGET(win));
			return RT_NULL;
		}
	}

	return win;
}

void rtgui_win_destroy(struct rtgui_win* win)
{
139
	if (win->style & RTGUI_WIN_STYLE_MODAL)
B
bernard.xiong 已提交
140
	{
141 142
		/* end modal */
		rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
B
bernard.xiong 已提交
143 144 145
	}
	else
	{
146
		rtgui_widget_destroy(RTGUI_WIDGET(win));
B
bernard.xiong 已提交
147 148 149
	}
}

B
bernard.xiong 已提交
150 151 152 153 154
void rtgui_win_close(struct rtgui_win* win)
{
	win->style |= RTGUI_WIN_STYLE_CLOSED;
}

B
bernard.xiong 已提交
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
rtgui_modal_code_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal)
{
	rtgui_modal_code_t result;

	RT_ASSERT(win != RT_NULL);
	result = RTGUI_MODAL_CANCEL;

	/* if it does not register into server, create it in server */
	if (RTGUI_TOPLEVEL(win)->server == RT_NULL)
	{
		if (_rtgui_win_create_in_server(win) == RT_FALSE)
			return result;
	}

	if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)))
	{
		/* send show message to server */
		struct rtgui_event_win_show eshow;
		RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
		eshow.wid = win;

		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&eshow),
			sizeof(struct rtgui_event_win_show)) != RT_EOK)
		{
			/* hide window failed */
			return result;
		}

		/* set window unhidden */
		RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
	}
	else rtgui_widget_update(RTGUI_WIDGET(win));

	if (is_modal == RT_TRUE)
	{
		if (win->parent_toplevel != RT_NULL)
		{
192
			rtgui_widget_t *parent_widget;
B
bernard.xiong 已提交
193

194 195
			/* set style */
			win->style |= RTGUI_WIN_STYLE_MODAL;
B
bernard.xiong 已提交
196

197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
			/* get root toplevel */
			parent_widget = RTGUI_WIDGET(win->parent_toplevel);
			if (RTGUI_IS_WORKBENCH(parent_widget))
			{
				rtgui_workbench_t* workbench;
				workbench = RTGUI_WORKBENCH(win->parent_toplevel);
				workbench->flag |= RTGUI_WORKBENCH_FLAG_MODAL_MODE;
				workbench->modal_widget = RTGUI_WIDGET(win);

				rtgui_workbench_event_loop(workbench);
				result = workbench->modal_code;
				workbench->flag &= ~RTGUI_WORKBENCH_FLAG_MODAL_MODE;
				workbench->modal_widget = RT_NULL;
			}
			else if (RTGUI_IS_WIN(parent_widget))
			{
				rtgui_win_t* parent_win;
				parent_win = RTGUI_WIN(win->parent_toplevel);
215
				parent_win->style |= RTGUI_WIN_STYLE_UNDER_MODAL;
216 217 218 219
				parent_win->modal_widget = RTGUI_WIDGET(win);

				rtgui_win_event_loop(parent_win);
				result = parent_win->modal_code;
220
				parent_win->style &= ~RTGUI_WIN_STYLE_UNDER_MODAL;
221 222
				parent_win->modal_widget = RT_NULL;
			}
B
bernard.xiong 已提交
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
		}
		else
		{
			/* which is a root window */
			win->style |= RTGUI_WIN_STYLE_MODAL;
			rtgui_win_event_loop(win);

			result = win->modal_code;
			win->style &= ~RTGUI_WIN_STYLE_MODAL;
		}
	}

	return result;
}

void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code)
{
	if (win->parent_toplevel != RT_NULL)
	{
242 243 244 245 246 247 248 249 250 251 252 253
		if (RTGUI_IS_WORKBENCH(win->parent_toplevel))
		{
			rtgui_workbench_t* workbench;

			/* which is shown under workbench */
			workbench = RTGUI_WORKBENCH(win->parent_toplevel);
			workbench->modal_code = modal_code;
			workbench->flag &= ~RTGUI_WORKBENCH_FLAG_MODAL_MODE;
		}
		else if (RTGUI_IS_WIN(win->parent_toplevel))
		{
			rtgui_win_t* parent_win;
B
bernard.xiong 已提交
254

255 256 257
			/* which is shown under win */
			parent_win = RTGUI_WIN(win->parent_toplevel);
			parent_win->modal_code = modal_code;
258
			parent_win->style &= ~RTGUI_WIN_STYLE_UNDER_MODAL;		
259
		}
B
bernard.xiong 已提交
260 261 262 263 264 265
	}
	else
	{
		/* which is a stand alone window */
		win->modal_code = modal_code;
	}
266 267 268

	/* remove modal mode */
	win->style &= ~RTGUI_WIN_STYLE_MODAL;
B
bernard.xiong 已提交
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
}

void rtgui_win_hiden(struct rtgui_win* win)
{
	RT_ASSERT(win != RT_NULL);

	if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)) &&
		RTGUI_TOPLEVEL(win)->server != RT_NULL)
	{
		/* send hidden message to server */
		struct rtgui_event_win_hide ehide;
		RTGUI_EVENT_WIN_HIDE_INIT(&ehide);
		ehide.wid = win;

		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&ehide),
			sizeof(struct rtgui_event_win_hide)) != RT_EOK)
		{
			rt_kprintf("hide win: %s failed\n", win->title);
			return;
		}

		/* set window hide and deactivated */
		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
		win->style &= ~RTGUI_WIN_STYLE_ACTIVATE;
	}
}

rt_bool_t rtgui_win_is_activated(struct rtgui_win* win)
{
	RT_ASSERT(win != RT_NULL);

300 301 302
	if (win->style & RTGUI_WIN_STYLE_ACTIVATE) return RT_TRUE;

	return RT_FALSE;
B
bernard.xiong 已提交
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
}

void rtgui_win_move(struct rtgui_win* win, int x, int y)
{
	struct rtgui_event_win_move emove;
	RTGUI_EVENT_WIN_MOVE_INIT(&emove);

	if (win == RT_NULL) return;

	if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
	{
		/* set win hide firstly */
		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));

		emove.wid 	= win;
		emove.x		= x;
		emove.y		= y;
		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&emove),
			sizeof(struct rtgui_event_win_move)) != RT_EOK)
		{
			return;
		}
	}

	/* move window to logic position */
	rtgui_widget_move_to_logic(RTGUI_WIDGET(win),
		x - RTGUI_WIDGET(win)->extent.x1,
		y - RTGUI_WIDGET(win)->extent.y1);

	/* set window visible */
	RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
	return;
}

static rt_bool_t rtgui_win_ondraw(struct rtgui_win* win)
{
	struct rtgui_dc* dc;
	struct rtgui_rect rect;
	struct rtgui_event_paint event;

	/* begin drawing */
	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(win));
	if (dc == RT_NULL) return RT_FALSE;

	/* get window rect */
	rtgui_widget_get_rect(RTGUI_WIDGET(win), &rect);
	/* fill area */
	rtgui_dc_fill_rect(dc, &rect);

	/* paint each widget */
	RTGUI_EVENT_PAINT_INIT(&event);
	event.wid = RT_NULL;
	rtgui_container_dispatch_event(RTGUI_CONTAINER(win), (rtgui_event_t*)&event);

	rtgui_dc_end_drawing(dc);

	return RT_FALSE;
}

rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
{
	struct rtgui_win* win = (struct rtgui_win*)widget;

	RT_ASSERT((win != RT_NULL) && (event != RT_NULL));

	switch (event->type)
	{
	case RTGUI_EVENT_WIN_SHOW:
		rtgui_win_show(win, RT_FALSE);
		break;

	case RTGUI_EVENT_WIN_HIDE:
		rtgui_win_hiden(win);
		break;

	case RTGUI_EVENT_WIN_CLOSE:
		if (win->on_close != RT_NULL)
		{
			if (win->on_close(widget, event) == RT_FALSE) return RT_TRUE;
		}

384 385 386 387 388 389 390 391 392
		if (win->style & RTGUI_WIN_STYLE_MODAL)
		{
			rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
		}
		else
		{
			/* destroy window */
			rtgui_win_destroy(win);
		}
B
bernard.xiong 已提交
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408

		/* exit event loop */
		return RT_TRUE;

	case RTGUI_EVENT_WIN_MOVE:
	{
		struct rtgui_event_win_move* emove = (struct rtgui_event_win_move*)event;

		/* move window */
		rtgui_win_move(win, emove->x, emove->y);
	}
	break;

	case RTGUI_EVENT_WIN_ACTIVATE:
		if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)))
		{
409 410
			/* activate a hide window */
			return RT_TRUE;
B
bernard.xiong 已提交
411 412 413
		}

		win->style |= RTGUI_WIN_STYLE_ACTIVATE;
414
#ifndef RTGUI_USING_SMALL_SIZE
B
bernard.xiong 已提交
415
		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
416 417
		else 
#endif
B
bernard.xiong 已提交
418
		rtgui_widget_update(RTGUI_WIDGET(win));
B
bernard.xiong 已提交
419 420 421 422 423 424 425 426

		if (win->on_activate != RT_NULL)
		{
			win->on_activate(widget, event);
		}
		break;

	case RTGUI_EVENT_WIN_DEACTIVATE:
427 428
		if (win->style & RTGUI_WIN_STYLE_MODAL)
		{
429
			/* do not deactivate a modal win, re-send win-show event */
430 431 432 433 434 435 436 437 438 439
			struct rtgui_event_win_show eshow;
			RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
			eshow.wid = win;

			rtgui_thread_send(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&eshow),
				sizeof(struct rtgui_event_win_show));
		}
		else
		{
			win->style &= ~RTGUI_WIN_STYLE_ACTIVATE;
440
#ifndef RTGUI_USING_SMALL_SIZE
441 442
			if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
			else 
443
#endif
444
				rtgui_win_ondraw(win);
B
bernard.xiong 已提交
445

446 447 448 449
			if (win->on_deactivate != RT_NULL)
			{
				win->on_deactivate(widget, event);
			}
B
bernard.xiong 已提交
450 451 452 453
		}
		break;

	case RTGUI_EVENT_PAINT:
454
#ifndef RTGUI_USING_SMALL_SIZE
B
bernard.xiong 已提交
455
		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
456 457 458
		else
#endif
			rtgui_win_ondraw(win);
B
bernard.xiong 已提交
459 460 461
		break;

	case RTGUI_EVENT_MOUSE_BUTTON:
462
		if (win->style & RTGUI_WIN_STYLE_UNDER_MODAL)
463 464 465 466 467 468
		{
			if (win->modal_widget != RT_NULL)
				return win->modal_widget->event_handler(win->modal_widget, event);
		}
 		else if (rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win), 
			(struct rtgui_event_mouse*)event) == RT_FALSE)
B
bernard.xiong 已提交
469
		{
470
#ifndef RTGUI_USING_SMALL_SIZE
B
bernard.xiong 已提交
471 472 473 474
			if (widget->on_mouseclick != RT_NULL)
			{
				return widget->on_mouseclick(widget, event);
			}
475
#endif
B
bernard.xiong 已提交
476 477 478 479 480 481 482 483
		}
		break;

	case RTGUI_EVENT_MOUSE_MOTION:
#if 0
		if (rtgui_widget_dispatch_mouse_event(widget,
			(struct rtgui_event_mouse*)event) == RT_FALSE)
		{
484
#ifndef RTGUI_USING_SMALL_SIZE
B
bernard.xiong 已提交
485 486 487 488 489
			/* handle event in current widget */
			if (widget->on_mousemotion != RT_NULL)
			{
				return widget->on_mousemotion(widget, event);
			}
490
#endif
B
bernard.xiong 已提交
491 492 493 494 495
		}
		else return RT_TRUE;
#endif
		break;

496
    case RTGUI_EVENT_KBD:
497
		if (win->style & RTGUI_WIN_STYLE_UNDER_MODAL)
498 499 500 501 502
		{
			if (win->modal_widget != RT_NULL)
				return win->modal_widget->event_handler(win->modal_widget, event);
		}
		else if (RTGUI_CONTAINER(win)->focused != widget)
503 504 505 506 507
		{
			RTGUI_CONTAINER(win)->focused->event_handler(RTGUI_CONTAINER(win)->focused, event);
		}
        break;

B
bernard.xiong 已提交
508 509 510 511 512 513 514 515 516 517 518
	default:
		/* call parent event handler */
		return rtgui_toplevel_event_handler(widget, event);
	}

	return RT_FALSE;
}

/* windows event loop */
void rtgui_win_event_loop(rtgui_win_t* wnd)
{
519
	rt_err_t result;
520 521
	rtgui_thread_t* tid;
	struct rtgui_event* event;
B
bernard.xiong 已提交
522

523 524 525 526 527
	tid = rtgui_thread_self();
	RT_ASSERT(tid != RT_NULL);

	/* point to event buffer */
	event = (struct rtgui_event*)tid->event_buffer;
B
bernard.xiong 已提交
528

529
	if (wnd->style & RTGUI_WIN_STYLE_UNDER_MODAL)
B
bernard.xiong 已提交
530
	{
531
		while (wnd->style & RTGUI_WIN_STYLE_UNDER_MODAL)
B
bernard.xiong 已提交
532
		{
533
			if (tid->on_idle != RT_NULL)
B
bernard.xiong 已提交
534
			{
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
				if (result == RT_EOK)
				{
					/* perform event handler */
					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
				}
				else if (result == -RT_ETIMEOUT)
				{
					tid->on_idle(RTGUI_WIDGET(wnd), RT_NULL);
				}
			}
			else
			{
				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
				if (result == RT_EOK)
				{
					/* perform event handler */
					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
				}
B
bernard.xiong 已提交
554 555 556 557 558 559 560
			}
		}
	}
	else
	{
		while (!(wnd->style & RTGUI_WIN_STYLE_CLOSED))
		{
561 562 563 564 565 566 567 568 569 570 571 572 573 574
			if (tid->on_idle != RT_NULL)
			{
				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
				if (result == RT_EOK)
				{
					/* perform event handler */
					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
				}
				else if (result == -RT_ETIMEOUT)
				{
					tid->on_idle(RTGUI_WIDGET(wnd), RT_NULL);
				}
			}
			else
B
bernard.xiong 已提交
575
			{
576 577 578 579 580 581
				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
				if (result == RT_EOK)
				{
					/* perform event handler */
					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
				}
B
bernard.xiong 已提交
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
			}
		}
	}

	/* destroy window */
	rtgui_widget_destroy(RTGUI_WIDGET(wnd));
}

void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect)
{
	struct rtgui_event_win_resize event;

	if (win == RT_NULL || rect == RT_NULL) return;

	RTGUI_WIDGET(win)->extent = *rect;

	if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
	{
		/* set window resize event to server */
		RTGUI_EVENT_WIN_RESIZE_INIT(&event);
		event.wid = win;
		event.rect = *rect;

		rtgui_thread_send(RTGUI_TOPLEVEL(win)->server, &(event.parent), sizeof(struct rtgui_event_win_resize));
	}
}

B
bernard.xiong 已提交
609
#ifndef RTGUI_USING_SMALL_SIZE
B
bernard.xiong 已提交
610 611 612 613 614 615 616
void rtgui_win_set_box(rtgui_win_t* win, rtgui_box_t* box)
{
	if (win == RT_NULL || box == RT_NULL) return;

	rtgui_container_add_child(RTGUI_CONTAINER(win), RTGUI_WIDGET(box));
	rtgui_widget_set_rect(RTGUI_WIDGET(box), &(RTGUI_WIDGET(win)->extent));
}
B
bernard.xiong 已提交
617
#endif
B
bernard.xiong 已提交
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668

void rtgui_win_set_onactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler)
{
	if (win != RT_NULL)
	{
		win->on_activate = handler;
	}
}

void rtgui_win_set_ondeactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler)
{
	if (win != RT_NULL)
	{
		win->on_deactivate = handler;
	}
}

void rtgui_win_set_onclose(rtgui_win_t* win, rtgui_event_handler_ptr handler)
{
	if (win != RT_NULL)
	{
		win->on_close = handler;
	}
}

void rtgui_win_set_title(rtgui_win_t* win, const char *title)
{
	/* send title to server */
	if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
	{
	}

	/* modify in local side */
	if (win->title != RT_NULL)
	{
		rtgui_free(win->title);
		win->title = RT_NULL;
	}

	if (title != RT_NULL)
	{
		win->title = rt_strdup(title);
	}
}

char* rtgui_win_get_title(rtgui_win_t* win)
{
	RT_ASSERT(win != RT_NULL);

	return win->title;
}