46,156 → 46,16 |
#include "helenos.xbm" |
#include "fb.h" |
|
#define EFB (-1) |
#define DEFAULT_BGCOLOR 0x000080 |
#define DEFAULT_FGCOLOR 0xffff00 |
|
#define DEFAULT_BGCOLOR 0x000080 |
#define DEFAULT_FGCOLOR 0xffff00 |
#define DEFAULT_LOGOCOLOR 0x0000ff |
|
#define MAIN_BGCOLOR 0x404000 |
#define MAIN_FGCOLOR 0x000000 |
#define MAIN_LOGOCOLOR 0x404000 |
|
#define SPACING (2) |
|
#define H_NO_VFBS 3 |
#define V_NO_VFBS 3 |
|
static void fb_putchar(int item,char ch); |
int create_window(int item,unsigned int x, unsigned int y,unsigned int x_size, unsigned int y_size, |
unsigned int BGCOLOR,unsigned int FGCOLOR,unsigned int LOGOCOLOR); |
void fb_init(int item,__address addr, unsigned int x, unsigned int y, unsigned int bpp, unsigned int scan, |
unsigned int BGCOLOR,unsigned int FGCOLOR,unsigned int LOGOCOLOR); |
|
unsigned int mod_col(unsigned int col,int mod); |
|
static int init_fb(void) |
{ |
__address fb_ph_addr; |
unsigned int fb_width; |
unsigned int fb_height; |
unsigned int fb_bpp; |
unsigned int fb_scanline; |
__address fb_addr; |
int a=0; |
int i,j,k; |
int w; |
char text[]="HelenOS Framebuffer driver\non Virtual Framebuffer\nVFB "; |
|
fb_ph_addr=sysinfo_value("fb.address.physical"); |
fb_width=sysinfo_value("fb.width"); |
fb_height=sysinfo_value("fb.height"); |
fb_bpp=sysinfo_value("fb.bpp"); |
fb_scanline=sysinfo_value("fb.scanline"); |
|
fb_addr=ALIGN_UP(((__address)set_maxheapsize(USER_ADDRESS_SPACE_SIZE_ARCH>>1)),PAGE_SIZE); |
|
map_physmem(task_get_id(),(void *)((__address)fb_ph_addr),(void *)fb_addr, |
(fb_scanline*fb_height+PAGE_SIZE-1)>>PAGE_WIDTH, |
AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE); |
|
fb_init(0,fb_addr, fb_width, fb_height, fb_bpp, fb_scanline, |
MAIN_BGCOLOR,MAIN_FGCOLOR,MAIN_LOGOCOLOR); |
|
fb_putchar(0,'\n'); |
fb_putchar(0,' '); |
|
for(i=0;i<H_NO_VFBS;i++) |
for(j=0;j<V_NO_VFBS;j++) { |
w = create_window(0,(fb_width/H_NO_VFBS)*i+SPACING, |
(fb_height/V_NO_VFBS)*j+SPACING,(fb_width/H_NO_VFBS)-2*SPACING , |
(fb_height/V_NO_VFBS)-2*SPACING,mod_col(DEFAULT_BGCOLOR,/*i+j*H_NO_VFBS*/0), |
mod_col(DEFAULT_FGCOLOR,/*i+j*H_NO_VFBS*/0), |
mod_col(DEFAULT_LOGOCOLOR,/*i+j*H_NO_VFBS)*/0)); |
|
if( w== EFB) |
return -1; |
|
for(k=0;text[k];k++) |
fb_putchar(w,text[k]); |
fb_putchar(w,w+'0'); |
fb_putchar(w,'\n'); |
} |
return 0; |
} |
|
int vfb_no = 1; |
void client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
int vfb = vfb_no++; |
|
if (vfb > VFB_CONNECTIONS) { |
ipc_answer_fast(iid, ELIMIT, 0,0); |
return; |
} |
ipc_answer_fast(iid, 0, 0, 0); |
|
while (1) { |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
ipc_answer_fast(callid,0,0,0); |
return; /* Exit thread */ |
|
case FB_PUTCHAR: |
fb_putchar(vfb,IPC_GET_ARG2(call)); |
ipc_answer_fast(callid,0,0,0); |
break; |
/* |
* case FB_CLEAR: |
ipc_answer_fast(callid,0,0,0); |
fb_putchar(vfb,IPC_GET_ARG2(call)); |
break; |
* case FB_GOTO: |
ipc_answer_fast(callid,0,0,0); |
fb_putchar(vfb,IPC_GET_ARG2(call)); |
break; |
*/ |
default: |
ipc_answer_fast(callid,ENOENT,0,0); |
} |
} |
} |
|
int main(int argc, char *argv[]) |
{ |
ipc_call_t call; |
ipc_callid_t callid; |
char connected = 0; |
int res; |
int c; |
ipcarg_t phonead; |
|
ipcarg_t retval, arg1, arg2; |
|
if(!sysinfo_value("fb")) |
return -1; |
|
if ((res = ipc_connect_to_me(PHONE_NS, SERVICE_VIDEO, 0, &phonead)) != 0) |
return -1; |
|
if (init_fb() != 0) |
return -1; |
|
async_manager(); |
/* Never reached */ |
return 0; |
} |
|
|
#define GRAPHICS_ITEMS 1024 |
|
|
/***************************************************************/ |
/* Pixel specific fuctions */ |
|
typedef void (*putpixel_fn_t)(int item,unsigned int x, unsigned int y, int color); |
typedef int (*getpixel_fn_t)(int item,unsigned int x, unsigned int y); |
typedef void (*putpixel_fn_t)(unsigned int x, unsigned int y, int color); |
typedef int (*getpixel_fn_t)(unsigned int x, unsigned int y); |
|
typedef struct framebuffer_descriptor |
{ |
struct { |
__u8 *fbaddress ; |
|
unsigned int xres ; |
203,65 → 63,69 |
unsigned int scanline ; |
unsigned int pixelbytes ; |
|
unsigned int position ; |
unsigned int columns ; |
unsigned int rows ; |
|
unsigned int BGCOLOR; |
unsigned int FGCOLOR; |
unsigned int LOGOCOLOR; |
|
putpixel_fn_t putpixel; |
getpixel_fn_t getpixel; |
|
}framebuffer_descriptor_t; |
} screen; |
|
void * graphics_items[GRAPHICS_ITEMS+1]={NULL}; |
typedef struct { |
int initialized; |
unsigned int x, y; |
unsigned int width, height; |
|
#define FB(__a__,__b__) (((framebuffer_descriptor_t*)(graphics_items[__a__]))->__b__) |
/* Text support in window */ |
unsigned int rows, cols; |
/* Style for text printing */ |
int bgcolor, fgcolor; |
/* Auto-cursor position */ |
int cursor_active, cur_x, cur_y; |
} viewport_t; |
|
#define COL_WIDTH 8 |
#define ROW_BYTES (FB(item,scanline) * FONT_SCANLINES) |
#define MAX_VIEWPORTS 128 |
static viewport_t viewports[128]; |
|
/* Allow only 1 connection */ |
static int client_connected = 0; |
|
#define RED(x, bits) ((x >> (16 + 8 - bits)) & ((1 << bits) - 1)) |
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
|
#define POINTPOS(x, y) (y * FB(item,scanline) + x * FB(item,pixelbytes)) |
#define COL_WIDTH 8 |
#define ROW_BYTES (screen.scanline * FONT_SCANLINES) |
|
#define POINTPOS(x, y) ((y) * screen.scanline + (x) * screen.pixelbytes) |
|
|
|
/** Put pixel - 24-bit depth, 1 free byte */ |
static void putpixel_4byte(int item,unsigned int x, unsigned int y, int color) |
static void putpixel_4byte(unsigned int x, unsigned int y, int color) |
{ |
*((__u32 *)(FB(item,fbaddress) + POINTPOS(x, y))) = color; |
*((__u32 *)(screen.fbaddress + POINTPOS(x, y))) = color; |
} |
|
/** Return pixel color - 24-bit depth, 1 free byte */ |
static int getpixel_4byte(int item,unsigned int x, unsigned int y) |
static int getpixel_4byte(unsigned int x, unsigned int y) |
{ |
return *((__u32 *)(FB(item,fbaddress) + POINTPOS(x, y))) & 0xffffff; |
return *((__u32 *)(screen.fbaddress + POINTPOS(x, y))) & 0xffffff; |
} |
|
/** Put pixel - 24-bit depth */ |
static void putpixel_3byte(int item,unsigned int x, unsigned int y, int color) |
static void putpixel_3byte(unsigned int x, unsigned int y, int color) |
{ |
unsigned int startbyte = POINTPOS(x, y); |
|
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN)) |
FB(item,fbaddress)[startbyte] = RED(color, 8); |
FB(item,fbaddress)[startbyte + 1] = GREEN(color, 8); |
FB(item,fbaddress)[startbyte + 2] = BLUE(color, 8); |
screen.fbaddress[startbyte] = RED(color, 8); |
screen.fbaddress[startbyte + 1] = GREEN(color, 8); |
screen.fbaddress[startbyte + 2] = BLUE(color, 8); |
#else |
FB(item,fbaddress)[startbyte + 2] = RED(color, 8); |
FB(item,fbaddress)[startbyte + 1] = GREEN(color, 8); |
FB(item,fbaddress)[startbyte + 0] = BLUE(color, 8); |
screen.fbaddress[startbyte + 2] = RED(color, 8); |
screen.fbaddress[startbyte + 1] = GREEN(color, 8); |
screen.fbaddress[startbyte + 0] = BLUE(color, 8); |
#endif |
|
} |
|
/** Return pixel color - 24-bit depth */ |
static int getpixel_3byte(int item,unsigned int x, unsigned int y) |
static int getpixel_3byte(unsigned int x, unsigned int y) |
{ |
unsigned int startbyte = POINTPOS(x, y); |
|
268,9 → 132,9 |
|
|
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN)) |
return FB(item,fbaddress)[startbyte] << 16 | FB(item,fbaddress)[startbyte + 1] << 8 | FB(item,fbaddress)[startbyte + 2]; |
return screen.fbaddress[startbyte] << 16 | screen.fbaddress[startbyte + 1] << 8 | screen.fbaddress[startbyte + 2]; |
#else |
return FB(item,fbaddress)[startbyte + 2] << 16 | FB(item,fbaddress)[startbyte + 1] << 8 | FB(item,fbaddress)[startbyte + 0]; |
return screen.fbaddress[startbyte + 2] << 16 | screen.fbaddress[startbyte + 1] << 8 | screen.fbaddress[startbyte + 0]; |
#endif |
|
|
277,86 → 141,124 |
} |
|
/** Put pixel - 16-bit depth (5:6:5) */ |
static void putpixel_2byte(int item,unsigned int x, unsigned int y, int color) |
static void putpixel_2byte(unsigned int x, unsigned int y, int color) |
{ |
/* 5-bit, 6-bits, 5-bits */ |
*((__u16 *)(FB(item,fbaddress) + POINTPOS(x, y))) = RED(color, 5) << 11 | GREEN(color, 6) << 5 | BLUE(color, 5); |
*((__u16 *)(screen.fbaddress + POINTPOS(x, y))) = RED(color, 5) << 11 | GREEN(color, 6) << 5 | BLUE(color, 5); |
} |
|
/** Return pixel color - 16-bit depth (5:6:5) */ |
static int getpixel_2byte(int item,unsigned int x, unsigned int y) |
static int getpixel_2byte(unsigned int x, unsigned int y) |
{ |
int color = *((__u16 *)(FB(item,fbaddress) + POINTPOS(x, y))); |
int color = *((__u16 *)(screen.fbaddress + POINTPOS(x, y))); |
return (((color >> 11) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3); |
} |
|
/** Put pixel - 8-bit depth (3:2:3) */ |
static void putpixel_1byte(int item,unsigned int x, unsigned int y, int color) |
static void putpixel_1byte(unsigned int x, unsigned int y, int color) |
{ |
FB(item,fbaddress)[POINTPOS(x, y)] = RED(color, 3) << 5 | GREEN(color, 2) << 3 | BLUE(color, 3); |
screen.fbaddress[POINTPOS(x, y)] = RED(color, 3) << 5 | GREEN(color, 2) << 3 | BLUE(color, 3); |
} |
|
/** Return pixel color - 8-bit depth (3:2:3) */ |
static int getpixel_1byte(int item,unsigned int x, unsigned int y) |
static int getpixel_1byte(unsigned int x, unsigned int y) |
{ |
int color = FB(item,fbaddress)[POINTPOS(x, y)]; |
int color = screen.fbaddress[POINTPOS(x, y)]; |
return (((color >> 5) & 0x7) << (16 + 5)) | (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5); |
} |
|
static void putpixel(int vp, unsigned int x, unsigned int y, int color) |
{ |
screen.putpixel(viewports[vp].x + x, viewports[vp].y + y, color); |
} |
static int getpixel(int vp, unsigned int x, unsigned int y) |
{ |
return screen.getpixel(viewports[vp].x + x, viewports[vp].y + y); |
} |
|
/** Fill line with color BGCOLOR */ |
static void clear_line(int item,unsigned int y) |
static void clear_line(int vp, unsigned int y) |
{ |
unsigned int x; |
for (x = 0; x < FB(item,xres); x++) |
FB(item,putpixel)(item,x, y, FB(item,BGCOLOR)); |
for (x = 0; x < viewports[vp].width; x++) |
putpixel(vp, x, y, viewports[vp].bgcolor); |
} |
|
|
/** Fill screen with background color */ |
static void clear_screen(int item) |
/** Fill viewport with background color */ |
static void clear_port(int vp) |
{ |
unsigned int y; |
for (y = 0; y < FB(item,yres); y++) |
{ |
clear_line(item,y); |
|
clear_line(vp, 0); |
for (y = viewports[vp].y+1; y < viewports[vp].y+viewports[vp].height; y++) { |
memcpy(&screen.fbaddress[POINTPOS(viewports[vp].x,y)], |
&screen.fbaddress[POINTPOS(viewports[vp].x,viewports[vp].y)], |
screen.pixelbytes * viewports[vp].width); |
} |
} |
|
/** Optimized scroll for windows that cover whole lines */ |
//static void scroll_optim(int vp, int rows) |
//{ |
/* TODO */ |
//} |
|
/** Scroll screen one row up */ |
static void scroll_screen(int item) |
/** Scroll port up/down |
* |
* @param vp Viewport to scroll |
* @param rows Positive number - scroll up, negative - scroll down |
*/ |
static void scroll_port(int vp, int rows) |
{ |
unsigned int i; |
unsigned int j; |
|
for(j=0;j<FB(item,yres)-FONT_SCANLINES;j++) |
memcpy((void *) FB(item,fbaddress)+j*FB(item,scanline), |
(void *) &FB(item,fbaddress)[ROW_BYTES+j*FB(item,scanline)], FB(item,pixelbytes)*FB(item,xres)); |
|
//memcpy((void *) FB(item,fbaddress), (void *) &FB(item,fbaddress)[ROW_BYTES], FB(item,scanline) * FB(item,yres) - ROW_BYTES); |
|
/* Clear last row */ |
for (i = 0; i < FONT_SCANLINES; i++) |
clear_line(item,(FB(item,rows) - 1) * FONT_SCANLINES + i); |
int y; |
int startline; |
int endline; |
|
if (rows > 0) { |
for (y=viewports[vp].y; y < viewports[vp].y+viewports[vp].height - rows*FONT_SCANLINES; y++) |
memcpy(&screen.fbaddress[POINTPOS(viewports[vp].x,y)], |
&screen.fbaddress[POINTPOS(viewports[vp].x,y + rows*FONT_SCANLINES)], |
screen.pixelbytes * viewports[vp].width); |
/* Clear last row */ |
startline = viewports[vp].y+FONT_SCANLINES*(viewports[vp].rows-1); |
endline = viewports[vp].y + viewports[vp].height; |
clear_line(vp, startline); |
for (y=startline+1;y < endline; y++) |
memcpy(&screen.fbaddress[POINTPOS(viewports[vp].x,y)], |
&screen.fbaddress[POINTPOS(viewports[vp].x,startline)], |
screen.pixelbytes * viewports[vp].width); |
|
} else if (rows < 0) { |
rows = -rows; |
for (y=viewports[vp].y + viewports[vp].height-1; y >= viewports[vp].y + rows*FONT_SCANLINES; y--) |
memcpy(&screen.fbaddress[POINTPOS(viewports[vp].x,y)], |
&screen.fbaddress[POINTPOS(viewports[vp].x,y - rows*FONT_SCANLINES)], |
screen.pixelbytes * viewports[vp].width); |
/* Clear first row */ |
clear_line(0, viewports[vp].bgcolor); |
for (y=1;y < rows*FONT_SCANLINES; y++) |
memcpy(&screen.fbaddress[POINTPOS(viewports[vp].x,viewports[vp].y+y)], |
&screen.fbaddress[POINTPOS(viewports[vp].x,viewports[vp].y)], |
screen.pixelbytes * viewports[vp].width); |
} |
} |
|
|
static void invert_pixel(int item,unsigned int x, unsigned int y) |
static void invert_pixel(int vp,unsigned int x, unsigned int y) |
{ |
FB(item,putpixel)(item, x, y, ~FB(item,getpixel)(item, x, y)); |
putpixel(vp, x, y, ~getpixel(vp, x, y)); |
} |
|
|
/** Draw one line of glyph at a given position */ |
static void draw_glyph_line(int item,unsigned int glline, unsigned int x, unsigned int y) |
static void draw_glyph_line(int vp,unsigned int glline, unsigned int x, unsigned int y) |
{ |
unsigned int i; |
|
for (i = 0; i < 8; i++) |
if (glline & (1 << (7 - i))) { |
FB(item,putpixel)(item,x + i, y, FB(item,FGCOLOR)); |
putpixel(vp, x + i, y, viewports[vp].fgcolor); |
} else |
FB(item,putpixel)(item,x + i, y, FB(item,BGCOLOR)); |
putpixel(vp, x + i, y, viewports[vp].bgcolor); |
} |
|
/***************************************************************/ |
363,16 → 265,16 |
/* Character-console functions */ |
|
/** Draw character at given position */ |
static void draw_glyph(int item,__u8 glyph, unsigned int col, unsigned int row) |
static void draw_glyph(int vp,__u8 glyph, unsigned int row, unsigned int col) |
{ |
unsigned int y; |
|
for (y = 0; y < FONT_SCANLINES; y++) |
draw_glyph_line(item ,fb_font[glyph * FONT_SCANLINES + y], col * COL_WIDTH, row * FONT_SCANLINES + y); |
draw_glyph_line(vp ,fb_font[glyph * FONT_SCANLINES + y], col * COL_WIDTH, row * FONT_SCANLINES + y); |
} |
|
/** Invert character at given position */ |
static void invert_char(int item,unsigned int col, unsigned int row) |
static void invert_char(int vp,unsigned int col, unsigned int row) |
{ |
unsigned int x; |
unsigned int y; |
379,17 → 281,11 |
|
for (x = 0; x < COL_WIDTH; x++) |
for (y = 0; y < FONT_SCANLINES; y++) |
invert_pixel(item,col * COL_WIDTH + x, row * FONT_SCANLINES + y); |
invert_pixel(vp, col * COL_WIDTH + x, row * FONT_SCANLINES + y); |
} |
|
/** Draw character at default position */ |
static void draw_char(int item,char chr) |
static void draw_logo(int vp,unsigned int startx, unsigned int starty) |
{ |
draw_glyph(item ,chr, FB(item,position) % FB(item,columns), FB(item,position) / FB(item,columns)); |
} |
|
static void draw_logo(int item,unsigned int startx, unsigned int starty) |
{ |
unsigned int x; |
unsigned int y; |
unsigned int byte; |
402,7 → 298,7 |
byte = helenos_bits[rowbytes * y + x / 8]; |
byte >>= x % 8; |
if (byte & 1) |
FB(item,putpixel)(item,startx + x, starty + y, FB(item,LOGOCOLOR)); |
putpixel(vp ,startx + x, starty + y, viewports[vp].fgcolor); |
} |
} |
|
409,52 → 305,36 |
/***************************************************************/ |
/* Stdout specific functions */ |
|
static void invert_cursor(int item) |
{ |
invert_char(item,FB(item,position) % FB(item,columns), FB(item,position) / FB(item,columns)); |
} |
|
/** Print character to screen |
/** Create new viewport |
* |
* Emulate basic terminal commands |
* @return New viewport number |
*/ |
static void fb_putchar(int item,char ch) |
static int viewport_create(unsigned int x, unsigned int y,unsigned int width, |
unsigned int height) |
{ |
|
switch (ch) { |
case '\n': |
invert_cursor(item); |
FB(item,position) += FB(item,columns); |
FB(item,position) -= FB(item,position) % FB(item,columns); |
int i; |
|
for (i=0; i < MAX_VIEWPORTS; i++) { |
if (!viewports[i].initialized) |
break; |
case '\r': |
invert_cursor(item); |
FB(item,position) -= FB(item,position) % FB(item,columns); |
break; |
case '\b': |
invert_cursor(item); |
if (FB(item,position) % FB(item,columns)) |
FB(item,position)--; |
break; |
case '\t': |
invert_cursor(item); |
do { |
draw_char(item,' '); |
FB(item,position)++; |
} while (FB(item,position) % 8); |
break; |
default: |
draw_char(item,ch); |
FB(item,position)++; |
} |
if (i == MAX_VIEWPORTS) |
return ELIMIT; |
|
viewports[i].initialized = 1; |
viewports[i].x = x; |
viewports[i].y = y; |
viewports[i].width = width; |
viewports[i].height = height; |
|
if (FB(item,position) >= FB(item,columns) * FB(item,rows)) { |
FB(item,position) -= FB(item,columns); |
scroll_screen(item); |
} |
viewports[i].rows = height / FONT_SCANLINES; |
viewports[i].cols = width / COL_WIDTH; |
|
viewports[i].bgcolor = DEFAULT_BGCOLOR; |
viewports[i].fgcolor = DEFAULT_FGCOLOR; |
|
invert_cursor(item); |
|
return i; |
} |
|
|
467,115 → 347,147 |
* @param scan Bytes per one scanline |
* |
*/ |
void fb_init(int item,__address addr, unsigned int x, unsigned int y, unsigned int bpp, unsigned int scan, |
unsigned int BGCOLOR,unsigned int FGCOLOR,unsigned int LOGOCOLOR) |
static void screen_init(__address addr, unsigned int xres, unsigned int yres, unsigned int bpp, unsigned int scan) |
{ |
|
if( (graphics_items[item]=malloc(sizeof(framebuffer_descriptor_t))) ==NULL) |
{ |
return; |
} |
|
switch (bpp) { |
case 8: |
FB(item,putpixel) = putpixel_1byte; |
FB(item,getpixel) = getpixel_1byte; |
FB(item,pixelbytes) = 1; |
screen.putpixel = putpixel_1byte; |
screen.getpixel = getpixel_1byte; |
screen.pixelbytes = 1; |
break; |
case 16: |
FB(item,putpixel) = putpixel_2byte; |
FB(item,getpixel) = getpixel_2byte; |
FB(item,pixelbytes) = 2; |
screen.putpixel = putpixel_2byte; |
screen.getpixel = getpixel_2byte; |
screen.pixelbytes = 2; |
break; |
case 24: |
FB(item,putpixel) = putpixel_3byte; |
FB(item,getpixel) = getpixel_3byte; |
FB(item,pixelbytes) = 3; |
screen.putpixel = putpixel_3byte; |
screen.getpixel = getpixel_3byte; |
screen.pixelbytes = 3; |
break; |
case 32: |
FB(item,putpixel) = putpixel_4byte; |
FB(item,getpixel) = getpixel_4byte; |
FB(item,pixelbytes) = 4; |
screen.putpixel = putpixel_4byte; |
screen.getpixel = getpixel_4byte; |
screen.pixelbytes = 4; |
break; |
} |
|
|
FB(item,fbaddress) = (unsigned char *) addr; |
FB(item,xres) = x; |
FB(item,yres) = y; |
FB(item,scanline) = scan; |
screen.fbaddress = (unsigned char *) addr; |
screen.xres = xres; |
screen.yres = yres; |
screen.scanline = scan; |
|
|
FB(item,rows) = y / FONT_SCANLINES; |
FB(item,columns) = x / COL_WIDTH; |
/* Create first viewport */ |
viewport_create(0,0,xres,yres); |
|
FB(item,BGCOLOR)=BGCOLOR; |
FB(item,FGCOLOR)=FGCOLOR; |
FB(item,LOGOCOLOR)=LOGOCOLOR; |
clear_port(0); |
} |
|
static int init_fb(void) |
{ |
__address fb_ph_addr; |
unsigned int fb_width; |
unsigned int fb_height; |
unsigned int fb_bpp; |
unsigned int fb_scanline; |
__address fb_addr; |
int a=0; |
int i,j,k; |
int w; |
char text[]="HelenOS Framebuffer driver\non Virtual Framebuffer\nVFB "; |
|
clear_screen(item); |
draw_logo(item,FB(item,xres) - helenos_width, 0); |
invert_cursor(item); |
fb_ph_addr=sysinfo_value("fb.address.physical"); |
fb_width=sysinfo_value("fb.width"); |
fb_height=sysinfo_value("fb.height"); |
fb_bpp=sysinfo_value("fb.bpp"); |
fb_scanline=sysinfo_value("fb.scanline"); |
|
} |
fb_addr=ALIGN_UP(((__address)set_maxheapsize(USER_ADDRESS_SPACE_SIZE_ARCH>>1)),PAGE_SIZE); |
|
map_physmem(task_get_id(),(void *)((__address)fb_ph_addr),(void *)fb_addr, |
(fb_scanline*fb_height+PAGE_SIZE-1)>>PAGE_WIDTH, |
AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE); |
|
screen_init(fb_addr, fb_width, fb_height, fb_bpp, fb_scanline); |
|
|
static int get_free_item() |
{ |
int item; |
for(item=0;graphics_items[item]!=NULL;item++); |
return (item==GRAPHICS_ITEMS)?EFB:item; |
return 0; |
} |
|
unsigned int mod_col(unsigned int col,int mod) |
void client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
if(mod & 1) col^=0xff; |
if(mod & 2) col^=0xff00; |
if(mod & 4) col^=0xff0000; |
return col; |
} |
ipc_callid_t callid; |
ipc_call_t call; |
int retval; |
int i; |
unsigned int row,col; |
char c; |
int vp = 0; |
|
if (client_connected) { |
ipc_answer_fast(iid, ELIMIT, 0,0); |
return; |
} |
ipc_answer_fast(iid, 0, 0, 0); /* Accept connection */ |
|
int create_window(int item,unsigned int x, unsigned int y,unsigned int x_size, unsigned int y_size, |
unsigned int BGCOLOR,unsigned int FGCOLOR,unsigned int LOGOCOLOR) |
{ |
int item_new; |
|
if(EFB==(item_new=get_free_item()))return EFB; |
|
|
if( (graphics_items[item_new]=malloc(sizeof(framebuffer_descriptor_t))) == NULL) |
{ |
return EFB; |
while (1) { |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
client_connected = 0; |
/* cleanup other viewports */ |
for (i=1; i < MAX_VIEWPORTS; i++) |
viewports[i].initialized = 0; |
ipc_answer_fast(callid,0,0,0); |
return; /* Exit thread */ |
case FB_PUTCHAR: |
c = IPC_GET_ARG1(call); |
row = IPC_GET_ARG2(call); |
col = IPC_GET_ARG3(call); |
if (row >= viewports[vp].rows || col >= viewports[vp].cols) { |
retval = EINVAL; |
break; |
} |
ipc_answer_fast(callid,0,0,0); |
draw_glyph(vp,c, row, col); |
continue; /* msg already answered */ |
case FB_CLEAR: |
clear_port(vp); |
retval = 0; |
break; |
/* case FB_CURSOR_GOTO: */ |
/* retval = 0; */ |
/* break; */ |
/* case FB_CURSOR_VISIBILITY: */ |
/* retval = 0; */ |
/* break; */ |
case FB_GET_CSIZE: |
ipc_answer_fast(callid, 0, viewports[vp].rows, viewports[vp].cols); |
continue; |
default: |
retval = ENOENT; |
} |
retval = ENOENT; |
ipc_answer_fast(callid,retval,0,0); |
} |
|
|
|
FB(item_new,putpixel) = FB(item,putpixel); |
FB(item_new,getpixel) = FB(item,getpixel); |
FB(item_new,pixelbytes) = FB(item,pixelbytes); |
} |
|
FB(item_new,fbaddress) = FB(item,fbaddress) + POINTPOS(x, y) ; |
FB(item_new,xres) = x_size; |
FB(item_new,yres) = y_size; |
FB(item_new,scanline) = FB(item,scanline); |
|
int main(int argc, char *argv[]) |
{ |
char connected = 0; |
int res; |
ipcarg_t phonead; |
|
FB(item_new,rows) = y_size / FONT_SCANLINES; |
FB(item_new,columns) = x_size / COL_WIDTH; |
if(!sysinfo_value("fb")) |
return -1; |
|
FB(item_new,BGCOLOR)=BGCOLOR; |
FB(item_new,FGCOLOR)=FGCOLOR; |
FB(item_new,LOGOCOLOR)=LOGOCOLOR; |
if ((res = ipc_connect_to_me(PHONE_NS, SERVICE_VIDEO, 0, &phonead)) != 0) |
return -1; |
|
if (init_fb() != 0) |
return -1; |
|
|
clear_screen(item_new); |
draw_logo(item_new,FB(item_new,xres) - helenos_width, 0); |
invert_cursor(item_new); |
|
return item_new; |
async_manager(); |
/* Never reached */ |
return 0; |
} |
|
|
|