Hi Olivier & others,

Please find attached a patch to include Etrex{Legend,Vista,Classic}
support in GarminDev. It's a straight port from QLandkarte, I've made
almost no changes except for the build system and a single include file
location.

Haven't tested it with my own device yet. Well, it builds, and that's what
counts, isn't it?

Jan-Pascal
Index: src/EtrexLegend/CDevice.cpp
===================================================================
--- src/EtrexLegend/CDevice.cpp	(revision 0)
+++ src/EtrexLegend/CDevice.cpp	(revision 0)
@@ -0,0 +1,676 @@
+/**********************************************************************************************
+    Copyright (C) 2007 Oliver Eichler [EMAIL PROTECTED]
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+  Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd.
+  or one of its subsidiaries.
+
+**********************************************************************************************/
+#include "CDevice.h"
+
+#include "../Platform.h"
+
+#include <Garmin.h>
+
+#include <cstdio>
+#include <iostream>
+#include <sstream>
+
+using namespace EtrexLegend;
+using namespace Garmin;
+using namespace std;
+
+#define GRMN_ETREX_LEGEND  411
+
+#define MAP_UPLOAD_BITRATE 115200// or 57600, 38400, 19200, 9600
+
+#define WAYPOINT_DL_BITRATE 57600
+#define TRACK_DL_BITRATE 57600
+#define GRMN_DEFAULT_BITRATE 9600
+
+#define PROGR_CALLBACK(state,message) \
+callback ( state,0,0,0,message )
+
+#define PROGR_CANCEL_CALLBACK(state,message,cancel) \
+callback ( state,0,cancel,0,message )
+
+CDevice::CDevice()
+: serial(0)
+{
+	supportsMaps = true;
+}
+
+
+CDevice::~CDevice()
+{
+
+}
+
+
+const string& CDevice::getCopyright()
+{
+    copyright = "<h1>QLandkarte Device Driver for EtrexLegend (EXPERIMENTAL)</h1>"
+        "<h2>Driver I/F Ver. " INTERFACE_VERSION "</h2>"
+        "<p>&#169; 2007 by Oliver Eichler ([EMAIL PROTECTED])</p>"
+        "<p>modified 2007 by Andreas Stenglein to work with serial eTrex Legend</p>"
+        "<p>This driver is distributed in the hope that it will be useful, "
+        "but WITHOUT ANY WARRANTY; without even the implied warranty of "
+        "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
+        "GNU General Public License for more details. </p>";
+    return copyright;
+}
+
+
+void CDevice::_acquire()
+{
+#if defined(WORDS_BIGENDIAN) || !defined(CAN_UNALIGNED)
+    throw exce_t(errSync, "This device has not yet been ported to your platform.");
+#endif
+    PROGR_CALLBACK ( 0,"acquiring" );
+
+    serial = new CSerial(port);
+
+    PROGR_CALLBACK ( 1,"acquiring ...");
+
+    serial->open();
+    serial->syncup();
+
+    if(strncmp(serial->getProductString().c_str(), devname.c_str(), devname.size()) != 0) {
+        string msg = "No " + devname + " unit detected. Please retry to select other device driver.";
+        throw exce_t(errSync,msg);
+    }
+
+    if(devid) {
+        if(serial->getProductId() != devid) {
+            string msg = "No " + devname + " unit detected. Please retry to select other device driver.";
+            throw exce_t(errSync,msg);
+        }
+    }
+    else {
+        string msg = "No " + devname + " unit detected. Please retry to select other device driver.";
+        throw exce_t(errSync,msg);
+    }
+
+}
+
+
+void CDevice::_uploadMap(const uint8_t * mapdata, uint32_t size, const char * key)
+{
+    if(supportsMaps == false)
+    {
+        IDeviceDefault::_uploadMap(mapdata, size, key);
+        return;
+    }
+    if(serial == 0) return;
+    int ready= 0;
+    int cancel = 0;
+
+    Packet_t command;
+    Packet_t response;
+
+    // ???
+    command.id   = 0x1C;
+    command.size = 2;
+    *(uint16_t*)command.payload = 0x0000;
+    serial->write(command);
+
+    // read SD Ram capacity
+    command.id   = Pid_Command_Data;
+    command.size = 2;
+    *(uint16_t*)command.payload = Cmnd_Transfer_Mem;
+    serial->write(command);
+
+                                 // FIXME:
+    while(serial->read(response) > 0) {
+
+        if(response.id == Pid_Capacity_Data) {
+            cout << "free memory: " << dec << (((uint32_t*)response.payload)[1] / (1024*1024)) << " MB" << endl;
+            uint32_t memory = ((uint32_t*)response.payload)[1];
+            if(memory < size) {
+                stringstream msg;
+                msg << "Failed to send map: Unit has not enought memory (available/needed): " << memory << "/" << size << " bytes";
+                throw exce_t(errBlocked,msg.str());
+            }
+        }
+    }
+
+#ifdef EXPERIMENTAL
+    // KEY_UPLOAD: UNTESTED: someone should check how/if this works
+    // send unlock key if present
+    if(key) {
+        command.id   = Pid_Tx_Unlock_Key;
+        command.size = strlen(key) + 1;
+        memcpy(command.payload,key,command.size);
+
+        serial->write(command);
+
+                                 // FIXME:
+        while(serial->read(response) > 0 ) {
+            if(response.id == Pid_Ack_Unlock_key) {
+                //TODO read data
+            }
+        }
+
+    }
+#endif
+
+    if (serial->setBitrate( MAP_UPLOAD_BITRATE)) {
+        throw exce_t(errBlocked,"Failed to change serial link to xxx bit per second");
+    }
+
+    // switch to map transfer mode erase old map(?)
+    command.id   = 75;
+    command.size = 2;
+    *(uint16_t*)command.payload = 0x000A;
+    serial->write(command);
+
+    sleep(10);
+
+    ready= 0;
+    while(!ready && serial->read(response) > 0) {
+        if(response.id == 74) {
+            ready= 1;
+            //TODO read data
+        }
+    }
+
+    callback(0,0,&cancel,"Upload maps ...",0);
+
+    uint32_t total  = size;
+    uint32_t offset = 0, chunkSize;
+    command.id   = 36;
+    // USB:    transfer file by chunks of 0x1000 - 0x0000C - sizeof(offset) = 0x0FF0 bytes
+    // Serial: transfer file by chunks of 0xfe - sizeof(offset) =  0xfa = 250 bytes
+    while(size && !cancel) {
+        chunkSize       = (size < (254 - sizeof(offset))) ? size : (254 - sizeof(offset));
+        command.size    = chunkSize + sizeof(offset);
+
+        *(uint32_t*)command.payload = offset;
+        memcpy(command.payload + sizeof(offset),mapdata,chunkSize);
+        size    -= chunkSize;
+        mapdata += chunkSize;
+        offset  += chunkSize;
+
+        serial->write(command);
+        // set progress
+        double progress = ((total - size) * 100.0) / total;
+        callback(progress,0,&cancel,0,"Transfering map data.");
+
+    }
+
+    callback(100,0,&cancel,0,"done");
+
+    // terminate map transfer mode (?)
+    command.id   = 45;
+    command.size = 2;
+    *(uint16_t*)command.payload = 0x000A;
+    serial->write(command);
+}
+
+
+void CDevice::_queryMap(std::list<Map_t>& maps)
+{
+    maps.clear();
+    if(supportsMaps == false)
+    {
+        IDeviceDefault::_queryMap(maps);
+        return;
+    }
+    if(serial == 0) return;
+
+    Packet_t command;
+    Packet_t response;
+
+    // ???
+    command.id   = 0x1C;
+    command.size = 2;
+    *(uint16_t*)command.payload = 0x0000;
+    serial->write(command);
+
+    // Request map overview table
+    command.id   = 0x59;
+    command.size = 19;
+    Map_Request_t * req = (Map_Request_t*)command.payload;
+    req->dummy1 = 0;
+    req->dummy2 = 10;
+    strcpy(req->section,"MAPSOURC.MPS");
+    serial->write(command);
+
+    uint32_t size   = 1024;
+    uint32_t fill   = 0;
+    char * pData    = (char*)calloc(1,size);
+
+    while(serial->read(response)) {
+        // acknowledge request (???)
+        if(response.id == 0x5B) {
+            //TODO: read data
+        }
+
+        // chunk of MAPSOURC.MPS section
+        // Each chunk is prepended by a chunk counter of type uint8_t.
+        // This has to be skipped. That's why the peculiar math.
+        if(response.id == 0x5A) {
+            // realloc memory if chunk does not fit
+            if((fill +  response.size - 1) > size) {
+                size += size;
+                pData = (char*)realloc(pData,size);
+            }
+
+            memcpy(&pData[fill], response.payload + 1, response.size - 1);
+
+            fill += response.size - 1;
+        }
+    }
+
+    Map_Info_t * pInfo = (Map_Info_t*)pData;
+    while(pInfo->tok == 0x4C) {
+        Map_t m;
+        char * pStr = pInfo->name1;
+        m.mapName = pStr;
+        pStr += strlen(pStr) + 1;
+        m.tileName = pStr;
+
+        maps.push_back(m);
+
+        pInfo =  (Map_Info_t*)(((char*)pInfo) + pInfo->size + sizeof(pInfo->tok) + sizeof(pInfo->size));
+    }
+
+    free(pData);
+}
+
+
+void CDevice::_downloadWaypoints(list<Garmin::Wpt_t>& waypoints)
+{
+    waypoints.clear();
+    if(serial == 0) return;
+
+    PROGR_CALLBACK ( 2,"Downloading waypoints ..." );
+
+    Packet_t command;
+    Packet_t response;
+
+    unsigned int nwpts = 0;
+    unsigned int cnt = 0;
+
+    // ???
+    command.id   = 0x1C;
+    command.size = 2;
+    *(uint16_t*)command.payload = 0x0000;
+    serial->write(command);
+
+#ifdef EXPERIMENTAL
+    if (serial->setBitrate( WAYPOINT_DL_BITRATE)) {
+        throw exce_t(errBlocked,"Failed to change serial link to xxx bit per second");
+    }
+#endif
+    // request waypoints
+    command.id   = Pid_Command_Data;
+    command.size = 2;
+    *(uint16_t*)command.payload = Cmnd_Transfer_Wpt;
+    serial->write(command);
+
+    PROGR_CALLBACK ( 5,"Downloading waypoints ..." );
+
+    while(1) {
+        if(!serial->read(response)) continue;
+
+        if(response.id == Pid_Records) {
+            nwpts = *(uint16_t*)response.payload;
+#ifdef DBG_SHOW_WAYPOINT
+            cout << "number of waypoints:" << *(int16_t*)response.payload << endl;
+#endif
+        }
+
+        if(response.id == Pid_Wpt_Data) {
+            D108_Wpt_t * srcWpt = (D108_Wpt_t*)response.payload;
+            waypoints.push_back(Wpt_t());
+            Wpt_t& tarWpt = waypoints.back();
+
+            tarWpt << *srcWpt;
+
+            ++cnt;
+            if (nwpts)
+                PROGR_CALLBACK ( 5 + ( cnt * 94 / nwpts ),"Downloading waypoints ..." );
+        }
+
+        if(response.id == Pid_Xfer_Cmplt) {
+            break;
+        }
+
+    }
+
+#if 0
+    // etrex Legend doesn't have a beeper
+    // unsupported by etrex Legend ?
+    // request proximity waypoints
+    command.id   = Pid_Command_Data;
+    command.size = 2;
+    *(uint16_t*)command.payload = Cmnd_Transfer_Prx;
+    serial->write(command);
+
+    while(1) {
+
+        if(!serial->read(response)) continue;
+
+        if(response.id == Pid_Records) {
+            //TODO read data
+#ifdef DBG_SHOW_WAYPOINT
+            cout << "number of proximity waypoints:" << *(int16_t*)response.payload << endl;
+#endif
+        }
+
+        if(response.id == Pid_Prx_Wpt_Data) {
+            D108_Wpt_t * srcWpt = (D108_Wpt_t*)response.payload;
+            waypoints.push_back(Wpt_t());
+            Wpt_t& tarWpt = waypoints.back();
+
+            tarWpt << *srcWpt;
+        }
+
+        if(response.id == Pid_Xfer_Cmplt) {
+            break;
+        }
+
+    }
+#endif
+
+#ifdef DBG_SHOW_WAYPOINT
+    list<Wpt_t>::const_iterator wpt = waypoints.begin();
+    while(wpt != waypoints.end()) {
+        cout << "-------------------------" << endl;
+        cout << "class      " << hex << (int)wpt->wpt_class << endl;
+        cout << "dspl_color " << hex << (int)wpt->dspl_color << endl;
+        cout << "dspl_attr  " << hex << (int)wpt->dspl_attr << endl;
+        cout << "smbl       " << dec <<(int)wpt->smbl << endl;
+        cout << "lat        " << wpt->lat << endl;
+        cout << "lon        " << wpt->lon << endl;
+        cout << "alt        " << wpt->alt << endl;
+        cout << "dpth       " << wpt->dpth << endl;
+        cout << "dist       " << wpt->dist << endl;
+        cout << "state      " << wpt->state << endl;
+        cout << "cc         " << wpt->cc << endl;
+        cout << "ete        " << wpt->ete << endl;
+        cout << "temp       " << wpt->temp << endl;
+        cout << "time       " << wpt->time << endl;
+        cout << "category   " << wpt->wpt_cat << endl;
+        cout << "ident      " << wpt->ident << endl;
+        cout << "comment    " << wpt->comment << endl;
+        cout << "facility   " << wpt->facility << endl;
+        cout << "city       " << wpt->city << endl;
+        cout << "addr       " << wpt->addr << endl;
+        cout << "crossroad  " << wpt->crossroad << endl;
+
+        ++wpt;
+    }
+#endif
+#ifdef EXPERIMENTAL
+    if (serial->setBitrate( GRMN_DEFAULT_BITRATE)) {
+        throw exce_t(errBlocked,"Failed to change serial link to xxx bit per second");
+    }
+#endif
+    PROGR_CALLBACK( 100,"Download complete" );
+}
+
+
+void CDevice::_uploadWaypoints(std::list<Garmin::Wpt_t>& waypoints)
+{
+    if(serial == 0) return;
+
+    PROGR_CALLBACK ( 2,"Uploading waypoints ..." );
+
+//     uint16_t prx_wpt_cnt = 0;
+    list<Wpt_t>::const_iterator wpt = waypoints.begin();
+
+    // does etrex Legend support prx waypoints?
+    while(wpt != waypoints.end()) {
+#if 0
+        if(wpt->dist != 1e25f) ++prx_wpt_cnt;
+#endif
+        ++wpt;
+    }
+
+    Packet_t command;
+    Packet_t response;
+
+    unsigned int packcntr = 0;
+    unsigned int npacks = waypoints.size();
+
+    // ???
+    command.id   = 0x1C;
+    command.size = 2;
+    *(uint16_t*)command.payload = 0x0000;
+    serial->write(command);
+
+#ifdef EXPERIMENTAL
+    if (serial->setBitrate( WAYPOINT_DL_BITRATE)) {
+        throw exce_t(errBlocked,"Failed to change serial link to xxx bit per second");
+    }
+#endif
+#if 0
+    // transmit proximity waypoints first
+    if(prx_wpt_cnt) {
+        //announce number of records
+        command.id   = Pid_Records;
+        command.size = 2;
+        *(uint16_t*)command.payload = prx_wpt_cnt;
+        serial->write(command);
+
+        wpt = waypoints.begin();
+        while(wpt != waypoints.end()) {
+            if(wpt->dist != 1e25f) {
+                command.id   = Pid_Prx_Wpt_Data;
+
+                D108_Wpt_t * p = (D108_Wpt_t *)command.payload;
+                command.size = *wpt >> *p;
+
+                serial->write(command);
+
+            }
+            ++wpt;
+        }
+
+        //announce number of records
+        command.id   = Pid_Xfer_Cmplt;
+        command.size = 2;
+        *(uint16_t*)command.payload = Cmnd_Transfer_Prx;
+        serial->write(command);
+
+    }
+#endif
+
+    //transmit _all_ waypoints
+    //announce number of records
+    command.id   = Pid_Records;
+    command.size = 2;
+    *(uint16_t*)command.payload = waypoints.size();
+    serial->write(command);
+
+    PROGR_CALLBACK ( 5,"Uploading waypoints ..." );
+
+    wpt = waypoints.begin();
+    while(wpt != waypoints.end()) {
+        ++packcntr;
+
+        command.id   = Pid_Wpt_Data;
+
+        D108_Wpt_t * p = (D108_Wpt_t *)command.payload;
+        command.size = *wpt >> *p;
+
+        serial->write(command);
+
+        ++wpt;
+
+        if ( npacks )
+            PROGR_CALLBACK ( 5 + (packcntr * 94 / npacks),"Uploading waypoints ..." );
+    }
+
+    //announce number of records
+    command.id   = Pid_Xfer_Cmplt;
+    command.size = 2;
+    *(uint16_t*)command.payload = Cmnd_Transfer_Wpt;
+    serial->write(command);
+
+#ifdef EXPERIMENTAL
+    if (serial->setBitrate( GRMN_DEFAULT_BITRATE)) {
+        throw exce_t(errBlocked,"Failed to change serial link to xxx bit per second");
+    }
+#endif
+    PROGR_CALLBACK ( 100,"Upload complete" );
+}
+
+
+void CDevice::_downloadTracks(std::list<Garmin::Track_t>& tracks)
+{
+    tracks.clear();
+    if(serial == 0) return;
+
+    PROGR_CALLBACK ( 2,"Downloading tracks ..." );
+
+    Packet_t command;
+    Packet_t response;
+
+    unsigned int npacks = 0;
+    unsigned int packcntr = 0;
+
+    // ???
+    command.id   = 0x1C;
+    command.size = 2;
+    *(uint16_t*)command.payload = 0x0000;
+    serial->write(command);
+
+#ifdef EXPERIMENTAL
+    if (serial->setBitrate( TRACK_DL_BITRATE)) {
+        throw exce_t(errBlocked, "Failed to change serial link to xxx bit per second");
+    }
+#endif
+
+    command.id   = Pid_Command_Data;
+    command.size = 2;
+    *(uint16_t*)command.payload = Cmnd_Transfer_Trk;
+    serial->write(command);
+
+    PROGR_CALLBACK ( 3,"Downloading tracks ..." );
+
+    int         trackidx = 0;
+    string      name;
+    Track_t *   track = 0;
+    while(1) {
+
+        if(!serial->read(response)) continue;
+
+        if ( response.id == Pid_Records )
+            npacks = *(uint16_t*)response.payload;
+
+        if(response.id == Pid_Trk_Hdr) {
+            ++packcntr;
+            trackidx = 0;
+            D310_Trk_Hdr_t * hdr = (D310_Trk_Hdr_t*)response.payload;
+            tracks.push_back(Track_t());
+            track = &tracks.back();
+
+            *track << *hdr;
+            name  = hdr->ident;
+
+        }
+
+        if(response.id == Pid_Trk_Data) {
+            ++packcntr;
+            D301_Trk_t * data = (D301_Trk_t*)response.payload;
+            TrkPt_t pt;
+            if(data->new_trk) {
+                if(trackidx) {
+                    tracks.push_back(Track_t());
+                    Track_t& t = tracks.back();
+                    t.color = track->color;
+                    t.dspl = track->dspl;
+                    char str[256];
+                    sprintf(str,"%s_%d",name.c_str(),trackidx++);
+                    t.ident = str;
+                    track = &t;
+                }
+                else {
+                    ++trackidx;
+                }
+            }
+
+            pt << *data;
+            track->track.push_back(pt);
+        }
+
+        if ( npacks )
+            PROGR_CALLBACK ( 3 + (packcntr * 96 / npacks),"Downloading tracks ..." );
+
+        if(response.id == Pid_Xfer_Cmplt) {
+            break;
+        }
+    }
+#ifdef EXPERIMENTAL
+    if (serial->setBitrate( GRMN_DEFAULT_BITRATE)) {
+        throw exce_t(errBlocked, "Failed to change serial link to xxx bit per second");
+    }
+#endif
+    PROGR_CALLBACK ( 100,"Download complete" );
+}
+
+
+void CDevice::_release()
+{
+    if(serial == 0) return;
+
+    serial->close();
+    delete serial;
+    serial = 0;
+}
+
+// just copied from GPSMAP60CSX driver, 20081006
+void CDevice::_getDevProperties(Garmin::DevProperties_t& dev_properties)
+{
+    if(serial == 0) return;
+    Packet_t command;
+    Packet_t response;
+
+    // ask for SD Ram capacity
+    command.id   = Pid_Command_Data;
+    command.size = 2;
+    *(uint16_t*)command.payload = Cmnd_Transfer_Mem;
+    serial->write(command);
+
+    // try to read SD Ram capacity
+    uint32_t memory = 0;
+    uint16_t tile_limit = 0;
+    while(serial->read(response)) {
+        if(response.id == Pid_Capacity_Data) {
+            tile_limit = ((uint16_t*)response.payload)[1];
+            memory = ((uint32_t*)response.payload)[1];
+        }
+    }
+    if(tile_limit == 0) {
+        throw exce_t(errRuntime,"Failed to send map: Unable to find the tile limit of the GPS");
+    }
+    if(memory == 0) {
+        throw exce_t(errRuntime,"Failed to send map: Unable to find the available memory of the GPS");
+    }
+
+    // add to the properties list
+    properties.memory_limit = memory;
+    properties.set.item.memory_limit = 1;
+    properties.maps_limit = tile_limit;
+    properties.set.item.maps_limit = 1;
+
+    // return the properties
+    dev_properties = properties;
+}
+
Index: src/EtrexLegend/loader.cpp
===================================================================
--- src/EtrexLegend/loader.cpp	(revision 0)
+++ src/EtrexLegend/loader.cpp	(revision 0)
@@ -0,0 +1,76 @@
+/**********************************************************************************************
+    Copyright (C) 2007 Oliver Eichler [EMAIL PROTECTED]
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+  Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd.
+  or one of its subsidiaries.
+
+**********************************************************************************************/
+
+#include "CDevice.h"
+
+namespace EtrexLegend
+{
+    static CDevice * device = 0;
+}
+
+
+extern "C" Garmin::IDevice * initEtrexLegend(const char * version)
+{
+    if(strncmp(version,INTERFACE_VERSION,5) != 0) {
+        return 0;
+    }
+    if(EtrexLegend::device == 0) {
+        EtrexLegend::device = new EtrexLegend::CDevice();
+    }
+    EtrexLegend::device->devname = "eTrex Legend";
+    EtrexLegend::device->devid = 411;
+    return EtrexLegend::device;
+}
+
+
+extern "C" Garmin::IDevice * initEtrexVista(const char * version)
+{
+    if(strncmp(version,INTERFACE_VERSION,5) != 0) {
+        return 0;
+    }
+    if(EtrexLegend::device == 0) {
+        EtrexLegend::device = new EtrexLegend::CDevice();
+    }
+    EtrexLegend::device->devname = "eTrex Vista";
+    EtrexLegend::device->devid = 169;
+    return EtrexLegend::device;
+}
+
+// I went back-and-forth on where to put the eTrex Classic
+// (https://buy.garmin.com/shop/shop.do?cID=167&pID=6403).  Visually,
+// and feature capabilities, it is probably close to the eTrex H.  However,
+// the eTrex Classic is of the same vintage as the eTrex Legend and eTrex Vista.
+// So, as far as firmware (and serial communications go), it is closer to those.
+// Therefore, I put it here.
+extern "C" Garmin::IDevice * const initEtrexClassic(const char * version)
+{
+    if(strncmp(version,INTERFACE_VERSION,5) != 0) {
+        return 0;
+    }
+    if(EtrexLegend::device == 0) {
+        EtrexLegend::device = new EtrexLegend::CDevice();
+    }
+    EtrexLegend::device->devname = "eTrex";
+    EtrexLegend::device->devid = 130;
+    EtrexLegend::device->supportsMaps = false;
+    return EtrexLegend::device;
+}
Index: src/EtrexLegend/CDevice.h
===================================================================
--- src/EtrexLegend/CDevice.h	(revision 0)
+++ src/EtrexLegend/CDevice.h	(revision 0)
@@ -0,0 +1,59 @@
+/**********************************************************************************************
+    Copyright (C) 2007 Oliver Eichler [EMAIL PROTECTED]
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+  Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd.
+  or one of its subsidiaries.
+
+**********************************************************************************************/
+#ifndef CDEVICE_H
+#define CDEVICE_H
+
+#include "IDeviceDefault.h"
+#include "CSerial.h"
+
+namespace EtrexLegend
+{
+
+    class CDevice : public Garmin::IDeviceDefault
+    {
+        public:
+            CDevice();
+            virtual ~CDevice();
+
+            std::string devname;
+            uint32_t devid;
+            bool supportsMaps;  // Does this device support map upload/download
+
+            const std::string& getCopyright();
+
+        private:
+            void _acquire();
+            void _uploadMap(const uint8_t * mapdata, uint32_t size, const char * key);
+            void _queryMap(std::list<Garmin::Map_t>& maps);
+            void _downloadWaypoints(std::list<Garmin::Wpt_t>& waypoints);
+            void _uploadWaypoints(std::list<Garmin::Wpt_t>& waypoints);
+            void _downloadTracks(std::list<Garmin::Track_t>& tracks);
+
+            void _getDevProperties(Garmin::DevProperties_t& dev_properties);
+
+            void _release();
+
+            Garmin::CSerial * serial;
+    };
+
+}
+#endif                           //CDEVICE_H
Index: src/EtrexLegend/CMakeLists.txt
===================================================================
--- src/EtrexLegend/CMakeLists.txt	(revision 0)
+++ src/EtrexLegend/CMakeLists.txt	(revision 0)
@@ -0,0 +1,33 @@
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+set(SRCS
+    loader.cpp
+    CDevice.cpp
+)
+
+set(HDRS
+    CDevice.h
+)
+
+include_directories(../)
+add_library(EtrexLegend SHARED ${SRCS} ${HDRS})
+target_link_libraries(EtrexLegend garmin usb pthread)
+
+set(ALIASES
+    EtrexVista
+    EtrexClassic
+)
+
+
+install(DIRECTORY ${LIBRARY_OUTPUT_PATH} DESTINATION ${QL_INSTALL_PATH})
+
+foreach(var ${ALIASES})
+    message(" ${var}")
+    add_custom_command( TARGET EtrexLegend
+                        POST_BUILD
+                        COMMAND ln ARGS -sf libEtrexLegend.so lib${var}.so
+                        WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
+                        )
+endforeach(var)
+
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 914)
+++ CMakeLists.txt	(working copy)
@@ -51,4 +51,5 @@
 
 add_subdirectory(./src)
 add_subdirectory(./src/GPSMap60CSx)
+add_subdirectory(./src/EtrexLegend)
 
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
QLandkarte-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qlandkarte-users

Reply via email to