00001
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef lint
00034
00035 #endif
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;
00054
00055 static WinHandle OffScreenWH;
00056 static Boolean DrawRectCleared;
00057 static Semicircle_Type P0;
00058 static Int32 LonByPixel,
00059
00060 LatByPixel;
00061 static UInt16 ActTrkIndex;
00062 static UInt16 CurrentTrackIndex;
00063
00064 #define BottomStatPos 2, 146
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
00137
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
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);
00174 debug (GTALKDBG_INFOS, ("HwrBacklight2 : P2"));
00175 if (set){
00176 if ((oldState && !newState) || (!oldState && newState)){
00177
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 }
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
00240
00241
00242
00243 WinInvertRectangle (&bounds2, r - 2);
00244 WinCopyRectangle (OffScreenWH, CurWH, &bounds, x - r, y - r, scrOR );
00245 WinSetDrawWindow (CurWH);
00246 }
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 {
00282 WinCopyRectangle (OffScreenWH, CurWH, &r, px, py, scrXOR );
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;
00303 y -= bh / 2;
00304 WinCopyRectangle (OffScreenWH, CurWH, &r, x, y, scrXOR );
00305 px = x;
00306 py = y;
00307 WinResetClip ();
00308 }
00309
00310
00317 static void
00318 DrawGrid ()
00319 {
00320 #define CENTMINUTES 19884108
00321 #define CENTKM 10736559
00322 #define CENTMI 17278774 // a verifier $$
00323
00324 Int32 deltalon = LonByPixel * DrawRect.extent.x,
00325
00326
00327
00328 latmax = MaxLatDisplayed (),
00329 pas,
00330
00331 lat0,
00332 lon0,
00333
00334 inc,
00335 unit,
00336 coef;
00337 UInt16 n;
00338 Semicircle_Type ll;
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;
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;
00361 if (n)
00362 StrPrintF (gbuf1, "%d %s", n, DistanceUnitNames[Prefs.distunit]);
00363 else
00364 {
00365 StrPrintF (gbuf1, "0,");
00366 for (n = coef / 100000; n; n /= 10)
00367 StrNCatSafe (gbuf1, "0", sizeof (gbuf1), 1);
00368
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
00376 WinResetClip ();
00377 }
00378
00379
00380
00389 static void
00390 DrawWaypoints (UInt16 category, Boolean rescale)
00391 {
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
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
00411 oldfont = FntSetFont (MidgetXS0FontID);
00412
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 }
00436 WinResetClip ();
00437
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 }
00447
00448
00459 Boolean
00460 DrawRoute (UInt16 index, Boolean rescale, Semicircle_Type * position)
00461 {
00462 Custom_Wpt_Type wpt;
00463 MemHandle
00464 RecH = NULL;
00465 void *RecP;
00466 UInt16 n,
00467 i;
00468 LocalFormatID fmt;
00469
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 {
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 }
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;
00546 if (latmax > 954437180L)
00547 latmax = 954437180L;
00548 P0.lat = latmin;
00549 P0.lon = lonmin;
00550 coef = (latmax + latmin) / 2 * PI / OnePower31;
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 {
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;
00567 }
00568 else
00569 P0.lat = (latmax / 2 + latmin / 2) - (DrawRect.extent.y * LatBP) / 2;
00570 LonByPixel = LonBP;
00571 LatByPixel = LatBP;
00572 }
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
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
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 }
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 }
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);
00704 FrmDrawForm (frm);
00705 WinDrawRectangleFrame (simpleFrame, &DrawRect);
00706 if (!OffScreenWH)
00707 OffScreenWH = WinCreateOffscreenWindow (160, 160, screenFormat, &error);
00708 CurrentTrackIndex = 0;
00709 scaled = 0;
00710 SelectedRteWptIndex = -1;
00711
00712 if (Prefs.PermTrackIndex)
00713 {
00714 DrawTrack (Prefs.PermTrackIndex - 1, 1, 0);
00715 scaled = 1;
00716 }
00717
00718 if (MapFlags.AllowedOps & MapOpWptDisp)
00719 {
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 {
00732 MapFlags.DrawRtes = 1;
00733 DrawRoute (CurrentRouteIndex, !scaled, NULL);
00734 scaled = 1;
00735 ShowObject(MapRteChk);
00736 }
00737 else
00738 {
00739
00740 MapFlags.DrawRtes = 0;
00741 }
00742
00743 if (MapFlags.AllowedOps & MapOpTrack)
00744 {
00745 MapFlags.DrawActTrk = 1;
00746 ActTrkIndex = init_active_trk ();
00747
00748 ShowObject(MapTrkChk);
00749 ShowObject(MapLogChk);
00750 }
00751 else
00752 {
00753
00754
00755 }
00756
00757 if (MapFlags.AllowedOps & MapOpMapTrack)
00758 {
00759 LstPtr = (ListPtr) GetObjPtr (MapListID);
00760 LstSetListChoices (LstPtr, NULL, DmNumRecordsInCategory (TrkDB, Prefs.trkcategory));
00761 LstSetDrawFunction (LstPtr, &MainListDraw);
00762 LstSetSelection (LstPtr, 0);
00763
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 {
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;
00787 if (MapFlags.AllowedOps & MapOpRteNew)
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
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);
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
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
00859
00860 frm = FrmGetActiveForm ();
00861 MemSet (&ClickPos, sizeof (ClickPos), 0);
00862 XYToLatLon (ClickPt, ClickPos.posn);
00863 #ifdef GRAPHICALROUTEEDIT
00864
00865 if ((GetControlValue (MapNewChk) || GetControlValue (MapInsChk)) && !RteWptClicked (CurrentRouteIndex, &index, ClickPt))
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
00875 CustomToAnyWpt (&ClickPos, G103Type, newp, 0);
00876
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))
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 {
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)){
00922 if ((lastindex==index)&&(TimGetTicks()<(lastclick+SysTicksPerSecond()))) {
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 {
00940
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:
00953 {
00954
00955
00956 D800_Pvt_Data_Type pvt;
00957 Custom_Trk_Point_Type trkpt;
00958
00959
00960 static UInt32 LastValidPvt;
00961 PointType wpt;
00962
00963
00964
00965
00966 if(!LastValidPvt)LastValidPvt=TimGetSeconds ();
00967
00968 GarminGetPVT (&pvt);
00969
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
00981
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) {
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
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);
01018 }
01019 else {
01020 UInt16 d=TimGetSeconds ()-LastValidPvt;
01021 if (!(d%10))SndPlaySystemSound(sndError);
01022 i = StrPrintF (gbuf1, "Bad PVT (last good %us ago) ",d);
01023
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:
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
01067
01068
01069
01070 RefreshDisplay (1);
01071 }
01072 SetControlValue (MapPlsChk, 0);
01073 handled = true;
01074 break;
01075
01076 case MapMnsChk:
01077 {
01078 Int32 estlon,
01079 ml = MaxLonDisplayed (),
01080 dl = LonByPixel * DrawRect.extent.x;
01081
01082
01083
01084 if (dl < DELTALONMAX)
01085 {
01086 if (ml >= (Int32) (LONMAX23 + P0.lon / 3L))
01087 estlon = LONMAX;
01088 else
01089 estlon = P0.lon + 3L * (dl / 2);
01090
01091 if (P0.lon <= (Int32) (LONMIN23 + ml / 3L))
01092 P0.lon = LONMIN;
01093 else
01094 P0.lon = P0.lon - dl / 2;
01095
01096
01097
01098
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:
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:
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:
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:
01138 NextLogTime = 1;
01139
01140 case MapTrkChk:
01141
01142
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
01160
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:
01177 SetControlValue (MapInsChk, 0);
01178 SetControlValue (MapDelChk, 0);
01179 break;
01180
01181 case MapInsChk:
01182 SetControlValue (MapNewChk, 0);
01183 SetControlValue (MapDelChk, 0);
01184 break;
01185
01186 case MapDelChk:
01187 SetControlValue (MapNewChk, 0);
01188 SetControlValue (MapInsChk, 0);
01189 break;
01190
01191 }
01192 break;
01193
01194 case EndOfOperationEvent:
01195
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 }
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 );
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);
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
01273
01274 r = 0.5 + wp->dst / 111120. * d2s / (float) LatByPixel;
01275 if (r > 3)
01276 Circle (point.x, point.y, r);
01277
01278 }
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 }
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 }
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 {
01352 NewCenterPos->lon = LONMAX - delta;
01353 }
01354 else if (delta > (UInt32) (NewCenterPos->lon - LONMIN))
01355 {
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 ());
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 )))
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 }
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 {
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 }
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 }