Hi, everyone: I am very sorry to trouble you, but I hope you can help to solve a problem about function "gdk_draw_rgb_image". I want to use function "gdk_draw_rgb_image" to show all colors in rgb buffer to the screen when the screen would be refreshed. My problems is that screen can only show the colors only one time, and then the screen becomes white. After screen is refreshed, how can I keep the colors on screen until next time to be refreshed? Thank you very much! The following is the most important codes(file about all codes is in attachment): static int gtk_l
cd_open(conf_object_t *lcd_dev, lcd_surface_t* surface) { lcd_gtk_device* dev = lcd_dev->obj; lcd_touchscreen_t* lcd_ts = SKY_get_interface(lcd_dev, LCD_TS_INTF_NAME); SkyEyeLCD_GTK *lcd; guint32 *fbmem; char *title; GtkWidget *touch_screen; assert(dev != NULL); DBG("In %s, width=%d, height=%d, begin_addr=0x%x,end_addr=0x%x\n, ", __FUNCTION__, surface->width, surface->height, surface->lcd_addr_begin, surface->lcd_addr_end); if (dev == NULL || surface->width <= 0 || surface->height <= 0) return -1; if ((fbmem = (guint32*)get_dma_addr(surface->lcd_addr_begin)) == NULL) { fprintf(stderr, "[GTK_LCD]:
Can't find LCD DMA from address 0x%x\n", surface->lcd_addr_begin); return -1; } DBG("In %s, fb_mem=0x%x\n", __FUNCTION__, fbmem); if ((lcd = (SkyEyeLCD_GTK*)malloc(sizeof(SkyEyeLCD_GTK))) == NULL) return -1; memset(lcd, 0, sizeof(SkyEyeLCD_GTK)); lcd->width = surface->width; lcd->virtual_width = surface->width + surface->lcd_line_offset; lcd->height = surface->height; lcd->depth = surface->depth; lcd->update_rect.width = -1; lcd->update_rect.height = -1; lcd->update_all = TRUE; lcd->fbmem = fbmem; /* allocate a ping-pong buffer to reduce unnecessary lcd fresh */ &n
bsp; lcd->fbmem_cp = (void *)malloc(surface->lcd_addr_end - surface->lcd_addr_begin); /* shenoubang 2012-4-9 */ gdk_rgb_init(); gtk_widget_set_default_colormap (gdk_rgb_get_cmap()); gtk_widget_set_default_visual (gdk_rgb_get_visual()); if(dev->lcd_lookup_color != NULL) { lcd->rgbbuf = (guchar*)malloc(lcd->width * lcd->height * 4); } else switch (lcd->depth) { case 1: case 2: case 4: lcd->rgbbuf = (guchar*)malloc(lcd->virtual_width * lcd->height); break; case 12: &
nbsp; case 16: lcd->rgbbuf = (guchar*)malloc(lcd->virtual_width * lcd->height * 3); break; case 8: case 24: case 32: lcd->rgbbuf = (guchar*)fbmem; break; default: break; } DBG("In %s, lcd->rgbbuf=0x%x\n", __FUNCTION__, lcd->rgbbuf); lcd->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_signal_connect(GTK_OBJECT(lcd->window), "delete-event", &n
bsp;GTK_SIGNAL_FUNC(gtk_true), NULL); DBG("In %s, lcd->rgbbuf=0x%x\n", __FUNCTION__, lcd->rgbbuf); lcd->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_signal_connect(GTK_OBJECT(lcd->window), "delete-event", GTK_SIGNAL_FUNC(gtk_true), NULL); if ((title = g_strdup_printf("%dx%dx%d SkyEye LCD & Touch Screen (GTK+)", lcd->width, lcd->height, lcd->depth)) != NULL) { gtk_window_set_title(GTK_WINDOW(lcd->window), title); g_free(title); } DBG("In %s, set title\n", __FUNCTION__); gtk_widget_set_usize(lcd->window, lcd->width, l
cd->height); gtk_widget_set_events(lcd->window, GDK_EXPOSURE_MASK); touch_screen = gtk_event_box_new(); /* shenobuang 2012-4-10 */ gtk_event_box_set_above_child (touch_screen, TRUE); gtk_event_box_set_visible_window (touch_screen, TRUE); DBG("In %s, set event\n", __FUNCTION__); if(lcd_ts){ skyeye_printf_in_color(GREEN, "In %s, Have touch screen register callback\n\n\n", __FUNCTION__); gtk_container_add(GTK_CONTAINER(lcd->window), touch_screen); gtk_widget_set_events(touch_screen, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); gtk
_signal_connect(GTK_OBJECT(touch_screen), "button-press-event", GTK_SIGNAL_FUNC(callback_button_press), (gpointer)lcd_ts); gtk_signal_connect(GTK_OBJECT(touch_screen), "button-release-event", GTK_SIGNAL_FUNC(callback_button_release), (gpointer)lcd_ts); gtk_signal_connect(GTK_OBJECT(touch_screen), "motion-notify-event", GTK_SIGNAL_FUNC(callback_motion_notify), (gpointer)lcd_ts); gtk_widget_realize(touch_screen); gdk_window_set_cursor(touch_screen->window, gdk_cursor_new(GDK_HAND2)); } //zy 2004-4-02 Add Drawing area lcd->drawing = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(touch_screen), lcd->drawing); gtk_signal_connect(GTK_OBJECT(lcd->drawing), "expose-event", GTK_SIGNAL_FUNC(callback_expose_event), dev); gtk_widget_show_all(lcd->window); DBG("In %s, show all\n", __FUNCTION__); if (dev->lcd_lookup_color == NULL){ } switch (lcd->depth) { case 1: lcd->colormap = gdk_rgb_cmap_new(colors1b, 2); break; case 2: break; case 4: lcd->co
lormap = gdk_rgb_cmap_new(colors4b, 16); break; case 8: lcd->colormap = gdk_rgb_cmap_new(colors8b, 256); break; default: break; } DBG("In %s, add redraw event\n", __FUNCTION__); //lcd->timer = gtk_timeout_add(200, (GtkFunction)callback_redraw, lcd->window); dev->gtk_win = (void*)lcd; #ifndef MK_LCD int timer_id; create_thread_scheduler(10000, Periodic_sched, timer_update, dev->obj, &timer_id); #endif //gtk_main_iteration_do(FALSE
); return 0; } static gboolean callback_expose_event(GtkWidget *widget, GdkEventExpose *event, lcd_gtk_device* dev) { ....... <ignore some codes> wordnum = lcd->virtual_width * rect.height * lcd->depth / 32; switch (lcd->depth) { case 16: { int refresh = 0; for (i = lcd->virtual_width * rect.y / 2; i < wordnum / 2; i++) { /* shenoubang 2012-4-9 */ &
nbsp; fbdata = ((guint64*)lcd->fbmem + i); fbdata_cp = ((guint64*)lcd->fbmem_cp + i); if (*fbdata != *fbdata_cp) { refresh = 1; *fbdata_cp = *fbdata; *(lcd->rgbbuf + i * 12 + 0) = (guchar)((*fbdata_cp & 0x0000f800) >> 8);
*(lcd->rgbbuf + i * 12 + 1) = (guchar)((*fbdata_cp & 0x000007e0) >> 3); *(lcd->rgbbuf + i * 12 + 2) = (guchar)((*fbdata_cp & 0x0000001f) << 3); *(lcd->rgbbuf + i * 12 + 3) = (guchar)((*fbdata_cp & 0xf8000000) >> 24); *(lcd->rgbb
uf + i * 12 + 4) = (guchar)((*fbdata_cp & 0x07e00000) >> 19); *(lcd->rgbbuf + i * 12 + 5) = (guchar)((*fbdata_cp & 0x001f0000) >> 13); *(lcd->rgbbuf + i * 12 + 6) = (guchar)(((*fbdata_cp >> 32) & 0x0000f800) >> 8); *(lcd->rgbbuf + i * 12 + 7) = (guchar)(((*fbdata_cp >> 32) & 0x000007e0) >> 3); *(lcd->rgbbuf + i * 12 + 8) = (guchar)(((*fbdata_cp >> 32) & 0x0000001f) << 3); *(lcd->rgbbuf + i * 12 + 9) = (guchar)(((*fbdata_cp >> 32) & 0xf8000000) >> 24); *(lcd->rgbbuf + i * 12 + 10) = (guchar)(((*fbdata_cp >> 32) & 0x07e00000) >> 19); *(lcd->rgbbuf + i * 12 + 11) = (guchar)(((*fbdata_cp >> 32) & 0x001f0000) >> 13); } } if (refresh) { GDK_THREADS_ENTER();
skyeye_printf_in_color(RED, "refresh: %d\n", refresh); gdk_draw_rgb_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, rect.y, lcd->width, rect.height, GDK_RGB_DITHER_MAX, (guchar*)lcd->rgbbuf + rect.y * lcd->virtual_width * 3,
lcd->virtual_width * 3); GDK_THREADS_LEAVE(); } } break; ......... <ignore some codes> return TRUE; } |
/* skyeye_lcd_gtk.c - LCD display emulation in an X window. ARMulator extensions for the ARM7100 family. Copyright (C) 1999 Ben Williamson 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * 1999 Written by Ben Williamson * 2004 - 2007 Modified by chy, zy, ywc, etc. * 04/13/2007 Modified for multi-devs by Anthony Lee */ #include <stdlib.h> #include <gdk/gdk.h> #include <gtk/gtk.h> #include <skyeye_types.h> #include <skyeye_class.h> #include <skyeye_interface.h> #include <skyeye_ram.h> #include <skyeye_mm.h> #include <skyeye_lcd_intf.h> #include <skyeye_device.h> #include <skyeye_sched.h> #include "lcd_gtk.h" #define DEBUG #include <skyeye_log.h> //extern unsigned int Pen_buffer[8]; static void timer_update(conf_object_t *lcd_dev); static guint32 colors1b[2] = { 0x000000, 0xffffff }; static guint32 colors4b[16] = { 0x000000, 0x000080, 0x008000, 0x008080, 0x800000, 0x800080, 0x808000, 0x808080, 0xc0c0c0, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00, 0xffffff }; static guint32 colors8b[256]; static void lcd_convert_callback(uint32 c, uint32 **buf_addr, void *noused) { /* the gtk's 32 bits rgb buffer : X-B-G-R */ *(*buf_addr) = ((c >> 16) | (c & 0xff00) | ((c & 0xff) << 16)); *buf_addr = ++(*buf_addr); } /* Copied from skyeye_lcd.c */ static void skyeye_convert_color_from_lcd_dma (lcd_gtk_device *dev, int x, int y, int w, int h, void (*func)(uint32, void*, void*), void *user_data1, void *user_data2) { #if 0 uint8 *dma; const uint32 *buf; const uint16 *buf16; const uint8 *buf8; uint32 block, color, c; int dx, dy, exw, exb, line_width; int i, k; *dma = get_dma_addr(dev->lcd_addr_begin); if (dma == NULL || lcd->lcd_lookup_color == NULL || func == NULL) return; if (!(lcd->depth == 1 || lcd->depth == 2 || lcd->depth == 4 || lcd->depth == 8 || lcd->depth == 16 || lcd->depth == 32)) return; if (lcd->width <= 0 || x < 0 || w <= 0 || x + w > lcd->width) return; if (lcd->height <= 0 || y < 0 || h <= 0 || y + h > lcd->height) return; line_width = (lcd->width + (int)lcd->lcd_line_offset); for (dy = y; dy < y + h; dy++) { exw = (((line_width * dy + x) * lcd->depth) % 32) / 8; exb = ((line_width * dy + x) * lcd->depth) % 8; buf = (const uint32*)(dma + 4 * (((line_width * dy + x) * lcd->depth) / 32)); for (dx = x; dx < x + w; buf++) { block = *buf; #ifndef HOST_IS_BIG_ENDIAN if (lcd->lcd_dma_swap_word == 1) { #else if (lcd->lcd_dma_swap_word == 0) { #endif block = (((block & 0xff) << 24) | ((block & 0xff00) << 8) | ((block & 0xff0000) >> 8) | (block >> 24)); } buf8 = (uint8*)█ buf16 = (uint16*)█ for (i = exw; i < 4 && dx < x + w; exw = 0) { if (lcd->depth < 16) { /* lcd->depth: 1, 2, 4, 8 */ color = (uint32)(*(buf8 + (lcd->lcd_color_right_to_left == 0 ? i : 3 - i))); for (k = exb; k < 8 && dx < x + w; k += lcd->depth, exb = 0) { if (lcd->lcd_color_right_to_left == 0) c = ((color >> (8 - (k + lcd->depth))) & ((1 << lcd->depth) - 1)); else c = ((color >> k) & ((1 << lcd->depth) - 1)); (*func)(lcd->lcd_lookup_color(lcd, c), user_data1, user_data2); dx++; } i += 1; } else if (lcd->depth == 16) { if (lcd->lcd_color_right_to_left == 0) color = (uint32)(*(buf16 + (i == 0 ? 0 : 1))); else color = (uint32)(*(buf16 + (i == 0 ? 1 : 0))); (*func)(lcd->lcd_lookup_color(lcd, color), user_data1, user_data2); dx++; i += 2; } else { /* lcd->depth: 32 */ color = block; (*func)(lcd->lcd_lookup_color(lcd, color), user_data1, user_data2); dx++; break; } } } } #endif } /* use rgbbuf */ static gboolean callback_expose_event(GtkWidget *widget, GdkEventExpose *event, lcd_gtk_device* dev) { int i, j, x, y, pix, bit; int wordnum; //for lcd_depth==16 , 1 word contain 2 pixel guint64 *fbdata = NULL; // |R1,G1,B1,R0,G0,B0| guint64 *fbdata_cp = NULL; int tribytenum; //for lcd_depth==12, 3 byte contain 2 pixel guchar fbdata8_0; // |G0,R0| guchar fbdata8_1; // |R1,B0| guchar fbdata8_2; // |B1,G1| GdkRectangle rect; SkyEyeLCD_GTK* lcd = dev->gtk_win; if (lcd == NULL) return FALSE; if (lcd->update_all == FALSE) { if (lcd->update_rect.width < 0 || lcd->update_rect.height < 0) return TRUE; rect = lcd->update_rect; rect.width += 1; rect.height += 1; lcd->update_rect.x = 0; lcd->update_rect.y = 0; lcd->update_rect.width = -1; lcd->update_rect.height = -1; } else { rect.x = 0; rect.y = 0; rect.width = lcd->width; rect.height = lcd->height; } wordnum = lcd->virtual_width * rect.height * lcd->depth / 32; tribytenum = lcd->virtual_width * rect.height * lcd->depth / 24; // anthonylee 2007-01-29 : for lcd_lookup_color //if (lcd->dev->lcd_lookup_color != NULL) { if (NULL) { uint32 *tmp = (uint32*)lcd->rgbbuf + rect.y * lcd->width; skyeye_convert_color_from_lcd_dma(dev, 0, rect.y, lcd->width, rect.height, (void (*)(uint32, void*, void*))lcd_convert_callback, &tmp, NULL); gdk_draw_rgb_32_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, rect.y, lcd->width, rect.height, GDK_RGB_DITHER_NORMAL, (guchar*)((uint32*)lcd->rgbbuf + rect.y * lcd->width), lcd->width * 4); } else switch (lcd->depth) { case 1: // case 2: case 4: // anthonylee 2007-01-28 for (j = rect.y; j < lcd->height; j++) { guchar *buf = (guchar*)lcd->fbmem + j * lcd->virtual_width * lcd->depth / 8; for (i = 0; i < lcd->width;) { int k; guchar c = *buf++; guchar *tmp = (guchar*)lcd->rgbbuf + j * lcd->virtual_width + i; for (k = 0; k < 8 / lcd->depth; k++, i++, tmp++) *tmp = (c >> (8 - ((k + 1) << (lcd->depth - 1)))) & ((1 << lcd->depth) - 1); } } gdk_draw_indexed_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, rect.y, lcd->width, rect.height, GDK_RGB_DITHER_NORMAL, (guchar*)lcd->rgbbuf + rect.y * lcd->virtual_width * lcd->depth / 8, lcd->virtual_width, lcd->colormap); break; case 8: gdk_draw_indexed_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, rect.y, lcd->width, rect.height, GDK_RGB_DITHER_NORMAL, (guchar*)lcd->rgbbuf + rect.y * lcd->virtual_width, lcd->virtual_width, lcd->colormap); break; case 12: for (i = lcd->virtual_width * rect.y / 2; i < tribytenum; i++) { fbdata8_0 = *((guchar*)lcd->fbmem + i * 3); fbdata8_1 = *((guchar*)lcd->fbmem + i * 3 + 1); fbdata8_2 = *((guchar*)lcd->fbmem + i * 3 + 2); *(lcd->rgbbuf + i * 6 + 0) = (fbdata8_0 & 0x0f) << 4; *(lcd->rgbbuf + i * 6 + 1) = (fbdata8_0 & 0xf0); *(lcd->rgbbuf + i * 6 + 2) = (fbdata8_1 & 0x0f) << 4; *(lcd->rgbbuf + i * 6 + 3) = (fbdata8_1 & 0xf0); *(lcd->rgbbuf + i * 6 + 4) = (fbdata8_2 & 0x0f) << 4; *(lcd->rgbbuf + i * 6 + 5) = (fbdata8_2 & 0xf0); } gdk_draw_rgb_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, rect.y, lcd->width, rect.height, GDK_RGB_DITHER_MAX, (guchar*)lcd->rgbbuf + rect.y * lcd->virtual_width * 3, lcd->virtual_width * 3); break; case 16: { int refresh = 0; for (i = lcd->virtual_width * rect.y / 2; i < wordnum / 2; i++) { /* shenoubang 2012-4-9 */ fbdata = ((guint64*)lcd->fbmem + i); fbdata_cp = ((guint64*)lcd->fbmem_cp + i); if (*fbdata != *fbdata_cp) { refresh = 1; *fbdata_cp = *fbdata; *(lcd->rgbbuf + i * 12 + 0) = (guchar)((*fbdata_cp & 0x0000f800) >> 8); *(lcd->rgbbuf + i * 12 + 1) = (guchar)((*fbdata_cp & 0x000007e0) >> 3); *(lcd->rgbbuf + i * 12 + 2) = (guchar)((*fbdata_cp & 0x0000001f) << 3); *(lcd->rgbbuf + i * 12 + 3) = (guchar)((*fbdata_cp & 0xf8000000) >> 24); *(lcd->rgbbuf + i * 12 + 4) = (guchar)((*fbdata_cp & 0x07e00000) >> 19); *(lcd->rgbbuf + i * 12 + 5) = (guchar)((*fbdata_cp & 0x001f0000) >> 13); *(lcd->rgbbuf + i * 12 + 6) = (guchar)(((*fbdata_cp >> 32) & 0x0000f800) >> 8); *(lcd->rgbbuf + i * 12 + 7) = (guchar)(((*fbdata_cp >> 32) & 0x000007e0) >> 3); *(lcd->rgbbuf + i * 12 + 8) = (guchar)(((*fbdata_cp >> 32) & 0x0000001f) << 3); *(lcd->rgbbuf + i * 12 + 9) = (guchar)(((*fbdata_cp >> 32) & 0xf8000000) >> 24); *(lcd->rgbbuf + i * 12 + 10) = (guchar)(((*fbdata_cp >> 32) & 0x07e00000) >> 19); *(lcd->rgbbuf + i * 12 + 11) = (guchar)(((*fbdata_cp >> 32) & 0x001f0000) >> 13); } } if (refresh) { GDK_THREADS_ENTER(); skyeye_printf_in_color(RED, "refresh: %d\n", refresh); gdk_draw_rgb_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, rect.y, lcd->width, rect.height, GDK_RGB_DITHER_MAX, (guchar*)lcd->rgbbuf + rect.y * lcd->virtual_width * 3, lcd->virtual_width * 3); GDK_THREADS_LEAVE(); } } break; case 24: gdk_draw_rgb_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, rect.y, lcd->width, rect.height, GDK_RGB_DITHER_NORMAL, (guchar*)lcd->rgbbuf + rect.y * lcd->virtual_width * 3, lcd->virtual_width * 3); break; case 32: gdk_draw_rgb_32_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, rect.y, lcd->width, rect.height, GDK_RGB_DITHER_NORMAL, (guchar*)((uint32*)lcd->rgbbuf + rect.y * lcd->virtual_width), lcd->virtual_width * 4); break; default: break; } return TRUE; } #if 1 //********** touch srceen event callback funtion by ywc ************ static void skPenEvent(int *buffer, int eventType, int stateType, int x, int y) { // printf("\nSkyEye: skPenEvent():event type=%d\n(x=%d,y=%d)\n",down,x,y); buffer[0] = x; buffer[1] = y; buffer[2] = 0; // dx buffer[3] = 0; // dy buffer[4] = eventType; // event from pen (DOWN,UP,CLICK,MOVE) buffer[5] = stateType; // state of pen (DOWN,UP,ERROR) buffer[6] = 1; // no of the event buffer[7] = 0; // time of the event (ms) since ts_open } static void callback_button_press(GtkWidget *w, GdkEventButton *event, gpointer object) { int *Pen_buffer; lcd_touchscreen_t *obj = object; Pen_buffer = get_pen_buffer(); skPenEvent(Pen_buffer, 0, 0, event->x, event->y); obj->touchscreen_update_status(obj->obj, Pen_buffer); } static void callback_button_release(GtkWidget *w, GdkEventButton *event, gpointer object) { int *Pen_buffer; lcd_touchscreen_t *obj = object; Pen_buffer = get_pen_buffer(); skPenEvent(Pen_buffer, 0, 1, event->x, event->y); obj->touchscreen_update_status(obj->obj, Pen_buffer); } static void callback_motion_notify(GtkWidget *w, GdkEventMotion *event, gpointer object) { int *Pen_buffer; lcd_touchscreen_t *obj = object; Pen_buffer = get_pen_buffer(); /* * when mouse is moving, generate an skyeye pen motion event * should changed to "when mouse is pressed and moving" */ if (Pen_buffer[5] == 0){ skPenEvent(Pen_buffer, 1, 0, event->x, event->y); obj->touchscreen_update_status(obj->obj, Pen_buffer); } } #endif static gint callback_redraw(GtkWidget *window) { //g_print("In %s\n", __FUNCTION__); gtk_widget_queue_draw(window); return TRUE; } static int gtk_lcd_open(conf_object_t *lcd_dev, lcd_surface_t* surface) { lcd_gtk_device* dev = lcd_dev->obj; lcd_touchscreen_t* lcd_ts = SKY_get_interface(lcd_dev, LCD_TS_INTF_NAME); SkyEyeLCD_GTK *lcd; guint32 *fbmem; char *title; GtkWidget *touch_screen; assert(dev != NULL); DBG("In %s, width=%d, height=%d, begin_addr=0x%x,end_addr=0x%x\n, ", __FUNCTION__, surface->width, surface->height, surface->lcd_addr_begin, surface->lcd_addr_end); if (dev == NULL || surface->width <= 0 || surface->height <= 0) return -1; if ((fbmem = (guint32*)get_dma_addr(surface->lcd_addr_begin)) == NULL) { fprintf(stderr, "[GTK_LCD]: Can't find LCD DMA from address 0x%x\n", surface->lcd_addr_begin); return -1; } DBG("In %s, fb_mem=0x%x\n", __FUNCTION__, fbmem); if ((lcd = (SkyEyeLCD_GTK*)malloc(sizeof(SkyEyeLCD_GTK))) == NULL) return -1; memset(lcd, 0, sizeof(SkyEyeLCD_GTK)); lcd->width = surface->width; lcd->virtual_width = surface->width + surface->lcd_line_offset; lcd->height = surface->height; lcd->depth = surface->depth; lcd->update_rect.width = -1; lcd->update_rect.height = -1; lcd->update_all = TRUE; lcd->fbmem = fbmem; /* allocate a ping-pong buffer to reduce unnecessary lcd fresh */ lcd->fbmem_cp = (void *)malloc(surface->lcd_addr_end - surface->lcd_addr_begin); /* shenoubang 2012-4-9 */ gdk_rgb_init(); gtk_widget_set_default_colormap (gdk_rgb_get_cmap()); gtk_widget_set_default_visual (gdk_rgb_get_visual()); if(dev->lcd_lookup_color != NULL) { lcd->rgbbuf = (guchar*)malloc(lcd->width * lcd->height * 4); } else switch (lcd->depth) { case 1: case 2: case 4: lcd->rgbbuf = (guchar*)malloc(lcd->virtual_width * lcd->height); break; case 12: case 16: lcd->rgbbuf = (guchar*)malloc(lcd->virtual_width * lcd->height * 3); break; case 8: case 24: case 32: lcd->rgbbuf = (guchar*)fbmem; break; default: break; } DBG("In %s, lcd->rgbbuf=0x%x\n", __FUNCTION__, lcd->rgbbuf); lcd->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_signal_connect(GTK_OBJECT(lcd->window), "delete-event", GTK_SIGNAL_FUNC(gtk_true), NULL); if ((title = g_strdup_printf("%dx%dx%d SkyEye LCD & Touch Screen (GTK+)", lcd->width, lcd->height, lcd->depth)) != NULL) { gtk_window_set_title(GTK_WINDOW(lcd->window), title); g_free(title); } DBG("In %s, set title\n", __FUNCTION__); gtk_widget_set_usize(lcd->window, lcd->width, lcd->height); gtk_widget_set_events(lcd->window, GDK_EXPOSURE_MASK); touch_screen = gtk_event_box_new(); /* shenobuang 2012-4-10 */ gtk_event_box_set_above_child (touch_screen, TRUE); gtk_event_box_set_visible_window (touch_screen, TRUE); DBG("In %s, set event\n", __FUNCTION__); if(lcd_ts){ skyeye_printf_in_color(GREEN, "In %s, Have touch screen register callback\n\n\n", __FUNCTION__); gtk_container_add(GTK_CONTAINER(lcd->window), touch_screen); gtk_widget_set_events(touch_screen, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); gtk_signal_connect(GTK_OBJECT(touch_screen), "button-press-event", GTK_SIGNAL_FUNC(callback_button_press), (gpointer)lcd_ts); gtk_signal_connect(GTK_OBJECT(touch_screen), "button-release-event", GTK_SIGNAL_FUNC(callback_button_release), (gpointer)lcd_ts); gtk_signal_connect(GTK_OBJECT(touch_screen), "motion-notify-event", GTK_SIGNAL_FUNC(callback_motion_notify), (gpointer)lcd_ts); gtk_widget_realize(touch_screen); gdk_window_set_cursor(touch_screen->window, gdk_cursor_new(GDK_HAND2)); } //zy 2004-4-02 Add Drawing area lcd->drawing = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(touch_screen), lcd->drawing); gtk_signal_connect(GTK_OBJECT(lcd->drawing), "expose-event", GTK_SIGNAL_FUNC(callback_expose_event), dev); gtk_widget_show_all(lcd->window); DBG("In %s, show all\n", __FUNCTION__); if (dev->lcd_lookup_color == NULL){ } switch (lcd->depth) { case 1: lcd->colormap = gdk_rgb_cmap_new(colors1b, 2); break; case 2: break; case 4: lcd->colormap = gdk_rgb_cmap_new(colors4b, 16); break; case 8: lcd->colormap = gdk_rgb_cmap_new(colors8b, 256); break; default: break; } DBG("In %s, add redraw event\n", __FUNCTION__); //lcd->timer = gtk_timeout_add(200, (GtkFunction)callback_redraw, lcd->window); dev->gtk_win = (void*)lcd; #ifndef MK_LCD int timer_id; create_thread_scheduler(10000, Periodic_sched, timer_update, dev->obj, &timer_id); #endif //gtk_main_iteration_do(FALSE); return 0; } static int gtk_lcd_close(conf_object_t* lcd_dev) { lcd_gtk_device* dev = lcd_dev->obj; SkyEyeLCD_GTK *lcd = dev ? dev->gtk_win : NULL; if(lcd == NULL) return -1; if (lcd->rgbbuf != NULL && lcd->rgbbuf != (void*)lcd->fbmem) free(lcd->rgbbuf); gtk_timeout_remove(lcd->timer); gtk_widget_destroy(lcd->window); if (lcd->colormap) gdk_rgb_cmap_free(lcd->colormap); free(lcd); dev->gtk_win = NULL; dev->lcd_addr_end = dev->lcd_addr_begin = 0; return 0; } static int gtk_lcd_filter_write(conf_object_t *lcd_dev, uint32 addr, uint32 data, size_t count) { int offsetADDR1, offsetADDR2; int w, x1, y1, x2, y2; lcd_gtk_device* dev = lcd_dev->obj; SkyEyeLCD_GTK *lcd = dev ? (SkyEyeLCD_GTK*)(dev->gtk_win) : NULL; if (lcd == NULL || addr < dev->lcd_addr_begin || addr > dev->lcd_addr_end) return 0; offsetADDR1 = (int)(addr - dev->lcd_addr_begin) * 8 / lcd->depth; offsetADDR2 = offsetADDR1 + (int)count * 8 / lcd->depth; w = lcd->virtual_width; x1 = MIN(offsetADDR1 % w, w - 1); y1 = MIN(offsetADDR1 / w, lcd->height - 1); x2 = MIN(offsetADDR2 % w, w - 1); y2 = MIN(offsetADDR2 / w, lcd->height - 1); if (lcd->update_rect.width < 0 || lcd->update_rect.height < 0) { lcd->update_rect.x = min(x1, x2); lcd->update_rect.y = min(y1, y2); lcd->update_rect.width = max(x1, x2) - lcd->update_rect.x; lcd->update_rect.height = max(y1, y2) - lcd->update_rect.y; } else { int l = min(min(x1, x2), lcd->update_rect.x); int t = min(min(y1, y2), lcd->update_rect.y); int r = max(max(x1, x2), lcd->update_rect.x + lcd->update_rect.width); int b = max(max(y1, y2), lcd->update_rect.y + lcd->update_rect.height); lcd->update_rect.x = l; lcd->update_rect.y = t; lcd->update_rect.width = r - l; lcd->update_rect.height = b - t; } lcd->update_all = FALSE; return 0; } static int gtk_lcd_update(conf_object_t *lcd_dev) { lcd_gtk_device* dev = lcd_dev->obj; if (dev == NULL || dev->gtk_win == NULL) return -1; gtk_main_iteration_do(FALSE); SkyEyeLCD_GTK *lcd = dev->gtk_win; gtk_widget_queue_draw(lcd->window); if(dev->master != NULL && dev->master->trigger != NULL) /* send the signal to lcd controller when finished refresh */ dev->master->trigger(dev->master->conf_obj); return 0; } static void timer_update(conf_object_t *lcd_dev){ gtk_lcd_update(lcd_dev); } static conf_object_t* new_gtk_lcd(char* obj_name) { static int tmp_argc = 0; static gboolean once = FALSE; guint32 i; if (obj_name == NULL) return NULL; if (once == FALSE) { if (gtk_init_check(&tmp_argc, NULL) == FALSE) { fprintf(stderr, "[GTK_LCD]: Can't initalize GTK+\n"); return NULL; } /* shenoubang 2012-4-9 */ //gdk_rgb_init(); // ywc 2004-07-24 creat the 256 colormap from 8 TRUE_COLOR-8-332 // should add PSEUDOCOLOR palette for depth==8 for (i = 0; i < 256; i++) { colors8b[i] = ((i & 0x000000e0) << 16) + ((i & 0x0000001c) << 11) + ((i & 0x00000003) << 6); } once = TRUE; } lcd_gtk_device* dev = skyeye_mm_zero(sizeof(lcd_gtk_device)); dev->width = 640; dev->height = 480; dev->depth = 16; dev->obj = new_conf_object(obj_name, dev); //dev->gtk_win = gtk_win; /* lcd update*/ int timer_id; //create_thread_scheduler(5000, Periodic_sched, timer_update, dev->obj, &timer_id); lcd_control_intf* lcd_ctrl = skyeye_mm_zero(sizeof(lcd_control_intf)); lcd_ctrl->conf_obj = dev->obj; lcd_ctrl->lcd_open = gtk_lcd_open; lcd_ctrl->lcd_close = gtk_lcd_close; lcd_ctrl->lcd_update = gtk_lcd_update; lcd_ctrl->lcd_filter_read = NULL; lcd_ctrl->lcd_filter_write = gtk_lcd_filter_write; lcd_ctrl->lcd_lookup_color = NULL; SKY_register_interface(lcd_ctrl, obj_name, LCD_CTRL_INTF_NAME); simple_signal_intf* refresh_signal = skyeye_mm_zero(sizeof(simple_signal_intf)); refresh_signal->conf_obj = NULL; refresh_signal->trigger = NULL; SKY_register_interface(refresh_signal, obj_name, SIMPLE_SIGNAL_INTF_NAME); dev->master = refresh_signal; return dev->obj; } void free_gtk_lcd(conf_object_t* dev){ } void init_gtk_lcd(){ static skyeye_class_t class_data = { .class_name = "gtk_lcd", .class_desc = "gtk lcd", .new_instance = new_gtk_lcd, .free_instance = free_gtk_lcd, .get_attr = NULL, .set_attr = NULL }; SKY_register_class(class_data.class_name, &class_data); }