GadgetSeed  0.9.6
framebuf.c
[詳解]
1 /** @file
2  @brief フレームバッファドライバ(16ビットカラー)
3 
4  フレームバッファドライバは仮想グラフィックメモリだけを持つデバイスド
5  ライバです。
6 
7  上位のグラフィックライブラリより使用されます。
8  下位ドライバに、LCDドライバ等の実際に表示できるデバイスが必要です。
9 
10  register()実行時に下位ビデオデバイス名を指定することが出来ます。
11 
12  @date 2017.01.15
13  @author Takashi SHUDO
14 */
15 
16 #include "device.h"
17 #include "framebuf.h"
18 #include "device/video_ioctl.h"
19 #include "graphics.h"
20 #include "tkprintf.h"
21 #include "sysconfig.h"
22 
23 //#define DEBUGKBITS 0x03
24 #include "dkprintf.h"
25 
26 
27 static void framebuf_set_forecolor(struct st_framebuf_context *fc, unsigned int color)
28 {
29  fc->fore_color = color;
30 }
31 
32 static void framebuf_set_backcolor(struct st_framebuf_context *fc, unsigned int color)
33 {
34  fc->back_color = color;
35 }
36 
37 static void framebuf_draw_point(struct st_framebuf_context *fc, int x, int y)
38 {
39  PIXEL_DATA *dp;
40 
41  dp = (PIXEL_DATA *)fc->fb_ptr[fc->draw_frame] + (y * fc->width) + x;
42 
43  *dp = (PIXEL_DATA)fc->fore_color;
44 }
45 
46 static inline void framebuf_set_ptr(struct st_framebuf_context *fc)
47 {
48  fc->draw_ptr = fc->fb_ptr[fc->draw_frame]
49  + (fc->pen_y * fc->width * sizeof(PIXEL_DATA))
50  + (fc->pen_x * sizeof(PIXEL_DATA));
51 }
52 
53 static inline unsigned int framebuf_read_point(struct st_framebuf_context *fc)
54 {
55  unsigned int rtn = *(PIXEL_DATA *)(fc->draw_ptr);
56 
57  fc->pen_x ++;
58  fc->draw_ptr += sizeof(PIXEL_DATA);
59  if(fc->pen_x > fc->clip.right) {
60  fc->pen_x = fc->clip.left;
61  fc->pen_y ++;
62  framebuf_set_ptr(fc);
63  }
64 
65  return rtn;
66 }
67 
68 static inline void framebuf_write_point(struct st_framebuf_context *fc, unsigned int color)
69 {
70  *(PIXEL_DATA *)(fc->draw_ptr) = (PIXEL_DATA)color;
71 
72  fc->pen_x ++;
73  fc->draw_ptr += sizeof(PIXEL_DATA);
74  if(fc->pen_x > fc->clip.right) {
75  fc->pen_x = fc->clip.left;
76  fc->pen_y ++;
77  framebuf_set_ptr(fc);
78  }
79 }
80 
81 static void framebuf_repeat_data(struct st_framebuf_context *fc, int len)
82 {
83  while(len) {
84  framebuf_write_point(fc, fc->fore_color);
85  len --;
86  }
87 }
88 
89 static void framebuf_fill_screen(struct st_framebuf_context *fc, unsigned int data)
90 {
91  unsigned int count = (fc->mem_size)/sizeof(PIXEL_DATA);
92  PIXEL_DATA *dp = (PIXEL_DATA *)fc->fb_ptr[fc->draw_frame];
93 
94  while(count) {
95  *dp = (PIXEL_DATA)data;
96  dp ++;
97  count --;
98  }
99 }
100 
101 static const char def_v_dev[] = DEF_DEV_NAME_VIDEO;
102 
103 static struct st_framebuf_context fb_ctx;
104 
105 static int framebuf_register(struct st_device *dev, char *param)
106 {
107  struct st_device *v_dev;
108  struct st_video_info *v_info;
109  struct st_framebuf_context *fc;
110  char *dev_name = (char *)def_v_dev;
111 
112  if(param != 0) {
113  dev_name = param;
114  }
115 
116  v_dev = open_device(dev_name);
117  if(v_dev == 0) {
118  SYSERR_PRINT("Cannot open device \"%s\"\n", dev_name);
119  return -1;
120  }
121 
122  dev->info = (void *)(v_dev->info);
123  dev->private_data = &fb_ctx;
124 
125  v_info = dev->info;
126  fc = &fb_ctx;
127 
128  fc->v_dev = v_dev;
129  fc->width = v_info->width;
130  fc->height = v_info->height;
131  fc->pixcel_byte = 2; // 16bit color
132  fc->disp_frame = 0;
133  fc->draw_frame = 0;
134  fc->fb_ptr[0] = v_info->frame_buf_ptr[0];
135  fc->fb_ptr[1] = v_info->frame_buf_ptr[1];
136  fc->mem_size = v_info->mem_size;
137  fc->fore_color = RGB(0, 0, 0);
138  fc->clip.left = 0;
139  fc->clip.top = 0;
140  fc->clip.right = fc->width;
141  fc->clip.bottom = fc->height;
142  fc->pen_x = 0;
143  fc->pen_y = 0;
144  fc->draw_ptr = fc->fb_ptr[0];
145 
146  return 0;
147 }
148 
149 static int framebuf_read(struct st_device *dev, void *data, unsigned int size)
150 {
151  struct st_framebuf_context *fc = (struct st_framebuf_context *)(dev->private_data);
152  int i;
153  PIXEL_DATA *dp = (PIXEL_DATA *)data;
154 
155  DKFPRINTF(0x01, "data = %p, size = %ld\n", data, size);
156 
157  for(i=0; i<size/sizeof(PIXEL_DATA); i++) {
158  //PIXEL_DATA tmp = (((PIXEL_DATA)(*data)) << 8) + (*(data + 1));
159  *dp = framebuf_read_point(fc);
160  dp ++;
161  }
162 
163  return size;
164 }
165 
166 static int framebuf_write(struct st_device *dev, const void *data, unsigned int size)
167 {
168  struct st_framebuf_context *fc = (struct st_framebuf_context *)(dev->private_data);
169  int i;
170  PIXEL_DATA *dp = (PIXEL_DATA *)data;
171 
172  DKFPRINTF(0x01, "data = %p, size = %ld\n", data, size);
173 
174  for(i=0; i<size/sizeof(PIXEL_DATA); i++) {
175  //PIXEL_DATA tmp = (((PIXEL_DATA)(*data)) << 8) + (*(data + 1));
176  framebuf_write_point(fc, *dp);
177  dp ++;
178  }
179 
180  return size;
181 }
182 
183 static int framebuf_ioctl(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
184 {
185  struct st_framebuf_context *fc = (struct st_framebuf_context *)(dev->private_data);
186 
187  DKFPRINTF(0x01, "com = %08lX, arg = %08lX\n", com, arg);
188 
189  switch(IOCTL(com)) {
191  if(arg >= MAX_FRAMEBUF) {
192  return -1;
193  }
194  fc->disp_frame = arg;
195 
196  // 表示バッファを変更
198  break;
199 
201  return fc->disp_frame;
202  break;
203 
205  if(arg >= MAX_FRAMEBUF) {
206  return -1;
207  }
208  fc->draw_frame = arg;
209  fc->draw_ptr = fc->fb_ptr[arg];
210  break;
211 
213  return fc->draw_frame;
214  break;
215 
216  case IOCMD_VIDEO_SETRECT:
217  {
218  struct st_rect *rect = (struct st_rect *)param;
219  fc->clip.left = rect->left;
220  fc->clip.top = rect->top;
221  fc->clip.right = rect->right;
222  fc->clip.bottom = rect->bottom;
223  fc->pen_x = rect->left;
224  fc->pen_y = rect->top;
225  framebuf_set_ptr(fc);
226  }
227  break;
228 
230  {
231  fc->clip.left = 0;
232  fc->clip.top = 0;
233  fc->clip.right = fc->width;
234  fc->clip.bottom = fc->height;
235  fc->pen_x = fc->clip.left;
236  fc->pen_y = fc->clip.top;
237  framebuf_set_ptr(fc);
238  }
239  break;
240 
241  case IOCMD_VIDEO_CLEAR:
242  framebuf_fill_screen(fc, RGB(0, 0, 0));
243  break;
244 
245  case IOCMD_VIDEO_FILL:
246  framebuf_fill_screen(fc, arg);
247  break;
248 
250  switch(arg) {
251  case 0:
252  break;
253 
254  case 1:
255  break;
256  }
257  break;
258 
261  framebuf_write_point(fc, arg);
262  break;
263 
265  framebuf_set_forecolor(fc, (unsigned int)arg);
266  break;
267 
269  framebuf_set_backcolor(fc, (unsigned int)arg);
270  break;
271 
273  framebuf_repeat_data(fc, arg);
274  break;
275 
277  {
278  int x = ((arg >> 0) & 0xffff);
279  int y = ((arg >> 16) & 0xffff);
280  int dx = x;
281  int dy = y;
282 
283  framebuf_draw_point(fc, dx, dy);
284  }
285  break;
286 
288  {
289  int sbit = ((com >> 12) & 0x7);
290  int count = (com & 0x0fff);
291  unsigned char *data = (unsigned char *)param;
292  unsigned char bit = (0x80 >> sbit);
293  int i;
294 
295  for(i=0; i<count; i++) {
296  if(*data & bit) {
297  framebuf_write_point(fc, fc->fore_color);
298  } else {
299  framebuf_write_point(fc, fc->back_color);
300  }
301  if(bit == 0x01) {
302  bit = 0x80;
303  data ++;
304  } else {
305  bit >>= 1;
306  }
307  }
308  }
309  break;
310 
311  case IOCMD_VIDEO_SCROLL:
312  {
313  int i, j;
314  PIXEL_DATA *sp;
315  PIXEL_DATA *dp;
316  //int x = (short)((arg >> 0) & 0xffff);
317  int y = (short)((arg >> 16) & 0xffff);
318 
319  sp = (PIXEL_DATA *)fc->fb_ptr[fc->draw_frame]
320  + (-y * fc->width);
321  dp = (PIXEL_DATA *)fc->fb_ptr[fc->draw_frame];
322 
323  for(j=0; j<(fc->height + y); j++) {
324  for(i=0; i<fc->width; i++) {
325  *dp = *sp;
326  dp ++;
327  sp ++;
328  }
329  }
330  }
331  break;
332 
335  // 何もしない
336  break;
337 
338  default:
339  SYSERR_PRINT("Unknow command %08lX arg %08lX\n", com, arg);
340  return -1;
341  }
342 
343  return 0;
344 }
345 
346 struct st_device framebuf_device = {
347  .name = "fb",
348  .explan = "Frame buffer(16 bit color)",
349  .register_dev = framebuf_register,
350  .read = framebuf_read,
351  .write = framebuf_write,
352  .ioctl = framebuf_ioctl,
353 };
#define IOCTL(ioctl)
ioctlコマンド
Definition: std_ioctl.h:29
#define IOCMD_VIDEO_NOLOCK_WRITE_WORD
2バイト表示データを転送する(MUTEXロックは無視)
Definition: video_ioctl.h:62
unsigned int back_color
バックカラー
Definition: framebuf.h:26
#define IOCMD_VIDEO_GETDRAWFRAME
描画フレーム番号を取得する
Definition: video_ioctl.h:50
short pen_y
描画ペンのY座標
Definition: framebuf.h:29
unsigned int fore_color
フォアカラー
Definition: framebuf.h:25
unsigned short height
表示高さドット数
Definition: video_ioctl.h:33
void * info
デバイス情報データポインタ
Definition: device.h:28
#define IOCMD_VIDEO_CLEAR
全画面初期化
Definition: video_ioctl.h:52
画像表示デバイスドライバ ioctl 用マクロ定義
#define IOCMD_VIDEO_SETDRAWFRAME
描画フレーム番号を設定する
Definition: video_ioctl.h:49
#define IOCMD_VIDEO_UNLOCK_DEVICE
デバイスをMUTEXアンロックする
Definition: video_ioctl.h:45
フレームバッファドライバ用コンテキスト定義
#define IOCMD_VIDEO_SETRECT
描画データ転送範囲を矩形で設定する
Definition: video_ioctl.h:55
矩形
Definition: graphics.h:64
画像表示デバイス情報
Definition: video_ioctl.h:30
struct st_device * open_device(char *name)
デバイスをオープンする
Definition: device.c:262
void * private_data
ドライバ固有データポインタ
Definition: device.h:29
unsigned int mem_size
1フレームのメモリバイト数
Definition: framebuf.h:23
#define IOCMD_VIDEO_REPEAT_DATA
指定ドット数分フォアカラーで描画する
Definition: video_ioctl.h:66
short top
左上頂点のY座標
Definition: graphics.h:66
short bottom
右下頂点のY座標
Definition: graphics.h:68
short left
左上頂点のX座標
Definition: graphics.h:65
#define IOCMD_VIDEO_DRAW_PIXEL
フォアカラーで1ドット描画する
Definition: video_ioctl.h:67
#define IOCMD_VIDEO_DRAW_BITS
ビットパターンを描画する
Definition: video_ioctl.h:68
#define IOCMD_VIDEO_GETDISPFRAME
表示フレーム番号を取得する
Definition: video_ioctl.h:48
unsigned char * fb_ptr[MAX_FRAMEBUF]
フレームバッファメモリポインタ
Definition: framebuf.h:22
short right
右下頂点のX座標
Definition: graphics.h:67
#define IOCMD_VIDEO_SCROLL
表示位置を変更(スクロール)する
Definition: video_ioctl.h:53
カーネル用機能限定printf
unsigned short draw_frame
描画フレームバッファ番号
Definition: framebuf.h:21
#define MAX_FRAMEBUF
最大フレームバッファ数
Definition: graphics.h:14
short pen_x
描画ペンのX座標
Definition: framebuf.h:28
struct st_device * v_dev
下位デバイスドライバ
Definition: framebuf.h:16
unsigned short width
表示幅ドット数
Definition: video_ioctl.h:32
フレームバッファコンテキスト
Definition: framebuf.h:15
unsigned char * draw_ptr
描画ペンのメモリアドレス
Definition: framebuf.h:30
#define IOCMD_VIDEO_LOCK_DEVICE
デバイスをMUTEXロックする
Definition: video_ioctl.h:44
#define IOCMD_VIDEO_RESETRECT
描画データ転送範囲を全表示範囲にする
Definition: video_ioctl.h:56
#define IOCMD_VIDEO_SET_BACKCOLOR
バックカラーを設定する
Definition: video_ioctl.h:65
unsigned short pixcel_byte
1ピクセルのデータバイト数
Definition: framebuf.h:19
unsigned int mem_size
フレームバッファメモリサイズ
Definition: video_ioctl.h:37
#define IOCMD_VIDEO_SETDISPFRAME
表示フレーム番号を設定する
Definition: video_ioctl.h:47
struct st_rect clip
描画クリッピングエリア
Definition: framebuf.h:27
unsigned char * frame_buf_ptr[MAX_FRAMEBUF]
フレームバッファポインタ
Definition: video_ioctl.h:36
#define DEF_DEV_NAME_VIDEO
標準ビデオデバイス名
Definition: video_ioctl.h:16
unsigned short disp_frame
表示フレームバッファ番号
Definition: framebuf.h:20
short height
フレームバッファ高さピクセル数
Definition: framebuf.h:18
デバイスドライバAPI
デバイスドライバ構造体
Definition: device.h:25
カーネル、ドライバ(非タスク)デバッグ用マクロ
#define IOCMD_VIDEO_WRITE_WORD
2バイト表示データを転送する(未使用)
Definition: video_ioctl.h:59
int ioctl_device(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
デバイスを制御する
Definition: device.c:525
char name[MAX_DEVNAMELRN]
デバイス名文字列
Definition: device.h:26
short width
フレームバッファ幅ピクセル数
Definition: framebuf.h:17
#define IOCMD_VIDEO_SET_FORECOLOR
フォアカラーを設定する
Definition: video_ioctl.h:64
グラフィックライブラリ
unsigned short PIXEL_DATA
$gsc グラフィックデバイスは24ビットカラー
Definition: graphics.h:17
#define IOCMD_VIDEO_BCKLIGHT
バックライトを制御する(未使用)
Definition: video_ioctl.h:70
#define IOCMD_VIDEO_FILL
全画面を任意の色に描画する
Definition: video_ioctl.h:54