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

📄 fbcon.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 * At the moment fbcon_putc() cannot blit across vertical wrap boundary * Implies should only really hardware scroll in rows. Only reason for * restriction is simplicity & efficiency at the moment. */static __inline__ int real_y(struct display *p, int y){   int rows = p->vrows;   y += p->yscroll;   return(y < rows ? y : y-rows);}static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height,                       int width){   int unit = conp->vc_num;   struct display *p = &disp[unit];   u_int y_break;   if (!p->can_soft_blank && console_blanked)      return(0);   if ((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&       (sx <= p->cursor_x) && (p->cursor_x < sx+width))      CURSOR_UNDRAWN();   /* Split blits that cross physical y_wrap boundary */   y_break = p->vrows-p->yscroll;   if (sy < y_break && sy+height-1 >= y_break) {      u_int b = y_break-sy;      p->dispsw->clear(conp, p, real_y(p, sy), sx, b, width);      p->dispsw->clear(conp, p, real_y(p, sy+b), sx, height-b, width);   } else      p->dispsw->clear(conp, p, real_y(p, sy), sx, height, width);   return(0);}static int fbcon_putc(struct vc_data *conp, int c, int y, int x){   int unit = conp->vc_num;   struct display *p = &disp[unit];   if (!p->can_soft_blank && console_blanked)      return(0);   if ((p->cursor_x == x) && (p->cursor_y == y))       CURSOR_UNDRAWN();   p->dispsw->putc(conp, p, c, real_y(p, y), x);   return(0);}static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,                       int x){   int unit = conp->vc_num;   struct display *p = &disp[unit];   if (!p->can_soft_blank && console_blanked)      return(0);   if ((p->cursor_y == y) && (x <= p->cursor_x) && (p->cursor_x < x+count))      CURSOR_UNDRAWN();   p->dispsw->putcs(conp, p, s, count, real_y(p, y), x);   return(0);}static int fbcon_cursor(struct vc_data *conp, int mode){   int unit = conp->vc_num;   struct display *p = &disp[unit];   if (CURSOR_UNDRAWN ())      p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));   p->cursor_x = conp->vc_x;   p->cursor_y = conp->vc_y;   switch (mode) {      case CM_ERASE:         cursor_on = 0;         break;      case CM_MOVE:      case CM_DRAW:         vbl_cursor_cnt = CURSOR_DRAW_DELAY;         cursor_on = 1;         break;   }   return(0);}static void fbcon_vbl_handler(int irq, struct pt_regs *fp, void *dummy){   struct display *p;   if (!cursor_on)      return;   if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {      /* Here no check is possible for console changing. The console       * switching code should set vbl_cursor_cnt to an appropriate value.       */      p = &disp[fg_console];      p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));      cursor_drawn ^= 1;      vbl_cursor_cnt = cursor_blink_rate;   }}static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count){   int unit = conp->vc_num;   struct display *p = &disp[unit];   if (!p->can_soft_blank && console_blanked)      return(0);   fbcon_cursor(conp, CM_ERASE);   /*    * ++Geert: Only use ywrap/ypan if the console is in text mode    */   switch (dir) {      case SM_UP:         if (t == 0 && b == conp->vc_rows &&             vt_cons[unit]->vc_mode == KD_TEXT) {            if (count > conp->vc_rows)             /* Maximum realistic size */               count = conp->vc_rows;            switch (p->scrollmode) {               case SCROLL_YWRAP:                  p->yscroll += count;                  if (p->yscroll >= p->vrows) /* Deal with wrap */                     p->yscroll -= p->vrows;                  p->var.xoffset = 0;                  p->var.yoffset = p->yscroll*p->fontheight;                  p->var.vmode |= FB_VMODE_YWRAP;                  fb_info->updatevar(unit);                  break;               case SCROLL_YPAN:                  p->yscroll += count;                  if (p->yscroll+conp->vc_rows > p->vrows) {                     p->dispsw->bmove(p, p->yscroll, 0, 0, 0, b-count,                                      conp->vc_cols);                     p->yscroll = 0;                  }                  p->var.xoffset = 0;                  p->var.yoffset = p->yscroll*p->fontheight;                  p->var.vmode &= ~FB_VMODE_YWRAP;                  fb_info->updatevar(unit);                  break;               case SCROLL_YMOVE:                  p->dispsw->bmove(p, count, 0, 0, 0, b-count, conp->vc_cols);                  break;            }         } else            fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);         fbcon_clear(conp, b-count, 0, count, conp->vc_cols);         break;      case SM_DOWN:         if (t == 0 && b == conp->vc_rows &&             vt_cons[unit]->vc_mode == KD_TEXT) {            if (count > conp->vc_rows)             /* Maximum realistic size */               count = conp->vc_rows;            switch (p->scrollmode) {               case SCROLL_YWRAP:                  p->yscroll -= count;                  if (p->yscroll < 0)              /* Deal with wrap */                     p->yscroll += p->vrows;                  p->var.xoffset = 0;                  p->var.yoffset = p->yscroll*p->fontheight;                  p->var.vmode |= FB_VMODE_YWRAP;                  fb_info->updatevar(unit);                  break;               case SCROLL_YPAN:                  p->yscroll -= count;                  if (p->yscroll < 0) {                     p->yscroll = p->vrows-conp->vc_rows;                     p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, b-count,                                      conp->vc_cols);                  }                  p->var.xoffset = 0;                  p->var.yoffset = p->yscroll*p->fontheight;                  p->var.vmode &= ~FB_VMODE_YWRAP;                  fb_info->updatevar(unit);                  break;               case SCROLL_YMOVE:                  p->dispsw->bmove(p, 0, 0, count, 0, b-count, conp->vc_cols);                  break;            }         } else            fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);         /* Fixed bmove() should end Arno's frustration with copying?          * Confucius says:          *    Man who copies in wrong direction, end up with trashed data          */         fbcon_clear(conp, t, 0, count, conp->vc_cols);         break;      case SM_LEFT:         fbcon_bmove(conp, 0, t+count, 0, t, conp->vc_rows, b-t-count);         fbcon_clear(conp, 0, b-count, conp->vc_rows, count);         break;      case SM_RIGHT:         fbcon_bmove(conp, 0, t, 0, t+count, conp->vc_rows, b-t-count);         fbcon_clear(conp, 0, t, conp->vc_rows, count);         break;   }   return(0);}static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,                       int height, int width){   int unit = conp->vc_num;   struct display *p = &disp[unit];   if (!p->can_soft_blank && console_blanked)      return(0);   if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&        (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||       ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&        (dx <= p->cursor_x) && (p->cursor_x < dx+width)))      fbcon_cursor(conp, CM_ERASE);   /* Split blits that cross physical y_wrap case.    * Pathological case involves 4 blits, better to use recursive    * code rather than unrolled case    *    * Recursive invocations don't need to erase the cursor over and    * over again, so we use fbcon_bmove_rec()    */   fbcon_bmove_rec(p, sy, sx, dy, dx, height, width, p->vrows-p->yscroll);   return(0);}static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,                            int height, int width, u_int y_break){   u_int b;   if (sy < y_break && sy+height > y_break) {      b = y_break-sy;      if (dy < sy) {       /* Avoid trashing self */         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);      } else {         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);      }      return;   }   if (dy < y_break && dy+height > y_break) {      b = y_break-dy;      if (dy < sy) {       /* Avoid trashing self */         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);      } else {         fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);         fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);      }      return;   }   p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);}static int fbcon_switch(struct vc_data *conp){   if (fb_info && fb_info->switch_con)      (*fb_info->switch_con)(conp->vc_num);   return(0);}static int fbcon_blank(int blank){   struct display *p = &disp[fg_console];   fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);   if (!p->can_soft_blank)      if (blank) {         if (p->visual == FB_VISUAL_MONO01)             mymemset(p->screen_base, p->var.xres_virtual*p->var.yres_virtual*                                      p->var.bits_per_pixel>>3);          else             mymemclear(p->screen_base, p->var.xres_virtual*p->var.yres_virtual*                                        p->var.bits_per_pixel>>3);         return(0);      } else {         /* Tell console.c that it has to restore the screen itself */         return(1);      }   (*fb_info->blank)(blank);   return(0);}static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data){	int unit = conp->vc_num;	struct display *p = &disp[unit];	int i, size, alloc;	size = (p->fontwidth+7)/8 * p->fontheight * 256;	alloc = (*w+7)/8 * *h * 256;	*w = p->fontwidth;	*h = p->fontheight;   	if (alloc < size)		/* allocation length not sufficient */		return( -ENAMETOOLONG );	if ((i = verify_area( VERIFY_WRITE, (void *)data, size )))		return i;	memcpy_tofs( data, p->fontdata, size );	return( 0 );}#define REFCOUNT(fd)	(((int *)(fd))[-1])static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data){	int unit = conp->vc_num;	struct display *p = &disp[unit];	int i, size, userspace = 1, resize;	char *old_data = NULL, *new_data;	if (w < 0)		w = p->fontwidth;	if (h < 0)		h = p->fontheight;		printk("Set_font, w=%d, h=%d, data=%s\n", w, h, data);		if (w == 0) {		/* engage predefined font, name in 'data' */		char name[MAX_FONT_NAME+1];	   		if ((i = verify_area( VERIFY_READ, (void *)data, MAX_FONT_NAME )))			return i;		memcpy_fromfs( name, data, MAX_FONT_NAME );		name[sizeof(name)-1] = 0;				if (!findsoftfont( name, &w, &h, (u_char **)&data ))			return( -ENOENT );		userspace = 0;	}	else if (w == 1) {		/* copy font from some other console in 'h'*/		struct display *op;		if (h < 0 || !vc_cons_allocated( h ))			return( -ENOTTY );		if (h == unit)			return( 0 ); /* nothing to do */		op = &disp[h];		if (op->fontdata == p->fontdata)			return( 0 ); /* already the same font... */		resize = (op->fontwidth != p->fontwidth) ||			     (op->fontheight != p->fontheight);		if (p->userfont)			old_data = p->fontdata;		p->fontdata = op->fontdata;		w = p->fontwidth = op->fontwidth;		h = p->fontheight = op->fontheight;		if ((p->userfont = op->userfont))			REFCOUNT(p->fontdata)++; /* increment usage counter */		goto activate;	}	if ((p->dispsw != &dispsw_mono) && (w != 8))		/* Currently only fontwidth == 8 supported */		return( -ENXIO );	if ((p->dispsw == &dispsw_mono) && (w != 8) && (w != 4))		return( -ENXIO );			resize = (w != p->fontwidth) || (h != p->fontheight);	size = (w+7)/8 * h * 256;		if (p->userfont)		old_data = p->fontdata;		if (userspace) {		if ((i = verify_area( VERIFY_READ, (void *)data, size )))			return i;		if (!(new_data = kmalloc( sizeof(int)+size, GFP_USER )))			return( -ENOMEM );		new_data += sizeof(int);		REFCOUNT(new_data) = 1; /* usage counter */		memcpy_fromfs( new_data, data, size );		p->fontdata = new_data;		p->userfont = 1;	}	else {		p->fontdata = data;		p->userfont = 0;	}	p->fontwidth = w;	p->fontheight = h;  activate:	if (resize) {		p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */		if (divides(p->ywrapstep, p->fontheight))			p->scrollmode = SCROLL_YWRAP;		else if (divides(p->ypanstep, p->fontheight) &&				 p->var.yres_virtual >= p->var.yres+p->fontheight)			p->scrollmode = SCROLL_YPAN;		else			p->scrollmode = SCROLL_YMOVE;		vc_resize_con( p->var.yres/h, p->var.xres/w, unit );	}	else if (unit == fg_console)		update_screen( unit );		if (old_data) {		if (--REFCOUNT(old_data) == 0) {			kfree( old_data - sizeof(int) );		}	}		return( 0 );}/* ====================================================================== *//* *    Low Level Operations for the various display memory organizations. * *    Currently only the following organizations are supported here: * *      - Monochrome *      - Color Interleaved Planes 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -