/uspace/trunk/fb/ppm.h |
---|
0,0 → 1,37 |
/* |
* Copyright (C) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef _PPM_H_ |
#define _PPM_H_ |
int draw_ppm(unsigned char *data, size_t datasz, unsigned int sx, |
unsigned int sy, |
unsigned int maxwidth, unsigned int maxheight, |
void (*putpixel)(int,unsigned int, unsigned int, int),int vp); |
#endif |
/uspace/trunk/fb/main.c |
---|
39,25 → 39,18 |
#include "ega.h" |
#include "main.h" |
void receive_comm_area(ipc_callid_t callid, ipc_call_t *call, void **area, |
size_t maxsize) |
void receive_comm_area(ipc_callid_t callid, ipc_call_t *call, void **area) |
{ |
void *dest; |
if (*area) { |
ipc_answer_fast(callid, ELIMIT, 0, 0); |
return; |
dest = as_get_mappable_page(IPC_GET_ARG2(*call)); |
if (ipc_answer_fast(callid, 0, (sysarg_t)dest, 0) == 0) { |
if (*area) |
as_area_destroy(*area); |
*area = dest; |
} |
if (IPC_GET_ARG2(*call) > ALIGN_UP(maxsize, PAGE_SIZE)) { |
ipc_answer_fast(callid, EINVAL, 0, 0); |
return; |
} |
dest = as_get_mappable_page(maxsize); |
if (ipc_answer_fast(callid, 0, (sysarg_t)dest, 0) == 0) |
*area = dest; |
} |
int main(int argc, char *argv[]) |
{ |
ipcarg_t phonead; |
/uspace/trunk/fb/fb.c |
---|
46,6 → 46,7 |
#include "fb.h" |
#include "main.h" |
#include "../console/screenbuffer.h" |
#include "ppm.h" |
#define DEFAULT_BGCOLOR 0x000080 |
#define DEFAULT_FGCOLOR 0xffff00 |
474,7 → 475,89 |
cursor_print(vp); |
} |
static int shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
{ |
static keyfield_t *interbuffer = NULL; |
static size_t intersize = 0; |
static char *pixmap = NULL; |
static ipcarg_t pixmap_id = 0; |
static size_t pixmap_size; |
int handled = 1; |
int retval = 0; |
viewport_t *vport = &viewports[vp]; |
unsigned int x,y; |
switch (IPC_GET_METHOD(*call)) { |
case IPC_M_AS_AREA_SEND: |
/* We accept one area for data interchange */ |
if (IPC_GET_ARG1(*call) == pixmap_id) { |
void *dest = as_get_mappable_page(IPC_GET_ARG2(*call)); |
pixmap_size = IPC_GET_ARG2(*call); |
if (!ipc_answer_fast(callid, 0, (sysarg_t)dest, 0)) |
pixmap = dest; |
else |
pixmap_id = 0; |
if (pixmap[0] != 'P') |
while (1) |
; |
return 1; |
} else { |
intersize = IPC_GET_ARG2(*call); |
receive_comm_area(callid,call,(void **)&interbuffer); |
} |
return 1; |
case FB_PREPARE_SHM: |
if (pixmap_id) |
retval = EBUSY; |
else |
pixmap_id = IPC_GET_ARG1(*call); |
break; |
case FB_DROP_SHM: |
if (pixmap) { |
as_area_destroy(pixmap); |
pixmap = NULL; |
} |
pixmap_id = 0; |
break; |
case FB_DRAW_PPM: |
if (!pixmap) { |
retval = EINVAL; |
break; |
} |
x = IPC_GET_ARG1(*call); |
y = IPC_GET_ARG2(*call); |
if (x > vport->width || y > vport->height) { |
retval = EINVAL; |
break; |
} |
draw_ppm(pixmap, pixmap_size, IPC_GET_ARG1(*call), IPC_GET_ARG2(*call), |
vport->width - x, vport->height - y, putpixel, vp); |
break; |
case FB_DRAW_TEXT_DATA: |
if (!interbuffer) { |
retval = EINVAL; |
break; |
} |
if (intersize < vport->cols*vport->rows*sizeof(*interbuffer)) { |
retval = EINVAL; |
break; |
} |
draw_text_data(vp, interbuffer); |
break; |
default: |
handled = 0; |
} |
if (handled) |
ipc_answer_fast(callid, retval, 0, 0); |
return handled; |
} |
/** Function for handling connections to FB |
* |
*/ |
486,8 → 569,6 |
int i; |
unsigned int row,col; |
char c; |
keyfield_t *interbuffer = NULL; |
size_t intersize = 0; |
int vp = 0; |
viewport_t *vport = &viewports[0]; |
505,6 → 586,9 |
cursor_blink(vp); |
continue; |
} |
if (shm_handle(callid, &call, vp)) |
continue; |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
client_connected = 0; |
513,25 → 597,7 |
vport->initialized = 0; |
ipc_answer_fast(callid,0,0,0); |
return; /* Exit thread */ |
case IPC_M_AS_AREA_SEND: |
/* We accept one area for data interchange */ |
intersize = IPC_GET_ARG2(call); |
receive_comm_area(callid,&call,(void **)&interbuffer, |
sizeof(*interbuffer)*viewports[0].cols*viewports[0].rows); |
continue; |
case FB_DRAW_TEXT_DATA: |
if (!interbuffer) { |
retval = EINVAL; |
break; |
} |
if (intersize < vport->cols*vport->rows*sizeof(*interbuffer)) { |
retval = EINVAL; |
break; |
} |
draw_text_data(vp, interbuffer); |
retval = 0; |
break; |
case FB_PUTCHAR: |
c = IPC_GET_ARG1(call); |
row = IPC_GET_ARG2(call); |
/uspace/trunk/fb/main.h |
---|
29,7 → 29,6 |
#ifndef __MAIN_H_ |
#define __MAIN_H_ |
void receive_comm_area(ipc_callid_t callid, ipc_call_t *call, void **area, |
size_t maxsize); |
void receive_comm_area(ipc_callid_t callid, ipc_call_t *call, void **area); |
#endif |
/uspace/trunk/fb/Makefile |
---|
49,7 → 49,8 |
font-8x16.c \ |
main.c \ |
sysio.c \ |
ega.c |
ega.c \ |
ppm.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
/uspace/trunk/fb/ega.c |
---|
110,7 → 110,7 |
/* We accept one area for data interchange */ |
intersize = IPC_GET_ARG2(call); |
if (intersize >= scr_width*scr_height*sizeof(*interbuf)) { |
receive_comm_area(callid,&call,(void **)&interbuf, scr_width*scr_height*sizeof(*interbuf)); |
receive_comm_area(callid,&call,(void **)&interbuf); |
continue; |
} |
retval = EINVAL; |
/uspace/trunk/fb/ppm.c |
---|
0,0 → 1,112 |
/* |
* Copyright (C) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <types.h> |
#include <errno.h> |
#include "ppm.h" |
static void skip_whitespace(unsigned char **data) |
{ |
retry: |
while (**data == ' ' || **data == '\t' || **data == '\n' || **data == '\r') |
(*data)++; |
if (**data == '#') { |
while (1) { |
if (**data == '\n' || **data == '\r') |
break; |
(*data)++; |
} |
goto retry; |
} |
} |
static void read_num(unsigned char **data, unsigned int *num) |
{ |
*num = 0; |
while (**data >= '0' && **data <= '9') { |
*num *= 10; |
*num += **data - '0'; |
(*data)++; |
} |
} |
/** Draw PPM pixmap |
* |
* @param data Pointer to PPM data |
* @param datasz Maximum data size |
* @param x Coordinate of upper left corner |
* @param y Coordinate of upper left corner |
* @param maxwidth Maximum allowed width for picture |
* @param maxheight Maximum allowed height for picture |
* @param putpixel Putpixel function used to print bitmap |
*/ |
int draw_ppm(unsigned char *data, size_t datasz, unsigned int sx, |
unsigned int sy, |
unsigned int maxwidth, unsigned int maxheight, |
void (*putpixel)(int,unsigned int, unsigned int, int),int vp) |
{ |
unsigned int width, height; |
unsigned int maxcolor; |
int i; |
void *maxdatap = data + datasz; |
unsigned int color; |
unsigned int coef; |
/* Read magic */ |
if (data[0] != 'P' || data[1] != '6') |
return EINVAL; |
data+=2; |
skip_whitespace(&data); |
read_num(&data, &width); |
skip_whitespace(&data); |
read_num(&data,&height); |
skip_whitespace(&data); |
read_num(&data,&maxcolor); |
data++; |
if (maxcolor == 0 || maxcolor > 255 || width*height > datasz) { |
return EINVAL; |
} |
coef = 255/maxcolor; |
if (coef*maxcolor > 255) |
coef -= 1; |
for (i=0; i < width*height; i++) { |
/* Crop picture if we don't fit into region */ |
if (i % width > maxwidth || i/width > maxheight) { |
data += 3; |
continue; |
} |
color = ((data[0]*coef) << 16) + ((data[1]*coef) << 8) + data[0]*coef; |
(*putpixel)(vp, sx+(i % width), sy+(i / width), color); |
data += 3; |
} |
} |