Initial revision

This commit is contained in:
William Ferrell
1999-12-09 23:15:14 +00:00
commit 2635c3085d
139 changed files with 24298 additions and 0 deletions
+718
View File
@@ -0,0 +1,718 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include "lcd.h"
#include "CFontz.h"
#include "drv_base.h"
#include "../render.h"
#include "../../shared/debug.h"
#include "../../shared/str.h"
static int custom=0;
typedef enum {
hbar = 1,
vbar = 2,
bign = 4,
beat = 8 } custom_type;
static int fd;
static void CFontz_linewrap(int on);
static void CFontz_autoscroll(int on);
static void CFontz_hidecursor();
static void CFontz_reboot();
// TODO: Get rid of this variable?
lcd_logical_driver *CFontz;
// TODO: Get the frame buffers working right
/////////////////////////////////////////////////////////////////
// Opens com port and sets baud correctly...
//
int CFontz_init(lcd_logical_driver *driver, char *args)
{
char *argv[64];
int argc;
struct termios portset;
int i;
int tmp;
int reboot=0;
int contrast=140;
char device[256] = "/dev/lcd";
int speed=B9600;
CFontz = driver;
//debug("CFontz_init: Args(all): %s\n", args);
argc = get_args(argv, args, 64);
/*
for(i=0; i<argc; i++)
{
printf("Arg(%i): %s\n", i, argv[i]);
}
*/
for(i=0; i<argc; i++)
{
//printf("Arg(%i): %s\n", i, argv[i]);
if(0 == strcmp(argv[i], "-d") ||
0 == strcmp(argv[i], "--device"))
{
if(i + 1 > argc) {
fprintf(stderr, "CFontz_init: %s requires an argument\n",
argv[i]);
return -1;
}
strcpy(device, argv[++i]);
}
else if(0 == strcmp(argv[i], "-c") ||
0 == strcmp(argv[i], "--contrast"))
{
if(i + 1 > argc) {
fprintf(stderr, "CFontz_init: %s requires an argument\n",
argv[i]);
return -1;
}
tmp = atoi(argv[++i]);
if((tmp < 0) || (tmp > 255)){
fprintf(stderr, "CFontz_init: %s argument must between 0 and 255. Using default value.\n",
argv[i]);
} else contrast = tmp;
}
else if(0 == strcmp(argv[i], "-b") ||
0 == strcmp(argv[i], "--brightness"))
{
if(i + 1 > argc) {
fprintf(stderr, "CFontz_init: %s requires an argument\n",
argv[i]);
return -1;
}
tmp = atoi(argv[++i]);
if((tmp < 0) || (tmp > 255)){
fprintf(stderr, "CFontz_init: %s argument must between 0 and 255. Using default value.\n",
argv[i]);
} else backlight_brightness = tmp;
}
else if(0 == strcmp(argv[i], "-o") ||
0 == strcmp(argv[i], "--off-bright"))
{
if(i + 1 > argc) {
fprintf(stderr, "CFontz_init: %s requires an argument\n",
argv[i]);
return -1;
}
tmp = atoi(argv[++i]);
if((tmp < 0) || (tmp > 255)){
fprintf(stderr, "CFontz_init: %s argument must between 0 and 255. Using default value.\n",
argv[i]);
} else backlight_off_brightness = tmp;
}
else if(0 == strcmp(argv[i], "-s") ||
0 == strcmp(argv[i], "--speed"))
{
if(i + 1 > argc) {
fprintf(stderr, "CFontz_init: %s requires an argument\n",
argv[i]);
return -1;
}
tmp = atoi(argv[++i]);
if(tmp==1200) speed=B1200;
else if(tmp==2400) speed=B2400;
else if(tmp==9600) speed=B9600;
else if(tmp==19200) speed=B19200;
else {
fprintf(stderr, "CFontz_init: %s argument must be 1200, 2400, or 9600. Using default value.\n",
argv[i]);
}
}
else if(0 == strcmp(argv[i], "-h") ||
0 == strcmp(argv[i], "--help"))
{
printf("LCDproc CrystalFontz LCD driver\n"
"\t-d\t--device\tSelect the output device to use [/dev/lcd]\n"
"\t-t\t--type\t\tSelect the LCD type (size) [20x4]\n"
"\t-c\t--contrast\tSet the initial contrast [140]\n"
"\t-b\t--brightness\tSet the initial brightness [255]\n"
"\t-o\t--off-bright\tSet the initial brightness [0]\n"
"\t-s\t--speed\t\tSet the communication speed [9600]\n"
"\t-r\t--reboot\tReinitialize the LCD's BIOS\n"
"\t-h\t--help\t\tShow this help information\n");
return -1;
}
else if(0 == strcmp(argv[i], "-r") ||
0 == strcmp(argv[i], "--reboot"))
{
printf("LCDd: rebooting CrystalFontz LCD...\n");
reboot=1;
}
else
{
printf("Invalid parameter: %s\n", argv[i]);
}
}
// Set up io port correctly, and open it...
fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
fprintf(stderr, "CFontz_init: failed (%s)\n", strerror(errno));
return -1;
}
//else fprintf(stderr, "CFontz_init: opened device %s\n", device);
tcgetattr(fd, &portset);
// This is necessary in Linux, but does not exist in irix.
#ifndef IRIX
cfmakeraw(&portset);
#endif
cfsetospeed(&portset, speed);
cfsetispeed(&portset, speed);
tcsetattr(fd, TCSANOW, &portset);
// Set display-specific stuff..
if(reboot)
{
CFontz_reboot();
sleep(4);
reboot=0;
}
sleep(1);
CFontz_hidecursor();
CFontz_linewrap(1);
CFontz_autoscroll(0);
CFontz_backlight(backlight_brightness);
if(!driver->framebuf)
{
fprintf(stderr, "CFontz_init: No frame buffer.\n");
driver->close();
return -1;
}
// Set the functions the driver supports...
driver->clear = (void *)-1;
driver->string = (void *)-1;
// driver->chr = CFontz_chr;
driver->chr = CFontz_chr;
driver->vbar = CFontz_vbar;
driver->init_vbar = CFontz_init_vbar;
driver->hbar = CFontz_hbar;
driver->init_hbar = CFontz_init_hbar;
driver->num = CFontz_num;
driver->init_num = CFontz_init_num;
driver->init = CFontz_init;
driver->close = CFontz_close;
driver->flush = CFontz_flush;
driver->flush_box = CFontz_flush_box;
driver->contrast = CFontz_contrast;
driver->backlight = CFontz_backlight;
driver->set_char = CFontz_set_char;
driver->icon = CFontz_icon;
driver->draw_frame = CFontz_draw_frame;
CFontz_contrast(contrast);
lcd.cellwid = 6;
lcd.cellhgt = 8;
debug("CFontz: foo!\n");
return fd;
}
/////////////////////////////////////////////////////////////////
// Clean-up
//
void CFontz_close()
{
close (fd);
if(CFontz->framebuf) free(CFontz->framebuf);
CFontz->framebuf = NULL;
}
void CFontz_flush()
{
CFontz_draw_frame(lcd.framebuf);
}
void CFontz_flush_box(int lft, int top, int rgt, int bot)
{
int y;
char out[LCD_MAX_WIDTH];
// printf("Flush (%i,%i)-(%i,%i)\n", lft, top, rgt, bot);
for(y=top; y<=bot; y++)
{
sprintf(out, "%c%c%c", 17, lft, y);
write(fd, out, 4);
write(fd, lcd.framebuf+(y*lcd.wid)+lft, rgt-lft+1);
}
}
/////////////////////////////////////////////////////////////////
// Prints a character on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void CFontz_chr(int x, int y, char c)
{
y--;
x--;
if(c < 32 && c >= 0) c += 128;
lcd.framebuf[(y*lcd.wid) + x] = c;
}
/////////////////////////////////////////////////////////////////
// Changes screen contrast (0-255; 140 seems good)
//
int CFontz_contrast(int contrast)
{
int realcontrast;
char out[4];
static int status=140;
if(contrast > 0)
{
status=contrast;
realcontrast = (((int)(status)) * 100) / 255;
sprintf(out, "%c%c", 15, realcontrast);
write(fd, out, 3);
}
return status;
}
/////////////////////////////////////////////////////////////////
// Sets the backlight on or off -- can be done quickly for
// an intermediate brightness...
//
void CFontz_backlight(int on)
{
char out[4];
if(on)
{
sprintf(out, "%c%c", 14, (unsigned char)(on * 100 / 255));
//sprintf(out, "%c%c", 14, 100);
}
else
{
sprintf(out, "%c%c", 14, 0);
}
write(fd, out, 3);
}
/////////////////////////////////////////////////////////////////
// Toggle the built-in linewrapping feature
//
static void CFontz_linewrap(int on)
{
char out[4];
if(on)
sprintf(out, "%c", 23);
else
sprintf(out, "%c", 24);
write(fd, out, 1);
}
/////////////////////////////////////////////////////////////////
// Toggle the built-in automatic scrolling feature
//
static void CFontz_autoscroll(int on)
{
char out[4];
if(on)
sprintf(out, "%c", 19);
else
sprintf(out, "%c", 20);
write(fd, out, 1);
}
/////////////////////////////////////////////////////////////////
// Get rid of the blinking curson
//
static void CFontz_hidecursor()
{
char out[4];
sprintf(out, "%c", 4);
write(fd, out, 1);
}
/////////////////////////////////////////////////////////////////
// Reset the display bios
//
static void CFontz_reboot()
{
char out[4];
sprintf(out, "%c", 26);
write(fd, out, 1);
}
/////////////////////////////////////////////////////////////////
// Sets up for vertical bars. Call before lcd.vbar()
//
void CFontz_init_vbar()
{
char a[] = {
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,1,1,1,1,1,
};
char b[] = {
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,1,1,1,1,1,
0,1,1,1,1,1,
};
char c[] = {
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
};
char d[] = {
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
};
char e[] = {
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
};
char f[] = {
0,0,0,0,0,0,
0,0,0,0,0,0,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
};
char g[] = {
0,0,0,0,0,0,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
0,1,1,1,1,1,
};
if(custom!=vbar) {
CFontz_set_char(1,a);
CFontz_set_char(2,b);
CFontz_set_char(3,c);
CFontz_set_char(4,d);
CFontz_set_char(5,e);
CFontz_set_char(6,f);
CFontz_set_char(7,g);
custom=vbar;
}
}
/////////////////////////////////////////////////////////////////
// Inits horizontal bars...
//
void CFontz_init_hbar()
{
char a[] = {
1,0,0,0,0,0,
1,0,0,0,0,0,
1,0,0,0,0,0,
1,0,0,0,0,0,
1,0,0,0,0,0,
1,0,0,0,0,0,
1,0,0,0,0,0,
1,0,0,0,0,0,
};
char b[] = {
1,1,0,0,0,0,
1,1,0,0,0,0,
1,1,0,0,0,0,
1,1,0,0,0,0,
1,1,0,0,0,0,
1,1,0,0,0,0,
1,1,0,0,0,0,
1,1,0,0,0,0,
};
char c[] = {
1,1,1,0,0,0,
1,1,1,0,0,0,
1,1,1,0,0,0,
1,1,1,0,0,0,
1,1,1,0,0,0,
1,1,1,0,0,0,
1,1,1,0,0,0,
1,1,1,0,0,0,
};
char d[] = {
1,1,1,1,0,0,
1,1,1,1,0,0,
1,1,1,1,0,0,
1,1,1,1,0,0,
1,1,1,1,0,0,
1,1,1,1,0,0,
1,1,1,1,0,0,
1,1,1,1,0,0,
};
char e[] = {
1,1,1,1,1,0,
1,1,1,1,1,0,
1,1,1,1,1,0,
1,1,1,1,1,0,
1,1,1,1,1,0,
1,1,1,1,1,0,
1,1,1,1,1,0,
1,1,1,1,1,0,
};
char f[] = {
1,1,1,1,1,1,
1,1,1,1,1,1,
1,1,1,1,1,1,
1,1,1,1,1,1,
1,1,1,1,1,1,
1,1,1,1,1,1,
1,1,1,1,1,1,
1,1,1,1,1,1,
};
if(custom!=hbar) {
CFontz_set_char(1,a);
CFontz_set_char(2,b);
CFontz_set_char(3,c);
CFontz_set_char(4,d);
CFontz_set_char(5,e);
CFontz_set_char(6,f);
custom=hbar;
}
}
/////////////////////////////////////////////////////////////////
// Draws a vertical bar...
//
void CFontz_vbar(int x, int len)
{
char map[9] = {32, 1, 2, 3, 4, 5, 6, 7, 255 };
int y;
for(y=lcd.hgt; y > 0 && len>0; y--)
{
if(len >= lcd.cellhgt) CFontz_chr(x, y, 255);
else CFontz_chr(x, y, map[len]);
len -= lcd.cellhgt;
}
}
/////////////////////////////////////////////////////////////////
// Draws a horizontal bar to the right.
//
void CFontz_hbar(int x, int y, int len)
{
char map[7] = { 32, 1, 2, 3, 4, 5, 6 };
for(; x<=lcd.wid && len>0; x++)
{
if(len >= lcd.cellwid) CFontz_chr(x,y,map[6]);
else CFontz_chr(x, y, map[len]);
len -= lcd.cellwid;
}
}
/////////////////////////////////////////////////////////////////
// Sets up for big numbers.
//
void CFontz_init_num()
{
}
/////////////////////////////////////////////////////////////////
// Writes a big number.
//
void CFontz_num(int x, int num)
{
char out[5];
sprintf(out, "%c%c%c", 28, x, num);
write(fd, out, 3);
}
/////////////////////////////////////////////////////////////////
// Sets a custom character from 0-7...
//
// For input, values > 0 mean "on" and values <= 0 are "off".
//
// The input is just an array of characters...
//
void CFontz_set_char(int n, char *dat)
{
char out[4];
int row, col;
int letter;
if(n < 0 || n > 7) return;
if(!dat) return;
sprintf(out, "%c%c", 25, n);
write(fd, out, 2);
for(row=0; row<lcd.cellhgt; row++)
{
letter = 0;
for(col=0; col<lcd.cellwid; col++)
{
letter <<= 1;
letter |= (dat[(row*lcd.cellwid) + col] > 0);
}
write(fd, &letter, 1);
}
}
void CFontz_icon(int which, char dest)
{
char icons[3][6*8] = {
{
1,1,1,1,1,1, // Empty Heart
1,0,1,0,1,1,
0,0,0,0,0,1,
0,0,0,0,0,1,
0,0,0,0,0,1,
1,0,0,0,1,1,
1,1,0,1,1,1,
1,1,1,1,1,1,
},
{
1,1,1,1,1,1, // Filled Heart
1,0,1,0,1,1,
0,1,0,1,0,1,
0,1,1,1,0,1,
0,1,1,1,0,1,
1,0,1,0,1,1,
1,1,0,1,1,1,
1,1,1,1,1,1,
},
{
0,0,0,0,0,0, // Ellipsis
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0,
1,0,1,0,1,0,
},
};
if(custom==bign) custom=beat;
CFontz_set_char(dest, &icons[which][0]);
}
/////////////////////////////////////////////////////////////
// Blasts a single frame onscreen, to the lcd...
//
// Input is a character array, sized lcd.wid*lcd.hgt
//
void CFontz_draw_frame(char *dat)
{
char out[LCD_MAX_WIDTH * LCD_MAX_HEIGHT];
int i;
if(!dat) return;
// Custom characters start at 128, not at 0.
/*
for(i=0; i<lcd.wid*lcd.hgt; i++)
{
if(dat[i] < 32 && dat[i] >= 0) dat[i] += 128;
}
*/
for(i=0; i<lcd.hgt; i++)
{
sprintf(out, "%c%c%c", 17, 0, i);
write(fd, out, 3);
write(fd, dat+(lcd.wid*i), lcd.wid);
}
/*
sprintf(out, "%c", 1);
write(fd, out, 1);
write(fd, dat, lcd.wid*lcd.hgt);
*/
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef CFONTZ_H
#define CFONTZ_H
extern lcd_logical_driver *CFontz;
int CFontz_init(lcd_logical_driver *driver, char *device);
void CFontz_close();
void CFontz_flush();
void CFontz_flush_box(int lft, int top, int rgt, int bot);
void CFontz_chr(int x, int y, char c) ;
int CFontz_contrast(int contrast);
void CFontz_backlight(int on);
void CFontz_init_vbar();
void CFontz_init_hbar();
void CFontz_vbar(int x, int len);
void CFontz_hbar(int x, int y, int len);
void CFontz_init_num();
void CFontz_num(int x, int num);
void CFontz_set_char(int n, char *dat);
void CFontz_icon(int which, char dest);
void CFontz_draw_frame(char *dat);
#endif
+92
View File
@@ -0,0 +1,92 @@
# example irmanrc file for libirman 0.4.1
# should be either /usr/local/etc/irmanrc.conf or ~/.irmanrc
# set the default port name
port /dev/ttyS0
bind jvc-play 7ddfd7fc0000
bind jvc-pause 7dddd7fc0000
bind jvc-stop 7ddd7ffc0000
bind jvc-prev 7ddff5fc0000
bind jvc-next 7dddf5fc0000
bind jvc-fwd 7ddf5ffc0000
bind jvc-rew 7ddd5ffc0000
bind jvc-1 7ffdff7c0000
bind jvc-2 7fff7f7c0000
bind jvc-3 7ffd7f7c0000
bind jvc-4 7fffdf7c0000
bind jvc-5 7ffddf7c0000
bind jvc-6 7fff5f7c0000
bind jvc-7 7ffd5f7c0000
bind jvc-8 7ffff77c0000
bind jvc-9 7ffdf77c0000
bind jvc-0 7fffff7c0000
bind jvc-rec e51000000000
bind jvc-vol+ b91000000000
bind jvc-vol- ad1000000000
bind jvc-mute f91000000000
bind jvc-/|// f11000000000
bind jvc-display 151000000000
bind jvc-search<< 351000000000
bind jvc-search>> 491000000000
bind jvc-operate c91000000000
bind sony-md-power a9e000000000
bind sony-md-eject 69e000000000
bind -cancel 051000000000
alias workman-play jvc-play
alias workman-pause jvc-pause
alias workman-stop jvc-stop
alias workman-prev jvc-prev
alias workman-next jvc-next
alias workman-rew jvc-rew
alias workman-fwd jvc-fwd
#alias workman-power jvc-power
#alias workman-eject jvc-eject
alias ircd-play jvc-play
alias ircd-pause jvc-pause
alias ircd-stop jvc-stop
alias ircd-prev jvc-rew
alias ircd-next jvc-fwd
#alias ircd-power jvc-power
#alias ircd-eject jvc-eject
alias lcdproc-A jvc-1
alias lcdproc-B jvc-2
alias lcdproc-C jvc-3
alias lcdproc-D jvc-4
alias lcdproc-E jvc-5
alias lcdproc-F jvc-6
alias lcdproc-G jvc-7
alias lcdproc-H jvc-8
alias lcdproc-I jvc-9
alias lcdproc-J jvc-0
alias lcdproc-K jvc-play
alias lcdproc-L jvc-pause
alias lcdproc-M jvc-stop
alias lcdproc-N jvc-prev
alias lcdproc-O jvc-next
alias lcdproc-P jvc-fwd
alias lcdproc-Q jvc-rew
alias lcdproc-R jvc-rec
alias lcdproc-S jvc-vol+
alias lcdproc-T jvc-vol-
alias lcdproc-U jvc-mute
alias lcdproc-V jvc-/|//
alias lcdproc-W jvc-display
alias lcdproc-X jvc-search<<
alias lcdproc-Y jvc-search>>
alias lcdproc-Z jvc-operate
# just an idea for 0.5
# assign workman sony-md
# would be like: alias workman-* sony-md-*
# this allows remote level control.
# { "(remote level) control", not "remote (level control)"! }
# also
# set REMOTES /usr/local/share/libir/
# include ${REMOTES}/sony-md
# include ${REMOTES}/philips-rc5
+45
View File
@@ -0,0 +1,45 @@
########################################################################
# You shouldn't need to touch anything below here.
########################################################################
include ../../Makefile.config
TARGET = libLCDdrivers.a
OBJ += lcd.o drv_base.o $(DOBJ)
SOURCES = Makefile lcd.c lcd.h \
MtxOrb.c MtxOrb.h wirz-sli.c wirz-sli.h text.c text.h \
curses_drv.c curses_drv.h drv_base.c drv_base.h \
hd44780.c hd44780.h port.h joy.c joy.h irman.c irman.h \
CFontz.c CFontz.h
INCLUDE = -I../../shared
###################################################################
# Compilation...
#
all: $(TARGET)
$(TARGET): $(OBJ) Makefile
$(AR) rcs $(TARGET) $(OBJ)
#$(TARGET): $(OBJ) Makefile
# $(GCC) -s $(MISC) $(INCLUDE) -o $(TARGET) $(OBJ) $(LIB)
%.o: %.c %.h Makefile
$(GCC) -c $(MISC) $(INCLUDE) $<
##################################################################
# Other stuff...
#
clean:
rm -f $(OBJ) *.o $(DOBJ) $(TARGET) *~ core
edit:
nedit $(SOURCES) $(EXTRAS) &
todo:
@echo ---------------===========================================
@grep TODO $(SOURCES) | grep -v SOURCES
@grep FIXME $(SOURCES) | grep -v SOURCES
@echo ---------------===========================================
File diff suppressed because it is too large Load Diff
+31
View File
@@ -0,0 +1,31 @@
#ifndef MTXORB_H
#define MTXORB_H
extern lcd_logical_driver *MtxOrb;
int MtxOrb_init(lcd_logical_driver *driver, char *device);
void MtxOrb_clear();
void MtxOrb_close();
void MtxOrb_flush();
void MtxOrb_flush_box(int lft, int top, int rgt, int bot);
void MtxOrb_chr(int x, int y, char c) ;
int MtxOrb_contrast(int contrast);
void MtxOrb_backlight(int on);
void MtxOrb_output(int on);
void MtxOrb_init_vbar();
void MtxOrb_init_hbar();
void MtxOrb_vbar(int x, int len);
void MtxOrb_hbar(int x, int y, int len);
void MtxOrb_init_num();
void MtxOrb_num(int x, int num);
void MtxOrb_set_char(int n, char *dat);
void MtxOrb_icon(int which, char dest);
void MtxOrb_draw_frame(char *dat);
char MtxOrb_getkey();
void MtxOrb_init_all(int type);
int MtxOrb_ask_bar(int type);
void MtxOrb_set_known_char(int car, int type);
#endif
+322
View File
@@ -0,0 +1,322 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#ifdef xBSD
#include <ncurses.h>
#else
#include <curses.h>
#endif
#include "../../shared/str.h"
#include "lcd.h"
#include "curses_drv.h"
#include "drv_base.h"
lcd_logical_driver *curses_drv;
int PAD=255;
int ELLIPSIS=7;
//////////////////////////////////////////////////////////////////////////
////////////////////// For Curses Terminal Output ////////////////////////
//////////////////////////////////////////////////////////////////////////
static char icon_char = '@';
int curses_drv_init(struct lcd_logical_driver *driver, char *args)
{
char *argv[64];
int argc;
int i,j;
argc = get_args(argv, args, 64);
for(i=0; i<argc; i++)
{
if(0 == strcmp(argv[i], "-f") ||
0 == strcmp(argv[i], "--forecolor"))
{
if(i + 1 > argc) {
fprintf(stderr, "curses_init: %s requires an argument\n",
argv[i]);
return -1;
}
// TODO: color display in curses driver!
printf("Sorry, colors not yet implemented...\n");
//strcpy(device, argv[++i]);
}
else if(0 == strcmp(argv[i], "-b") ||
0 == strcmp(argv[i], "--backcolor"))
{
if(i + 1 > argc) {
fprintf(stderr, "curses_init: %s requires an argument\n",
argv[i]);
return -1;
}
// TODO: color display in curses driver!
printf("Sorry, colors not yet implemented...\n");
//strcpy(device, argv[++i]);
}
else if(0 == strcmp(argv[i], "-B") ||
0 == strcmp(argv[i], "--backlight"))
{
if(i + 1 > argc) {
fprintf(stderr, "curses_init: %s requires an argument\n",
argv[i]);
return -1;
}
// TODO: color display in curses driver!
printf("Sorry, colors not yet implemented...\n");
//strcpy(device, argv[++i]);
}
else if(0 == strcmp(argv[i], "-h") ||
0 == strcmp(argv[i], "--help"))
{
printf("LCDproc [n]curses driver\n"
"\t-f\t--forecolor\tChange the foreground color\n"
"\t-b\t--backcolor\tChange the backlight's \"off\" color\n"
"\t-B\t--backlight\tChange the backlight's \"on\" color\n"
"\t-h\t--help\t\tShow this help information\n");
return -1;
}
else
{
printf("Invalid parameter: %s\n", argv[i]);
}
}
curses_drv = driver;
// Init curses...
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
nonl();
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
curses_drv_clear();
// Override output functions...
driver->clear = curses_drv_clear;
driver->string = curses_drv_string;
driver->chr = curses_drv_chr;
driver->vbar = curses_drv_vbar;
driver->init_vbar = NULL;
driver->hbar = curses_drv_hbar;
driver->init_hbar = NULL;
driver->num = curses_drv_num;
driver->init_num = curses_drv_init_num;
driver->init = curses_drv_init;
driver->close = curses_drv_close;
driver->flush = curses_drv_flush;
driver->flush_box = curses_drv_flush_box;
driver->contrast = NULL;
driver->backlight = NULL;
driver->set_char = NULL;
driver->icon = curses_drv_icon;
driver->draw_frame = curses_drv_draw_frame;
driver->getkey = curses_drv_getkey;
// Change the character used for padding the title bars...
PAD = '#';
// Change the character used for "..."
ELLIPSIS = '~';
return 200; // 200 is arbitrary. (must be 1 or more)
}
void curses_drv_close()
{
// Close curses
clear();
move(0,0);
refresh();
endwin();
drv_base_close();
}
/////////////////////////////////////////////////////////////////
// Clears the LCD screen
//
void curses_drv_clear()
{
clear();
}
/////////////////////////////////////////////////////////////////
// Prints a string on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void curses_drv_string(int x, int y, char string[])
{
int i;
unsigned char *c;
for(i=0; string[i]; i++)
{
c = &string[i];
switch(*c)
{
case 0: *c = icon_char; break;
case 255: *c = '#'; break;
}
}
mvaddstr(y-1, x-1, string);
}
/////////////////////////////////////////////////////////////////
// Prints a character on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void curses_drv_chr(int x, int y, char c)
{
switch(c)
{
case 0: c = icon_char; break;
case -1: c = '#'; break;
}
mvaddch(y-1, x-1, c);
}
/////////////////////////////////////////////////////////////////
// Sets up for big numbers.
//
void curses_drv_init_num()
{
}
/////////////////////////////////////////////////////////////////
// Writes a big number.
//
void curses_drv_num(int x, int num)
{
char c;
int y, dx;
c='0'+num;
// printf(&c,"%1d",num);
for(y=1; y<5; y++)
for(dx=0; dx<3; dx++)
curses_drv_chr(x+dx, y, c);
}
/////////////////////////////////////////////////////////////////
// Draws a vertical bar; erases entire column onscreen.
//
void curses_drv_vbar(int x, int len)
{
char map[]="_.,,ooO8";
int y;
for(y=lcd.hgt; y > 0 && len>0; y--)
{
if(len >= lcd.cellhgt) curses_drv_chr(x, y, '8');
else curses_drv_chr(x, y, map[len-1]);
len -= lcd.cellhgt;
}
// move(4-len/lcd.cellhgt, x-1);
// vline(0, len/lcd.cellhgt);
}
/////////////////////////////////////////////////////////////////
// Draws a horizontal bar to the right.
//
void curses_drv_hbar(int x, int y, int len)
{
for(; x<=lcd.wid && len>0; x++)
{
if(len>=lcd.cellwid)
curses_drv_chr(x, y, '=');
else
curses_drv_chr(x, y, '-');
len -= lcd.cellwid;
}
// move(y-1, x-1);
// hline(0, len/lcd.cellwid);
}
/////////////////////////////////////////////////////////////////
// Sets character 0 to an icon...
//
void curses_drv_icon(int which, char dest)
{
if(dest == 0)
switch(which)
{
case 0: icon_char = '+'; break;
case 1: icon_char = '*'; break;
default: icon_char = '#'; break;
}
}
//////////////////////////////////////////////////////////////////
// Flushes all output to the lcd...
//
void curses_drv_flush()
{
curses_drv_draw_frame(curses_drv->framebuf);
}
void curses_drv_flush_box(int lft, int top, int rgt, int bot)
{
curses_drv_flush();
}
void curses_drv_draw_frame(char *dat)
{
// border(0, 0, 0, 0, 0, 0, lcd.wid+1, lcd.hgt+1);
refresh();
}
char curses_drv_getkey()
{
int i;
i = getch();
if(i == KEY_LEFT) return 'D';
if(i == KEY_UP) return 'B';
if(i == KEY_DOWN) return 'C';
if(i == KEY_RIGHT) return 'A';
if(i != ERR) return i;
else return 0;
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef LCD_CURSES_H
#define LCD_CURSES_H
extern lcd_logical_driver *curses_drv;
int curses_drv_init(struct lcd_logical_driver *driver, char *args);
void curses_drv_close();
void curses_drv_clear();
void curses_drv_flush();
void curses_drv_string(int x, int y, char string[]);
void curses_drv_chr(int x, int y, char c);
void curses_drv_vbar(int x, int len);
void curses_drv_hbar(int x, int y, int len);
void curses_drv_icon(int which, char dest);
void curses_drv_flush();
void curses_drv_flush_box(int lft, int top, int rgt, int bot);
void curses_drv_draw_frame(char *dat);
char curses_drv_getkey();
void curses_drv_init_num();
void curses_drv_num(int x, int num);
#endif
+288
View File
@@ -0,0 +1,288 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#include "../lcd.h"
#include "debug.h"
//////////////////////////////////////////////////////////////////////////
////////////////////// For Debugging Output //////////////////////////////
//////////////////////////////////////////////////////////////////////////
// TODO: somehow allow access to the driver->framebuffer to each
// function...
int debug_init(struct lcd_logical_driver *driver, char *args)
{
printf("debug_init(%s)\n", device);
if(!driver->framebuf)
{
printf("Allocating frame buffer (%ix%i)\n", lcd.wid, lcd.hgt);
driver->framebuf = malloc(lcd.wid * lcd.hgt);
}
if(!driver->framebuf)
{
debug_close();
return -1;
}
if(driver->framebuf) printf("Frame buffer: %i\n", (int)driver->framebuf);
debug_clear();
driver->clear = debug_clear;
driver->string = debug_string;
driver->chr = debug_chr;
driver->vbar = debug_vbar;
driver->hbar = debug_hbar;
driver->init_num = debug_init_num;
driver->num = debug_num;
driver->init = debug_init;
driver->close = debug_close;
driver->flush = debug_flush;
driver->flush_box = debug_flush_box;
driver->contrast = debug_contrast;
driver->backlight = debug_backlight;
driver->set_char = debug_set_char;
driver->icon = debug_icon;
driver->init_vbar = debug_init_vbar;
driver->init_hbar = debug_init_hbar;
driver->draw_frame = debug_draw_frame;
driver->getkey = debug_getkey;
return 200; // 200 is arbitrary. (must be 1 or more)
}
void debug_close()
{
// Ack! This shouldn't crash the program, but does.. Why??
printf("debug_close()\n");
// This is the line which crashes.
if(driver->framebuf) free(driver->framebuf);
if(driver->framebuf) printf("Frame buffer: %i\n", (int)driver->framebuf);
driver->framebuf = NULL;
// printf("debug_close() finished\n");
}
/////////////////////////////////////////////////////////////////
// Clears the LCD screen
//
void debug_clear()
{
printf("clear()\n");
memset(driver->framebuf, ' ', lcd.wid*lcd.hgt);
}
//////////////////////////////////////////////////////////////////
// Flushes all output to the lcd...
//
void debug_flush()
{
printf("flush()\n");
lcd.draw_frame();
}
/////////////////////////////////////////////////////////////////
// Prints a string on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void debug_string(int x, int y, char string[])
{
int i;
printf("string(%i, %i):%s \n", x, y, string);
x -= 1; // Convert 1-based coords to 0-based...
y -= 1;
for(i=0; string[i]; i++)
{
driver->framebuf[(y*lcd.wid) + x + i] = string[i];
}
}
/////////////////////////////////////////////////////////////////
// Prints a character on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void debug_chr(int x, int y, char c)
{
printf("character(%i, %i):%c\n", x, y, c);
y--;
x--;
lcd.framebuf[(y*lcd.wid) + x] = c;
}
void debug_contrast(int contrast)
{
printf("Contrast: %i\n", contrast);
}
void debug_backlight(int on)
{
if(on)
{
printf("Backlight ON\n");
}
else
{
printf("Backlight OFF\n");
}
}
void debug_init_vbar()
{
printf("Vertical bars.\n");
}
void debug_init_hbar()
{
printf("Horizontal bars.\n");
}
void debug_init_num()
{
printf("Big Numbers.\n");
}
void debug_num(int x, int num)
{
printf("BigNum(%i, %i)\n", x, num);
}
void debug_set_char(int n, char *dat)
{
printf("Set Character %i\n", n);
}
/////////////////////////////////////////////////////////////////
// Draws a vertical bar; erases entire column onscreen.
//
void debug_vbar(int x, int len)
{
int y;
printf("Vbar(%i, %i)\n", x, len);
for(y=lcd.hgt; y > 0 && len>0; y--)
{
debug_chr(x, y, '|');
len -= lcd.cellhgt;
}
}
/////////////////////////////////////////////////////////////////
// Draws a horizontal bar to the right.
//
void debug_hbar(int x, int y, int len)
{
printf("Hbar(%i, %i, %i)\n", x, y, len);
for(; x<lcd.wid && len>0; x++)
{
debug_chr(x,y,'-');
len -= lcd.cellwid;
}
}
/////////////////////////////////////////////////////////////////
// Sets character 0 to an icon...
//
void debug_icon(int which, char dest)
{
printf("Char %i is icon %i\n", dest, which);
}
void debug_flush_box(int lft, int top, int rgt, int bot)
{
printf("Flush Box(%i, %i)-(%i, %i)\n", lft, top, rgt, bot);
debug_flush();
}
void debug_draw_frame(char *dat)
{
int i, j;
char out[LCD_MAX_WIDTH];
printf("draw_frame()\n");
if(!dat) return;
// printf("Frame (%ix%i): \n%s\n", lcd.wid, lcd.hgt, dat);
for(i=0; i<lcd.wid; i++)
{
out[i] = '-';
}
out[lcd.wid] = 0;
printf("+%s+\n", out);
for(i=0; i<lcd.hgt; i++)
{
for(j=0; j<lcd.wid; j++)
{
out[j] = dat[j+(i*lcd.wid)];
}
out[lcd.wid] = 0;
printf("|%s|\n", out);
}
for(i=0; i<lcd.wid; i++)
{
out[i] = '-';
}
out[lcd.wid] = 0;
printf("+%s+\n", out);
}
char debug_getkey()
{
printf("Trying to grab keypress.\n");
return 0;
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef LCD_DEBUG_H
#define LCD_DEBUG_H
int debug_init(struct lcd_logical_driver *driver, char *args);
void debug_close();
void debug_clear();
void debug_flush();
void debug_string(int x, int y, char string[]);
void debug_chr(int x, int y, char c);
void debug_contrast(int contrast);
void debug_backlight(int on);
void debug_init_vbar();
void debug_init_hbar();
void debug_init_num();
void debug_vbar(int x, int len);
void debug_hbar(int x, int y, int len);
void debug_num(int x, int num);
void debug_set_char(int n, char *dat);
void debug_icon(int which, char dest);
void debug_flush_box(int lft, int top, int rgt, int bot);
void debug_draw_frame(char *dat);
char debug_getkey();
#endif
+311
View File
@@ -0,0 +1,311 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#include "lcd.h"
#include "drv_base.h"
//////////////////////////////////////////////////////////////////////////
////////////////////// Base "class" to derive from ///////////////////////
//////////////////////////////////////////////////////////////////////////
lcd_logical_driver *drv_base;
// TODO: Get lcd.framebuf to properly work as whatever driver is running...
////////////////////////////////////////////////////////////
// init() should set up any device-specific stuff, and
// point all the function pointers.
int drv_base_init(struct lcd_logical_driver *driver, char *args)
{
// printf("drv_base_init()\n");
drv_base = driver;
driver->wid = 20;
driver->hgt = 4;
// You must use driver->framebuf here, but may use lcd.framebuf later.
if(!driver->framebuf)
driver->framebuf = malloc(driver->wid * driver->hgt);
if(!driver->framebuf)
{
drv_base_close();
return -1;
}
// Debugging...
// if(lcd.framebuf) printf("Frame buffer: %i\n", (int)lcd.framebuf);
memset(driver->framebuf, ' ', driver->wid*driver->hgt);
// drv_base_clear();
driver->cellwid = 5;
driver->cellhgt = 8;
driver->clear = drv_base_clear;
driver->string = drv_base_string;
driver->chr = drv_base_chr;
driver->vbar = drv_base_vbar;
driver->init_vbar = drv_base_init_vbar;
driver->hbar = drv_base_hbar;
driver->init_hbar = drv_base_init_hbar;
driver->num = drv_base_num;
driver->init_num = drv_base_init_num;
driver->init = drv_base_init;
driver->close = drv_base_close;
driver->flush = drv_base_flush;
driver->flush_box = drv_base_flush_box;
driver->contrast = drv_base_contrast;
driver->backlight = drv_base_backlight;
driver->set_char = drv_base_set_char;
driver->icon = drv_base_icon;
driver->draw_frame = drv_base_draw_frame;
driver->getkey = drv_base_getkey;
return 200; // 200 is arbitrary. (must be 1 or more)
}
// Below here, you may use either lcd.framebuf or driver->framebuf..
// lcd.framebuf will be set to the appropriate buffer before calling
// your driver.
void drv_base_close()
{
if(lcd.framebuf != NULL) free(lcd.framebuf);
lcd.framebuf = NULL;
}
/////////////////////////////////////////////////////////////////
// Clears the LCD screen
//
void drv_base_clear()
{
memset(lcd.framebuf, ' ', lcd.wid*lcd.hgt);
}
//////////////////////////////////////////////////////////////////
// Flushes all output to the lcd...
//
void drv_base_flush()
{
//lcd.draw_frame(lcd.framebuf);
}
/////////////////////////////////////////////////////////////////
// Prints a string on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void drv_base_string(int x, int y, char string[])
{
int i;
x -= 1; // Convert 1-based coords to 0-based...
y -= 1;
for(i=0; string[i]; i++)
{
// Check for buffer overflows...
if((y*lcd.wid) + x + i > (lcd.wid*lcd.hgt)) break;
lcd.framebuf[(y*lcd.wid) + x + i] = string[i];
}
}
/////////////////////////////////////////////////////////////////
// Prints a character on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void drv_base_chr(int x, int y, char c)
{
y--;
x--;
lcd.framebuf[(y*lcd.wid) + x] = c;
}
//////////////////////////////////////////////////////////////////////
// Sets the contrast of the display. Value is 0-255, where 140 is
// what I consider "just right".
//
int drv_base_contrast(int contrast)
{
// printf("Contrast: %i\n", contrast);
return -1;
}
//////////////////////////////////////////////////////////////////////
// Turns the lcd backlight on or off...
//
void drv_base_backlight(int on)
{
/*
if(on)
{
printf("Backlight ON\n");
}
else
{
printf("Backlight OFF\n");
}
*/
}
//////////////////////////////////////////////////////////////////////
// Tells the driver to get ready for vertical bargraphs.
//
void drv_base_init_vbar()
{
// printf("Vertical bars.\n");
}
//////////////////////////////////////////////////////////////////////
// Tells the driver to get ready for horizontal bargraphs.
//
void drv_base_init_hbar()
{
// printf("Horizontal bars.\n");
}
//////////////////////////////////////////////////////////////////////
// Tells the driver to get ready for big numbers, if possible.
//
void drv_base_init_num()
{
// printf("Big Numbers.\n");
}
//////////////////////////////////////////////////////////////////////
// Draws a big (4-row) number.
//
void drv_base_num(int x, int num)
{
// printf("BigNum(%i, %i)\n", x, num);
}
//////////////////////////////////////////////////////////////////////
// Changes the font data of character n.
//
void drv_base_set_char(int n, char *dat)
{
// printf("Set Character %i\n", n);
}
/////////////////////////////////////////////////////////////////
// Draws a vertical bar, from the bottom of the screen up.
//
void drv_base_vbar(int x, int len)
{
int y;
for(y=lcd.hgt; y > 0 && len>0; y--)
{
drv_base_chr(x, y, '|');
len -= lcd.cellhgt;
}
}
/////////////////////////////////////////////////////////////////
// Draws a horizontal bar to the right.
//
void drv_base_hbar(int x, int y, int len)
{
for(; x<=lcd.wid && len>0; x++)
{
drv_base_chr(x,y,'-');
len -= lcd.cellwid;
}
}
/////////////////////////////////////////////////////////////////
// Sets character 0 to an icon...
//
void drv_base_icon(int which, char dest)
{
// printf("Char %i set to icon %i\n", dest, which);
}
//////////////////////////////////////////////////////////////////////
// Send a rectangular area to the display.
//
// I've just called drv_base_flush() because there's not much point yet
// in flushing less than the entire framebuffer.
//
void drv_base_flush_box(int lft, int top, int rgt, int bot)
{
//drv_base_flush();
}
//////////////////////////////////////////////////////////////////////
// Draws the framebuffer on the display.
//
// The commented-out code is from the text driver.
//
void drv_base_draw_frame(char *dat)
{
/*
int i, j;
char out[LCD_MAX_WIDTH];
if(!dat) return;
for(i=0; i<lcd.wid; i++)
{
out[i] = '-';
}
out[lcd.wid] = 0;
printf("+%s+\n", out);
for(i=0; i<lcd.hgt; i++)
{
for(j=0; j<lcd.wid; j++)
{
out[j] = dat[j+(i*lcd.wid)];
}
out[lcd.wid] = 0;
printf("|%s|\n", out);
}
for(i=0; i<lcd.wid; i++)
{
out[i] = '-';
}
out[lcd.wid] = 0;
printf("+%s+\n", out);
*/
}
//////////////////////////////////////////////////////////////////////
// Tries to read a character from an input device...
//
// Return 0 for "nothing available".
//
char drv_base_getkey()
{
return 0;
}
+119
View File
@@ -0,0 +1,119 @@
#ifndef LCD_DRV_BASE_H
#define LCD_DRV_BASE_H
/********************************************************************
How to make a driver for LCDproc
Note: Insert the name of your driver in place of the phrase "new_driver".
1. Copy drv_base.c and drv_base.h to new_driver.c and new_driver.h.
2. Decide which functions you want to override, which ones you want
to leave alone, and which ones you don't want at all. If you
write your own driver functions, they will get called when
appropriate. Or, you can let the default driver "drv_base"
handle a function for you. But, if you really don't want a
function, you can completely prevent your driver from providing
it. This is discussed in step 5.
2.1. Remove all functions which you don't want to override, and the
ones you don't want at all.
3. Rename all functions from "drv_base_*" to "new_driver_*".
4. Write the new driver functions.
Be sure to do one of the following in/for your new_driver_close():
- free the framebuffer lcd.framebuf
- let the default driver handle close()
- call drv_base_close()
This will ensure that the frame buffer gets freed.
5. Register your functions in your new_driver_init(), like the following:
driver->clear = new_driver_clear; // We want to handle this one
driver->string = (void *)-1; // Leave this to the default
driver->getkey = NULL; // This should never get called
The convention here is to set NULL for all the functions which
your driver doesn't handle (and which you don't want the default
functions to be called for). Or, set -1 to indicate that the
driver should support the function but can use the default
behavior in drv_base.c. Or, to indicate that your driver should
handle a function, just set it like clear() above.
6. Add the driver to lcd.c, in the physical drivers section, protected
by an #ifdef like the rest of the drivers are.
7. Add your driver to the Makefile, and Makefile.config, in the same
style as the existing ones.
Notes:
Don't call lcd.whatever() functions within your driver. This causes
a lot of potentially puzzling problems.
However, feel free to access lcd.framebuf in your driver (but not in
your init() function!). It will always point to the frame buffer
you should be writing to. This will usually be your own frame
buffer, but could potentially be another frame buffer, if another
driver wants to access your functions.
Your driver will be provided with a frame buffer which contains one
byte per character on the LCD. The default is a 20x4, so that's 80
bytes. You can free this and reallocate it to something else if you
need to. A graphical driver may want to do this, for example.
If you don't set a function pointer, it will default to NULL, since
they get nullified before the driver's init() is called.
Assume that your driver may be added or removed dynamically, and
that more than one instance may exist at a time. In other words, it
should init and close cleanly, and not depend on global variables.
Special arguments will be passed through the "args" variable to your
_init() function. This is just a string, and you determine the
syntax of it. Please document the syntax so that it can easily be
included in the lcdproc config file. I suggest arguments such as
"port=0x378" or "-device /dev/ttyS0". These come directly from the
lcdproc server config file, so they should be human-readable. An
example may look like this:
# Set up two MtxOrb LCD's and a curses display on VT 2
Driver MtxOrb -device /dev/ttyS0 -keypad on
Driver curses -color off -size 20x4 -vt 2
Driver MtxOrb -device /dev/ttyS3 -size 20x2 -keypad off
# Before you ask, no, not all of these options are implemented yet.
Also, the driver API (if it can be called that) may change soon.
There seem to be several functions which just don't do anything
important... and there are other potential improvements too.
And... When in doubt, look at how the other drivers do it. :)
******************************************************************/
extern lcd_logical_driver *drv_base;
int drv_base_init(struct lcd_logical_driver *driver, char *args);
void drv_base_close();
void drv_base_clear();
void drv_base_flush();
void drv_base_string(int x, int y, char string[]);
void drv_base_chr(int x, int y, char c);
int drv_base_contrast(int contrast);
void drv_base_backlight(int on);
void drv_base_output(int on);
void drv_base_vbar(int x, int len);
void drv_base_init_vbar();
void drv_base_hbar(int x, int y, int len);
void drv_base_init_hbar();
void drv_base_num(int x, int num);
void drv_base_init_num();
void drv_base_set_char(int n, char *dat);
void drv_base_icon(int which, char dest);
void drv_base_flush_box(int lft, int top, int rgt, int bot);
void drv_base_draw_frame(char *dat);
char drv_base_getkey();
#endif
+562
View File
@@ -0,0 +1,562 @@
/* Driver module for Hitachi HD44780 based Optrex DMC-20481 LCD display
* The module is operated in it's 4 bit-mode to be connected to a single
* 8 bit-port
*
* Copyright (c) 1998 Richard Rognlie GNU Public License
* <rrognlie@gamerz.net>
*
* Large quantities of this code lifted (nearly verbatim) from
* the lcd4.c module of lcdtext. Copyright (C) 1997 Matthias Prinke
* <m.prinke@trashcan.mcnet.de> and covered by GNU's GPL.
* In particular, this program is free software and comes WITHOUT
* ANY WARRANTY.
*
* Matthias stole (er, adapted) the code from the package lcdtime by
* Benjamin Tse (blt@mundil.cs.mu.oz.au), August/October 1995
* which uses the LCD-controller's 8 bit-mode.
* References: port.h by <damianf@wpi.edu>
* Data Sheet LTN211, Philips
* Various FAQs and TXTs about Hitachi's LCD Controller HD44780 -
* www.paranoia.com/~filipg is a good starting point ???
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/perm.h>
#include "../../shared/str.h"
#include "lcd.h"
#include "hd44780.h"
#include "drv_base.h"
lcd_logical_driver *HD44780;
#define EN 64
#define RW 32
#define RS 16
#ifndef LPTPORT
unsigned int port = 0x378;
#else
unsigned int port = LPTPORT;
#endif
static int lcd_x=0;
static int lcd_y=0;
static void HD44780_linewrap(int on);
static void HD44780_autoscroll(int on);
static int lp;
static void HD44780_senddata(unsigned char flags, unsigned char ch)
{
unsigned char h = ch >> 4;
unsigned char l = ch & 15;
port_out(lp, 128 | EN | flags | h); usleep(1); port_out(lp, 128 | flags | h);
port_out(lp, 128 | EN | flags | l); usleep(1); port_out(lp, 128 | flags | l);
}
/////////////////////////////////////////////////////////////////
// Opens com port and sets baud correctly...
//
int HD44780_init(lcd_logical_driver *driver, char *args)
{
char *argv[64];
int argc;
int i;
HD44780 = driver;
argc = get_args(argv, args, 64);
for(i=0; i<argc; i++)
{
//printf("Arg(%i): %s\n", i, argv[i]);
if(0 == strcmp(argv[i], "-p") ||
0 == strcmp(argv[i], "--port"))
{
if(i + 1 > argc) {
fprintf(stderr, "HD44780_init: %s requires an argument\n",
argv[i]);
return -1;
}
printf("Sorry, runtime lpt-port switching not yet implemented...\n");
//strcpy(device, argv[++i]);
}
else if(0 == strcmp(argv[i], "-c") ||
0 == strcmp(argv[i], "--contrast"))
{
if(i + 1 > argc) {
fprintf(stderr, "HD44780_init: %s requires an argument\n",
argv[i]);
return -1;
}
printf("Sorry, contrast changing not yet implemented...\n");
//contrast = atoi(argv[++i]);
}
else if(0 == strcmp(argv[i], "-h") ||
0 == strcmp(argv[i], "--help"))
{
printf("LCDproc HD44780 driver\n"
"\t-p\t--port\tSelect the output device to use [0x%x]\n"
"\t-c\t--contrast\tSet the initial contrast [default]\n"
"\t-h\t--help\t\tShow this help information\n",
port);
return -1;
}
else
{
printf("Invalid parameter: %s\n", argv[i]);
}
}
// Set up io port correctly, and open it...
if ((ioperm(port,1,1)) == -1) {
fprintf(stderr, "HD44780_init: failed (%s)\n", strerror(errno));
return -1;
}
lp = port;
// init HD44780
port_out(lp, 128 | EN | 3); usleep(1); port_out(lp, 128 | 3); usleep(5000);
port_out(lp, 128 | EN | 3); usleep(1); port_out(lp, 128 | 3); usleep(150);
port_out(lp, 128 | EN | 3); usleep(1); port_out(lp, 128 | 3);
// now in 8-bit mode... set 4-bit mode
port_out(lp, 128 | EN | 2); usleep(1); port_out(lp, 128 | 2);
// now in 4-bit mode... set 2 line, small char mode
HD44780_senddata(0, 32 | 8);
//clear
HD44780_senddata(0, 1);
// set lcd on (4), cursor_on (2), and cursor_blink(1)
HD44780_senddata(0, 8 | 4 | 0 | 0);
// Set display-specific stuff..
//HD44780_linewrap(1);
//HD44780_autoscroll(1);
// Make sure the frame buffer is there...
if (!HD44780->framebuf)
HD44780->framebuf = (unsigned char *) malloc(lcd.wid * lcd.hgt);
if (!HD44780->framebuf) {
//HD44780_close();
return -1;
}
// Set the functions the driver supports...
driver->clear = (void *)-1;
driver->string = (void *)-1;
driver->chr = (void *)-1;
driver->vbar = HD44780_vbar;
driver->init_vbar = HD44780_init_vbar;
driver->hbar = HD44780_hbar;
driver->init_hbar = HD44780_init_hbar;
driver->num = HD44780_num;
driver->init_num = HD44780_init_num;
driver->init = HD44780_init;
driver->close = (void *)-1;
driver->flush = HD44780_flush;
driver->flush_box = HD44780_flush_box;
driver->contrast = HD44780_contrast;
driver->backlight = HD44780_backlight;
driver->set_char = HD44780_set_char;
driver->icon = HD44780_icon;
driver->draw_frame = HD44780_draw_frame;
driver->getkey = NULL;
return lp;
}
/////////////////////////////////////////////////////////////////
// Clean-up
//
/*
void HD44780_close()
{
drv_base_close();
}
*/
static void HD44780_position(int x, int y)
{
int val = x + (y%2) * 0x40;
if (y>=2) val += 20;
HD44780_senddata(0,128|val);
lcd_x = x;
lcd_y = y;
}
void HD44780_flush()
{
HD44780_draw_frame(lcd.framebuf);
}
void HD44780_flush_box(int lft, int top, int rgt, int bot)
{
int x,y;
// printf("Flush (%i,%i)-(%i,%i)\n", lft, top, rgt, bot);
for (y=top; y<=bot; y++) {
HD44780_position(lft,y);
for (x=lft ; x<=rgt ; x++) {
HD44780_senddata(RS,lcd.framebuf[(y*20)+x]);
}
//write(fd, lcd.framebuf[(y*20)+lft, rgt-lft+1]);
}
}
/////////////////////////////////////////////////////////////////
// Changes screen contrast (0-255; 140 seems good)
//
int HD44780_contrast(int contrast)
{
return 0;
}
/////////////////////////////////////////////////////////////////
// Sets the backlight on or off -- can be done quickly for
// an intermediate brightness...
//
void HD44780_backlight(int on)
{
}
/////////////////////////////////////////////////////////////////
// Toggle the built-in linewrapping feature
//
static void HD44780_linewrap(int on)
{
}
/////////////////////////////////////////////////////////////////
// Toggle the built-in automatic scrolling feature
//
static void HD44780_autoscroll(int on)
{
HD44780_senddata(0,4 | on * 2);
}
/////////////////////////////////////////////////////////////////
// Sets up for vertical bars. Call before lcd.vbar()
//
void HD44780_init_vbar()
{
char a[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
};
char b[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
};
char c[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
char d[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
char e[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
char f[] = {
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
char g[] = {
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
HD44780_set_char(1,a);
HD44780_set_char(2,b);
HD44780_set_char(3,c);
HD44780_set_char(4,d);
HD44780_set_char(5,e);
HD44780_set_char(6,f);
HD44780_set_char(7,g);
}
/////////////////////////////////////////////////////////////////
// Inits horizontal bars...
//
void HD44780_init_hbar()
{
char a[] = {
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
};
char b[] = {
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
};
char c[] = {
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
};
char d[] = {
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
};
HD44780_set_char(1,a);
HD44780_set_char(2,b);
HD44780_set_char(3,c);
HD44780_set_char(4,d);
}
/////////////////////////////////////////////////////////////////
// Draws a vertical bar...
//
void HD44780_vbar(int x, int len)
{
char map[9] = {32, 1, 2, 3, 4, 5, 6, 7, 255 };
int y;
for(y=lcd.hgt; y > 0 && len>0; y--) {
if (len >= lcd.cellhgt)
drv_base_chr(x, y, 255);
else
drv_base_chr(x, y, map[len]);
len -= lcd.cellhgt;
}
}
/////////////////////////////////////////////////////////////////
// Draws a horizontal bar to the right.
//
void HD44780_hbar(int x, int y, int len)
{
char map[6] = { 32, 1, 2, 3, 4, 255 };
for (; x<=lcd.wid && len>0; x++) {
if (len >= lcd.cellwid)
drv_base_chr(x,y,255);
else
drv_base_chr(x, y, map[len]);
len -= lcd.cellwid;
}
}
/////////////////////////////////////////////////////////////////
// Sets up for big numbers.
//
void HD44780_init_num()
{
char out[3];
sprintf(out, "%cn", 254);
//write(fd, out, 2);
}
/////////////////////////////////////////////////////////////////
// Writes a big number.
//
void HD44780_num(int x, int num)
{
char out[5];
sprintf(out, "%c#%c%c", 254, x, num);
//write(fd, out, 4);
}
/////////////////////////////////////////////////////////////////
// Sets a custom character from 0-7...
//
// For input, values > 0 mean "on" and values <= 0 are "off".
//
// The input is just an array of characters...
//
void HD44780_set_char(int n, char *dat)
{
int row, col;
int letter;
if(n < 0 || n > 7) return;
if(!dat) return;
HD44780_senddata(0, 64 | n*8);
for(row=0; row<lcd.cellhgt; row++) {
letter = 0;
for(col=0; col<lcd.cellwid; col++) {
letter <<= 1;
letter |= (dat[(row*lcd.cellwid) + col] > 0);
}
HD44780_senddata(RS, letter);
}
}
void HD44780_icon(int which, char dest)
{
char icons[3][5*8] = {
{
1,1,1,1,1, // Empty Heart
1,0,1,0,1,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,0,0,0,1,
1,1,0,1,1,
1,1,1,1,1,
},
{
1,1,1,1,1, // Filled Heart
1,0,1,0,1,
0,1,0,1,0,
0,1,1,1,0,
0,1,1,1,0,
1,0,1,0,1,
1,1,0,1,1,
1,1,1,1,1,
},
{
0,0,0,0,0, // Ellipsis
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,0,1,0,1,
},
};
HD44780_set_char(dest, &icons[which][0]);
}
/////////////////////////////////////////////////////////////
// Blasts a single frame onscreen, to the lcd...
//
// Input is a character array, sized lcd.wid*lcd.hgt
//
void HD44780_draw_frame(char *dat)
{
int x,y;
if (!dat) return;
for (y=0; y<=3; y++) {
HD44780_position(0,y);
for (x=0 ; x<=19 ; x++) {
HD44780_senddata(RS,dat[(y*lcd.wid)+x]);
}
}
}
+49
View File
@@ -0,0 +1,49 @@
/* Driver module for Hitachi HD44780 based Optrex DMC-20481 LCD display
* The module is operated in it's 4 bit-mode to be connected to a single
* 8 bit-port
*
* Copyright (c) 1998 Richard Rognlie GNU Public License
* <rrognlie@gamerz.net>
*
* Large quantities of this code lifted (nearly verbatim) from
* the lcd4.c module of lcdtext. Copyright (C) 1997 Matthias Prinke
* <m.prinke@trashcan.mcnet.de> and covered by GNU's GPL.
* In particular, this program is free software and comes WITHOUT
* ANY WARRANTY.
*
* Matthias stole (er, adapted) the code from the package lcdtime by
* Benjamin Tse (blt@mundil.cs.mu.oz.au), August/October 1995
* which uses the LCD-controller's 8 bit-mode.
* References: port.h by <damianf@wpi.edu>
* Data Sheet LTN211, Philips
* Various FAQs and TXTs about Hitachi's LCD Controller HD44780 -
* www.paranoia.com/~filipg is a good starting point ???
*/
#ifndef HD44780_H
#define HD44780_H
#include "port.h"
extern lcd_logical_driver *hd44780;
int HD44780_init(struct lcd_logical_driver *driver, char *args);
void HD44780_close();
void HD44780_flush();
void HD44780_flush_box(int lft, int top, int rgt, int bot);
int HD44780_contrast(int contrast);
void HD44780_backlight(int on);
void HD44780_init_vbar();
void HD44780_init_hbar();
void HD44780_vbar(int x, int len);
void HD44780_hbar(int x, int y, int len);
void HD44780_init_num();
void HD44780_num(int x, int num);
void HD44780_set_char(int n, char *dat);
void HD44780_icon(int which, char dest);
void HD44780_draw_frame(char *dat);
#endif
+21
View File
@@ -0,0 +1,21 @@
Hmm...
How to do multiple drivers...
lcd_sample_func(parameters)
{
D'oh..
}
lcd_driver_caller()
{
foreach driver (@drivers)
{
if(driver supports function)
call driver's function
else if(driver uses defaults)
call default function
else don't do anything
}
}
+218
View File
@@ -0,0 +1,218 @@
/* irmanin.c - test/demo of LIBIR's to interface with lcdproc (LCDd) */
/* Copyright (C) 1999 David Glaude loosely based on workmanir.c */
/* workmanir.c - test/demo of LIBIR's high level command functions */
/* Copyright (C) 1998 Tom Wheeley, see file COPYING for details */
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <errno.h>
#define __u32 unsigned int
#define __u8 unsigned char
#include "../../shared/debug.h"
#include "../../shared/str.h"
#define NAME_LENGTH 128
#include "lcd.h"
#include "irmanin.h"
#include "../../../libirman-0.4.1b/irman.h"
char *progname = "irmanin";
char *codes[] = {
/* dummy */ NULL,
/* KeyToLcd */ "lcdproc-A",
/* KeyToLcd */ "lcdproc-B",
/* KeyToLcd */ "lcdproc-C",
/* KeyToLcd */ "lcdproc-D",
/* KeyToLcd */ "lcdproc-E",
/* KeyToLcd */ "lcdproc-F",
/* KeyToLcd */ "lcdproc-G",
/* KeyToLcd */ "lcdproc-H",
/* KeyToLcd */ "lcdproc-I",
/* KeyToLcd */ "lcdproc-J",
/* KeyToLcd */ "lcdproc-K",
/* KeyToLcd */ "lcdproc-L",
/* KeyToLcd */ "lcdproc-M",
/* KeyToLcd */ "lcdproc-N",
/* KeyToLcd */ "lcdproc-O",
/* KeyToLcd */ "lcdproc-P",
/* KeyToLcd */ "lcdproc-Q",
/* KeyToLcd */ "lcdproc-R",
/* KeyToLcd */ "lcdproc-S",
/* KeyToLcd */ "lcdproc-T",
/* KeyToLcd */ "lcdproc-U",
/* KeyToLcd */ "lcdproc-V",
/* KeyToLcd */ "lcdproc-W",
/* KeyToLcd */ "lcdproc-X",
/* KeyToLcd */ "lcdproc-Y",
/* KeyToLcd */ "lcdproc-Z",
/* end */ NULL
};
//////////////////////////////////////////////////////////////////////////
////////////////////// Base "class" to derive from ///////////////////////
//////////////////////////////////////////////////////////////////////////
lcd_logical_driver *irmanin;
//void sigterm(int sig)
//{
// ir_free_commands();
// ir_finish();
// raise(sig);
//}
////////////////////////////////////////////////////////////
// init() should set up any device-specific stuff, and
// point all the function pointers.
int irmanin_init(struct lcd_logical_driver *driver, char *args)
{
char device[256];
char *ptrdevice;
char config[256];
char *ptrconfig;
char *portname;
char *argv[64];
int argc, i, j;
char *filename;
ptrconfig=NULL;
ptrdevice=NULL;
irmanin = driver;
argc = get_args(argv, args, 64);
for(i=0; i<argc; i++)
{
//printf("Arg(%i): %s\n", i, argv[i]);
if(0 == strcmp(argv[i], "-d") ||
0 == strcmp(argv[i], "--device"))
{
if(i + 1 > argc) {
fprintf(stderr, "irmanin_init: %s requires an argument\n",
argv[i]);
return -1;
}
strcpy(device, argv[++i]);
ptrdevice=device;
}
else if(0 == strcmp(argv[i], "-c") ||
0 == strcmp(argv[i], "--config"))
{
if(i + 1 > argc) {
fprintf(stderr, "irmanin_init: %s requires an argument\n",
argv[i]);
return -1;
}
strcpy(config, argv[++i]);
ptrconfig=config;
}
else if(0 == strcmp(argv[i], "-h") ||
0 == strcmp(argv[i], "--help"))
{
printf("LCDproc IrMan input driver\n"
"\t-d\t--device\tSelect the input device to use\n"
"\t-d\t--config\tSelect the configuration file to use\n"
"\t-h\t--help\t\tShow this help information\n");
return -1;
}
else
{
printf("Invalid parameter: %s\n", argv[i]);
}
}
if (ir_init_commands(ptrconfig, 1) < 0) {
fprintf(stderr, "error initialising commands: %s\n", strerror(errno));
exit(1);
}
portname = ir_default_portname();
if(portname==NULL){
if(ptrdevice==NULL){
portname=ptrdevice;
}else{
fprintf(stderr, "error no device defined\n");
exit(1);
}
}
driver->getkey = irmanin_getkey;
driver->close = irmanin_close;
for (i=1; codes[i] != NULL; i++) {
if (ir_register_command(codes[i], i) < 0) {
if (errno == ENOENT) {
fprintf(stderr, "%s: no code set for `%s'\n", progname, codes[i]);
} else {
fprintf(stderr, "error registering `%s': `%s'\n", codes[i], strerror(errno));
}
}
}
errno = 0;
if (ir_init(portname) < 0) {
fprintf(stderr, "%s: error initialising Irman: `%s'\n", strerror(errno), portname);
exit(1);
}
return 1; // 200 is arbitrary. (must be 1 or more)
}
void irmanin_close()
{
if(irmanin->framebuf != NULL) free(irmanin->framebuf);
irmanin->framebuf = NULL;
ir_free_commands();
ir_finish();
}
//////////////////////////////////////////////////////////////////////
// Tries to read a character from an input device...
//
// Return 0 for "nothing available".
//
char irmanin_getkey()
{
int i;
int cmd;
char key;
key=(char)0;
switch (cmd=ir_poll_command()) {
case IR_CMD_ERROR:
fprintf(stderr, "%s: error reading command: %s\n", progname, strerror(errno));
break;
case IR_CMD_UNKNOWN:
break;
default:
key=(char)('A'-1+cmd);
break;
}
return key;
}
/* end of irmanin.c */
+12
View File
@@ -0,0 +1,12 @@
#ifndef LCD_IRMANIN__H
#define LCD_IRMANIN_H
extern lcd_logical_driver *joy;
int irmanin_init(struct lcd_logical_driver *driver, char *args);
void irmanin_close();
char irmanin_getkey();
#endif
+218
View File
@@ -0,0 +1,218 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#define __u32 unsigned int
#define __u8 unsigned char
#include <linux/joystick.h>
#include "../../shared/debug.h"
#include "../../shared/str.h"
#define NAME_LENGTH 128
#include "lcd.h"
#include "joy.h"
//////////////////////////////////////////////////////////////////////////
////////////////////// Base "class" to derive from ///////////////////////
//////////////////////////////////////////////////////////////////////////
lcd_logical_driver *joy;
int fd;
struct js_event js;
char axes = 2;
char buttons = 2;
int jsversion = 0x000800;
char jsname[NAME_LENGTH] = "Unknown";
int *axis;
int *button;
// Configured for a Gravis Gamepad (2 axis, 4 button)
char *axismap = "EFGHIJKLMNOPQRST";
char *buttonmap = "BDACEFGHIJKLMNOP";
////////////////////////////////////////////////////////////
// init() should set up any device-specific stuff, and
// point all the function pointers.
int joy_init(struct lcd_logical_driver *driver, char *args)
{
char device[256];
char *argv[64];
int argc, i, j;
joy = driver;
strcpy(device, "/dev/js0");
argc = get_args(argv, args, 64);
for(i=0; i<argc; i++)
{
//printf("Arg(%i): %s\n", i, argv[i]);
if(0 == strcmp(argv[i], "-d") ||
0 == strcmp(argv[i], "--device"))
{
if(i + 1 > argc) {
fprintf(stderr, "joy_init: %s requires an argument\n",
argv[i]);
return -1;
}
strcpy(device, argv[++i]);
}
else if(0 == strcmp(argv[i], "-a") ||
0 == strcmp(argv[i], "--axes"))
{
if(i + 1 > argc) {
fprintf(stderr, "joy_init: %s requires an argument\n",
argv[i]);
return -1;
}
strncpy(axismap, argv[++i], 16);
}
else if(0 == strcmp(argv[i], "-b") ||
0 == strcmp(argv[i], "--buttons"))
{
if(i + 1 > argc) {
fprintf(stderr, "joy_init: %s requires an argument\n",
argv[i]);
return -1;
}
strncpy(buttonmap, argv[++i], 16);
}
else if(0 == strcmp(argv[i], "-h") ||
0 == strcmp(argv[i], "--help"))
{
printf("LCDproc Joystick input driver\n"
"\t-d\t--device\tSelect the input device to use [/dev/js0]\n"
"\t-a\t--axes\t\tModify the axis map [%s]\n"
"\t-b\t--buttons\tModify the button map [%s]\n"
"\t-h\t--help\t\tShow this help information\n",
axismap, buttonmap);
return -1;
}
else
{
printf("Invalid parameter: %s\n", argv[i]);
}
}
driver->getkey = joy_getkey;
driver->close = joy_close;
/* FIXME: This crashes!
if(args)
{
if(strlen(args) > 0)
strcpy(device, args);
}
*/
fd = open (device, O_RDONLY);
fcntl(fd, F_SETFL, O_NONBLOCK);
if(fd < 0) return -1;
ioctl(fd, JSIOCGVERSION, &jsversion);
ioctl(fd, JSIOCGAXES, &axes);
ioctl(fd, JSIOCGBUTTONS, &buttons);
ioctl(fd, JSIOCGNAME(NAME_LENGTH), jsname);
debug("Joystick (%s) has %d axes and %d buttons. Driver version is %d.%d.%d.\n",
jsname, axes, buttons,
jsversion >> 16, (jsversion >> 8) & 0xff, jsversion & 0xff);
axis = calloc(axes, sizeof(int));
button = calloc(buttons, sizeof(char));
return fd; // 200 is arbitrary. (must be 1 or more)
}
void joy_close()
{
if(joy->framebuf != NULL) free(joy->framebuf);
close(fd);
joy->framebuf = NULL;
// Why do I have so much trouble getting memory freed without segfaults??
//if(axis) free(axis);
//if(button) free(button);
}
//////////////////////////////////////////////////////////////////////
// Tries to read a character from an input device...
//
// Return 0 for "nothing available".
//
char joy_getkey()
{
int i;
int err;
err = read(fd, &js, sizeof(struct js_event));
if (err <= 0) return 0;
if (err != sizeof(struct js_event)) {
fprintf(stderr, "\nerror reading joystick\n");
return 0;
}
// if(js.type & JS_EVENT_INIT) return 0;
switch(js.type & ~JS_EVENT_INIT) {
case JS_EVENT_BUTTON:
button[js.number] = js.value;
break;
case JS_EVENT_AXIS:
axis[js.number] = js.value;
break;
}
if (buttons) {
//printf("Buttons: ");
for (i = 0; i < buttons; i++)
//printf("%2d:%s ", i, button[i] ? "on " : "off");
if(button[i]) return buttonmap[i];
}
if (axes) {
//printf("Axes: ");
for (i = 0; i < axes; i++)
{
//printf("%2d:%6d ", i, axis[i]);
// Eliminate noise...
if(axis[i] > 20000) return axismap[(2*i) + 1];
if(axis[i] < -20000) return axismap[(2*i)];
}
}
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef LCD_JOY_H
#define LCD_JOY_H
extern lcd_logical_driver *joy;
int joy_init(struct lcd_logical_driver *driver, char *args);
void joy_close();
char joy_getkey();
#endif
+727
View File
@@ -0,0 +1,727 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#include "LL.h"
#include "lcd.h"
#include "drv_base.h"
#ifdef MTXORB_DRV
#include "MtxOrb.h"
#endif
#ifdef CFONTZ_DRV
#include "CFontz.h"
#endif
#ifdef TEXT_DRV
#include "text.h"
#endif
#ifdef DEBUG_DRV
#include "debug.h"
#endif
#ifdef CURSES_DRV
#include "curses_drv.h"
#endif
#ifdef HD44780_DRV
#include "hd44780.h"
#endif
#ifdef SLI_DRV
#include "wirz-sli.h"
#endif
#ifdef JOY_DRV
#include "joy.h"
#endif
#ifdef IRMANIN_DRV
#include "irmanin.h"
#endif
// TODO: Make a Windows server, and clients...?
lcd_logical_driver lcd;
lcd_physical_driver drivers[] =
{
{ "base", drv_base_init, },
#ifdef MTXORB_DRV
{ "MtxOrb", MtxOrb_init, },
#endif
#ifdef CFONTZ_DRV
{ "CFontz", CFontz_init, },
#endif
#ifdef HD44780_DRV
{ "HD44780", HD44780_init, },
#endif
#ifdef SLI_DRV
{ "sli", sli_init, },
#endif
#ifdef TEXT_DRV
{ "text", text_init, },
#endif
#ifdef DEBUG_DRV
{ "debug", debug_init, },
#endif
#ifdef CURSES_DRV
{ "curses", curses_drv_init, },
#endif
#ifdef JOY_DRV
{ "joy", joy_init, },
#endif
#ifdef IRMANIN_DRV
{ "irmanin", irmanin_init, },
#endif
{ NULL, NULL, },
};
LL *list;
////////////////////////////////////////////////////////////
// This sets up which driver to use and initializes stuff.
//
int lcd_init(char *args)
{
// int i;
int err;
list = LL_new();
if(!list)
{
printf("Error allocating driver list.\n");
return -1;
}
lcd_drv_init(NULL, NULL);
err = lcd_add_driver("base", args);
lcd.wid = 20;
lcd.hgt = 4;
return err;
/*
drv_base_init(args);
for(i=0; drivers[i].name; i++)
{
if(!strcmp(driver, drivers[i].name))
{
return drivers[i].init(args);
}
}
printf("Invalid driver: %s\n", driver);
return -1;
*/
}
// TODO: lcd_remove_driver()
int lcd_add_driver(char *driver, char *args)
{
int i;
lcd_logical_driver *add;
for(i=0; drivers[i].name; i++)
{
//printf("Checking driver: %s\n", drivers[i].name);
if(0 == strcmp(driver, drivers[i].name))
{
//printf("Found driver: %s (%s)\n", drivers[i].name, driver);
add = malloc(sizeof(lcd_logical_driver));
if(!add)
{
printf("Couldn't allocate driver \"%s\".\n", driver);
return -1;
}
//printf("Allocated driver\n");
memset(add, 0, sizeof(lcd_logical_driver));
add->wid = lcd.wid; add->hgt = lcd.hgt;
add->cellwid = lcd.cellwid; add->cellhgt = lcd.cellhgt;
// printf("LCD driver info:\n\twid: %i\thgt: %i\n",
// add->wid, add->hgt);
add->framebuf = malloc(add->wid * add->hgt);
if(!add->framebuf)
{
printf("Couldn't allocate framebuffer for driver \"%s\".\n",
driver);
free(add);
return -1;
}
//printf("Allocated frame buffer\n");
LL_Push(list, (void *)add);
return drivers[i].init(add, args);
}
}
return -1;
}
// TODO: Put lcd_shutdown in the shutdown function...
int lcd_shutdown()
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
//printf("driver...\n");
lcd.framebuf = driver->framebuf;
if((int)driver->close > 0)
{
driver->close();
}
else if((int)driver->close == -1)
{
drv_base->close();
}
LL_Shift(list);
// FIXME: This crashes!
//if(driver) free(driver);
//printf("...freed\n");
}
} while(LL_Length(list) > 0);
return 0;
}
int lcd_drv_init(struct lcd_logical_driver *driver, char *args)
{
// printf("lcd_drv_init()\n");
lcd.wid = LCD_MAX_WID;
lcd.hgt = LCD_MAX_HGT;
lcd.framebuf = NULL;
/*
if(!lcd.framebuf)
lcd.framebuf = malloc(lcd.wid * lcd.hgt);
if(!lcd.framebuf)
{
lcd_drv_close();
return -1;
}
memset(lcd.framebuf, ' ', lcd.wid*lcd.hgt);
*/
// Debugging...
// if(lcd.framebuf) printf("Frame buffer: %i\n", (int)lcd.framebuf);
lcd.cellwid = 5;
lcd.cellhgt = 8;
// Set up these wrapper functions...
lcd.clear = lcd_drv_clear;
lcd.string = lcd_drv_string;
lcd.chr = lcd_drv_chr;
lcd.vbar = lcd_drv_vbar;
lcd.hbar = lcd_drv_hbar;
lcd.init_num = lcd_drv_init_num;
lcd.num = lcd_drv_num;
lcd.init = lcd_drv_init;
lcd.close = lcd_drv_close;
lcd.flush = lcd_drv_flush;
lcd.flush_box = lcd_drv_flush_box;
lcd.contrast = lcd_drv_contrast;
lcd.backlight = lcd_drv_backlight;
lcd.output = lcd_drv_output;
lcd.set_char = lcd_drv_set_char;
lcd.icon = lcd_drv_icon;
lcd.init_vbar = lcd_drv_init_vbar;
lcd.init_hbar = lcd_drv_init_hbar;
lcd.draw_frame = lcd_drv_draw_frame;
lcd.getkey = lcd_drv_getkey;
return 1; // 1 is arbitrary. (must be 1 or more)
}
//////////////////////////////////////////////////////////////////////
// All functions below here call their respective driver functions...
//
// The way it works is this:
// It loops through the list of drivers, calling each one to keep
// them all synchronized. During this loop...
// - First, set the framebuffer to point to the drivers' framebuffer.
// (this ensures that whatever driver gets called will operate on
// the correct buffer)
// - Then, it checks to see what sort of call to make.
// driver->func() > 0 means it should call the driver function.
// driver->func() == NULL means it should not make a call.
// driver->func() == -1 means it should call the generic driver.
//////////////////////////////////////////////////////////////////////
void lcd_drv_close()
{
lcd_logical_driver *driver;
// printf("lcd_drv_close()\n");
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->close > 0)
{
printf("Calling close()\n");
driver->close();
}
else if((int)driver->close == -1)
{
drv_base->close();
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_clear()
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->clear > 0)
driver->clear();
else if((int)driver->clear == -1)
{
drv_base->clear();
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_flush()
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->flush > 0)
driver->flush();
else if((int)driver->flush == -1)
{
drv_base->flush();
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_string(int x, int y, char string[])
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->string > 0)
driver->string(x,y,string);
else if((int)driver->string == -1)
{
drv_base->string(x,y,string);
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_chr(int x, int y, char c)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->chr > 0)
driver->chr(x,y,c);
else if((int)driver->chr == -1)
{
drv_base->chr(x,y,c);
}
}
} while(LL_Next(list) == 0);
}
int lcd_drv_contrast(int contrast)
{
int res=0;
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->contrast > 0)
{
res=driver->contrast(contrast);
if(res >= 0) return res;
}
/*
else if((int)driver->contrast == -1)
{
res=drv_base->contrast(contrast);
}
*/
}
} while(LL_Next(list) == 0);
return res;
}
void lcd_drv_backlight(int on)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->backlight > 0)
driver->backlight(on);
else if((int)driver->backlight == -1)
{
drv_base->backlight(on);
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_output(int on)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do
{
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->output > 0)
driver->output(on);
else if((int)driver->output == -1)
{
drv_base->output(on);
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_init_vbar()
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->init_vbar > 0)
driver->init_vbar();
else if((int)driver->init_vbar == -1)
{
drv_base->init_vbar();
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_init_hbar()
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->init_hbar > 0)
driver->init_hbar();
else if((int)driver->init_hbar == -1)
{
drv_base->init_hbar();
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_init_num()
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->init_num > 0)
driver->init_num();
else if((int)driver->init_num == -1)
{
drv_base->init_num();
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_num(int x, int num)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->num > 0)
driver->num(x,num);
else if((int)driver->num == -1)
{
drv_base->num(x,num);
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_set_char(int n, char *dat)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->set_char > 0)
driver->set_char(n,dat);
else if((int)driver->set_char == -1)
{
drv_base->set_char(n,dat);
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_vbar(int x, int len)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->vbar > 0)
driver->vbar(x,len);
else if((int)driver->vbar == -1)
{
drv_base->vbar(x,len);
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_hbar(int x, int y, int len)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->hbar > 0)
driver->hbar(x,y,len);
else if((int)driver->hbar == -1)
{
drv_base->hbar(x,y,len);
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_icon(int which, char dest)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->icon > 0)
driver->icon(which,dest);
else if((int)driver->icon == -1)
{
drv_base->icon(which,dest);
}
}
} while(LL_Next(list) == 0);
}
void lcd_drv_flush_box(int lft, int top, int rgt, int bot)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->flush_box > 0)
driver->flush_box(lft,top,rgt,bot);
else if((int)driver->flush_box == -1)
{
drv_base->flush_box(lft,top,rgt,bot);
}
}
} while(LL_Next(list) == 0);
}
// TODO: Check whether lcd.draw_frame() should really take a framebuffer
// TODO: as an argument, or if it should always use lcd.framebuf
void lcd_drv_draw_frame(char *dat)
{
lcd_logical_driver *driver;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->draw_frame > 0)
driver->draw_frame(dat);
else if((int)driver->draw_frame == -1)
{
drv_base->draw_frame(dat);
}
}
} while(LL_Next(list) == 0);
}
char lcd_drv_getkey()
{
lcd_logical_driver *driver;
char key;
LL_Rewind(list);
do {
driver = (lcd_logical_driver *)LL_Get(list);
if(driver)
{
lcd.framebuf = driver->framebuf;
if((int)driver->getkey > 0)
{
key = driver->getkey();
if(key) return key;
}
else if((int)driver->getkey == -1)
{
key = drv_base->getkey();
if(key) return key;
}
}
} while(LL_Next(list) == 0);
return 0;
}
+95
View File
@@ -0,0 +1,95 @@
#ifndef LCD_H
#define LCD_H
// Maximum supported sizes
#define LCD_MAX_WID 256
#define LCD_MAX_WIDTH 256
#define LCD_MAX_HGT 256
#define LCD_MAX_HEIGHT 256
int lcd_init(char *args);
int lcd_add_driver(char *driver, char *args);
int lcd_shutdown();
/////////////////////////////////////////////////////////////////
// Driver functions / info held here...
//
// Feel free to override any/all functions here with real driver
// functions...
//
typedef struct lcd_logical_driver
{
// Size in cells of the LCD
int wid, hgt;
// Size of each LCD cell, in pixels
int cellwid, cellhgt;
// Frame buffer...
char *framebuf;
// Functions which might be the same for all drivers...
void (*clear)();
void (*string)(int x, int y, char lcd[]);
void (*chr)(int x, int y, char c);
void (*vbar)(int x, int len);
void (*hbar)(int x, int y, int len);
void (*init_num)();
void (*num)(int x, int num);
// Functions which should probably be implemented in each driver...
int (*init)(struct lcd_logical_driver *driver, char *args);
void (*close)();
void (*flush)();
void (*flush_box)(int lft, int top, int rgt, int bot);
int (*contrast)(int contrast);
void (*backlight)(int on);
void (*output)(int on);
void (*set_char)(int n, char *dat);
void (*icon)(int which, char dest);
void (*init_vbar)();
void (*init_hbar)();
void (*draw_frame)();
// Returns 0 for "no key pressed", or (A-Z).
char (*getkey)();
// more?
} lcd_logical_driver;
typedef struct lcd_physical_driver
{
char *name;
int (*init)(struct lcd_logical_driver *driver, char *device);
} lcd_physical_driver;
extern lcd_logical_driver lcd;
int lcd_drv_init(lcd_logical_driver *driver, char *args);
void lcd_drv_close();
void lcd_drv_clear();
void lcd_drv_flush();
void lcd_drv_string(int x, int y, char string[]);
void lcd_drv_chr(int x, int y, char c);
int lcd_drv_contrast(int contrast);
void lcd_drv_backlight(int on);
void lcd_drv_output(int on);
void lcd_drv_init_vbar();
void lcd_drv_init_hbar();
void lcd_drv_init_num();
void lcd_drv_num(int x, int num);
void lcd_drv_set_char(int n, char *dat);
void lcd_drv_vbar(int x, int len);
void lcd_drv_hbar(int x, int y, int len);
void lcd_drv_icon(int which, char dest);
void lcd_drv_flush_box(int lft, int top, int rgt, int bot);
void lcd_drv_draw_frame();
char lcd_drv_getkey();
#endif
+124
View File
@@ -0,0 +1,124 @@
/* lcddriver.cd - test/demo of LIBIR's to interface with lcdproc (LCDd) */
/* Copyright (C) 1999 David Glaude loosely based on workmanir.c */
/* workmanir.c - test/demo of LIBIR's high level command functions */
/* Copyright (C) 1998 Tom Wheeley, see file COPYING for details */
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "irman.h"
char *progname = "lcddriver";
char *codes[] = {
/* dummy */ NULL,
/* KeyToLcd */ "lcdproc-A",
/* KeyToLcd */ "lcdproc-B",
/* KeyToLcd */ "lcdproc-C",
/* KeyToLcd */ "lcdproc-D",
/* KeyToLcd */ "lcdproc-E",
/* KeyToLcd */ "lcdproc-F",
/* KeyToLcd */ "lcdproc-G",
/* KeyToLcd */ "lcdproc-H",
/* KeyToLcd */ "lcdproc-I",
/* KeyToLcd */ "lcdproc-J",
/* KeyToLcd */ "lcdproc-K",
/* KeyToLcd */ "lcdproc-L",
/* KeyToLcd */ "lcdproc-M",
/* KeyToLcd */ "lcdproc-N",
/* KeyToLcd */ "lcdproc-O",
/* KeyToLcd */ "lcdproc-P",
/* KeyToLcd */ "lcdproc-Q",
/* KeyToLcd */ "lcdproc-R",
/* KeyToLcd */ "lcdproc-S",
/* KeyToLcd */ "lcdproc-T",
/* KeyToLcd */ "lcdproc-U",
/* KeyToLcd */ "lcdproc-V",
/* KeyToLcd */ "lcdproc-W",
/* KeyToLcd */ "lcdproc-X",
/* KeyToLcd */ "lcdproc-Y",
/* KeyToLcd */ "lcdproc-Z",
/* end */ NULL
};
//void sigterm(int sig)
//{
// ir_free_commands();
// ir_finish();
// raise(sig);
//}
// INIT $$$
int INIT()
{
int i;
char *filename;
if (ir_init_commands(NULL, 1) < 0) {
fprintf(stderr, "error initialising commands: %s\n", strerror(errno));
exit(1);
}
filename = ir_default_portname();
filename = "option";
}
for (i=1; codes[i] != NULL; i++) {
if (ir_register_command(codes[i], i) < 0) {
if (errno == ENOENT) {
fprintf(stderr, "%s: no code set for `%s'\n", progname, codes[i]);
} else {
fprintf(stderr, "error registering `%s': `%s'\n", codes[i], strerror(errno));
}
}
}
errno = 0;
if (ir_init(filename) < 0) {
fprintf(stderr, "%s: error initialising Irman: `%s'\n", strerror(errno));
exit(1);
}
return 0;
}
// KEY $$$
int KEY(void)
{
int i;
int cmd;
char key;
key=(char)0;
for(i=1;i;) {
switch (cmd=ir_get_command()) {
case IR_CMD_ERROR:
fprintf(stderr, "%s: error reading command: %s\n", progname, strerror(errno));
// No exit in LCDd !!!
// exit(1);
case IR_CMD_UNKNOWN:
fprintf(stderr,"IR unknown command\n");
default: key='A'-1+cmd; break;
}
}
}
// CLOSE $$$
int CLOSE()
{
ir_free_commands();
ir_finish();
return 0;
}
/* end of lcddriver.c */
+51
View File
@@ -0,0 +1,51 @@
/*-----------------------------------------------------------------------------
* port.h (by damianf@wpi.edu)
* Low level I/O functions taken from led-stat.txt
*
* Jan 22 95
*
* DOS part (tested only with DOS version of GCC, DJGPP)
* by M.Prinke <m.prinke@trashcan.mcnet.de> 3/97
*/
/* #define DOS */
#ifndef PORT_H
#define PORT_H
#endif
#ifndef DOS
static inline int port_in( int port )
{
unsigned char value;
__asm__ volatile ("inb %1,%0"
: "=a" (value)
: "d" ((unsigned short)port));
return value;
}
static inline void port_out( unsigned short int port, unsigned char val )
{
__asm__ volatile (
"outb %0,%1\n"
:
: "a" (val), "d" (port)
);
}
#else
#include <pc.h>
static inline int port_in( int port )
{
unsigned char value;
value = inportb((unsigned short) port);
return (int)value;
}
static inline void port_out( unsigned int port, unsigned char val )
{
outportb((unsigned short) port, val);
}
#endif
/**** END OF FILE ****/
+236
View File
@@ -0,0 +1,236 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#include "lcd.h"
#include "text.h"
#include "drv_base.h"
lcd_logical_driver *text;
//////////////////////////////////////////////////////////////////////////
////////////////////// For Text-Mode Output //////////////////////////////
//////////////////////////////////////////////////////////////////////////
int text_init(lcd_logical_driver *driver, char *args)
{
text = driver;
if(!driver->framebuf)
{
driver->close();
return -1;
}
driver->wid = 20;
driver->hgt = 4;
driver->cellwid = 5;
driver->cellhgt = 8;
driver->clear = (void *)-1;
driver->string = (void *)-1;
driver->chr = (void *)-1;
driver->vbar = text_vbar;
driver->init_vbar = NULL;
driver->hbar = text_hbar;
driver->init_hbar = NULL;
driver->num = (void *)-1;
driver->init_num = NULL;
driver->init = text_init;
driver->close = text_close;
driver->flush = text_flush;
driver->flush_box = NULL;
driver->contrast = NULL;
driver->backlight = NULL;
driver->set_char = NULL;
driver->icon = NULL;
driver->draw_frame = text_draw_frame;
driver->getkey = NULL;
return 200; // 200 is arbitrary. (must be 1 or more)
}
void text_close()
{
drv_base_close();
}
/////////////////////////////////////////////////////////////////
// Clears the LCD screen
//
void text_clear()
{
memset(lcd.framebuf, ' ', lcd.wid*lcd.hgt);
}
//////////////////////////////////////////////////////////////////
// Flushes all output to the lcd...
//
void text_flush()
{
text_draw_frame(lcd.framebuf);
}
/////////////////////////////////////////////////////////////////
// Prints a string on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void text_string(int x, int y, char string[])
{
int i;
x -= 1; // Convert 1-based coords to 0-based...
y -= 1;
for(i=0; string[i]; i++)
{
lcd.framebuf[(y*lcd.wid) + x + i] = string[i];
}
}
/////////////////////////////////////////////////////////////////
// Prints a character on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void text_chr(int x, int y, char c)
{
y--;
x--;
lcd.framebuf[(y*lcd.wid) + x] = c;
}
int text_contrast(int contrast)
{
// printf("Contrast: %i\n", contrast);
return 0;
}
void text_backlight(int on)
{
/*
if(on)
{
printf("Backlight ON\n");
}
else
{
printf("Backlight OFF\n");
}
*/
}
void text_init_vbar()
{
// printf("Vertical bars.\n");
}
void text_init_hbar()
{
// printf("Horizontal bars.\n");
}
void text_init_num()
{
// printf("Big Numbers.\n");
}
void text_num(int x, int num)
{
// printf("BigNum(%i, %i)\n", x, num);
}
void text_set_char(int n, char *dat)
{
// printf("Set Character %i\n", n);
}
/////////////////////////////////////////////////////////////////
// Draws a vertical bar; erases entire column onscreen.
//
void text_vbar(int x, int len)
{
int y;
for(y=lcd.hgt; y > 0 && len>0; y--)
{
text_chr(x, y, '|');
len -= lcd.cellhgt;
}
}
/////////////////////////////////////////////////////////////////
// Draws a horizontal bar to the right.
//
void text_hbar(int x, int y, int len)
{
for(; x<=lcd.wid && len>0; x++)
{
text_chr(x,y,'-');
len -= lcd.cellwid;
}
}
void text_flush_box(int lft, int top, int rgt, int bot)
{
text_flush();
}
void text_draw_frame(char *dat)
{
int i, j;
char out[LCD_MAX_WIDTH];
if(!dat) return;
// printf("Frame (%ix%i): \n%s\n", lcd.wid, lcd.hgt, dat);
for(i=0; i<lcd.wid; i++)
{
out[i] = '-';
}
out[lcd.wid] = 0;
printf("+%s+\n", out);
for(i=0; i<lcd.hgt; i++)
{
for(j=0; j<lcd.wid; j++)
{
out[j] = dat[j+(i*lcd.wid)];
}
out[lcd.wid] = 0;
printf("|%s|\n", out);
}
for(i=0; i<lcd.wid; i++)
{
out[i] = '-';
}
out[lcd.wid] = 0;
printf("+%s+\n", out);
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef LCD_TEXT_H
#define LCD_TEXT_H
extern lcd_logical_driver *text;
int text_init(struct lcd_logical_driver *driver, char *args);
void text_close();
void text_clear();
void text_flush();
void text_string(int x, int y, char string[]);
void text_chr(int x, int y, char c);
int text_contrast(int contrast);
void text_backlight(int on);
void text_init_vbar();
void text_init_hbar();
void text_init_num();
void text_vbar(int x, int len);
void text_hbar(int x, int y, int len);
void text_num(int x, int num);
void text_set_char(int n, char *dat);
void text_flush_box(int lft, int top, int rgt, int bot);
void text_draw_frame(char *dat);
#endif
+562
View File
@@ -0,0 +1,562 @@
/* wirz-sli.c -- Source file for LCDproc Wirz SLI driver
Copyright (C) 1999 Horizon Technologies-http://horizon.pair.com/
Written by Bryan Rittmeyer <bryanr@pair.com> - Released under GPL
LCD info: http://www.wirz.com/sli/ */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include "lcd.h"
#include "wirz-sli.h"
#include "drv_base.h"
#include "../../shared/debug.h"
#include "../../shared/str.h"
static int custom=0;
typedef enum {
hbar = 1,
vbar = 2,
bign = 4,
beat = 8 } custom_type;
static int fd;
static char lastframe[32];
lcd_logical_driver *sli;
/////////////////////////////////////////////////////////////////
// Opens com port and sets baud correctly...
//
int sli_init(lcd_logical_driver *driver, char *args)
{
char *argv[64];
int argc;
struct termios portset;
int i;
int tmp;
char out[2];
char device[256] = "/dev/lcd";
int speed=B19200;
sli = driver;
//debug("sli_init: Args(all): %s\n", args);
argc = get_args(argv, args, 64);
/*
for(i=0; i<argc; i++)
{
printf("Arg(%i): %s\n", i, argv[i]);
}
*/
for(i=0; i<argc; i++)
{
//printf("Arg(%i): %s\n", i, argv[i]);
if(0 == strcmp(argv[i], "-d") ||
0 == strcmp(argv[i], "--device"))
{
if(i + 1 > argc) {
fprintf(stderr, "sli_init: %s requires an argument\n",
argv[i]);
return -1;
}
strcpy(device, argv[++i]);
}
else if(0 == strcmp(argv[i], "-s") ||
0 == strcmp(argv[i], "--speed"))
{
if(i + 1 > argc) {
fprintf(stderr, "sli_init: %s requires an argument\n",
argv[i]);
return -1;
}
tmp = atoi(argv[++i]);
if(tmp==1200) speed=B1200;
else if(tmp==2400) speed=B2400;
else if(tmp==9600) speed=B9600;
else if(tmp==19200) speed=B19200;
else if(tmp==38400) speed=B38400;
else if(tmp==57600) speed=B57600;
else if(tmp==115200) speed=B115200;
else {
fprintf(stderr, "sli_init: %s argument must be 1200, 2400, 9600, 19200, 38400, 57600, or 115200. Using default value (19200).\n",
argv[i]);
}
}
else if(0 == strcmp(argv[i], "-h") ||
0 == strcmp(argv[i], "--help"))
{
printf("LCDproc Wirz SLI LCD driver\n"
"\t-d\t--device\tSelect the output device to use [/dev/lcd]\n"
"\t-s\t--speed\t\tSet the communication speed [19200]\n"
"\t-h\t--help\t\tShow this help information\n");
return -1;
}
else
{
printf("Invalid parameter: %s\n", argv[i]);
}
}
// Set up io port correctly, and open it...
fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
fprintf(stderr, "sli_init: failed (%s)\n", strerror(errno));
return -1;
}
//else fprintf(stderr, "sli_init: opened device %s\n", device);
tcgetattr(fd, &portset);
// This is necessary in Linux, but does not exist in irix.
#ifndef IRIX
cfmakeraw(&portset);
#endif
cfsetospeed(&portset, speed);
tcsetattr(fd, TCSANOW, &portset);
/* Initialize SLI using autobaud detection, and then turn off cursor
and clear screen */
usleep(150000); /* 150ms delay to allow SLI to power on */
out[0]=13; /* CR for SLI autobaud */
write(fd, out, 1);
usleep(3000); /* 3ms delay.. wait for it to autobaud */
out[0]=0x0FE;
out[1]=0x00C; /* No cursor */
write(fd, out, 2);
out[0]=0x0FE;
out[1]=0x001; /* Clear LCD, not sure if this belongs here */
write(fd, out, 2);
if(!driver->framebuf)
{
fprintf(stderr, "sli_init: No frame buffer.\n");
driver->close();
return -1;
}
// Set LCD parameters (I use a 16x2 LCD) -- small but still useful
// Its also much cheaper than the higher quality Matrix Orbital modules
// Currently, $30 for interface kit and 16x2 non-backlit LCD...
driver->wid = 15;
driver->hgt = 2;
// Set the functions the driver supports...
driver->clear = (void *)-1;
driver->string = (void *)-1;
driver->chr = (void *)-1;
driver->vbar = sli_vbar;
driver->init_vbar = sli_init_vbar;
driver->hbar = sli_hbar;
driver->init_hbar = sli_init_hbar;
driver->num = (void *)-1;
driver->init_num = (void *)-1;
driver->init = sli_init;
driver->close = sli_close;
driver->flush = sli_flush;
driver->flush_box = sli_flush_box;
driver->contrast = (void *)-1;
driver->backlight = (void *)-1;
driver->set_char = sli_set_char;
driver->icon = sli_icon;
driver->draw_frame = sli_draw_frame;
driver->getkey = (void *)-1;
return fd;
}
/* Clean-up */
void sli_close()
{
close(fd);
if(sli->framebuf) free(sli->framebuf);
sli->framebuf = NULL;
}
void sli_flush()
{
sli_draw_frame(lcd.framebuf);
}
/* no bounds checking is done in MtxOrb.c (which I shamelessly ripped)
this is bad imho, so I added it.. may remove later
speed is not a huge issue though, this isnt a
device driver or anything ;) */
void sli_flush_box(int lft, int top, int rgt, int bot)
{
int y;
char out[2]; /* Why does the matrix driver allocate so much here? */
/* simple bounds checking */
if((top>lcd.hgt)|(bot>lcd.hgt))
return;
if((lft>lcd.wid)|(rgt>lcd.wid))
return;
// printf("Flush (%i,%i)-(%i,%i)\n", lft, top, rgt, bot);
/* I like having hex, everywhere and all the time */
for(y=top; y<=bot; y++)
{
if(y==1)
sprintf(out, "%c%c", 0x0FE, 0x080+lft);
if(y==2)
sprintf(out, "%c%c", 0x0FE, 0x0C0+lft);
write(fd, out, 0x002);
write(fd, lcd.framebuf+(y*lcd.wid)+lft, rgt-lft+1);
}
}
/////////////////////////////////////////////////////////////////
// Prints a character on the lcd display, at position (x,y). The
// upper-left is (1,1), and the lower right should be (20,4).
//
void sli_chr(int x, int y, char c)
{
y--;
x--;
lcd.framebuf[(y*lcd.wid) + x] = c;
}
/////////////////////////////////////////////////////////////////
// Sets up for vertical bars. Call before lcd.vbar()
//
/* Because of the way we do this (custom characters in CGRAM)
we can't have both horizontal and vertical bars at once...
this also appears to be a limitation of the Matrix Orbital
modules so I will assume that all client coders know about it
I think it would be cool to use triangular stuff for the non-full
characters, so that you can do both bar types at once.. maybe I
will release a new version of the SLI driver that attempts this */
void sli_init_vbar()
{
char a[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
};
char b[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
};
char c[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
char d[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
char e[] = {
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
char f[] = {
0,0,0,0,0,
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
char g[] = {
0,0,0,0,0,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
};
if(custom!=vbar) {
sli_set_char(1,a);
sli_set_char(2,b);
sli_set_char(3,c);
sli_set_char(4,d);
sli_set_char(5,e);
sli_set_char(6,f);
sli_set_char(7,g);
custom=vbar;
}
}
/////////////////////////////////////////////////////////////////
// Inits horizontal bars...
//
void sli_init_hbar()
{
char a[] = {
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
};
char b[] = {
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
1,1,0,0,0,
};
char c[] = {
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
1,1,1,0,0,
};
char d[] = {
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
1,1,1,1,0,
};
if(custom!=hbar) {
sli_set_char(1,a);
sli_set_char(2,b);
sli_set_char(3,c);
sli_set_char(4,d);
custom=hbar;
}
}
/////////////////////////////////////////////////////////////////
// Draws a vertical bar...
//
/* It would be cool if you could start a vertical bar at any y
like the horizontal bar routine can start at any x... but
since we only have 2 lines anyway this is rather pointless
for me to add */
void sli_vbar(int x, int len)
{
char map[9] = {32, 1, 2, 3, 4, 5, 6, 7, 255 };
int y;
for(y=lcd.hgt; y > 0 && len>0; y--)
{
if(len >= lcd.cellhgt) sli_chr(x, y, 255);
else sli_chr(x, y, map[len]);
len -= lcd.cellhgt;
}
}
/////////////////////////////////////////////////////////////////
// Draws a horizontal bar to the right.
//
void sli_hbar(int x, int y, int len)
{
char map[6] = { 32, 1, 2, 3, 4, 255 };
for(; x<=lcd.wid && len>0; x++)
{
if(len >= lcd.cellwid) sli_chr(x,y,255);
else sli_chr(x, y, map[len]);
len -= lcd.cellwid;
}
}
/////////////////////////////////////////////////////////////////
// Sets a custom character from 0-7...
//
// For input, values > 0 mean "on" and values <= 0 are "off".
//
// The input is just an array of characters...
//
void sli_set_char(int n, char *dat)
{
char out[2];
int row, col;
int letter;
/* SLI also has 8 user definable characters */
if(n < 0 || n > 7) return;
if(!dat) return;
/* Move cursor to CGRAM */
out[0]=0x0FE;
out[1]=0x040+8*n;
write(fd, out, 2);
for(row=0; row<lcd.cellhgt; row++)
{
letter = 0;
for(col=0; col<lcd.cellwid; col++)
{
letter <<= 1;
letter |= (dat[(row*lcd.cellwid) + col] > 0);
}
letter|=0x020; /* SLI can't accept CR, LF, etc in this character! */
write(fd, &letter, 1);
}
/* Move cursor back to DDRAM */
out[0]=0x0FE;
out[1]=0x080;
write(fd, out, 2);
}
void sli_icon(int which, char dest)
{
char icons[3][5*8] = {
{
1,1,1,1,1, // Empty Heart
1,0,1,0,1,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,0,0,0,1,
1,1,0,1,1,
1,1,1,1,1,
},
{
1,1,1,1,1, // Filled Heart
1,0,1,0,1,
0,1,0,1,0,
0,1,1,1,0,
0,1,1,1,0,
1,0,1,0,1,
1,1,0,1,1,
1,1,1,1,1,
},
{
0,0,0,0,0, // Ellipsis
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
1,0,1,0,1,
},
};
if(custom==bign) custom=beat;
sli_set_char(dest, &icons[which][0]);
}
/////////////////////////////////////////////////////////////
// Blasts a single frame onscreen, to the lcd...
//
// Input is a character array, sized lcd.wid*lcd.hgt
//
void sli_draw_frame(char *dat)
{
char out[2]; /* Again, why does the Matrix driver allocate so much here? */
int y;
if(!dat) return;
/*
out[0]=0x0FE;
out[1]=0x001;
write(fd, out, 2);
*/
/* Don't update if we have no new data
this keeps me from getting a migraine
(just like those copyleft penguin mints... mmmmmm) */
// if (!strncmp(dat,lastframe,32)) /* Nothing has changed */
// return;
/* Do the actual refresh */
out[0]=0x0FE;
out[1]=0x080;
write(fd, out, 2);
write(fd, &dat[0], 16);
usleep(10);
write(fd, &dat[16],15);
// strncpy(lastframe,dat,32); // Update lastframe...
}
+33
View File
@@ -0,0 +1,33 @@
/* wirz-sli.h -- Header file for LCDproc Wirz SLI driver
Copyright (C) 1999 Horizon Technologies-http://horizon.pair.com/
Written by Bryan Rittmeyer <bryanr@pair.com> - Released under GPL
LCD info: http://www.wirz.com/sli/ */
#ifndef SLI_H
#define SLI_H
extern lcd_logical_driver *sli;
int sli_init(lcd_logical_driver *driver, char *device);
void sli_close();
void sli_flush();
void sli_flush_box(int lft, int top, int rgt, int bot);
void sli_chr(int x, int y, char c) ;
int sli_contrast(int contrast);
void sli_backlight(int on);
void sli_init_vbar();
void sli_init_hbar();
void sli_vbar(int x, int len);
void sli_hbar(int x, int y, int len);
void sli_init_num();
void sli_num(int x, int num);
void sli_set_char(int n, char *dat);
void sli_icon(int which, char dest);
void sli_draw_frame(char *dat);
char sli_getkey();
#endif