⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skyeye_lcd_gtk.c

📁 这是Skyeye 0.9 版本的源代码
💻 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 + -