From bbf68d15e513d4799f651acd4fd9f88fe3a03ffd Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Sun, 5 Jun 2011 15:16:41 +0000 Subject: [PATCH] change graphic driver as RT-Thread device driver git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1454 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/rtgui/SConscript | 3 + components/rtgui/common/dc_client.c | 22 +- components/rtgui/common/dc_hw.c | 18 +- components/rtgui/common/framebuffer_driver.c | 225 ++++++++++++++++++ components/rtgui/common/pixel_driver.c | 92 +++++++ components/rtgui/include/rtgui/color.h | 18 ++ components/rtgui/include/rtgui/dc.h | 1 - components/rtgui/include/rtgui/driver.h | 76 ++++-- .../rtgui/include/rtgui/widgets/widget.h | 1 + components/rtgui/server/driver.c | 96 ++++---- components/rtgui/server/mouse.c | 6 +- components/rtgui/server/server.c | 8 +- components/rtgui/widgets/widget.c | 12 +- 13 files changed, 480 insertions(+), 98 deletions(-) create mode 100644 components/rtgui/common/framebuffer_driver.c create mode 100644 components/rtgui/common/pixel_driver.c diff --git a/components/rtgui/SConscript b/components/rtgui/SConscript index fef097d779..58b7aa2c84 100644 --- a/components/rtgui/SConscript +++ b/components/rtgui/SConscript @@ -29,6 +29,8 @@ common/asc12font.c common/asc16font.c common/hz12font.c common/hz16font.c +common/framebuffer_driver.c +common/pixel_driver.c """) server_src = Split(""" @@ -47,6 +49,7 @@ widgets/container.c widgets/combobox.c widgets/iconbox.c widgets/label.c +widgets/textview.c widgets/listctrl.c widgets/menu.c widgets/progressbar.c diff --git a/components/rtgui/common/dc_client.c b/components/rtgui/common/dc_client.c index 2e29a17160..f2db68d8e8 100644 --- a/components/rtgui/common/dc_client.c +++ b/components/rtgui/common/dc_client.c @@ -194,7 +194,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc) rt_kprintf("show cursor\n"); #endif /* update screen */ - hw_driver->screen_update(&(owner->extent)); + rtgui_graphic_driver_screen_update(hw_driver, &(owner->extent)); #else #ifdef RTGUI_USING_MOUSE_CURSOR /* show cursor */ @@ -202,7 +202,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc) #endif /* update screen */ - hw_driver->screen_update(&(owner->extent)); + rtgui_graphic_driver_screen_update(hw_driver, &(owner->extent)); #endif } } @@ -222,7 +222,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc) rt_kprintf("show cursor\n"); #endif /* update screen */ - hw_driver->screen_update(&(owner->extent)); + rtgui_graphic_driver_screen_update(hw_driver, &(owner->extent)); #else /* send to server to end drawing */ struct rtgui_event_update_end eupdate; @@ -258,7 +258,7 @@ static void rtgui_dc_client_draw_point(struct rtgui_dc* self, int x, int y) if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) == RT_EOK) { /* draw this point */ - hw_driver->set_pixel(&(owner->gc.foreground), x, y); + hw_driver->ops->set_pixel(&(owner->gc.foreground), x, y); } } @@ -279,7 +279,7 @@ static void rtgui_dc_client_draw_color_point(struct rtgui_dc* self, int x, int y if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) == RT_EOK) { /* draw this point */ - hw_driver->set_pixel(&color, x, y); + hw_driver->ops->set_pixel(&color, x, y); } } @@ -316,7 +316,7 @@ static void rtgui_dc_client_draw_vline(struct rtgui_dc* self, int x, int y1, int if (prect->y2 < y2) y2 = prect->y2; /* draw vline */ - hw_driver->draw_vline(&(owner->gc.foreground), x, y1, y2); + hw_driver->ops->draw_vline(&(owner->gc.foreground), x, y1, y2); } else for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) { @@ -335,7 +335,7 @@ static void rtgui_dc_client_draw_vline(struct rtgui_dc* self, int x, int y1, int if (prect->y2 < y2) draw_y2 = prect->y2; /* draw vline */ - hw_driver->draw_vline(&(owner->gc.foreground), x, draw_y1, draw_y2); + hw_driver->ops->draw_vline(&(owner->gc.foreground), x, draw_y1, draw_y2); } } @@ -373,7 +373,7 @@ static void rtgui_dc_client_draw_hline(struct rtgui_dc* self, int x1, int x2, in if (prect->x2 < x2) x2 = prect->x2; /* draw hline */ - hw_driver->draw_hline(&(owner->gc.foreground), x1, x2, y); + hw_driver->ops->draw_hline(&(owner->gc.foreground), x1, x2, y); } else for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) { @@ -392,7 +392,7 @@ static void rtgui_dc_client_draw_hline(struct rtgui_dc* self, int x1, int x2, in if (prect->x2 < x2) draw_x2 = prect->x2; /* draw hline */ - hw_driver->draw_hline(&(owner->gc.foreground), draw_x1, draw_x2, y); + hw_driver->ops->draw_hline(&(owner->gc.foreground), draw_x1, draw_x2, y); } } @@ -455,7 +455,7 @@ static void rtgui_dc_client_blit_line (struct rtgui_dc* self, int x1, int x2, in if (prect->x2 < x2) x2 = prect->x2; /* draw hline */ - hw_driver->draw_raw_hline(line_data, x1, x2, y); + hw_driver->ops->draw_raw_hline(line_data, x1, x2, y); } else for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) { @@ -474,7 +474,7 @@ static void rtgui_dc_client_blit_line (struct rtgui_dc* self, int x1, int x2, in if (prect->x2 < x2) draw_x2 = prect->x2; /* draw hline */ - hw_driver->draw_raw_hline(line_data + (draw_x1 - x1) * hw_driver->byte_per_pixel, draw_x1, draw_x2, y); + hw_driver->ops->draw_raw_hline(line_data + (draw_x1 - x1) * hw_driver->byte_per_pixel, draw_x1, draw_x2, y); } } diff --git a/components/rtgui/common/dc_hw.c b/components/rtgui/common/dc_hw.c index 4dc9264e41..c0dac5c6ea 100644 --- a/components/rtgui/common/dc_hw.c +++ b/components/rtgui/common/dc_hw.c @@ -170,7 +170,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc) rt_kprintf("show cursor\n"); #endif /* update screen */ - self->hw_driver->screen_update(&(owner->extent)); + rtgui_graphic_driver_screen_update(self->hw_driver, &(owner->extent)); #else #ifdef RTGUI_USING_MOUSE_CURSOR /* show cursor */ @@ -178,7 +178,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc) #endif /* update screen */ - self->hw_driver->screen_update(&(owner->extent)); + rtgui_graphic_driver_screen_update(self->hw_driver, &(owner->extent)); #endif } } @@ -198,7 +198,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc) rt_kprintf("show cursor\n"); #endif /* update screen */ - self->hw_driver->screen_update(&(owner->extent)); + rtgui_graphic_driver_screen_update(self->hw_driver, &(owner->extent)); #else /* send to server to end drawing */ struct rtgui_event_update_end eupdate; @@ -230,7 +230,7 @@ static void rtgui_dc_hw_draw_point(struct rtgui_dc* self, int x, int y) y = y + dc->owner->extent.y1; /* draw this point */ - dc->hw_driver->set_pixel(&(dc->owner->gc.foreground), x, y); + dc->hw_driver->ops->set_pixel(&(dc->owner->gc.foreground), x, y); } static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* self, int x, int y, rtgui_color_t color) @@ -244,7 +244,7 @@ static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* self, int x, int y, rt y = y + dc->owner->extent.y1; /* draw this point */ - dc->hw_driver->set_pixel(&color, x, y); + dc->hw_driver->ops->set_pixel(&color, x, y); } /* @@ -262,7 +262,7 @@ static void rtgui_dc_hw_draw_vline(struct rtgui_dc* self, int x, int y1, int y2) y2 = y2 + dc->owner->extent.y1; /* draw vline */ - dc->hw_driver->draw_vline(&(dc->owner->gc.foreground), x, y1, y2); + dc->hw_driver->ops->draw_vline(&(dc->owner->gc.foreground), x, y1, y2); } /* @@ -281,7 +281,7 @@ static void rtgui_dc_hw_draw_hline(struct rtgui_dc* self, int x1, int x2, int y) y = y + dc->owner->extent.y1; /* draw hline */ - dc->hw_driver->draw_hline(&(dc->owner->gc.foreground), x1, x2, y); + dc->hw_driver->ops->draw_hline(&(dc->owner->gc.foreground), x1, x2, y); } static void rtgui_dc_hw_fill_rect (struct rtgui_dc* self, struct rtgui_rect* rect) @@ -302,7 +302,7 @@ static void rtgui_dc_hw_fill_rect (struct rtgui_dc* self, struct rtgui_rect* rec /* fill rect */ for (index = dc->owner->extent.y1 + rect->y1; index < dc->owner->extent.y1 + rect->y2; index ++) { - dc->hw_driver->draw_hline(&color, x1, x2, index); + dc->hw_driver->ops->draw_hline(&color, x1, x2, index); } } @@ -318,7 +318,7 @@ static void rtgui_dc_hw_blit_line (struct rtgui_dc* self, int x1, int x2, int y, x2 = x2 + dc->owner->extent.x1; y = y + dc->owner->extent.y1; - dc->hw_driver->draw_raw_hline(line_data, x1, x2, y); + dc->hw_driver->ops->draw_raw_hline(line_data, x1, x2, y); } static void rtgui_dc_hw_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect) diff --git a/components/rtgui/common/framebuffer_driver.c b/components/rtgui/common/framebuffer_driver.c new file mode 100644 index 0000000000..477e096eed --- /dev/null +++ b/components/rtgui/common/framebuffer_driver.c @@ -0,0 +1,225 @@ +#include +#include + +#define GET_PIXEL(dst, x, y, type) \ + (type *)((rt_uint8_t*)((dst)->framebuffer) + (y) * (dst)->pitch + (x) * (dst)->byte_per_pixel) + +static void _rgb565_set_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t) = rtgui_color_to_565(*c); +} + +static void _rgb565_get_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + rt_uint16_t pixel; + + pixel = *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t); + + /* get pixel from color */ + *c = rtgui_color_from_565(pixel); +} + +static void _rgb565_draw_hline(rtgui_color_t *c, rt_base_t x1, rt_base_t x2, rt_base_t y) +{ + rt_ubase_t index; + rt_uint16_t pixel; + rt_uint16_t *pixel_ptr; + + /* get pixel from color */ + pixel = rtgui_color_to_565(*c); + + /* get pixel pointer in framebuffer */ + pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint16_t); + + for (index = x1; index < x2; index ++) + { + *pixel_ptr = pixel; + pixel_ptr ++; + } +} + +static void _rgb565_draw_vline(rtgui_color_t *c, rt_base_t x , rt_base_t y1, rt_base_t y2) +{ + rt_uint8_t *dst; + rt_uint16_t pixel; + rt_ubase_t index; + + pixel = rtgui_color_to_565(*c); + dst = GET_PIXEL(rtgui_graphic_get_device(), x, y1, rt_uint8_t); + for (index = y1; index < y2; index ++) + { + *(rt_uint16_t*)dst = pixel; + dst += rtgui_graphic_get_device()->pitch; + } +} + +static void _rgb565p_set_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t) = rtgui_color_to_565p(*c); +} + +static void _rgb565p_get_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + rt_uint16_t pixel; + + pixel = *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t); + + /* get pixel from color */ + *c = rtgui_color_from_565p(pixel); +} + +static void _rgb565p_draw_hline(rtgui_color_t *c, rt_base_t x1, rt_base_t x2, rt_base_t y) +{ + rt_ubase_t index; + rt_uint16_t pixel; + rt_uint16_t *pixel_ptr; + + /* get pixel from color */ + pixel = rtgui_color_to_565p(*c); + + /* get pixel pointer in framebuffer */ + pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint16_t); + + for (index = x1; index < x2; index ++) + { + *pixel_ptr = pixel; + pixel_ptr ++; + } +} + +static void _rgb565p_draw_vline(rtgui_color_t *c, rt_base_t x , rt_base_t y1, rt_base_t y2) +{ + rt_uint8_t *dst; + rt_uint16_t pixel; + rt_ubase_t index; + + pixel = rtgui_color_to_565p(*c); + dst = GET_PIXEL(rtgui_graphic_get_device(), x, y1, rt_uint8_t); + for (index = y1; index < y2; index ++) + { + *(rt_uint16_t*)dst = pixel; + dst += rtgui_graphic_get_device()->pitch; + } +} + +/* draw raw hline */ +static void framebuffer_draw_raw_hline(rt_uint8_t *pixels, rt_base_t x1, rt_base_t x2, rt_base_t y) +{ + rt_uint8_t *dst; + + dst = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint8_t); + rt_memcpy(dst, pixels, (x2 - x1) * rtgui_graphic_get_device()->byte_per_pixel); +} + +const struct rtgui_graphic_driver_ops _framebuffer_rgb565_ops = +{ + _rgb565_set_pixel, + _rgb565_get_pixel, + _rgb565_draw_hline, + _rgb565_draw_vline, + framebuffer_draw_raw_hline, +}; + +const struct rtgui_graphic_driver_ops _framebuffer_rgb565p_ops = +{ + _rgb565p_set_pixel, + _rgb565p_get_pixel, + _rgb565p_draw_hline, + _rgb565p_draw_vline, + framebuffer_draw_raw_hline, +}; + +#define FRAMEBUFFER (rtgui_graphic_get_device()->framebuffer) +#define MONO_PIXEL(framebuffer, x, y) \ + ((rt_uint8_t**)(framebuffer))[y/8][x] + +static void _mono_set_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + if (*c == white) + MONO_PIXEL(FRAMEBUFFER, x, y) &= ~(1 << (y%8)); + else + MONO_PIXEL(FRAMEBUFFER, x, y) |= (1 << (y%8)); +} + +static void _mono_get_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + if (MONO_PIXEL(FRAMEBUFFER, x, y) & (1 << (y%8))) + *c = black; + else + *c = white; +} + +static void _mono_draw_hline(rtgui_color_t *c, rt_base_t x1, rt_base_t x2, rt_base_t y) +{ + rt_ubase_t index; + + if (*c == white) + for (index = x1; index < x2; index ++) + { + MONO_PIXEL(FRAMEBUFFER, index, y) &= ~(1 << (y%8)); + } + else + for (index = x1; index < x2; index ++) + { + MONO_PIXEL(FRAMEBUFFER, index, y) |= (1 << (y%8)); + } +} + +static void _mono_draw_vline(rtgui_color_t *c, rt_base_t x , rt_base_t y1, rt_base_t y2) +{ + rt_ubase_t index; + + if (*c == white) + for (index = y1; index < y2; index ++) + { + MONO_PIXEL(FRAMEBUFFER, x, index) &= ~(1 << (index%8)); + } + else + for (index = y1; index < y2; index ++) + { + MONO_PIXEL(FRAMEBUFFER, x, index) |= (1 << (index%8)); + } +} + +/* draw raw hline */ +static void _mono_draw_raw_hline(rt_uint8_t *pixels, rt_base_t x1, rt_base_t x2, rt_base_t y) +{ + rt_ubase_t index; + + for (index = x1; index < x2; index ++) + { + if (pixels[index/8] && (1 << (index % 8))) + MONO_PIXEL(FRAMEBUFFER, index, y) |= (1 << (y%8)); + else + MONO_PIXEL(FRAMEBUFFER, index, y) &= ~(1 << (y%8)); + } +} + +const struct rtgui_graphic_driver_ops _framebuffer_mono_ops = +{ + _mono_set_pixel, + _mono_get_pixel, + _mono_draw_hline, + _mono_draw_vline, + _mono_draw_raw_hline, +}; + +const struct rtgui_graphic_driver_ops *rtgui_framebuffer_get_ops(int pixel_format) +{ + switch (pixel_format) + { + case PIXEL_FORMAT_MONO: + return &_framebuffer_mono_ops; + case PIXEL_FORMAT_GRAY4: + break; + case PIXEL_FORMAT_GRAY16: + break; + case PIXEL_FORMAT_RGB565: + return &_framebuffer_rgb565_ops; + case PIXEL_FORMAT_RGB565P: + return &_framebuffer_rgb565p_ops; + } + + return RT_NULL; +} + diff --git a/components/rtgui/common/pixel_driver.c b/components/rtgui/common/pixel_driver.c new file mode 100644 index 0000000000..1140acc66c --- /dev/null +++ b/components/rtgui/common/pixel_driver.c @@ -0,0 +1,92 @@ +#include +#include + +static void _pixeldevice_set_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + switch (rtgui_graphic_get_device()->pixel_format) + { + case PIXEL_FORMAT_RGB565: + { + rt_uint16_t pixel; + pixel = rtgui_color_to_565(*c); + rt_device_write(rtgui_graphic_get_device()->device, PIXEL_POSITION(x, y), &pixel, + sizeof(pixel)); + } + break; + + case PIXEL_FORMAT_RGB888: + { + rt_uint32_t pixel; + pixel = rtgui_color_to_888(*c); + rt_device_write(rtgui_graphic_get_device()->device, PIXEL_POSITION(x, y), &pixel, + 3); + } + + break; + } +} + +static void _pixeldevice_get_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + switch (rtgui_graphic_get_device()->pixel_format) + { + case PIXEL_FORMAT_RGB565: + { + rt_uint16_t pixel; + rt_device_read(rtgui_graphic_get_device()->device, PIXEL_POSITION(x, y), &pixel, + rtgui_graphic_get_device()->byte_per_pixel); + /* get pixel from color */ + *c = rtgui_color_from_565(pixel); + } + break; + + case PIXEL_FORMAT_RGB888: + { + rt_uint32_t pixel; + rt_device_read(rtgui_graphic_get_device()->device, PIXEL_POSITION(x, y), &pixel, + 3); + /* get pixel from color */ + *c = rtgui_color_from_888(pixel); + } + break; + } +} + +static void _pixeldevice_draw_hline(rtgui_color_t *c, rt_base_t x1, rt_base_t x2, rt_base_t y) +{ + rt_ubase_t index; + + for (index = x1; index < x2; index ++) + _pixeldevice_set_pixel(c, index, y); +} + +static void _pixeldevice_vline(rtgui_color_t *c, rt_base_t x , rt_base_t y1, rt_base_t y2) +{ + rt_ubase_t index; + + for (index = y1; index < y2; index ++) + _pixeldevice_set_pixel(c, x, index); +} + +/* draw raw hline */ +static void _pixeldevice_draw_raw_hline(rt_uint8_t *pixels, rt_base_t x1, rt_base_t x2, rt_base_t y) +{ + rt_device_write(rtgui_graphic_get_device()->device, PIXEL_POSITION(x1, y), pixels, + (x2 - x1) * rtgui_graphic_get_device()->byte_per_pixel); +} + +/* pixel device */ +const struct rtgui_graphic_driver_ops _pixeldevice_ops = +{ + _pixeldevice_set_pixel, + _pixeldevice_get_pixel, + _pixeldevice_draw_hline, + _pixeldevice_vline, + _pixeldevice_draw_raw_hline, +}; + +const struct rtgui_graphic_driver_ops *rtgui_pixel_device_get_ops(int pixel_format) +{ + return &_pixeldevice_ops; +} + diff --git a/components/rtgui/include/rtgui/color.h b/components/rtgui/include/rtgui/color.h index e13f461885..0e78bd0fd3 100644 --- a/components/rtgui/include/rtgui/color.h +++ b/components/rtgui/include/rtgui/color.h @@ -92,5 +92,23 @@ rt_inline rtgui_color_t rtgui_color_from_565p(rt_uint16_t pixel) return color; } +/* convert rtgui color to RGB */ +rt_inline rt_uint32_t rtgui_color_to_888(rtgui_color_t c) +{ + rt_uint32_t pixel; + + pixel = RTGUI_RGB_R(c) << 16 | RTGUI_RGB_G(c) << 8 | RTGUI_RGB_B(c); + return pixel; +} + +rt_inline rtgui_color_t rtgui_color_from_888(rt_uint32_t pixel) +{ + rtgui_color_t color; + + color = RTGUI_RGB(((pixel >> 16) & 0xff), ((pixel >> 8) & 0xff), pixel & 0xff); + + return color; +} + #endif diff --git a/components/rtgui/include/rtgui/dc.h b/components/rtgui/include/rtgui/dc.h index 866192cbb4..bca0a65015 100644 --- a/components/rtgui/include/rtgui/dc.h +++ b/components/rtgui/include/rtgui/dc.h @@ -24,7 +24,6 @@ enum rtgui_dc_type RTGUI_DC_HW, RTGUI_DC_CLIENT, RTGUI_DC_BUFFER, - RTGUI_DC_IMLIB2, }; struct rtgui_dc_engine diff --git a/components/rtgui/include/rtgui/driver.h b/components/rtgui/include/rtgui/driver.h index 79856856ba..4cc187fb2d 100644 --- a/components/rtgui/include/rtgui/driver.h +++ b/components/rtgui/include/rtgui/driver.h @@ -17,24 +17,40 @@ #include #include -struct rtgui_graphic_driver +#define LCD_RECT_UPDATE 0 +#define LCD_ON 1 +#define LCD_OFF 2 +#define LCD_GET_INFO 3 +#define LCD_MODE_SET 4 + +enum { - /* driver name */ - char* name; + PIXEL_FORMAT_MONO = 0, + PIXEL_FORMAT_GRAY4, + PIXEL_FORMAT_GRAY16, + PIXEL_FORMAT_RGB332, + PIXEL_FORMAT_RGB444, + PIXEL_FORMAT_RGB565, + PIXEL_FORMAT_RGB565P, + PIXEL_FORMAT_RGB666, + PIXEL_FORMAT_RGB888, + PIXEL_FORMAT_ARGB888 +}; +#define PIXEL_POSITION(x, y) ((x << 16) | y) - /* byte per pixel */ - rt_uint16_t byte_per_pixel; +struct rt_lcd_info +{ + rt_uint8_t pixel_format; + rt_uint8_t byte_per_pixel; - /* screen width and height */ rt_uint16_t width; rt_uint16_t height; - /* screen update */ - void (*screen_update)(rtgui_rect_t* rect); - - /* get video frame buffer */ - rt_uint8_t* (*get_framebuffer)(void); + rt_uint8_t *framebuffer; +}; +struct rtgui_graphic_driver_ops +{ /* set and get pixel in (x, y) */ void (*set_pixel) (rtgui_color_t *c, rt_base_t x, rt_base_t y); void (*get_pixel) (rtgui_color_t *c, rt_base_t x, rt_base_t y); @@ -44,24 +60,40 @@ struct rtgui_graphic_driver /* draw raw hline */ void (*draw_raw_hline)(rt_uint8_t *pixels, rt_base_t x1, rt_base_t x2, rt_base_t y); - - /* the driver list */ - rtgui_list_t list; }; -#ifdef RTGUI_USING_GRAPHIC_DRIVER_LIST -void rtgui_graphic_driver_add(struct rtgui_graphic_driver* driver); -void rtgui_graphic_driver_remove(struct rtgui_graphic_driver* driver); +struct rtgui_graphic_driver +{ + /* pixel format and byte per pixel */ + rt_uint8_t pixel_format; + rt_uint8_t byte_per_pixel; + rt_uint16_t pitch; + + /* screen width and height */ + rt_uint16_t width; + rt_uint16_t height; + + /* framebuffer address and ops */ + volatile rt_uint8_t *framebuffer; + rt_device_t device; + const struct rtgui_graphic_driver_ops *ops; +}; -struct rtgui_graphic_driver* rtgui_graphic_driver_find(char* name); -#else void rtgui_graphic_driver_add(const struct rtgui_graphic_driver* driver); -#endif -const struct rtgui_graphic_driver* rtgui_graphic_driver_get_default(void); +struct rtgui_graphic_driver* rtgui_graphic_driver_get_default(void); void rtgui_graphic_driver_get_rect(const struct rtgui_graphic_driver *driver, rtgui_rect_t *rect); -void rtgui_graphic_driver_get_default_rect(rtgui_rect_t *rect); +void rtgui_graphic_driver_screen_update(struct rtgui_graphic_driver* driver, rtgui_rect_t *rect); +rt_uint8_t* rtgui_graphic_driver_get_framebuffer(struct rtgui_graphic_driver* driver); + +rt_err_t rtgui_graphic_set_device(rt_device_t device); + +rt_inline struct rtgui_graphic_driver* rtgui_graphic_get_device() +{ + extern struct rtgui_graphic_driver _driver; + return &_driver; +} #endif diff --git a/components/rtgui/include/rtgui/widgets/widget.h b/components/rtgui/include/rtgui/widgets/widget.h index 9dfd40f0ae..ab44d23b39 100644 --- a/components/rtgui/include/rtgui/widgets/widget.h +++ b/components/rtgui/include/rtgui/widgets/widget.h @@ -152,6 +152,7 @@ void rtgui_widget_set_oncommand(rtgui_widget_t* widget, rtgui_event_handler_ptr /* get and set rect of widget */ void rtgui_widget_get_rect(rtgui_widget_t* widget, rtgui_rect_t *rect); void rtgui_widget_set_rect(rtgui_widget_t* widget, const rtgui_rect_t* rect); +void rtgui_widget_set_rectangle(rtgui_widget_t* widget, int x, int y, int width, int height); void rtgui_widget_get_extent(rtgui_widget_t* widget, rtgui_rect_t *rect); #ifndef RTGUI_USING_SMALL_SIZE diff --git a/components/rtgui/server/driver.c b/components/rtgui/server/driver.c index 5e086f022e..43b4b8ac43 100644 --- a/components/rtgui/server/driver.c +++ b/components/rtgui/server/driver.c @@ -13,72 +13,72 @@ */ #include -#ifdef RTGUI_USING_GRAPHIC_DRIVER_LIST -struct rtgui_list_node _rtgui_graphic_driver_list = {RT_NULL}; +struct rtgui_graphic_driver _driver; -void rtgui_graphic_driver_add(struct rtgui_graphic_driver* driver) +extern const struct rtgui_graphic_driver_ops *rtgui_pixel_device_get_ops(int pixel_format); +extern const struct rtgui_graphic_driver_ops *rtgui_framebuffer_get_ops(int pixel_format); + +/* get default driver */ +struct rtgui_graphic_driver* rtgui_graphic_driver_get_default() { - rtgui_list_insert(&_rtgui_graphic_driver_list, &(driver->list)); + return &_driver; } -void rtgui_graphic_driver_remove(struct rtgui_graphic_driver* driver) +void rtgui_graphic_driver_get_rect(const struct rtgui_graphic_driver *driver, rtgui_rect_t *rect) { - rtgui_list_remove(&_rtgui_graphic_driver_list, &(driver->list)); + RT_ASSERT(rect != RT_NULL); + RT_ASSERT(driver != RT_NULL); + + rect->x1 = rect->y1 = 0; + rect->x2 = driver->width; + rect->y2 = driver->height; } -struct rtgui_graphic_driver* rtgui_graphic_driver_find(char* name) +rt_err_t rtgui_graphic_set_device(rt_device_t device) { - struct rtgui_list_node* node; - struct rtgui_graphic_driver* driver; + rt_err_t result; + struct rt_lcd_info info; - /* search in list */ - rtgui_list_foreach(node, &(_rtgui_graphic_driver_list)) + /* get framebuffer address */ + result = rt_device_control(device, LCD_GET_INFO, &info); + if (result != RT_EOK) { - driver = rtgui_list_entry(node, struct rtgui_graphic_driver, list); - - /* find it */ - if (rt_strncmp(driver->name, name, RTGUI_NAME_MAX) == 0) - { - return driver; - } + /* get device information failed */ + return -RT_ERROR; } - return RT_NULL; -} - -struct rtgui_graphic_driver* rtgui_graphic_driver_get_default() -{ - return rtgui_list_entry(_rtgui_graphic_driver_list.next, - struct rtgui_graphic_driver, list); -} -#else -static const struct rtgui_graphic_driver* _default_graphic_driver = RT_NULL; + /* initialize framebuffer driver */ + _driver.device = device; + _driver.pixel_format = info.pixel_format; + _driver.byte_per_pixel = info.byte_per_pixel; + _driver.width = info.width; + _driver.height = info.height; + _driver.pitch = _driver.width * _driver.byte_per_pixel; + _driver.framebuffer = info.framebuffer; -void rtgui_graphic_driver_add(const struct rtgui_graphic_driver* driver) -{ - _default_graphic_driver = driver; + if (info.framebuffer != RT_NULL) + { + /* is a frame buffer device */ + _driver.ops = rtgui_framebuffer_get_ops(_driver.pixel_format); + } + else + { + /* is a pixel device */ + _driver.ops = rtgui_pixel_device_get_ops(_driver.pixel_format); + } + + return RT_EOK; } -const struct rtgui_graphic_driver* rtgui_graphic_driver_get_default() +/* screen update */ +void rtgui_graphic_driver_screen_update(struct rtgui_graphic_driver* driver, rtgui_rect_t *rect) { - return _default_graphic_driver; -} -#endif - - -void rtgui_graphic_driver_get_rect(const struct rtgui_graphic_driver *driver, rtgui_rect_t *rect) -{ - RT_ASSERT(rect != RT_NULL); - RT_ASSERT(driver != RT_NULL); - - rect->x1 = rect->y1 = 0; - rect->x2 = driver->width; - rect->y2 = driver->height; + rt_device_control(driver->device, LCD_RECT_UPDATE, rect); } -void rtgui_graphic_driver_get_default_rect(rtgui_rect_t *rect) +/* get video frame buffer */ +rt_uint8_t* rtgui_graphic_driver_get_framebuffer(struct rtgui_graphic_driver* driver) { - /* return default the extent of default driver */ - rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), rect); + return (rt_uint8_t*)driver->framebuffer; } diff --git a/components/rtgui/server/mouse.c b/components/rtgui/server/mouse.c index 83b3b171e9..a28087cd0b 100644 --- a/components/rtgui/server/mouse.c +++ b/components/rtgui/server/mouse.c @@ -140,7 +140,7 @@ void rtgui_mouse_init() /* init cursor */ _rtgui_cursor->bpp = gd->byte_per_pixel; - _rtgui_cursor->framebuffer = gd->get_framebuffer(); + _rtgui_cursor->framebuffer = rtgui_graphic_driver_get_framebuffer(gd); _rtgui_cursor->screen_pitch = _rtgui_cursor->bpp * gd->width; #ifdef RTGUI_USING_MOUSE_CURSOR @@ -430,7 +430,7 @@ static void rtgui_winrect_show() void (*set_pixel) (rtgui_color_t *c, rt_base_t x, rt_base_t y); c = black; - set_pixel = rtgui_graphic_driver_get_default()->set_pixel; + set_pixel = rtgui_graphic_driver_get_default()->ops->set_pixel; win_rect = _rtgui_cursor->win_rect; win_rect_inner = win_rect; @@ -470,7 +470,7 @@ static void rtgui_winrect_show() } /* update rect */ - rtgui_graphic_driver_get_default()->screen_update(&win_rect); + rtgui_graphic_driver_screen_update(rtgui_graphic_driver_get_default(), &win_rect); } #define display_direct_memcpy(src, dest, src_pitch, dest_pitch, height, len) \ diff --git a/components/rtgui/server/server.c b/components/rtgui/server/server.c index 26a4bcf6e0..5b90b64b1b 100644 --- a/components/rtgui/server/server.c +++ b/components/rtgui/server/server.c @@ -188,10 +188,12 @@ void rtgui_server_handle_set_wm(struct rtgui_event_set_wm *event) void rtgui_server_handle_update(struct rtgui_event_update_end* event) { - const struct rtgui_graphic_driver* driver = rtgui_graphic_driver_get_default(); + struct rtgui_graphic_driver* driver; + + driver = rtgui_graphic_driver_get_default(); if (driver != RT_NULL) { - driver->screen_update(&(event->rect)); + rtgui_graphic_driver_screen_update(driver, &(event->rect)); } } @@ -277,7 +279,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event) if (rtgui_server_focus_topwin != wnd) { /* raise this window */ - rtgui_topwin_raise(wnd->wid, wnd->tid); + rtgui_topwin_activate_win(wnd); rtgui_server_focus_panel = RT_NULL; } diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c index 32280c3d58..91a14ac27e 100644 --- a/components/rtgui/widgets/widget.c +++ b/components/rtgui/widgets/widget.c @@ -56,7 +56,7 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget) #endif /* set default event handler */ - widget->event_handler = rtgui_widget_event_handler; + rtgui_widget_set_event_handler(widget,rtgui_widget_event_handler); /* init user data private to 0 */ widget->user_data = 0; @@ -132,6 +132,16 @@ void rtgui_widget_set_rect(rtgui_widget_t* widget, const rtgui_rect_t* rect) } } +void rtgui_widget_set_rectangle(rtgui_widget_t* widget, int x, int y, int width, int height) +{ + rtgui_rect_t rect; + + rect.x1 = x; rect.y1 = y; + rect.x2 = x + width; rect.y2 = y + height; + + rtgui_widget_set_rect(widget, &rect); +} + void rtgui_widget_set_parent(rtgui_widget_t* widget, rtgui_widget_t* parent) { /* set parent and toplevel widget */ -- GitLab