display.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 
00045 #include <dev/term.h>
00046 
00047 #include <sys/thread.h>
00048 #include <sys/timer.h>
00049 #include <sys/event.h>
00050 
00051 #include <arpa/inet.h>
00052 
00053 #include "config.h"
00054 #include "player.h"
00055 #include "display.h"
00056 
00057 u_short lcd_offset;
00058 
00059 #define DISPLAY_LINES       2
00060 #define DISPLAY_VCOLUMNS    80
00061 
00062 char *sline[2];
00063 char *mline[2];
00064 u_short mticks[2];
00065 
00066 FILE *lcd;
00067 
00068 HANDLE updevt;
00069 
00070 /*
00071  * Background thread for playing stream.
00072  */
00073 THREAD(Displayer, arg)
00074 {
00075     u_int step[2] = { 0, 0 };
00076     u_int stepmx[2] = { 0, 0 };
00077     char *line;
00078     char *sptr = 0;
00079     u_char scrolling = DISPLAY_LINES;
00080     u_char ln;
00081 
00082     fputs(ESC_CURSOROFF, lcd);
00083     NutThreadSetPriority(128);
00084     for (;;) {
00085         NutEventWait(&updevt, 125);
00086 
00087         for (ln = 0; ln < DISPLAY_LINES; ln++) {
00088             if (mticks[ln]) {
00089                 line = mline[ln];
00090                 mticks[ln]--;
00091             } else
00092                 line = sline[ln];
00093             if (stepmx[ln] != strlen(line)) {
00094                 sptr = 0;
00095                 scrolling = DISPLAY_LINES;
00096                 stepmx[ln] = strlen(line);
00097                 step[ln] = 0;
00098             }
00099             fprintf(lcd, ESC_POS "%c" "\x20", ln + 32);
00100             if (stepmx[ln] <= 16) {
00101                 fputs(line, lcd);
00102                 if (stepmx[ln] < 16)
00103                     fputs(ESC_CLREOL, lcd);
00104             } else {
00105                 if (step[ln] == stepmx[ln]) {
00106                     if (scrolling == DISPLAY_LINES)
00107                         scrolling = ln;
00108                     if (scrolling == ln) {
00109                         if (sptr == 0)
00110                             sptr = line;
00111                         else {
00112                             sptr++;
00113                             if (strlen(sptr) <= 16)
00114                                 step[ln]++;
00115                         }
00116                         fprintf(lcd, "%.16s", sptr);
00117                     }
00118                 } else if (step[ln]++ == 0) {
00119                     fprintf(lcd, "%.16s", line);
00120                     sptr = 0;
00121                     scrolling = DISPLAY_LINES;
00122                 } else if (step[ln] >= stepmx[ln] + 16)
00123                     step[ln] = 0;
00124             }
00125         }
00126     }
00127 }
00128 
00129 void DisplayStation(RADIOSTATION * rsp)
00130 {
00131     if (rsp->rs_port) {
00132         if (rsp->rs_name && rsp->rs_name[0])
00133             strncpy(sline[0], rsp->rs_name, DISPLAY_VCOLUMNS);
00134         else
00135             strncpy(sline[0], inet_ntoa(rsp->rs_ip), DISPLAY_VCOLUMNS);
00136     } else
00137         sline[0][0] = 0;
00138 }
00139 
00145 void DisplayStatus(u_char status)
00146 {
00147     RADIOSTATION *rsp = &station[radio.rc_cstation];
00148 
00149     if (radio.rc_cstatus != status) {
00150         if (status == DIST_FORCE)
00151             status = radio.rc_cstatus;
00152         else
00153             radio.rc_cstatus = status;
00154 
00155         if (status == DIST_NONE) {
00156             strcpy(sline[0], "NutPiper");
00157             strcpy(sline[1], "Version 1.0");
00158             NutEventPost(&updevt);
00159         } else if (status == DIST_DEAD) {
00160             sprintf(sline[0], "Station %03u", radio.rc_cstation);
00161             strcpy(sline[1], "not available");
00162             NutEventPost(&updevt);
00163         } else if (status == DIST_CONNECTING) {
00164             DisplayStation(rsp);
00165             strcpy(sline[1], "Connecting...");
00166             NutEventPost(&updevt);
00167         } else if (status == DIST_CONNECTED) {
00168             DisplayStation(rsp);
00169             if (player.psi_metatitle && player.psi_metatitle[0])
00170                 strncpy(sline[1], player.psi_metatitle, DISPLAY_VCOLUMNS);
00171             else if (rsp->rs_genre && rsp->rs_genre[0])
00172                 strncpy(sline[1], rsp->rs_genre, DISPLAY_VCOLUMNS);
00173             NutEventPost(&updevt);
00174         }
00175     }
00176 }
00177 
00186 void DisplayMessage(u_char row, u_char secs, CONST char *fmt, ...)
00187 {
00188     va_list ap;
00189 
00190     va_start(ap, fmt);
00191     if (secs) {
00192         vsprintf(mline[row], fmt, ap);
00193         mticks[row] = secs * 4;
00194     } else
00195         vsprintf(sline[row], fmt, ap);
00196     va_end(ap);
00197 
00198     NutEventPost(&updevt);
00199 }
00200 
00206 void DisplayEntry(u_char rs)
00207 {
00208     RADIOSTATION *rsp = &station[rs];
00209 
00210     if (rsp->rs_port && rsp->rs_name)
00211         sprintf(sline[0], "%03u %.12s", rs, rsp->rs_name);
00212     else
00213         sprintf(sline[0], "%03u", rs);
00214 
00215     if (rsp->rs_scandead)
00216         strcpy(sline[1], "not available");
00217     else if (rsp->rs_scantitle)
00218         strncpy(sline[1], rsp->rs_scantitle, DISPLAY_VCOLUMNS);
00219     else if (rsp->rs_genre)
00220         strncpy(sline[1], rsp->rs_genre, DISPLAY_VCOLUMNS);
00221     else if (rsp->rs_ip)
00222         strncpy(sline[1], inet_ntoa(rsp->rs_ip), DISPLAY_VCOLUMNS);
00223     else
00224         sline[1][0] = 0;
00225 
00226     NutEventPost(&updevt);
00227 }
00228 
00236 int DisplayInit(char *name)
00237 {
00238     if ((lcd = fopen(name, "w")) == 0)
00239         return -1;
00240 
00241     if ((sline[0] = malloc(DISPLAY_VCOLUMNS + 1)) == 0 ||
00242         (sline[1] = malloc(DISPLAY_VCOLUMNS + 1)) == 0 ||
00243         (mline[0] = malloc(DISPLAY_VCOLUMNS + 1)) == 0 || (mline[1] = malloc(DISPLAY_VCOLUMNS + 1)) == 0)
00244         return -1;
00245     sline[0][DISPLAY_VCOLUMNS] = 0;
00246     sline[1][DISPLAY_VCOLUMNS] = 0;
00247 
00248     if (NutThreadCreate("displ", Displayer, 0, 512) == 0)
00249         return -1;
00250 
00251     DisplayStatus(DIST_NONE);
00252 
00253     return 0;
00254 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/