display.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003 by egnite Software GmbH
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in the
00014  *    documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the copyright holders nor the names of
00016  *    contributors may be used to endorse or promote products derived
00017  *    from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00023  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00026  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00027  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00028  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00029  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  * For additional information see http://www.ethernut.de/
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  * Background thread for playing stream.
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 }

© 2000-2010 by contributors - visit http://www.ethernut.de/