Main Page | File List | Globals | Related Pages

map.c

00001 
00012 /* 
00013    Copyright (C) 2001-2004 Christian Claveleira (Christian.Claveleira@cru.fr)
00014 
00015    This program is free software; you can redistribute it and/or
00016    modify it under the terms of the GNU General Public License
00017    as published by the Free Software Foundation; either version 2
00018    of the License, or (at your option) any later version.
00019    
00020    This program is distributed in the hope that it will be useful,
00021    but WITHOUT ANY WARRANTY; without even the implied warranty of
00022    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023    GNU General Public License for more details.
00024    
00025    You should have received a copy of the GNU General Public License
00026    along with this program; if not, write to the Free Software
00027    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00028    
00029  */
00030 
00031 /*      $Id: map.c,v 1.8 2004/01/25 09:18:12 clavelei Exp clavelei $     */
00032 
00033 #ifndef lint
00034 //static char vcid[] = "$Id: map.c,v 1.8 2004/01/25 09:18:12 clavelei Exp clavelei $";
00035 #endif /* lint */
00036 
00037 #define ALLOW_ACCESS_TO_INTERNALS_OF_BITMAPS               // dirty !  $$
00038 #include <PalmOS.h>
00039 #include <PalmCompatibility.h>
00040 #include "gtalkRsc.h"
00041 #include "latlong.h"
00042 #include "MathLib.h"
00043 #include "gpslib.h"
00044 #include "gtalk.h"
00045 #include "gpsutil.h"
00046 #include "map.h"
00047 #include "log.h"
00048 #include "dbio.h"
00049 #include "route.h"
00050 #include "memo.h"
00051 
00052 MapFlagsType MapFlags;
00053 RectangleType DrawRect;                /* draw rectangle in graphic window */
00054 
00055 static WinHandle OffScreenWH;          /* offscreen work window handle */
00056 static Boolean DrawRectCleared;        /* set if draw rectangle cleared */
00057 static Semicircle_Type P0;             /* top left displayed coord. in graphic window */
00058 static Int32 LonByPixel,                       /* longitude coefficient (y) in graphic window */
00059 
00060   LatByPixel;                          /* latitude coefficient (x) in graphic window */
00061 static UInt16 ActTrkIndex;
00062 static UInt16 CurrentTrackIndex;
00063 
00064 #define BottomStatPos 2, 146                               /* bottom status display position */
00065 
00066 static void DrawGrid (void)    MAP_SECTION;
00067      static void DrawWaypoints (UInt16 category, Boolean rescale) MAP_SECTION;
00068      static Int32 MaxLonDisplayed (void) MAP_SECTION;
00069      static Int32 MaxLatDisplayed (void) MAP_SECTION;
00070      static void DisplayWpt (Custom_Wpt_Type * wp, Boolean invert) MAP_SECTION;
00071      static void RefreshDisplay (Boolean Erase) MAP_SECTION;
00072      static void DisplayPosition (Semicircle_Type * ptp) MAP_SECTION;
00073      static void DrawCalibrate (Int32 latmin, Int32 latmax, Int32 lonmin, Int32 lonmax) MAP_SECTION;
00074      static void ReCenterDisplay (Semicircle_Type * NewCenterPos) MAP_SECTION;
00075      static Boolean WptClicked (WordPtr index, PointType point) MAP_SECTION;
00076 static void MapFormClean(void);
00077 #ifdef GRAPHICALROUTEEDIT
00078      static Boolean RteWptClicked (Word rteindex, WordPtr wptindexp, PointType point) MAP_SECTION;
00079 #endif
00080 
00087 #define WptVisible(wp) (((wp).posn.lat >= P0.lat) && \
00088       ((wp).posn.lat <= Latmax) && \
00089       ((wp).posn.lon >= P0.lon) && \
00090       ((wp).posn.lon <= Lonmax))
00091 
00092 
00099 #define PosVisible(pos) (((pos).lat >= P0.lat) && \
00100       ((pos).lat <= MaxLatDisplayed ()) && \
00101       ((pos).lon >= P0.lon) && \
00102       ((pos).lon <= MaxLonDisplayed ()))
00103 
00104 
00112 #define LatLonToXY(p,pix) pix.x=DrawRect.topLeft.x+((p).lon - P0.lon)/LonByPixel;\
00113            pix.y=DrawRect.topLeft.y+DrawRect.extent.y-((p).lat -P0.lat)/LatByPixel
00114 
00115 
00123 #define XYToLatLon(pix,p) (p).lon= (pix.x-DrawRect.topLeft.x)*LonByPixel+P0.lon;\
00124           (p).lat=(DrawRect.topLeft.y+DrawRect.extent.y-pix.y)*LatByPixel+P0.lat
00125 
00126 
00135 static Boolean HwrBacklight(Boolean set, Boolean newState) SYS_TRAP(sysTrapHwrBacklightV33);
00136 /* static UInt8 SysLCDBrightness(Boolean set, UInt8 newBrightnessLevel) */
00137 /*        SYS_TRAP(sysTrapSysLCDBrightness); */
00138      
00139 static Boolean BacklightIsOn(void) {
00140   UInt32 glRomVersion;
00141 
00142   FtrGet(sysFtrCreator, sysFtrNumROMVersion, &glRomVersion);
00143   if (glRomVersion < sysMakeROMVersion(5,0,0,sysROMStageRelease,0)) {
00144     return HwrBacklight(false, false);
00145   }
00146   else {
00147     UInt8 brightnessLevel = SysLCDBrightness(false, 0);
00148     return brightnessLevel ? true : false;
00149   }
00150 }
00151 
00152 #define hwrDispBacklight 0x12
00153 // this function works for get/set in 3.x-4.x and for getting in 5.x
00154 void HwrDisplayAttributes(Boolean set, UInt8 kind, void *val)  SYS_TRAP(sysTrapHwrDisplayAttributes);
00155 
00164 static Boolean HwrBacklight2(Boolean set, Boolean newState){
00165   UInt32 glRomVersion;
00166   Boolean oldState;
00167 
00168   FtrGet(sysFtrCreator, sysFtrNumROMVersion, &glRomVersion);
00169   debug (GTALKDBG_INFOS, ("HwrBacklight2 : P1, glRomVersion=%lx",glRomVersion));
00170   if (glRomVersion < sysMakeROMVersion(4,0,0,sysROMStageRelease,0)) {
00171     oldState=HwrBacklight(false, false);
00172   }
00173   else    HwrDisplayAttributes(false, hwrDispBacklight, &oldState); // always works -> non !
00174   debug (GTALKDBG_INFOS, ("HwrBacklight2 : P2"));
00175   if (set){
00176     if ((oldState && !newState) || (!oldState && newState)){
00177       // enqueue request for backlight toggle
00178       EvtEnqueueKey(vchrBacklight, 0, commandKeyMask);
00179     }
00180   }
00181   return oldState;
00182 }
00183 
00184 
00192 static void BeepBeep (UInt16 repeat)
00193 {
00194   SndCommandType cmd;
00195 
00196   for (; repeat; repeat--)
00197     {
00198       cmd.cmd = sndCmdFreqDurationAmp;
00199       cmd.param1 = 1200;
00200       cmd.param2 = 100;
00201       cmd.param3 = sndMaxAmp;
00202       SndDoCmd (NULL, &cmd, 0);
00203       cmd.param1 = 1000;
00204       cmd.param2 = 600;
00205       SndDoCmd (NULL, &cmd, 0);
00206       SysTaskDelay (sysTicksPerSecond / 2);
00207     }
00208 }                                                          /* BeepBeep */
00209 
00210 
00211 
00221 static void
00222 Circle (UInt16 x, UInt16 y, UInt16 r)
00223 {
00224     RectangleType bounds = { {x - r, y - r}, {2 * r, 2 * r} }, bounds2 =
00225     {
00226         {
00227         bounds.topLeft.x + 1, bounds.topLeft.y + 1}
00228         ,
00229         {
00230         bounds.extent.x - 2, bounds.extent.y - 2}
00231     };
00232     WinHandle CurWH = WinGetDrawWindow ();
00233 
00234     if (!OffScreenWH)
00235         return;
00236     WinSetDrawWindow (OffScreenWH);
00237     WinEraseWindow ();
00238     WinDrawRectangle (&bounds, r);
00239     /*      bounds.topLeft.x++; */
00240     /*      bounds.topLeft.y++; */
00241     /*      bounds.extent.x -= 2; */
00242     /*      bounds.extent.y -= 2; */
00243     WinInvertRectangle (&bounds2, r - 2);
00244     WinCopyRectangle (OffScreenWH, CurWH, &bounds, x - r, y - r, scrOR /*  scrAND */ );
00245     WinSetDrawWindow (CurWH);
00246 }                                                          /* Circle */
00247 
00248 
00259 static void
00260 RedrawBitmap (int BitmapID, SWord x, SWord y)
00261 {
00262     static SWord px,
00263       py,
00264       bw,
00265       bh;
00266     static int pbitmapid;
00267     WinHandle CurWH;
00268     RectangleType r;
00269     MemHandle ResH;
00270     BitmapPtr BitP;
00271 
00272     if (!OffScreenWH)
00273         return;
00274     WinSetClip (&DrawRect);
00275     CurWH = WinGetDrawWindow ();
00276     r.topLeft.x = 0;
00277     r.topLeft.y = 0;
00278     r.extent.x = bw;
00279     r.extent.y = bh;
00280     if (!DrawRectCleared)
00281     {                                                      /* effacement precedent dessin ? */
00282         WinCopyRectangle (OffScreenWH, CurWH, &r, px, py, scrXOR /*  scrAND */ );
00283         WinDrawLine (px + bw / 2, py + bh / 2, x, y);
00284     }
00285     DrawRectCleared = 0;
00286 
00287     ResH = DmGetResource ('Tbmp', BitmapID);
00288     if (ResH)
00289     {
00290         BitP = MemHandleLock (ResH);
00291         bh = BitP->height;
00292         bw = BitP->width;
00293         WinSetDrawWindow (OffScreenWH);
00294         WinDrawBitmap (BitP, 0, 0);
00295         WinSetDrawWindow (CurWH);
00296         MemHandleUnlock (ResH);
00297         DmReleaseResource (ResH);
00298         r.extent.x = bw;
00299         r.extent.y = bh;
00300         pbitmapid = BitmapID;
00301     }
00302     x -= bw / 2;                                           /* recentrage  */
00303     y -= bh / 2;
00304     WinCopyRectangle (OffScreenWH, CurWH, &r, x, y, scrXOR /*  scrAND */ );
00305     px = x;
00306     py = y;
00307     WinResetClip ();
00308 }                                                          /* RedrawBitmap */
00309 
00310 
00317 static void
00318 DrawGrid ()
00319 {                                                          /* quadrillage */
00320 #define CENTMINUTES 19884108
00321 #define CENTKM      10736559
00322 #define CENTMI      17278774                               // a verifier $$
00323 
00324     Int32 deltalon = LonByPixel * DrawRect.extent.x,    /* longitude couverte */
00325         //    deltalat = LatByPixel * DrawRect.extent.y, /* latitude couverte */
00326         //      lonmax = MaxLonDisplayed (),
00327 
00328       latmax = MaxLatDisplayed (),
00329       pas,                             /* pas de quadrillage */
00330 
00331       lat0,
00332       lon0,                            /* origine quadrillage */
00333 
00334       inc,
00335       unit,
00336       coef;
00337     UInt16 n;
00338     Semicircle_Type ll;                /* current lat/lon */
00339     PointType p;
00340 
00341     WinSetClip (&DrawRect);
00342     unit = Prefs.distunit == metric ? CENTKM : Prefs.distunit == nautical ? CENTMINUTES : CENTMI;
00343     for (coef = 10, pas = unit; deltalon / pas <= 1; coef *= 10)
00344         pas = unit / coef;
00345     lon0 = (P0.lon / pas) * pas;                           /* lat/lon depart quadrillage */
00346     lat0 = (P0.lat / pas) * pas;
00347     ll.lat = lat0;
00348     for (ll.lon = lon0, inc = 0; inc <= deltalon; ll.lon += pas, inc += pas)
00349     {
00350         LatLonToXY (ll, p);
00351         WinDrawGrayLine (p.x, DrawRect.topLeft.y, p.x, DrawRect.topLeft.y + DrawRect.extent.y);
00352     }
00353     ll.lon = lon0;
00354     for (ll.lat = lat0; ll.lat < latmax; ll.lat += pas)
00355     {
00356         LatLonToXY (ll, p);
00357         WinDrawGrayLine (DrawRect.topLeft.x, p.y, DrawRect.topLeft.x + DrawRect.extent.x, p.y);
00358     }
00359 
00360     n = 1000 / coef;                                       /* echelle de distance */
00361     if (n)
00362         StrPrintF (gbuf1, "%d %s", n, DistanceUnitNames[Prefs.distunit]);       /* >= 1 nm */
00363     else
00364     {                                                      /* < 1 nm */
00365         StrPrintF (gbuf1, "0,");
00366         for (n = coef / 100000; n; n /= 10)
00367             StrNCatSafe (gbuf1, "0", sizeof (gbuf1), 1);
00368         //      StrNCatSafe (gbuf1, "1 nm", sizeof (gbuf1), 4);
00369         StrPrintF (gbuf1 + StrLen (gbuf1), "1 %s", DistanceUnitNames[Prefs.distunit]);
00370     }
00371     WinDrawChars (gbuf1, StrLen (gbuf1),
00372                   DrawRect.topLeft.x + DrawRect.extent.x - 2 - FntCharsWidth (gbuf1,
00373                                                                               StrLen (gbuf1)),
00374                   DrawRect.topLeft.y + 2);
00375     //WinDrawLine (DrawRect.topLeft.x + DrawRect.extent.x, DrawRect.topLeft.y+10, DrawRect.topLeft.x + DrawRect.extent.x-(pas/LonByPixel), DrawRect.topLeft.y+10);
00376     WinResetClip ();
00377 }                                                          /* DrawGrid */
00378 
00379 
00380 
00389 static void
00390 DrawWaypoints (UInt16 category, Boolean rescale)
00391 {                                                          /* trace des waypoints  */
00392     Custom_Wpt_Type wp;
00393     MemHandle font129H;
00394     Err error;
00395     UInt16 i,
00396       pos;
00397     void *font129p;
00398     FontID oldfont;
00399     Int32 Lonmax = MaxLonDisplayed (),
00400       Latmax = MaxLatDisplayed ();
00401     //              Semicircle_Type position;
00402     Int32 latmin = LATMAX,
00403       latmax = LATMIN,
00404       lonmin = LONMAX,
00405       lonmax = LONMIN;
00406 
00407     font129H = DmGetResource ('NFNT', MidgetXS0FontRSCID);
00408     font129p = MemHandleLock (font129H);
00409     FntDefineFont (MidgetXS0FontID, font129p);
00410     //    oldfont = UICurrentFontPtr;                              // $$  
00411     oldfont = FntSetFont (MidgetXS0FontID);
00412     //    UICurrentFontPtr = font129p;                             // $$  
00413 
00414     WinSetClip (&DrawRect);
00415     pos = 0;
00416     for (i = DmNumRecordsInCategory (WptDB, category); i > 0; i--)
00417     {
00418         DmQueryNextInCategory (WptDB, &pos, category);
00419         IndexToCustomWpt (pos, WptDB, &wp);
00420         pos++;
00421         if (rescale)
00422         {
00423             if (wp.posn.lat < latmin)
00424                 latmin = wp.posn.lat;
00425             else if (wp.posn.lat > latmax)
00426                 latmax = wp.posn.lat;
00427             if (wp.posn.lon < lonmin)
00428                 lonmin = wp.posn.lon;
00429             else if (wp.posn.lon > lonmax)
00430                 lonmax = wp.posn.lon;
00431             continue;
00432         }
00433         if (WptVisible (wp))
00434             DisplayWpt (&wp, 0);
00435     }                                                      /* for */
00436     WinResetClip ();
00437     //    UICurrentFontPtr = oldfont;                              // $$
00438     FntSetFont (oldfont);
00439     MemHandleUnlock (font129H);
00440     error = DmReleaseResource (font129H);
00441     if (rescale)
00442     {
00443         DrawCalibrate (latmin, latmax, lonmin, lonmax);
00444         DrawWaypoints (category, 0);
00445     }
00446 }                                                          /* DrawWaypoints */
00447 
00448 
00459 Boolean
00460 DrawRoute (UInt16 index, Boolean rescale, Semicircle_Type * position)
00461 {
00462     Custom_Wpt_Type wpt;
00463     MemHandle                                              /*  ResH, */
00464         RecH = NULL;
00465     void *RecP;
00466     UInt16 n,
00467       i;
00468     LocalFormatID fmt;
00469     //    BitmapPtr BitP;
00470     PointType point,
00471       oldpoint = { 0, 0 };
00472     Boolean inside = 0;
00473     Int32 latmin = LATMAX,
00474       latmax = LATMIN,
00475       lonmin = LONMAX,
00476       lonmax = LONMIN;
00477 
00478     debug (GTALKDBG_CALLS, ("<->DrawRoute(%d)", (int) rescale));
00479     WinSetClip (&DrawRect);
00480     RecH = DmQueryRecord (RteDB, index);
00481     if (RecH)
00482     {
00483         n = WptsInRteDB (RecH);
00484         RecP = MemHandleLock (RecH);
00485         for (i = 1; i <= n; i++)
00486         {
00487             fmt = PtrToCustomWpt ((Object *) (RecP + OffsetOfObjectInRec (RecH, i)), &wpt);
00488             if (fmt)
00489             {                                              /* wpt ? */
00490                 if (position)
00491                 {
00492                     inside |= WptHit (&wpt, position);
00493                     continue;
00494                 }
00495                 if (wpt.posn.lat < latmin)
00496                     latmin = wpt.posn.lat;
00497                 else if (wpt.posn.lat > latmax)
00498                     latmax = wpt.posn.lat;
00499                 if (wpt.posn.lon < lonmin)
00500                     lonmin = wpt.posn.lon;
00501                 else if (wpt.posn.lon > lonmax)
00502                     lonmax = wpt.posn.lon;
00503 
00504                 if (rescale)
00505                     continue;
00506                 DisplayWpt (&wpt, 0);
00507                 LatLonToXY (wpt.posn, point);
00508                 if (i > 1)
00509                     WinDrawLine (oldpoint.x, oldpoint.y, point.x, point.y);
00510                 oldpoint.x = point.x;
00511                 oldpoint.y = point.y;
00512             }
00513         }
00514         MemHandleUnlock (RecH);
00515     }
00516     WinResetClip ();
00517     if (rescale && !position)
00518     {
00519         DrawCalibrate (latmin, latmax, lonmin, lonmax);
00520         DrawRoute (index, 0, NULL);
00521     }
00522     return (inside);
00523 }                                                          /* DrawRoute */
00524 
00525 
00536 static void
00537 DrawCalibrate (Int32 latmin, Int32 latmax, Int32 lonmin, Int32 lonmax)
00538 {
00539     double coef,
00540       LatBP,
00541       LonBP;
00542 
00543     debug (GTALKDBG_CALLS, ("<->DrawCalibrate(%ld,%ld,%ld,%ld)", latmin, latmax, lonmin, lonmax));
00544     if (latmin < -954437180L)
00545         latmin = -954437180L;                              /* 80° */
00546     if (latmax > 954437180L)
00547         latmax = 954437180L;
00548     P0.lat = latmin;                                       /*  origine */
00549     P0.lon = lonmin;
00550     coef = (latmax + latmin) / 2 * PI / OnePower31;        /* lat moyenne en radian */
00551     coef = cos (coef);
00552     if (coef < 0)
00553         coef = -coef;
00554 
00555     LonBP = (lonmax - lonmin) / DrawRect.extent.x;
00556     if (LonBP < 10)
00557         LonBP = 10;
00558     LatBP = LonBP * coef;
00559 
00560     if (((latmax - latmin) / LatBP) > DrawRect.extent.y)
00561     {                                                      /* on depasse en latitude ? */
00562         LatBP = (latmax - latmin) / DrawRect.extent.y;
00563         if (LatBP < 10)
00564             LatBP = 10;
00565         LonBP = LatBP / coef;
00566         P0.lon = (lonmax / 2 + lonmin / 2) - (DrawRect.extent.x * LonBP) / 2;   /* recentrage */
00567     }
00568     else
00569         P0.lat = (latmax / 2 + latmin / 2) - (DrawRect.extent.y * LatBP) / 2;   /* recentrage */
00570     LonByPixel = LonBP;
00571     LatByPixel = LatBP;
00572 }                                                          /* DrawCalibrate */
00573 
00574 
00585 void
00586 DrawTrack (UInt16 index, Boolean rescale, Boolean Clear)
00587 {
00588     Object *RecP;
00589     Custom_Trk_Point_Type *ht;
00590     Compact_Trk_Point_Type *cht;
00591     PointType CurrentPoint,
00592       PreviousPoint = { -1, 0 };
00593     UInt16 n;
00594     MemHandle RecH;
00595 
00596     debug (GTALKDBG_CALLS, ("<->DrawTrack()"));
00597     if (Clear)
00598     {
00599         WinEraseRectangle (&DrawRect, 0);
00600         DrawRectCleared = 1;
00601     }
00602     //    else WinSetPattern(grayPattern);
00603     RecH = DmQueryRecord (TrkDB, index);
00604     if (!RecH)
00605         return;
00606     n = TrkptsInTrkDB (RecH);
00607     RecP = MemHandleLock (RecH);
00608     if (rescale)
00609         DrawCalibrate (RecP->d.CustTrkHdr.latmin, RecP->d.CustTrkHdr.latmax,
00610                        RecP->d.CustTrkHdr.lonmin, RecP->d.CustTrkHdr.lonmax);
00611     WinSetClip (&DrawRect);
00612     if (RecP->d.CustTrkHdr.type == CustomTrkPt)
00613     {
00614         ht = (Custom_Trk_Point_Type *) ((void *) RecP + SizeOfObject (RecP));
00615         for (; n > 0; n--, ht++)
00616         {
00617             LatLonToXY (ht->posn, CurrentPoint);
00618             if (ht->new_trk || (PreviousPoint.x < 0))
00619                 WinDrawLine (CurrentPoint.x, CurrentPoint.y, CurrentPoint.x, CurrentPoint.y);
00620             else
00621                 WinDrawLine (PreviousPoint.x, PreviousPoint.y, CurrentPoint.x, CurrentPoint.y);
00622             //else WinFillLine(PreviousPoint.x, PreviousPoint.y, CurrentPoint.x, CurrentPoint.y);
00623             PreviousPoint.x = CurrentPoint.x;
00624             PreviousPoint.y = CurrentPoint.y;
00625         }
00626     }
00627     else
00628     {
00629         cht = (Compact_Trk_Point_Type *) ((void *) RecP + SizeOfObject (RecP));
00630         for (; n > 0; n--, cht++)
00631         {
00632             LatLonToXY (cht->posn, CurrentPoint);
00633             if (cht->new_trk || (PreviousPoint.x < 0))
00634                 WinDrawLine (CurrentPoint.x, CurrentPoint.y, CurrentPoint.x, CurrentPoint.y);
00635             else
00636                 WinDrawLine (PreviousPoint.x, PreviousPoint.y, CurrentPoint.x, CurrentPoint.y);
00637             PreviousPoint.x = CurrentPoint.x;
00638             PreviousPoint.y = CurrentPoint.y;
00639         }
00640     }
00641     MemHandleUnlock (RecH);
00642     WinResetClip ();
00643 }                                                          /* DrawTrack */
00644 
00645 
00654 static void
00655 SetTimeOfNextAlarm (UInt32 alarmTime, DWord ref)
00656 {
00657     UInt16 cardNo;
00658     LocalID dbID;
00659     DmSearchStateType searchInfo;
00660 
00661     DmGetNextDatabaseByTypeCreator (true, &searchInfo,
00662                                     sysFileTApplication, GPilotSID, true, &cardNo, &dbID);
00663     if (AlmSetAlarm (cardNo, dbID, ref, alarmTime, true))
00664         SndPlaySystemSound (sndError);
00665 }                                                          /* SetTimeOfNextAlarm */
00666 
00667 
00675 Boolean
00676 MapFormHandleEvent (EventPtr e)
00677 {
00678     static FormPtr frm;
00679     static Boolean atProximity;
00680     static UInt32 NextLogTime;
00681     static ListPtr LstPtr;
00682     static UInt16 RteWptIndex,
00683       OldRouteIndex;
00684     static int SelectedRteWptIndex;
00685     static Boolean BackLightOn;
00686     Custom_Rte_Hdr_Type RteHdr;
00687     Err error;
00688     ControlPtr PopupPtr;
00689     Boolean scaled,
00690       handled = false;
00691     UInt16 i;
00692 
00693     if (e->eType != nilEvent) debug_in (GTALKDBG_CALLS, ("->MapFormHandleEvent(%s)", e->eType > LASTVALIDEVTNAME ?StrIToA(gbuf1,e->eType):EvtNames[e->eType]));
00694     switch (e->eType)
00695     {
00696     case nilEvent:
00697         GpslibTicks ();
00698         break;
00699 
00700     case frmOpenEvent:
00701         frm = FrmGetActiveForm ();
00702         handled = true;
00703         GetObjectBounds (MapDrawingID, &DrawRect);         /* recup bound box du gadget */
00704         FrmDrawForm (frm);                                 // position a voir
00705         WinDrawRectangleFrame (simpleFrame, &DrawRect);
00706         if (!OffScreenWH)
00707             OffScreenWH = WinCreateOffscreenWindow (160, 160, screenFormat, &error);    /* offscreen work window for bitmaps */
00708         CurrentTrackIndex = 0;
00709         scaled = 0;
00710         SelectedRteWptIndex = -1;
00711 
00712         if (Prefs.PermTrackIndex)
00713         {                                                  /* background track */
00714             DrawTrack (Prefs.PermTrackIndex - 1, 1, 0);
00715             scaled = 1;
00716         }
00717 
00718         if (MapFlags.AllowedOps & MapOpWptDisp)
00719         {                                                  /* drawing of current waypoints */
00720             MapFlags.DrawWpts = 1;
00721             if (!(MapFlags.AllowedOps & MapOpRteEdit))
00722             {
00723                 DrawWaypoints (Prefs.wptcategory, !scaled);
00724                 scaled = 1;
00725             }
00726         }
00727         else
00728             MapFlags.DrawWpts = 0;
00729 
00730         if (MapFlags.AllowedOps & MapOpActiveRte)
00731         {                                                  /* drawing of active route */
00732             MapFlags.DrawRtes = 1;
00733             DrawRoute (CurrentRouteIndex, !scaled, NULL);
00734             scaled = 1;
00735             ShowObject(MapRteChk);
00736         }
00737         else
00738         {
00739           // HideObject (MapRteChk);
00740             MapFlags.DrawRtes = 0;
00741         }
00742 
00743         if (MapFlags.AllowedOps & MapOpTrack)
00744         {                                                  /* real time tracking */
00745             MapFlags.DrawActTrk = 1;
00746             ActTrkIndex = init_active_trk ();              // $$
00747             //      DrawWaypoints (Prefs.wptcategory, 1);
00748             ShowObject(MapTrkChk);
00749             ShowObject(MapLogChk);
00750         }
00751         else
00752         {
00753           // HideObject (MapTrkChk);
00754             //      HideObject (MapLogChk);
00755         }
00756 
00757         if (MapFlags.AllowedOps & MapOpMapTrack)
00758         {                                                  /* supplementary selectionable track ? */
00759             LstPtr = (ListPtr) GetObjPtr (MapListID);
00760             LstSetListChoices (LstPtr, NULL, DmNumRecordsInCategory (TrkDB, Prefs.trkcategory));
00761             LstSetDrawFunction (LstPtr, &MainListDraw);
00762             LstSetSelection (LstPtr, 0);
00763             //      LstMakeItemVisible (LstPtr, DatumIndex);
00764             LstSetHeight (LstPtr, min (LstGetNumberOfItems (LstPtr), 10));
00765             PopupPtr = (ControlPtr) GetObjPtr (MapPopupID);
00766             CtlSetLabel (PopupPtr, "Choose track");
00767         }
00768         else
00769             HideObject (MapPopupID);
00770 #ifdef GRAPHICALROUTEEDIT
00771 
00772         if ((MapFlags.AllowedOps & MapOpRteEdit) || (MapFlags.AllowedOps & MapOpRteNew))
00773         {                                                  /* edition/creation of route */
00774             ShowObject (MapNewChk);
00775             ShowObject (MapDelChk);
00776             ShowObject (MapInsChk);
00777             ShowObject (MapBtCancelID);
00778 
00779             OldRouteIndex = CurrentRouteIndex;
00780             error = CopyOrCreateRoute (&RteHdr, CurrentRouteIndex, MapFlags.AllowedOps & MapOpRteNew);
00781             if (error)
00782             {
00783                 FrmReturnToForm (0);
00784                 break;
00785             }
00786             CurrentRouteIndex = DmNumRecords (RteDB) - 1;  /* la route de travail est la derniere */
00787             if (MapFlags.AllowedOps & MapOpRteNew)         /* MapFlags.AllowedOps|=MapOpRteEdit */
00788                 RteWptIndex = 0;
00789             else
00790             {
00791                 MemHandle RecH = DmQueryRecord (RteDB, CurrentRouteIndex);
00792                 if (RecH)
00793                     RteWptIndex = WptsInRteDB (RecH);
00794                 DrawRoute (CurrentRouteIndex, !scaled, NULL);
00795             }
00796             MapFlags.DrawRtes = 1;
00797             MainListDirty = 1;
00798         }
00799 #endif
00800         //      ActTrkIndex=init_active_trk(); pas a sa place ?
00801 
00802         SetControlValue (MapWptChk, MapFlags.DrawWpts);
00803         SetControlValue (MapGrdChk, MapFlags.DrawGrd);
00804         SetControlValue (MapRteChk, MapFlags.DrawRtes);
00805         atProximity = 0;
00806         RefreshDisplay (0);
00807         i = StrPrintF (gbuf1, "Datum : %s", gDatum[Prefs.datum].name);
00808         WinDrawChars (gbuf1, i, BottomStatPos);
00809 
00810         break;
00811 
00812     case frmCloseEvent:
00813       MapFormClean();
00814         break;
00815 
00816     case popSelectEvent:
00817         if (e->data.popSelect.controlID == MapPopupID)
00818         {
00819             MemHandle RecH;
00820             UInt16 oldindex = CurrentTrackIndex;
00821             CurrentTrackIndex = 0;
00822             DmSeekRecordInCategory (TrkDB, &CurrentTrackIndex, e->data.popSelect.selection,
00823                                     dmSeekForward, Prefs.trkcategory);
00824             RecH = DmQueryRecord (TrkDB, CurrentTrackIndex);    /* recup du nom */
00825             if (RecH)
00826             {
00827                 Object *RecP = MemHandleLock (RecH);
00828                 StrNCopySafe (gbuf1, RecP->d.CustTrkHdr.name, 12);
00829                 CtlSetLabel (e->data.popSelect.controlP, gbuf1);
00830                 MemHandleUnlock (RecH);
00831             }
00832             if (++CurrentTrackIndex != oldindex)
00833                 if (!oldindex)
00834                     DrawTrack (CurrentTrackIndex - 1, !Prefs.PermTrackIndex,
00835                                !Prefs.PermTrackIndex);
00836                 else
00837                     RefreshDisplay (1);
00838             else
00839             {
00840                 CurrentTrackIndex = 0;
00841                 RefreshDisplay (1);
00842             }
00843             handled = true;
00844         }
00845         break;
00846 
00847     case penDownEvent:
00848         if (RctPtInRectangle (e->screenX, e->screenY, &DrawRect))
00849         {
00850             //      Semicircle_Type     ct;
00851             PointType ClickPt = { e->screenX, e->screenY };
00852             Object o;
00853             ObjectPtr newp = &o;
00854             Custom_Wpt_Type ClickPos;
00855             Word index;
00856             static Word lastindex=dmMaxRecordIndex;
00857             static UInt32 lastclick;
00858             //      UInt16 l;
00859 
00860             frm = FrmGetActiveForm ();                     // optimisable $$
00861             MemSet (&ClickPos, sizeof (ClickPos), 0);
00862             XYToLatLon (ClickPt, ClickPos.posn);
00863 #ifdef GRAPHICALROUTEEDIT
00864             //             if ((MapFlags.AllowedOps & MapOpRteEdit)||(MapFlags.AllowedOps & MapOpRteNew)){
00865             if ((GetControlValue (MapNewChk) || GetControlValue (MapInsChk)) && !RteWptClicked (CurrentRouteIndex, &index, ClickPt))    /* creation or insertion of route wpt */
00866             {
00867                 if (MapFlags.DrawWpts & WptClicked (&index, ClickPt))
00868                     IndexToCustomWpt (index, WptDB, &ClickPos);
00869                 else
00870                 {
00871                     StrPrintF (gbuf1, "R%d-%d", 10, RteWptIndex);
00872                     StrNCopySafe (ClickPos.ident, gbuf1, sizeof (ClickPos.ident));      // $$
00873                 }
00874                 //      error = CustomToDBWpt (&ClickPos, G103Type, -1, 0);  // $$
00875                 CustomToAnyWpt (&ClickPos, G103Type, newp, 0);
00876                 //    error = put_wpt (&(newp->d.g), 0, 0, newp->header.type, newp->header.size);  // $$
00877                 if (GetControlValue (MapNewChk))
00878                     error = EditRouteRecord (CurrentRouteIndex, RteWptIndex + 1, newp);
00879                 else
00880                     error = EditRouteRecord (CurrentRouteIndex, SelectedRteWptIndex, newp);
00881                 if (!error)
00882                     RteWptIndex++;
00883 
00884                 SetControlValue (MapInsChk, 0);
00885                 SelectedRteWptIndex = -1;
00886                 RefreshDisplay (1);                        // $$
00887                 DisplayWpt (&ClickPos, 1);
00888             }
00889             else if (GetControlValue (MapDelChk))          /* suppression of a route wpt */
00890             {
00891                 if (RteWptClicked (CurrentRouteIndex, &index, ClickPt))
00892                 {
00893                     if (!EditRouteRecord (CurrentRouteIndex, index, NULL))
00894                         RteWptIndex--;
00895                     RefreshDisplay (1);                    // $$
00896                     SetControlValue (MapDelChk, 0);
00897                 }
00898                 SelectedRteWptIndex = -1;
00899             }
00900             else if (GetControlValue (MapRteChk)
00901                      && RteWptClicked (CurrentRouteIndex, &index, ClickPt))
00902             {                                              /* selection of a route wpt */
00903                 LocalFormatID fmt;
00904                 void *RecP;
00905                 MemHandle RecH = DmQueryRecord (RteDB, CurrentRouteIndex);
00906                 if (RecH)
00907                 {
00908                     RecP = MemHandleLock (RecH);
00909                     fmt =
00910                         PtrToCustomWpt ((Object *) (RecP +
00911                                                     OffsetOfObjectInRec (RecH, index)), &ClickPos);
00912                     MemHandleUnlock (RecH);
00913                     if (SelectedRteWptIndex >= 0)
00914                         RefreshDisplay (1);
00915                     DisplayWpt (&ClickPos, 1);
00916                     SelectedRteWptIndex = index;
00917                 }
00918             }
00919             else
00920 #endif
00921               if (MapFlags.DrawWpts & WptClicked (&index, ClickPt)){  /* wpt selected ? */
00922                 if ((lastindex==index)&&(TimGetTicks()<(lastclick+SysTicksPerSecond()))) { /* double click ? */
00923                   CurrentRecordIndex=index;
00924                   FrmPopupForm (EditForm);
00925                 }
00926                 else {
00927                   int l;
00928                   lastclick=TimGetTicks();
00929                   IndexToCustomWpt (lastindex, WptDB, &ClickPos);
00930                   DisplayWpt (&ClickPos, 0);
00931                   IndexToCustomWpt (index, WptDB, &ClickPos);
00932                   DisplayWpt (&ClickPos, 1);
00933                   l=StrPrintF (gbuf1, "%s",ClickPos.cmnt);
00934                   WinDrawChars (gbuf1, l, BottomStatPos);
00935                   lastindex=index;
00936                 }
00937               }
00938 else
00939             {                                              /* recentrage */
00940                 //              long deltalon;
00941                 Semicircle_Type CenterPos;
00942                 XYToLatLon (ClickPt, CenterPos);
00943                 ReCenterDisplay (&CenterPos);
00944                 RefreshDisplay (1);
00945                 DisplayPosition (&ClickPos.posn);
00946                 SelectedRteWptIndex = -1;
00947             }
00948             handled = true;
00949         }
00950         break;
00951 
00952     case PvtReceivedEvent:                                 /* position recue */
00953         {
00954             //        Semicircle_Type CurrentWGS84Pos;
00955 /*          Radian_Type *PositionP; */
00956             D800_Pvt_Data_Type pvt;
00957             Custom_Trk_Point_Type trkpt;
00958 /*          SWord epex, */
00959 /*            epey; */
00960             static UInt32 LastValidPvt;
00961             PointType wpt;
00962             //      double latitude,
00963             //        longitude;
00964             //      UInt16 l;
00965 
00966             if(!LastValidPvt)LastValidPvt=TimGetSeconds ();
00967             //      SndPlaySystemSound (sndClick);
00968             GarminGetPVT (&pvt);
00969             //      PositionP = (Radian_Type *) & (e->data);
00970             CurrentWGS84Pos.lat = pvt.posn.lat * OnePower31Pi;
00971             CurrentWGS84Pos.lon = pvt.posn.lon * OnePower31Pi;
00972             if (!PosVisible (CurrentWGS84Pos))
00973             {
00974                 ReCenterDisplay (&CurrentWGS84Pos);
00975                 RefreshDisplay (1);
00976             }
00977             LatLonToXY (CurrentWGS84Pos, wpt);
00978             if (pvt.fix >invalid){
00979               RedrawBitmap (Target1ID, wpt.x, wpt.y);
00980             //      epex=(UInt16)pvt.epe/LonByPixel;
00981             //      epey=(UInt16)pvt.epe/LatByPixel;
00982               DisplayPosition (&CurrentWGS84Pos);
00983               LastValidPvt=TimGetSeconds ();
00984             }
00985             if (MapFlags.DrawRtes)
00986             {
00987                 if (!atProximity)
00988                 {
00989                     if ((atProximity = DrawRoute (CurrentRouteIndex, 0, &CurrentWGS84Pos)))
00990                         BeepBeep (5);
00991                 }
00992                 else
00993                     atProximity = DrawRoute (CurrentRouteIndex, 0, &CurrentWGS84Pos);
00994             }
00995             if (NextLogTime && (TimGetSeconds () >= NextLogTime))
00996               {
00997                 EventType evt;
00998                 trkpt.posn.lat = CurrentWGS84Pos.lat;
00999                 trkpt.posn.lon = CurrentWGS84Pos.lon;
01000                 trkpt.time = pvt.wn_days * 86400 + (UInt32) (pvt.tow + 0.5);
01001                 trkpt.alt = pvt.alt + pvt.msl_hght;
01002                 trkpt.new_trk = NextLogTime == 1 ? 1 :  
01003                   TimGetSeconds ()>(NextLogTime+5*Prefs.loginterval)?1:0;
01004                 if (pvt.fix >invalid) { /* if datas ok, schedule next alarm and switch off */
01005                   push_active_trkpt (trkpt);
01006                   if (NextLogTime == 1)
01007                     NextLogTime = TimGetSeconds ();
01008                   NextLogTime += Prefs.loginterval;
01009                   if (TimGetSeconds () >= NextLogTime)
01010                     NextLogTime = TimGetSeconds () + Prefs.loginterval;
01011                   //  SysTaskDelay (sysTicksPerSecond / 4);  // anti-dérapage ? $$
01012                   SetTimeOfNextAlarm (NextLogTime + 2, 0);
01013                   evt.eType = keyDownEvent;
01014                   evt.data.keyDown.chr = hardPowerChr;
01015                   evt.data.keyDown.keyCode = 0;
01016                   evt.data.keyDown.modifiers = commandKeyMask;
01017                   EvtAddEventToQueue (&evt);               /* pb si le gps s'arrete */
01018                 }
01019                 else {    /* datas not ok, no switch off but precaution */
01020                   UInt16 d=TimGetSeconds ()-LastValidPvt;
01021                   if (!(d%10))SndPlaySystemSound(sndError);
01022                   i = StrPrintF (gbuf1, "Bad PVT (last good %us ago) ",d);
01023                   //              if(LastValidPvt)i += StrPrintF (gbuf1+i, "(last good %us ago)",d);
01024                   WinDrawChars (gbuf1, i, BottomStatPos);
01025                   SetTimeOfNextAlarm (TimGetSeconds ()+15, 0);
01026                 }
01027               }
01028         }
01029         handled = true;
01030         break;
01031 
01032     case ctlSelectEvent:
01033         switch (e->data.ctlSelect.controlID)
01034         {
01035         case MapBtOKID:
01036             if (MapFlags.AllowedOps && MapOpRteNew)
01037             {
01038                 MemHandle RecH = DmQueryRecord (RteDB, CurrentRouteIndex);
01039                 if (RecH && !WptsInRteDB (RecH))
01040                     DmRemoveRecord (RteDB, CurrentRouteIndex);
01041             }
01042             if (MapFlags.AllowedOps & MapOpRteEdit)
01043             {
01044                 DmRemoveRecord (RteDB, OldRouteIndex);
01045             }
01046             MainListDirty = 1;
01047             MapFormClean();
01048             FrmReturnToForm (0);
01049             handled = true;
01050             break;
01051 
01052         case MapBtCancelID:
01053             DmRemoveRecord (RteDB, CurrentRouteIndex);
01054             MapFormClean();
01055             FrmReturnToForm (0);
01056             handled = true;
01057             break;
01058 
01059         case MapPlsChk:                            /* zoom + */
01060             if (LonByPixel > 10)
01061             {
01062                 P0.lat += (LatByPixel * DrawRect.extent.y) / 4;
01063                 P0.lon += (LonByPixel * DrawRect.extent.x) / 4;
01064                 LonByPixel /= 2;
01065                 LatByPixel /= 2;
01066 /*              DrawCalibrate(  P0.lat + (LatByPixel * DrawRect.extent.y) / 4, */
01067 /*                              P0.lat + 3*(LatByPixel * DrawRect.extent.y) / 4, */
01068 /*                              P0.lon + (LonByPixel * DrawRect.extent.x) / 4, */
01069 /*                              P0.lon + 3*(LonByPixel * DrawRect.extent.x) / 4); */
01070                 RefreshDisplay (1);
01071             }
01072             SetControlValue (MapPlsChk, 0);
01073             handled = true;
01074             break;
01075 
01076         case MapMnsChk:                            /* zoom - */
01077             {
01078                 Int32 estlon,
01079                   ml = MaxLonDisplayed (),
01080                   dl = LonByPixel * DrawRect.extent.x;
01081                 //        P0.lat -= (LatByPixel * DrawRect.extent.y) / 2;
01082 
01083                 //                  if (MaxLonDisplayed () >= (P0.lon / 2 + LONMAX / 2))
01084                 if (dl < DELTALONMAX)
01085                 {                                          // bornons le zoom
01086                     if (ml >= (Int32) (LONMAX23 + P0.lon / 3L))
01087                         estlon = LONMAX;                   // pas plus de 180°
01088                     else
01089                         estlon = P0.lon + 3L * (dl / 2);
01090                     //if (P0.lon <= (MaxLonDisplayed () / 2 + LONMIN / 2))
01091                     if (P0.lon <= (Int32) (LONMIN23 + ml / 3L))
01092                         P0.lon = LONMIN;
01093                     else
01094                         P0.lon = P0.lon - dl / 2;
01095 
01096                     /*        P0.lon -= (LonByPixel * DrawRect.extent.x) / 2; */
01097                     /*        LonByPixel *= 2;     */
01098                     /*        LatByPixel *= 2; */
01099                     ml = (LatByPixel * DrawRect.extent.y) / 2L;
01100                     DrawCalibrate (P0.lat - ml, P0.lat + 3L * ml, P0.lon, estlon);
01101 
01102                     RefreshDisplay (1);
01103                 }
01104                 SetControlValue (MapMnsChk, 0);
01105                 handled = true;
01106             }
01107             break;
01108 
01109         case MapWptChk:                            /* waypoint display */
01110             MapFlags.DrawWpts = e->data.ctlSelect.on;
01111             if (MapFlags.DrawWpts)
01112                 DrawWaypoints (dmAllCategories, 0);
01113             else
01114                 RefreshDisplay (1);
01115             handled = true;
01116             break;
01117 
01118         case MapRteChk:                            /* route display */
01119             MapFlags.DrawRtes = e->data.ctlSelect.on;
01120             atProximity = 0;
01121             if (MapFlags.DrawRtes)
01122                 DrawRoute (CurrentRouteIndex, 0, NULL);
01123             else
01124                 RefreshDisplay (1);
01125             handled = true;
01126             break;
01127 
01128         case MapGrdChk:                            /* grid display */
01129             MapFlags.DrawGrd = e->data.ctlSelect.on;
01130             if (MapFlags.DrawGrd)
01131                 DrawGrid ();
01132             else
01133                 RefreshDisplay (1);
01134             handled = true;
01135             break;
01136 
01137         case MapLogChk:                            /* logging */
01138             NextLogTime = 1;
01139 
01140         case MapTrkChk:                            /* tracking */
01141             //        MapFlags.DrawActTrk = e->data.ctlSelect.on;
01142             //        if (MapFlags.DrawActTrk)
01143             if (e->data.ctlSelect.on)
01144             {
01145                 MustCallGpslibTicks = 1;
01146                 error = GarminStartPVT ();
01147                 if (error)
01148                 {
01149                     UInt16 l;
01150                     SetControlValue (MapLogChk, 0);
01151                     SetControlValue (MapTrkChk, 0);
01152                     SndPlaySystemSound (sndError);
01153                     l = StrPrintF (gbuf1, "error %d when starting PVT", error); // $$
01154                     WinDrawChars (gbuf1, l, BottomStatPos);     // $$
01155                 }
01156                 else
01157                 {
01158           if (NextLogTime) BackLightOn=HwrBacklight2(1, 0); // $$
01159                     //                ActTrkIndex = init_active_trk ();      // $$
01160                     //                DrawTrack (ActTrkIndex, 0, 0);
01161                 }
01162             }
01163             else
01164             {
01165 BackLightOn=HwrBacklight2(1, BackLightOn); // $$
01166                 RefreshDisplay (1);
01167                 GarminStopPVT ();
01168                 MustCallGpslibTicks = 0;
01169                 GPSEndOfOperation ();
01170                 NextLogTime = 0;
01171                 SetTimeOfNextAlarm (NextLogTime,0);
01172             }
01173             handled = true;
01174             break;
01175 
01176         case MapNewChk:                            /* new route point */
01177             SetControlValue (MapInsChk, 0);
01178             SetControlValue (MapDelChk, 0);
01179             break;
01180 
01181         case MapInsChk:                            /* insert route point */
01182             SetControlValue (MapNewChk, 0);
01183             SetControlValue (MapDelChk, 0);
01184             break;
01185 
01186         case MapDelChk:                            /* delete route point */
01187             SetControlValue (MapNewChk, 0);
01188             SetControlValue (MapInsChk, 0);
01189             break;
01190 
01191         }
01192         break;
01193 
01194     case EndOfOperationEvent:
01195         //        if (MapFlags.DrawActTrk)
01196         if (GetControlValue (MapTrkChk))
01197         {                                                  // $$
01198             UInt16 l;                  // $$
01199             SndPlaySystemSound (sndError);                 // $$
01200             l = StrPrintF (gbuf1, "Unexpected disconnection !");        // $$
01201             WinDrawChars (gbuf1, l, BottomStatPos);        // $$
01202         }                                                  // $$
01203         handled = true;
01204         break;
01205 
01206     case keyDownEvent:
01207  if (e->data.keyDown.modifiers & poweredOnKeyMask)HwrBacklight2(1, BackLightOn); // $$
01208      break;
01209 
01210     default:
01211         break;
01212     }
01213 
01214     if (e->eType != nilEvent) debug_out (GTALKDBG_CALLS, 
01215                                          ("<-MapFormHandleEvent(%s)=%d", 
01216                                           e->eType > LASTVALIDEVTNAME ?StrIToA(gbuf1,e->eType):EvtNames[e->eType], handled));
01217     return handled;
01218 }                                                          // MapFormHandleEvent
01219 
01220 static Int32
01221 MaxLonDisplayed ()
01222 {
01223     return (P0.lon + (LonByPixel * DrawRect.extent.x));
01224 }
01225 
01226 static Int32
01227 MaxLatDisplayed ()
01228 {
01229     return (P0.lat + (LatByPixel * DrawRect.extent.y));
01230 }
01231 
01232 
01241 static void
01242 DisplayWpt (Custom_Wpt_Type * wp, Boolean invert)
01243 {
01244     MemHandle ResH;
01245     PointType point;
01246     BitmapPtr BitP;
01247     static const float d2s = ((Int32) 1 << 30) / 90.0;
01248     int r;
01249 #define WptYOffset 3
01250 
01251     LatLonToXY (wp->posn, point);
01252 #if 1
01253     ResH = DmGetResource ('Tbmp', PointBMID /*  wp->smbl + DotBMID */ );
01254     if (ResH)
01255     {
01256         BitP = MemHandleLock (ResH);
01257         WinDrawBitmap (BitP, point.x - (BitP->width) / 2, point.y - (BitP->height) / 2);
01258         MemHandleUnlock (ResH);
01259         DmReleaseResource (ResH);
01260     }
01261 #else
01262     DrawSymbol (symb_gid2lid (wp->smbl), point.x, point.y);     // $$ -> pb de centrage et transparence
01263 #endif
01264     if (invert)
01265         WinDrawInvertedChars (wp->ident, StrLen (wp->ident),
01266                               point.x - FntCharsWidth (wp->ident, StrLen (wp->ident)) / 2,
01267                               point.y + WptYOffset);
01268     else
01269         WinDrawChars (wp->ident, StrLen (wp->ident),
01270                       point.x - FntCharsWidth (wp->ident, StrLen (wp->ident)) / 2, point.y + WptYOffset);
01271 
01272     // long delta=(d2s/60+0.5); // 1 mn
01273     // long delta= wp->dst/111120.*d2s+0.5;
01274     r = 0.5 + wp->dst / 111120. * d2s / (float) LatByPixel;     /* rayon(pixel)=d(m)/1°(m)*d2s/LatByPixel */
01275     if (r > 3)
01276         Circle (point.x, point.y, r);                      // $$
01277 
01278 }                                                          /* DisplayWpt */
01279 
01280 
01290 static void
01291 RefreshDisplay (Boolean Erase)
01292 {
01293     if (Erase)
01294     {
01295         WinEraseRectangle (&DrawRect, 0);
01296         DrawRectCleared = 1;
01297     }
01298     if (MapFlags.DrawGrd)
01299         DrawGrid ();
01300     if (MapFlags.DrawTrk || MapFlags.DrawActTrk)
01301         DrawTrack (ActTrkIndex, 0, 0);
01302     if (Prefs.PermTrackIndex)
01303         DrawTrack (Prefs.PermTrackIndex - 1, 0, 0);
01304     if (CurrentTrackIndex)
01305         DrawTrack (CurrentTrackIndex - 1, 0, 0);
01306     if (MapFlags.DrawActTrk)
01307         DrawTrack (ActTrkIndex, 0, 0);
01308     if (MapFlags.DrawRtes)
01309         DrawRoute (CurrentRouteIndex, 0, NULL);
01310     if (MapFlags.DrawWpts)
01311         DrawWaypoints (dmAllCategories, 0);
01312 }                                                          /* RefreshDisplay */
01313 
01314 
01322 static void
01323 DisplayPosition (Semicircle_Type * ptp)
01324 {
01325     double latitude,
01326       longitude;
01327     int l;
01328 
01329     SemiToDegre (ptp, &latitude, &longitude);
01330     translate (FromWGS84, &latitude, &longitude, Prefs.datum);
01331     l = StrPrintF (gbuf1, "%s ", DegreToChars (latitude, 0, Prefs.displaymode));
01332     l += StrPrintF (gbuf1 + l, "%s   ", DegreToChars (longitude, 1, Prefs.displaymode));
01333     WinDrawChars (gbuf1, l, BottomStatPos);
01334 }                                                          /* DisplayPosition */
01335 
01336 
01345 static void
01346 ReCenterDisplay (Semicircle_Type * NewCenterPos)
01347 {
01348     UInt32 delta = LonByPixel * DrawRect.extent.x / 2;
01349 
01350     if (delta > (UInt32) (LONMAX - NewCenterPos->lon))
01351     {                                                      // depassement vers l'E ?
01352         NewCenterPos->lon = LONMAX - delta;
01353     }
01354     else if (delta > (UInt32) (NewCenterPos->lon - LONMIN))
01355     {                                                      // depassement vers l'W ?
01356         NewCenterPos->lon = LONMIN + delta;
01357     }
01358     P0.lon = NewCenterPos->lon - delta;
01359     P0.lat = NewCenterPos->lat - LatByPixel * DrawRect.extent.y / 2;
01360     DrawCalibrate (P0.lat, MaxLatDisplayed (), P0.lon, MaxLonDisplayed ());     /* recalibrage */
01361 }
01362 
01363 
01364 
01365 #define SELECTDIST 6
01366 
01375 static Boolean
01376 WptClicked (WordPtr indexp, PointType point)
01377 {
01378     ObjectHandle RecH;
01379     Custom_Wpt_Type wp;
01380     PointType p;
01381     UInt16 c = 0;
01382     UInt16 d,
01383       dmin = 1000;
01384     Int32 Lonmax = MaxLonDisplayed (),
01385       Latmax = MaxLatDisplayed ();
01386 
01387     while ((RecH =
01388             (ObjectHandle) DmQueryNextInCategory (WptDB, &c,
01389                                                   dmAllCategories /*  Prefs.wptcategory */ )))
01390     {
01391         HandleToCustomWpt (RecH, &wp);
01392         if (WptVisible (wp))
01393         {
01394             LatLonToXY (wp.posn, p);
01395             if (p.x > point.x)
01396                 d = p.x - point.x;
01397             else
01398                 d = point.x - p.x;
01399             if (p.y > point.y)
01400                 d += (p.y - point.y);
01401             else
01402                 d += (point.y - p.y);
01403             if (d < dmin)
01404             {
01405                 dmin = d;
01406                 *indexp = c;
01407             }
01408         }
01409         c++;
01410     }
01411     if (dmin < SELECTDIST)
01412         return (true);
01413     else
01414         return (false);
01415 }                                                          /* WptClicked */
01416 
01417 #ifdef GRAPHICALROUTEEDIT
01418 
01419 
01429 static Boolean
01430 RteWptClicked (Word rteindex, WordPtr wptindexp, PointType point)
01431 {
01432     MemHandle RecH = NULL;
01433     void *RecP;
01434     UInt16 n,
01435       i;
01436     PointType p;
01437     LocalFormatID fmt;
01438     Custom_Wpt_Type wp;
01439     UInt16 d,
01440       dmin = 1000;
01441     Int32 Lonmax = MaxLonDisplayed (),
01442       Latmax = MaxLatDisplayed ();
01443 
01444     RecH = DmQueryRecord (RteDB, rteindex);
01445     if (RecH)
01446     {
01447         n = WptsInRteDB (RecH);
01448         RecP = MemHandleLock (RecH);
01449         for (i = 1; i <= n; i++)
01450         {
01451             fmt = PtrToCustomWpt ((Object *) (RecP + OffsetOfObjectInRec (RecH, i)), &wp);
01452             if (fmt)
01453             {                                              /* wpt ? */
01454                 if (WptVisible (wp))
01455                 {
01456                     LatLonToXY (wp.posn, p);
01457                     if (p.x > point.x)
01458                         d = p.x - point.x;
01459                     else
01460                         d = point.x - p.x;
01461                     if (p.y > point.y)
01462                         d += (p.y - point.y);
01463                     else
01464                         d += (point.y - p.y);
01465                     if (d < dmin)
01466                     {
01467                         dmin = d;
01468                         *wptindexp = i;
01469                     }
01470                 }
01471             }
01472         }
01473         MemHandleUnlock (RecH);
01474     }
01475     if (dmin < SELECTDIST)
01476         return (true);
01477     else
01478         return (false);
01479 }                                                          /* RteWptClicked */
01480 
01481 #endif
01482 
01483 
01490 static void MapFormClean(){
01491   debug (GTALKDBG_CALLS, ("<->MapFormClean()"));
01492   if (OffScreenWH) {
01493     WinDeleteWindow (OffScreenWH, 0);
01494     OffScreenWH=NULL;
01495   }
01496   GarminStopPVT ();
01497   GPSEndOfOperation ();
01498   MustCallGpslibTicks = 0;
01499   MemSet(&MapFlags,sizeof(MapFlags),0);
01500 }  /* MapFormClean */

Generated on Sun Aug 29 11:00:40 2004 for GPilotS by doxygen 1.3.4