Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1546 → Rev 1547

/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,23 → 39,16
#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[])
/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;
}
}