00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042
00043 #include <dev/term.h>
00044
00045 #include <sys/thread.h>
00046 #include <sys/timer.h>
00047 #include <sys/event.h>
00048
00049 #include <arpa/inet.h>
00050
00051 #include "config.h"
00052 #include "player.h"
00053 #include "display.h"
00054
00055 uint16_t lcd_offset;
00056
00057 #define DISPLAY_LINES 2
00058 #define DISPLAY_VCOLUMNS 80
00059
00060 char *sline[2];
00061 char *mline[2];
00062 uint16_t mticks[2];
00063
00064 FILE *lcd;
00065
00066 HANDLE updevt;
00067
00068
00069
00070
00071 THREAD(Displayer, arg)
00072 {
00073 unsigned int step[2] = { 0, 0 };
00074 unsigned int stepmx[2] = { 0, 0 };
00075 char *line;
00076 char *sptr = 0;
00077 uint8_t scrolling = DISPLAY_LINES;
00078 uint8_t ln;
00079
00080 fputs(ESC_CURSOROFF, lcd);
00081 NutThreadSetPriority(128);
00082 for (;;) {
00083 NutEventWait(&updevt, 125);
00084
00085 for (ln = 0; ln < DISPLAY_LINES; ln++) {
00086 if (mticks[ln]) {
00087 line = mline[ln];
00088 mticks[ln]--;
00089 } else
00090 line = sline[ln];
00091 if (stepmx[ln] != strlen(line)) {
00092 sptr = 0;
00093 scrolling = DISPLAY_LINES;
00094 stepmx[ln] = strlen(line);
00095 step[ln] = 0;
00096 }
00097 fprintf(lcd, ESC_POS "%c" "\x20", ln + 32);
00098 if (stepmx[ln] <= 16) {
00099 fputs(line, lcd);
00100 if (stepmx[ln] < 16)
00101 fputs(ESC_CLREOL, lcd);
00102 } else {
00103 if (step[ln] == stepmx[ln]) {
00104 if (scrolling == DISPLAY_LINES)
00105 scrolling = ln;
00106 if (scrolling == ln) {
00107 if (sptr == 0)
00108 sptr = line;
00109 else {
00110 sptr++;
00111 if (strlen(sptr) <= 16)
00112 step[ln]++;
00113 }
00114 fprintf(lcd, "%.16s", sptr);
00115 }
00116 } else if (step[ln]++ == 0) {
00117 fprintf(lcd, "%.16s", line);
00118 sptr = 0;
00119 scrolling = DISPLAY_LINES;
00120 } else if (step[ln] >= stepmx[ln] + 16)
00121 step[ln] = 0;
00122 }
00123 }
00124 }
00125 }
00126
00127 void DisplayStation(RADIOSTATION * rsp)
00128 {
00129 if (rsp->rs_port) {
00130 if (rsp->rs_name && rsp->rs_name[0])
00131 strncpy(sline[0], rsp->rs_name, DISPLAY_VCOLUMNS);
00132 else
00133 strncpy(sline[0], inet_ntoa(rsp->rs_ip), DISPLAY_VCOLUMNS);
00134 } else
00135 sline[0][0] = 0;
00136 }
00137
00143 void DisplayStatus(uint8_t status)
00144 {
00145 RADIOSTATION *rsp = &station[radio.rc_cstation];
00146
00147 if (radio.rc_cstatus != status) {
00148 if (status == DIST_FORCE)
00149 status = radio.rc_cstatus;
00150 else
00151 radio.rc_cstatus = status;
00152
00153 if (status == DIST_NONE) {
00154 strcpy(sline[0], "NutPiper");
00155 strcpy(sline[1], "Version 1.0");
00156 NutEventPost(&updevt);
00157 } else if (status == DIST_DEAD) {
00158 sprintf(sline[0], "Station %03u", radio.rc_cstation);
00159 strcpy(sline[1], "not available");
00160 NutEventPost(&updevt);
00161 } else if (status == DIST_CONNECTING) {
00162 DisplayStation(rsp);
00163 strcpy(sline[1], "Connecting...");
00164 NutEventPost(&updevt);
00165 } else if (status == DIST_CONNECTED) {
00166 DisplayStation(rsp);
00167 if (player.psi_metatitle && player.psi_metatitle[0])
00168 strncpy(sline[1], player.psi_metatitle, DISPLAY_VCOLUMNS);
00169 else if (rsp->rs_genre && rsp->rs_genre[0])
00170 strncpy(sline[1], rsp->rs_genre, DISPLAY_VCOLUMNS);
00171 NutEventPost(&updevt);
00172 }
00173 }
00174 }
00175
00184 void DisplayMessage(uint8_t row, uint8_t secs, CONST char *fmt, ...)
00185 {
00186 va_list ap;
00187
00188 va_start(ap, fmt);
00189 if (secs) {
00190 vsprintf(mline[row], fmt, ap);
00191 mticks[row] = secs * 4;
00192 } else
00193 vsprintf(sline[row], fmt, ap);
00194 va_end(ap);
00195
00196 NutEventPost(&updevt);
00197 }
00198
00204 void DisplayEntry(uint8_t rs)
00205 {
00206 RADIOSTATION *rsp = &station[rs];
00207
00208 if (rsp->rs_port && rsp->rs_name)
00209 sprintf(sline[0], "%03u %.12s", rs, rsp->rs_name);
00210 else
00211 sprintf(sline[0], "%03u", rs);
00212
00213 if (rsp->rs_scandead)
00214 strcpy(sline[1], "not available");
00215 else if (rsp->rs_scantitle)
00216 strncpy(sline[1], rsp->rs_scantitle, DISPLAY_VCOLUMNS);
00217 else if (rsp->rs_genre)
00218 strncpy(sline[1], rsp->rs_genre, DISPLAY_VCOLUMNS);
00219 else if (rsp->rs_ip)
00220 strncpy(sline[1], inet_ntoa(rsp->rs_ip), DISPLAY_VCOLUMNS);
00221 else
00222 sline[1][0] = 0;
00223
00224 NutEventPost(&updevt);
00225 }
00226
00234 int DisplayInit(char *name)
00235 {
00236 if ((lcd = fopen(name, "w")) == 0)
00237 return -1;
00238
00239 if ((sline[0] = malloc(DISPLAY_VCOLUMNS + 1)) == 0 ||
00240 (sline[1] = malloc(DISPLAY_VCOLUMNS + 1)) == 0 ||
00241 (mline[0] = malloc(DISPLAY_VCOLUMNS + 1)) == 0 || (mline[1] = malloc(DISPLAY_VCOLUMNS + 1)) == 0)
00242 return -1;
00243 sline[0][DISPLAY_VCOLUMNS] = 0;
00244 sline[1][DISPLAY_VCOLUMNS] = 0;
00245
00246 if (NutThreadCreate("displ", Displayer, 0, 512) == 0)
00247 return -1;
00248
00249 DisplayStatus(DIST_NONE);
00250
00251 return 0;
00252 }