📄 skyeye_lcd_gtk.c
字号:
/*
armlcd.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
*/
#include <assert.h>
#include <sys/time.h>
static int lcd_base;
/*chy change 2002-12-3*/
//#define NO_LCD
#include <gtk/gtk.h>
#include <gdk/gdk.h> //added by ywc
#ifdef SKYEYE_LCD_TEST
typedef unsigned long ARMword;
typedef unsigned long ARMul_State;
#else
#include "armdefs.h"
#endif //SKYEYE_LCD_TEST
#include "skyeye_lcd.h"
//zy 2004-4-2 Add draw area
static GtkWidget *window;
static GtkWidget *TouchScreen; //add by ywc
static GtkWidget *LCD; //add by ywc
//zy 2004-4-2 Use Gdkgdb now ,so do not need GdkGc
//static GdkGC *gc[GREY_LEVELS];
static GdkColormap *point_colormap;
static int lcd_width, lcd_height, lcd_depth;
guchar *rgbbuf;
guint32 *fbSkyeyeADDR;
static struct GdkRgbCmap *colormap;
//by ywc 2004-07-24
extern mem_bank_t *bank_ptr (ARMword addr);
/* use rgbbuf */
expose_event (GtkWidget * widget, GdkEventExpose * event)
{
int i, x, y, pix, pixnum, bit;
int wordnum; //for lcd_depth==16 , 1 word contain 2 pixel
guint32 fbdata; // |R1,G1,B1,R0,G0,B0|
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|
wordnum = lcd_width * lcd_height * lcd_depth / 32;
tribytenum = lcd_width * lcd_height * lcd_depth / 24;
pixnum = lcd_width * lcd_height;
switch (lcd_depth)
{
case 1:
case 2:
case 4:
// should add code for scan the fb data to buf
gdk_draw_indexed_image (widget->window,
widget->style->
fg_gc[GTK_STATE_NORMAL], 0, 0,
lcd_width, lcd_height,
GDK_RGB_DITHER_NORMAL, rgbbuf,
lcd_width, colormap);
break;
case 8:
gdk_draw_indexed_image (widget->window,
widget->style->
fg_gc[GTK_STATE_NORMAL], 0, 0,
lcd_width, lcd_height,
GDK_RGB_DITHER_NORMAL, rgbbuf,
lcd_width, colormap);
//gdk_draw_gray_image (widget->window,
// widget->style->fg_gc[GTK_STATE_NORMAL],
// 0 , 0,lcd_width ,lcd_height,
// GDK_RGB_DITHER_NORMAL, rgbbuf,lcd_width);
break;
case 12:
for (i = 0; i < tribytenum; i++)
{
fbdata8_0 = *((guchar *) fbSkyeyeADDR + i * 3);
fbdata8_1 = *((guchar *) fbSkyeyeADDR + i * 3 + 1);
fbdata8_2 = *((guchar *) fbSkyeyeADDR + i * 3 + 2);
*(rgbbuf + i * 6 + 0) = (fbdata8_0 & 0x0f) << 4;
*(rgbbuf + i * 6 + 1) = (fbdata8_0 & 0xf0);
*(rgbbuf + i * 6 + 2) = (fbdata8_1 & 0x0f) << 4;
*(rgbbuf + i * 6 + 3) = (fbdata8_1 & 0xf0);
*(rgbbuf + i * 6 + 4) = (fbdata8_2 & 0x0f) << 4;
*(rgbbuf + i * 6 + 5) = (fbdata8_2 & 0xf0);
}
gdk_draw_rgb_image (widget->window,
widget->style->fg_gc[GTK_STATE_NORMAL],
0, 0, lcd_width, lcd_height,
GDK_RGB_DITHER_MAX, rgbbuf, lcd_width * 3);
break;
case 16:
//gettimeofday(&scan16start,NULL);
for (i = 0; i < wordnum; i++)
{
fbdata = *(fbSkyeyeADDR + i);
*(rgbbuf + i * 6 + 0) = (guchar) ((fbdata & 0x0000f800) >> 8);
*(rgbbuf + i * 6 + 1) = (guchar) ((fbdata & 0x000007e0) >> 3);
*(rgbbuf + i * 6 + 2) = (guchar) ((fbdata & 0x0000001f) << 3);
*(rgbbuf + i * 6 + 3) = (guchar) ((fbdata & 0xf8000000) >> 24);
*(rgbbuf + i * 6 + 4) = (guchar) ((fbdata & 0x07e00000) >> 19);
*(rgbbuf + i * 6 + 5) = (guchar) ((fbdata & 0x001f0000) >> 13);
}
gdk_draw_rgb_image (widget->window,
widget->style->fg_gc[GTK_STATE_NORMAL],
0, 0, lcd_width, lcd_height,
GDK_RGB_DITHER_MAX, rgbbuf, lcd_width * 3);
break;
case 24:
gdk_draw_rgb_image (widget->window,
widget->style->fg_gc[GTK_STATE_NORMAL],
0, 0, lcd_width, lcd_height,
GDK_RGB_DITHER_NORMAL, rgbbuf, lcd_width * 3);
break;
case 32:
gdk_draw_rgb_32_image (widget->window,
widget->style->fg_gc[GTK_STATE_NORMAL],
0, 0, lcd_width, lcd_height,
GDK_RGB_DITHER_NORMAL, rgbbuf, lcd_width * 4);
break;
default:
break;
}
return TRUE;
}
//********** touch srceen event callback funtion by ywc ************
unsigned long Pen_buffer[8];
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
}
void
callback_button_press (GtkWidget * w, GdkEventButton * event)
{
skPenEvent (Pen_buffer, 0, 1, event->x, event->y);
// g_print("button pressed , Skyeye get it !!!\n");
}
void
callback_button_release (GtkWidget * w, GdkEventButton * event)
{
skPenEvent (Pen_buffer, 1, 0, event->x, event->y);
// g_print("button released , Skyeye get it !!!\n\n");
}
void
callback_motion_notify (GtkWidget * w, GdkEventMotion * event)
{
//when mouse is moving, generate an skyeye pen motion event
//should changed to "when mouse is pressed and moving"
if (Pen_buffer[5] == 1)
{
skPenEvent (Pen_buffer, 2, 1, event->x, event->y);
}
// g_print("and moving , Skyeye get it !!!\n");
}
//***********************************************
#ifdef SKYEYE_LCD_TEST
int global_argc;
char **global_argv;
#else
extern int global_argc;
extern char **global_argv;
#endif
gint
redraw (gpointer pointer)
{
GdkRectangle update_rect;
update_rect.x = 0;
update_rect.y = 0;
update_rect.width = lcd_width;
update_rect.height = lcd_height;
if (1)
{
gtk_widget_draw ((GtkWidget *) pointer, &update_rect);
}
if (pointer)
{
return TRUE;
}
else
return FALSE;
}
int
gtk_lcd_update (struct lcd_device *lcd_dev)
{
gtk_main_iteration_do (FALSE);
}
int
gtk_lcd_open (struct lcd_device *lcd_dev)
{
guint32 i;
static int once = 0;
char *title;
char mode[100];
mem_bank_t *mbp;
guint32 colors8b[256];
//zy 2004-04-02
guint32 colors1b[] = {
0x000000, 0xffffff
};
guint32 colors4b[] = {
0x000000, 0x000080, 0x008000, 0x008080, 0x800000, 0x800080,
0x808000, 0x808080,
0xc0c0c0, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff,
0xffff00, 0xffffff
};
int width = lcd_dev->width;
int height = lcd_dev->height;
int depth = lcd_dev->depth;
ARMul_State *state = (ARMul_State *) lcd_dev->state;
if (!once)
{
once++;
gtk_init (&global_argc, &global_argv);
gdk_rgb_init ();
}
lcd_width = width;
lcd_height = height;
lcd_depth = depth;
lcd_dev->lcd_addr_end = lcd_dev->lcd_addr_begin +
(width * height * depth / 8) - 1;
lcd_base = lcd_dev->lcd_addr_begin;
// by ywc 2004-07-24 scan the framebuffer directly and don't use the buf
mbp = bank_ptr (lcd_base);
if (!mbp)
{
fprintf (stderr, "No bank at address 0x%x", lcd_base);
return;
}
fbSkyeyeADDR =
(guint32 *) & state->mem.rom[(mbp -
skyeye_config.mem.mem_banks)][(lcd_base -
mbp->addr) /
4];
switch (lcd_depth)
{
case 1:
case 2:
case 4:
rgbbuf = malloc (lcd_width * lcd_height);
break;
case 12:
case 16:
rgbbuf = malloc (lcd_width * lcd_height * 3);
break;
case 8:
case 24:
case 32:
rgbbuf = (guchar *) fbSkyeyeADDR;
break;
default:
break;
}
printf
("\nSKYEYE: lcd_addr_begin 0x%x,lcd_addr_end 0x%x, width %d, height %d, depth %d\n",
(lcd_dev->lcd_addr_begin), (lcd_dev->lcd_addr_end), width, height,
depth);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //create top level window
title = "SkyEye_LCD-Screen_Touch-Screen ";
//sprintf(mode,"%s%dx%dx%d",title,lcd_width,lcd_height,lcd_depth);
sprintf (mode, "%dx%dx%d %s", lcd_width, lcd_height, lcd_depth, title);
gtk_window_set_title (window, mode); //added by ywc
gtk_widget_set_usize (window, width, height);
gtk_widget_set_events (window, GDK_EXPOSURE_MASK);
TouchScreen = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (window), TouchScreen);
gtk_widget_set_events (GTK_OBJECT (TouchScreen), GDK_ENTER_NOTIFY_MASK
| GDK_LEAVE_NOTIFY_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
//| GDK_POINTER_MOTION_HINT_MASK);
gtk_signal_connect (GTK_OBJECT (TouchScreen), "button-press-event",
GTK_SIGNAL_FUNC (callback_button_press), NULL);
gtk_signal_connect (GTK_OBJECT (TouchScreen), "button-release-event",
GTK_SIGNAL_FUNC (callback_button_release), NULL);
gtk_signal_connect (GTK_OBJECT (TouchScreen), "motion-notify-event",
GTK_SIGNAL_FUNC (callback_motion_notify), NULL);
gtk_widget_show (TouchScreen);
gtk_widget_realize (TouchScreen);
gdk_window_set_cursor (TouchScreen->window, gdk_cursor_new (GDK_HAND2)); //cursor will change!
//zy 2004-4-02 Add Drawing area
LCD = gtk_drawing_area_new ();
gtk_container_add (GTK_CONTAINER (TouchScreen), LCD);
gtk_signal_connect (GTK_OBJECT (LCD), "expose-event",
GTK_SIGNAL_FUNC (expose_event), NULL);
gtk_widget_show (LCD);
gtk_widget_show_all (window);
point_colormap = gdk_window_get_colormap (LCD->window);
//gtk_widget_show(window);//show the top level window
// 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);
}
switch (lcd_depth)
{
case 1:
colormap = gdk_rgb_cmap_new (colors1b, (1 << depth));
break;
case 2:
break;
case 4:
colormap = gdk_rgb_cmap_new (colors4b, (1 << depth));
break;
case 8:
colormap = gdk_rgb_cmap_new (colors8b, (1 << depth));
break;
case 12:
case 16:
case 24:
case 32:
default:
break;
}
// gtk_timeout_add(500,redraw,window);
gtk_timeout_add (200, redraw, window);
// gtk_timeout_add(1000,redraw,window);
}
int
gtk_lcd_close (struct lcd_device *lcd_dev)
{
int i;
int depth = lcd_dev->depth;
//chy 2004-03-11
//ywc 2004-09-09 for free dynamic memory
if (depth == 1 || depth == 2 || depth == 4 || depth == 12 || depth == 16)
{
free (rgbbuf);
}
if (window)
{
gtk_widget_destroy (window);
window = NULL;
}
//zy 2004-04-02
if (colormap)
{
gdk_rgb_cmap_free (colormap);
colormap = NULL;
}
}
int
gtk_lcd_read (struct lcd_device *lcd_dev)
{
return 0;
}
int
gtk_lcd_write (struct lcd_device *lcd_dev)
{
return 0;
}
#ifdef SKYEYE_LCD_TEST
#include <unistd.h>
void
main (int argc, char **argv)
{
ARMul_State armstate;
ARMul_State *pas;
ARMword i, j, k;
global_argc = argc;
global_argv = argv;
pas = &armstate;
lcd_enable (pas, 240, 320, 4);
for (i = 0; i < 1000; i++)
{
lcd_write (pas, i + LCD_BASE, i);
lcd_cycle (pas);
}
sleep (5);
for (i = 0; i < 1000; i++)
{
lcd_write (pas, i + 1000 + LCD_BASE, i + 1000);
lcd_cycle (pas);
}
sleep (5);
}
#endif //SKYEYE_LCD_TEST
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -