aboutsummaryrefslogtreecommitdiffstats
path: root/drv_generic_bar.c
diff options
context:
space:
mode:
authorreinelt <>2004-01-20 05:36:59 +0000
committerreinelt <>2004-01-20 05:36:59 +0000
commit35b4d898d72f13de0b787ccd94970f517cd623f3 (patch)
tree425249827b2d9af46849c54f75a446f55369bf38 /drv_generic_bar.c
parent252cb9023289ad2af5993cf53c0d0fd7293cff27 (diff)
downloadlcd4linux-35b4d898d72f13de0b787ccd94970f517cd623f3.tar.gz
[lcd4linux @ 2004-01-20 05:36:59 by reinelt]
moved text-display-specific stuff to drv_generic_text moved all the bar stuff from drv_generic_bar to generic_text
Diffstat (limited to 'drv_generic_bar.c')
-rw-r--r--drv_generic_bar.c471
1 files changed, 0 insertions, 471 deletions
diff --git a/drv_generic_bar.c b/drv_generic_bar.c
deleted file mode 100644
index 0bf3f7e..0000000
--- a/drv_generic_bar.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/* $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 <reinelt@eunet.at>
- * Copyright 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
- *
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#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<LROWS*LCOLS; i++) {
- Bar[i].val1 = -1;
- Bar[i].val2 = -1;
- Bar[i].dir = 0;
- Bar[i].segment = -1;
- }
-
- for (i=0; i<nSegment;i++) {
- Segment[i].used = 0;
- }
-}
-
-
-void drv_generic_text_bar_add_segment(int val1, int val2, DIRECTION dir, int ascii)
-{
- Segment[fSegment].val1=val1;
- Segment[fSegment].val2=val2;
- Segment[fSegment].dir=dir;
- Segment[fSegment].used=0;
- Segment[fSegment].ascii=ascii;
-
- fSegment++;
- nSegment=fSegment;
-}
-
-
-static void drv_generic_text_bar_create_bar (int row, int col, DIRECTION dir, int len, int val1, int val2)
-{
- int rev=0;
-
- switch (dir) {
- case DIR_WEST:
- val1 = len-val1;
- val2 = len-val2;
- rev = 1;
-
- case DIR_EAST:
- while (len > 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; i<nSegment && Segment[i].used; i++);
-
- /* pack unused segments */
- for (j=i+1; j<nSegment; j++) {
- if (Segment[j].used)
- Segment[i++]=Segment[j];
- }
- nSegment=i;
-
- /* create needed segments */
- for (n=0; n<LROWS*LCOLS; n++) {
- if (Bar[n].dir==0) continue;
- res=Bar[n].dir & (DIR_EAST|DIR_WEST) ? XRES:YRES;
- for (i=0; i<nSegment; i++) {
- if (Segment[i].dir & Bar[n].dir) {
- l1 = Segment[i].val1; if (l1>RES) 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<res) return 65535;
- if (i2==res && j2<res) return 65535;
- if (i1==1 && j1!=1 && i2 > 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; i<nSegment; i++) {
- for (j=0; j<nSegment; j++) {
- error[i][j]=drv_generic_text_bar_segment_error(i,j);
- }
- }
-
- while (nSegment>fSegment+CHARS) {
-
- min=65535;
- pack_i=-1;
- pack_j=-1;
- for (i=fSegment; i<nSegment; i++) {
- if (pass1 && Segment[i].used) continue;
- for (j=0; j<nSegment; j++) {
- if (error[i][j]<min) {
- min=error[i][j];
- pack_i=i;
- pack_j=j;
- }
- }
- }
- if (pack_i==-1) {
- if (pass1) {
- pass1=0;
- continue;
- } else {
- error ("unable to compact bar characters");
- nSegment=CHARS;
- break;
- }
- }
-
-#if 1
- debug ("pack_segment: n=%d i=%d j=%d min=%d", nSegment, pack_i, pack_j, min);
- debug ("Pack_segment: i1=%d i2=%d j1=%d j2=%d\n",
- Segment[pack_i].val1, Segment[pack_i].val2,
- Segment[pack_j].val1, Segment[pack_j].val2);
-#endif
-
- nSegment--;
- Segment[pack_i]=Segment[nSegment];
-
- for (i=0; i<nSegment; i++) {
- error[pack_i][i]=error[nSegment][i];
- error[i][pack_i]=error[i][nSegment];
- }
-
- for (n=0; n<LROWS*LCOLS; n++) {
- if (Bar[n].segment==pack_i) Bar[n].segment=pack_j;
- if (Bar[n].segment==nSegment) Bar[n].segment=pack_i;
- }
- }
-}
-
-
-static void drv_generic_text_bar_define_chars (void(*defchar)(int ascii, char *matrix))
-{
- int c, i, j;
- char buffer[8];
-
- for (i=fSegment; i<nSegment; i++) {
- if (Segment[i].used) continue;
- if (Segment[i].ascii!=-1) continue;
- for (c=0; c<CHARS; c++) {
- for (j=fSegment; j<nSegment; j++) {
- if (Segment[j].ascii==c) break;
- }
- if (j==nSegment) break;
- }
- Segment[i].ascii=c;
- switch (Segment[i].dir) {
- case DIR_EAST:
- for (j=0; j<4; j++) {
- buffer[j ]=(1<<Segment[i].val1)-1;
- buffer[j+4]=(1<<Segment[i].val2)-1;
- }
- break;
- case DIR_WEST:
- for (j=0; j<4; j++) {
- buffer[j ]=255<<(XRES-Segment[i].val1);
- buffer[j+4]=255<<(XRES-Segment[i].val2);
- }
- break;
- case DIR_NORTH:
- for (j=0; j<Segment[i].val1; j++) {
- buffer[7-j]=(1<<XRES)-1;
- }
- for (; j<YRES; j++) {
- buffer[7-j]=0;
- }
- break;
- case DIR_SOUTH:
- for (j=0; j<Segment[i].val1; j++) {
- buffer[j]=(1<<XRES)-1;
- }
- for (; j<YRES; j++) {
- buffer[j]=0;
- }
- break;
- }
- defchar(c, buffer);
- }
-}
-
-
-int drv_generic_text_draw_bar (WIDGET *W, int goto_len,
- void (*drv_defchar)(int ascii, char *buffer),
- void (*drv_goto)(int row, int col),
- void (*drv_write)(char *buffer, int len))
-{
- WIDGET_BAR *B = W->data;
- 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; s<nSegment; s++) {
- Segment[s].used=0;
- }
-
- // set usage flags
- for (n=0; n<LROWS*LCOLS; n++) {
- if ((s=Bar[n].segment)!=-1) Segment[s].used=1;
- }
-
- // transfer bars into layout buffer
- for (n=0; n<LCOLS*LROWS; n++) {
- s=Bar[n].segment;
- if (s==-1) continue;
- c=Segment[s].ascii;
- if (c==-1) continue;
- if(c==LayoutFB[n]) continue;
- LayoutFB[n]=c;
- }
-
- // transfer differences to the display
- for (row=0; row<DROWS; row++) {
- for (col=0; col<DCOLS; col++) {
- int pos1, pos2, equal;
- if (LayoutFB[row*LCOLS+col]==DisplayFB[row*DCOLS+col]) continue;
- drv_goto (row, col);
- for (pos1=col, pos2=pos1, col++, equal=0; col<DCOLS; col++) {
- if (LayoutFB[row*LCOLS+col]==DisplayFB[row*DCOLS+col]) {
- // If we find just one equal byte, we don't break, because this
- // would require a goto, which takes several bytes, too.
- if (++equal>goto_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;
- }
-}
-