/* Try to open a connection to LCDd if support is enabled ** If it succeeeds configure our screen ** If it fails, print a message, disable support and continue */ void init_lcd (void) { if (!use_lcdd_menu) return; use_lcdd_menu = false; lcd_fd = socket(AF_INET, SOCK_STREAM, 0); if (lcd_fd > 0) { lcd_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *)); lcd_addr->sin_family = AF_INET; if (inet_pton(AF_INET, "127.0.0.1", (void *)(&(lcd_addr->sin_addr.s_addr))) >0) { lcd_addr->sin_port = htons(13666); if (connect(lcd_fd, (struct sockaddr *)lcd_addr, sizeof(struct sockaddr)) >= 0) { int flag = 1; if (setsockopt(lcd_fd, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag) ) == 0) { use_lcdd_menu = true; send_lcd("hello\n",6); while(!read_lcd()); /* wait for display info */ send_lcd("client_set name {squeeze}\n",26); send_lcd("screen_add main\n",16); send_lcd("screen_set main name {main}\n",28); send_lcd("screen_set main heartbeat off\n",30); send_lcd("widget_add main one string\n",27); send_lcd("widget_add main two string\n",27); if ( lcdd_compat ) send_lcd("screen_set main -priority 256\n",30); else send_lcd("screen_set main -priority info\n",31); setNonblocking(lcd_fd); } } } } /* If connect failed */ if (!use_lcdd_menu) { use_lcdd_menu = true; close_lcd(); fprintf(stderr,"Connect to LCDd failed!\n"); } }
/* Send line to lcdd */ void set_lcd_line(int lineid, char *text, int len) { int total = 27 + len; char cmd[total]; if (lineid == 1) memcpy(cmd,"widget_set main one 1 1 {",25); else memcpy(cmd,"widget_set main two 1 2 {",25); memcpy (cmd+25,text,len); memcpy(cmd+total-2,"}\n",2); send_lcd(cmd,total); }
/* This gets called once for each new sentence. */ static void update_lcd(struct gps_data_t *gpsdata) { char tmpbuf[255]; char *gridsquare; /* Get our location in Maidenhead. */ gridsquare = maidenhead(gpsdata->fix.latitude,gpsdata->fix.longitude); /* Fill in the latitude and longitude. */ if (gpsdata->fix.mode >= MODE_2D) { int track; char *s; s = deg_to_str(deg_type, fabs(gpsdata->fix.latitude)); snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd one 1 1 {Lat: %s %c}\n", s, (gpsdata->fix.latitude < 0) ? 'S' : 'N'); send_lcd(tmpbuf); s = deg_to_str(deg_type, fabs(gpsdata->fix.longitude)); snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd two 1 2 {Lon: %s %c}\n", s, (gpsdata->fix.longitude < 0) ? 'W' : 'E'); send_lcd(tmpbuf); /* As a pilot, a heading of "0" gives me the heebie-jeebies (ie, 0 == "invalid heading data", 360 == "North"). */ track=(int)(gpsdata->fix.track); if (track == 0) track = 360; snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd three 1 3 {%.1f %s %d deg}\n", gpsdata->fix.speed*speedfactor, speedunits, track); send_lcd(tmpbuf); } else { send_lcd("widget_set gpsd one 1 1 {Lat: n/a}\n"); send_lcd("widget_set gpsd two 1 2 {Lon: n/a}\n"); send_lcd("widget_set gpsd three 1 3 {n/a}\n"); } /* Fill in the altitude and fix status. */ if (gpsdata->fix.mode == MODE_3D) { int n; for(n=0;n<CLIMB-2;n++) climb[n]=climb[n+1]; climb[CLIMB-1]=gpsdata->fix.climb; avgclimb=0.0; for(n=0;n<CLIMB;n++) avgclimb+=climb[n]; avgclimb/=CLIMB; snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd four 1 4 {%d %s %s %d fpm }\n", (int)(gpsdata->fix.altitude*altfactor), altunits, gridsquare, (int)(avgclimb * METERS_TO_FEET * 60)); } else { snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd four 1 4 {n/a}\n"); } send_lcd(tmpbuf); }
/* reset the LCD */ static void reset_lcd(void) { /* Initialize. In theory, we should look at what's returned, as it tells us info on the attached LCD module. TODO. */ send_lcd("hello\n"); /* Set up the screen */ send_lcd("client_set name {GPSD test}\n"); send_lcd("screen_add gpsd\n"); send_lcd("widget_add gpsd one string\n"); send_lcd("widget_add gpsd two string\n"); send_lcd("widget_add gpsd three string\n"); send_lcd("widget_add gpsd four string\n"); }