From 252cb9023289ad2af5993cf53c0d0fd7293cff27 Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Tue, 20 Jan 2004 04:51:39 +0000 Subject: [lcd4linux @ 2004-01-20 04:51:39 by reinelt] moved generic stuff from drv_MatrixOrbital to drv_generic implemented new-stylish bars which are nearly finished --- drv_generic_bar.c | 471 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 471 insertions(+) create mode 100644 drv_generic_bar.c (limited to 'drv_generic_bar.c') diff --git a/drv_generic_bar.c b/drv_generic_bar.c new file mode 100644 index 0000000..0bf3f7e --- /dev/null +++ b/drv_generic_bar.c @@ -0,0 +1,471 @@ +/* $Id: drv_generic_bar.c,v 1.1 2004/01/20 04:51:39 reinelt Exp $ + * + * generic driver helper for bar creation + * + * Copyright 1999, 2000 Michael Reinelt + * Copyright 2004 The LCD4Linux Team + * + * This file is part of LCD4Linux. + * + * LCD4Linux is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * LCD4Linux is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * $Log: drv_generic_bar.c,v $ + * Revision 1.1 2004/01/20 04:51:39 reinelt + * moved generic stuff from drv_MatrixOrbital to drv_generic + * implemented new-stylish bars which are nearly finished + * + */ + +/* + * + * exported fuctions: + * + * Fixme: document me! + * + */ + +#include +#include +#include + +#include "debug.h" +#include "drv.h" +#include "widget.h" +#include "widget_bar.h" +#include "drv_generic.h" +#include "drv_generic_bar.h" + + +typedef struct { + int val1; + int val2; + DIRECTION dir; + int segment; +} BAR; + +typedef struct { + int val1; + int val2; + DIRECTION dir; + int used; + int ascii; +} SEGMENT; + + +static int RES; + +static int nSegment=0; +static int fSegment=0; +static SEGMENT Segment[128]; + +static BAR *Bar=NULL; + + +int drv_generic_text_bar_init (void) +{ + if (Bar) free (Bar); + + if ((Bar=malloc (LROWS*LCOLS*sizeof(BAR)))==NULL) { + error ("bar buffer allocation failed: out of memory"); + return -1; + } + + nSegment=0; + fSegment=0; + + drv_generic_text_bar_clear(); + + return 0; +} + + +void drv_generic_text_bar_clear(void) +{ + int i; + + for (i=0; i 0 && col < LCOLS) { + Bar[row*LCOLS+col].dir=dir; + Bar[row*LCOLS+col].segment=-1; + if (val1 >= XRES) { + Bar[row*LCOLS+col].val1 = rev?0:XRES; + val1 -= XRES; + } else { + Bar[row*LCOLS+col].val1 = rev?XRES-val1:val1; + val1 = 0; + } + if (val2 >= XRES) { + Bar[row*LCOLS+col].val2 = rev?0:XRES; + val2 -= XRES; + } else { + Bar[row*LCOLS+col].val2 = rev?XRES-val2:val2; + val2 = 0; + } + len--; + col++; + } + break; + + case DIR_SOUTH: + val1 = len-val1; + val2 = len-val2; + rev = 1; + + case DIR_NORTH: + while (len > 0 && row < LROWS) { + Bar[row*LCOLS+col].dir=dir; + Bar[row*LCOLS+col].segment=-1; + if (val1 >= YRES) { + Bar[row*LCOLS+col].val1 = rev?0:YRES; + val1 -= YRES; + } else { + Bar[row*LCOLS+col].val1 = rev?YRES-val1:val1; + val1 = 0; + } + if (val2 >= YRES) { + Bar[row*LCOLS+col].val2 = rev?0:YRES; + val2 -= YRES; + } else { + Bar[row*LCOLS+col].val2 = rev?YRES-val2:val2; + val2 = 0; + } + len--; + row++; + } + break; + + } +} + + +static void drv_generic_text_bar_create_segments (void) +{ + int i, j, n; + int res, l1, l2; + + /* find first unused segment */ + for (i=fSegment; iRES) l1=RES; + l2 = Segment[i].val2; if (l2>RES) l2=RES; + if (l1 == Bar[n].val1 && l2 == Bar[n].val2) break; + } + } + if (i==nSegment) { + nSegment++; + Segment[i].val1=Bar[n].val1; + Segment[i].val2=Bar[n].val2; + Segment[i].dir=Bar[n].dir; + Segment[i].used=0; + Segment[i].ascii=-1; + } + Bar[n].segment=i; + } +} + + +static int drv_generic_text_bar_segment_error (int i, int j) +{ + int res; + int i1, i2, j1, j2; + + if (i==j) return 65535; + if (!(Segment[i].dir & Segment[j].dir)) return 65535; + + res = Segment[i].dir&(DIR_EAST|DIR_WEST) ? XRES:YRES; + + i1=Segment[i].val1; if (i1>res) i1=res; + i2=Segment[i].val2; if (i2>res) i2=res; + j1=Segment[j].val1; if (j1>res) j1=res; + j2=Segment[j].val2; if (j2>res) j2=res; + + if (i1==0 && j1!=0) return 65535; + if (i2==0 && j2!=0) return 65535; + if (i1==res && j1 0) return 65535; + if (i2==1 && j2!=1 && j1 > 0) return 65535; + if (i1==i2 && j1!=j2) return 65535; + + return (i1-j1)*(i1-j1)+(i2-j2)*(i2-j2); +} + + +static void drv_generic_text_bar_pack_segments (void) +{ + int i, j, n, min; + int pack_i, pack_j; + int pass1=1; + int error[nSegment][nSegment]; + + if (nSegment<=fSegment+CHARS) { + return; + } + + for (i=0; ifSegment+CHARS) { + + min=65535; + pack_i=-1; + pack_j=-1; + for (i=fSegment; idata; + int row, col, len, max, val1, val2; + int c, n, s; + DIRECTION dir; + + row = W->row; + col = W->col; + dir = B->direction; + len = B->length; + + // maybe grow layout framebuffer + // bars *always* grow heading North or East! + if (dir==DIR_EAST || dir==DIR_WEST) { + drv_generic_text_resizeFB (row, col+len-1); + RES = XRES; + } else { + drv_generic_text_resizeFB (row, col); + RES = YRES; + } + max = len * RES; + val1 = B->val1 * (double)(max); + val2 = B->val2 * (double)(max); + + if (val1<1) val1=1; + else if (val1>max) val1=max; + + if (val2<1) val2=1; + else if (val2>max) val2=max; + + // create this bar + drv_generic_text_bar_create_bar (row, col, dir, len, val1, val2); + + // process all bars + drv_generic_text_bar_create_segments (); + drv_generic_text_bar_pack_segments (); + drv_generic_text_bar_define_chars(drv_defchar); + + // reset usage flags + for (s=0; sgoto_len) break; + } else { + pos2=col; + equal=0; + } + } + memcpy (DisplayFB+row*DCOLS+pos1, LayoutFB+row*LCOLS+pos1, pos2-pos1+1); + drv_write (DisplayFB+row*DCOLS+pos1, pos2-pos1+1); + debug ("Michi: bar(%d,%d) len=%d", row, pos1, pos2-pos1+1); + } + } + + return 0; + +} + +int drv_generic_text_bar_peek (int row, int col) +{ + int s; + + s=Bar[row*LCOLS+col].segment; + if (s==-1) { + return -1; + } else { + return Segment[s].ascii; + } +} + -- cgit v1.2.3