GPS4Palm

Source Code Documentation


MapForm.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * $RCSfile: MapForm_8c-source.html,v $
00004  *
00005  * GPS4Palm Map Form
00006  *
00007  * Application event loop for Palm GPS
00008  *   - determines image file type (GIF/PNG) and calls
00009  *     appropriate decoding function
00010  *   - allows zooming and panning of image
00011  *
00012  * created: 2002-12-15
00013  *
00014  * History:
00015  * 2007-07-10:  deep = 16 for scrDisplayMode (fs)
00016  *              set screen depth for depth > 8 disabled : resets Palm TX
00017  *              set palette for depth > 8 disabled : sometimes resets Palm TX
00018  *
00019  * 2003-05-03:  imported from Palm Image Viewer (piv)
00020  *              removed Handera specific code
00021  *              removed unused code
00022  *              (temporarily) disabled calls to (currently) unimplemented forms
00023  *
00024  * 2002-12-15:  first version, taken from the program PiNGer (pngmain.c)
00025  *                which is part of the ZBoxZ application suite (Rev. 0.30)
00026  *                by Tom Zerucha.
00027  *              Moved dobitmap() to separate file, restructured event loop,
00028  *                added some (file open and ZLib) checks, added some comments.
00029  *
00030  * This program is Copyright (C) 12/2002 Matthias Prinke
00031  * <matthias.prinke@surfeu.de> and covered by GNU's GPL.
00032  * In particular, this program is free software and comes WITHOUT
00033  * ANY WARRANTY.
00034  *
00035  * Changes for Palm TX are Copyright (C) 07/2007 Frank Saurbier
00036  * <frank.saurbier@surfeu.de> and covered by GNU's GPL.
00037  * In particular, this program is free software and comes WITHOUT
00038  * ANY WARRANTY.
00039  *
00040  * $Author: mp $
00041  *
00042  * $Date: 2007-10-08 20:40:33 $
00043  *
00044  * $Revision: 1.7.2.1 $
00045  *
00046  * $Log: MapForm_8c-source.html,v $
00046  * Revision 1.7.2.1  2007-10-08 20:40:33  mp
00046  * updated for gps4palm V0.9.5 beta
00046  *
00047  * Revision 1.37.2.1  2007-10-05 22:29:03  mp
00048  * added Frank's changes (fixes reset bug on TX)
00049  *
00050  * Revision 1.37  2005/05/16 19:16:18  mp
00051  * removed test code
00052  *
00053  * Revision 1.36  2005/05/16 17:16:30  mp
00054  * removed mapprefs.fetch handling in case of FS open failure
00055  *
00056  * Revision 1.35  2005/05/16 15:31:42  mp
00057  * added zoom to calculation of crosshair coordinates
00058  *
00059  * Revision 1.34  2005/05/15 12:52:55  mp
00060  * moved file handling functions to file_io.h
00061  * changed from global file reference/handle to file descriptor (fd)
00062  * structure passed to functions
00063  * map search/download code rewritten
00064  *
00065  * Revision 1.33  2005/04/17 18:35:19  mp
00066  * improved High-Density Display support
00067  *
00068  * Revision 1.32  2005/04/08 14:50:24  mp
00069  * added High-Density Display support
00070  *
00071  * Revision 1.31  2005/04/02 10:09:43  mp
00072  * modified Position2Clipboard() and Position2Geodb() to return 'handled'
00073  *
00074  * Revision 1.30  2005/04/02 07:26:59  mp
00075  * added PosgeodbMenu event handling
00076  *
00077  * Revision 1.29  2005/03/25 13:45:11  mp
00078  * added PosclipMenu event handling
00079  *
00080  * Revision 1.28  2005/03/24 09:17:30  mp
00081  * added support for FiveWay controller for panning
00082  *
00083  * Revision 1.27  2005/02/25 18:39:39  mp
00084  * replaced gCardNo by gPrefs.filecard, fixed VFS flag handling
00085  *
00086  * Revision 1.26  2005/02/19 19:56:53  mp
00087  * modified size of filename[]
00088  *
00089  * Revision 1.25  2005/02/19 18:25:27  mp
00090  * modified status messages while reading file
00091  *
00092  * Revision 1.24  2005/02/19 14:35:54  mp
00093  * added VFS support to search_map()
00094  *
00095  * Revision 1.23  2005/02/19 14:00:14  mp
00096  * fixed File Stream open
00097  *
00098  * Revision 1.22  2005/02/19 12:20:24  mp
00099  * fixed support for multiple cards (File Streaming API), added VFS support
00100  *
00101  * Revision 1.21  2005/01/23 18:41:06  mp
00102  * added PortsMenu event handling
00103  *
00104  * Revision 1.20  2004/12/19 10:05:36  mp
00105  * added call to UpdateStatus()
00106  *
00107  * Revision 1.19  2004/12/10 19:52:56  mp
00108  * replaced DmGet1Resource by DmGetResource
00109  *
00110  * Revision 1.18  2004/12/09 17:30:31  mp
00111  * replaced strings by string resources
00112  *
00113  * Revision 1.17  2004/12/08 20:49:47  mp
00114  * added track logging
00115  *
00116  * Revision 1.16  2004/11/30 20:44:35  mp
00117  * added TrackMenu event handling
00118  *
00119  * Revision 1.15  2004/11/25 20:15:08  mp
00120  * added finction calls: NotifyApproach() and UpdateActWpt()
00121  *
00122  * Revision 1.14  2004/11/24 21:13:58  mp
00123  * moved static function declarations from header to implementation file,
00124  * added AboutForm menu event handling
00125  *
00126  * Revision 1.13  2004/11/23 17:50:15  mp
00127  * removed unused variables, added #include "Utils.h"
00128  *
00129  * Revision 1.12  2004/11/21 11:33:22  mp
00130  * removed debug specific change
00131  *
00132  * Revision 1.11  2004/04/29 18:36:50  mp
00133  * added RouteForm, modified for doxygen
00134  *
00135  * Revision 1.10  2004/03/12 20:55:20  mp
00136  * moved invocation of init_radius() to GPS.c
00137  *
00138  * Revision 1.9  2004/03/11 21:28:10  mp
00139  * replaced gLon/gLat/gGPSok by equivalent gGPSData members
00140  *
00141  * Revision 1.8  2004/02/28 17:21:43  mp
00142  * added menuEvent WaypointMenu
00143  *
00144  * Revision 1.7  2003/12/30 19:48:40  mp
00145  * replaced printDouble() by format_number()
00146  *
00147  * Revision 1.6  2003/12/30 14:48:54  mp
00148  * renamed static functions
00149  *
00150  * Revision 1.5  2003/12/28 18:22:12  mp
00151  * Major parts of position display and map selection code rewritten.
00152  *
00153  * Revision 1.4  2003/11/20 20:57:14  mp
00154  * Main changes: added debug output (map center/current position/scale),
00155  * added invocation of FetchMap (some test code still in place),
00156  * added decoding of map parameters from filename.
00157  *
00158  * Revision 1.3  2003/10/18 16:14:34  mp
00159  * re-enabled interaction with FileSelForm
00160  *
00161  * Revision 1.2  2003/10/15 19:11:28  mp
00162  * renamed lat/lon to gLat/gLon, added extern declaration of gLat/gLon
00163  *
00164  * Revision 1.1.1.1  2003/07/14 18:59:29  mp
00165  * Imported GPS4Palm to CVS revision control.
00166  *
00167  *
00168  ****************************************************************************/
00169 #include <PalmOS.h>
00170 #include <PalmCompatibility.h>
00171 #include <Libraries/PalmOSGlue/PalmOSGlue.h>
00172 #ifdef HAVE_FIVEWAY_SDK
00173 #include <palmOne_68K.h>
00174 #endif
00175 #include <Extensions/ExpansionMgr/VFSMgr.h>
00176 #include "stringil.h"
00177 #include "ResourceDefines.h"
00178 #include "MapForm.h"
00179 #include "FileselForm.h"
00180 #include "dobitmap.h"
00181 #include "pngdec.h"
00182 #include "gifread.h"
00183 #include "common.h"
00184 #include "Serial.h"
00185 #include "GPS.h"
00186 #include "HandleMessage.h"
00187 #include "Data.h"               /* UpdateActWpt(), NotifyApproach() */
00188 #include "Clip.h"
00189 #include "geo.h"
00190 #include "georef.h"
00191 #include "fp.h"
00192 #include "Utils.h"
00193 #include "getdir.h"
00194 #include "file_io.h"
00195 #include "fiveway.h"
00196 
00197 #define ON_MAP(x,y) \
00198   ( (x >= dx+CROSS_X) && (x <= dx+dw-CROSS_X) && \
00199     (y >= dy+CROSS_Y) && (y <= dy+dh-CROSS_X))
00200 
00201 
00202 #define FW_ZOOM 0               /**< FiveWay Mode: Zoom */
00203 #define FW_PAN  1               /**< FiveWay Mode: Pan */
00204 //#define VERBOSE
00205 
00206 /* Preferences data structure */
00207 extern PrefsType gPrefs;
00208 
00209 /* GPS Data */
00210 /*   defined and modified in HandleMessage() (HandleMessage.c) */
00211 extern GPSType gGPSData;
00212 
00213 /* FiveWay Controller available */
00214 extern Boolean gFiveWayAvail;
00215 
00216 /* High-Density Display Feature Set available */
00217 extern Boolean          gHdFtrSet;
00218 
00219 /* OS 3.5 Feature Set available */
00220 extern Boolean          gFtrSet35;
00221 
00222 extern unsigned short int w, h, bandh;
00223 
00224 /* returns palette if color, etc. */
00225 extern unsigned int mapmax;
00226 extern RGBColorType map[256];
00227 
00228 
00229 /*
00230  * Note:
00231  * 'color' is also used to determine if
00232  * WinPushDrawState() and WinPopDrawState() may be called,
00233  * which require the 3.5 New Feature Set!
00234  */
00235 /** passed to PNG (maybe others) to generate greyscale or colors */
00236 Boolean color;
00237 
00238 /*
00239  * gPrefs Structure
00240  *   modified within MapFormHandleEvent(), doGIF(), doPNG(), and dobitmap()
00241  *   The filename is loaded from/saved to the application preferences.
00242  */
00243 extern PrefsType gPrefs;
00244 
00245 /* Static Functions */
00246 static void MapFormInit(void)                   MAPFORM_SECTION;
00247 static void MapFormDeinit(FormPtr frmP)         MAPFORM_SECTION;
00248 static void callFetchmap(void)                  MAPFORM_SECTION;
00249 static void eraseFilename(char *filename)               MAPFORM_SECTION;
00250 static void updateCross(Int32 x, Int32 y,
00251   Int32 *xo, Int32 *yo,
00252   double map_lat, double map_lon,
00253   UInt32 map_scale, int mag, UInt32 deep)       MAPFORM_SECTION;
00254 
00255 
00256 static void MapFormInit(void)
00257 {
00258         gFormOpened = true;
00259 }
00260 
00261 
00262 static void MapFormDeinit(FormPtr frmP)
00263 {
00264 #pragma unused(frmP)  
00265 
00266 }
00267 
00268 static void eraseFilename(char *filename)
00269 {     
00270   MemHandle             strH;                   /* string handle */
00271   MemPtr                strP;                   /* string ptr */
00272   
00273   /* get string from resource */
00274   strH = DmGetResource(strRsc, DecodeStr);
00275   
00276   if (strH != NULL) {
00277     /* string handle valid, lock it */
00278     strP = MemHandleLock(strH);
00279   
00280     WinEraseChars(strP, strlen(strP), 0, 0);
00281     WinEraseChars(filename, strlen(filename), 0, 12);
00282 
00283     /* unlock string handle */
00284     MemHandleUnlock(strH);
00285 
00286     /* release string resource */
00287     DmReleaseResource(strH);
00288   }
00289 }
00290 
00291 
00292 /*****************************************************************************
00293  * FUNCTION:    callFetchmap
00294  *
00295  * DESCRIPTION: Calls the application FetchMap to download new map.
00296  *              Before switching to FetchMap, the serial port is closed,
00297  *              the port multiplexer is disabled (mobile phone is default)
00298  *              and the application preferences are saved.
00299  *              The required map parameters are passed in the parameter block
00300  *              to FetchMap. After completion of FetchMap, GPS4Palm is opened
00301  *              again, but execution starts from PilotMain (as if started from
00302  *              the Application Launcher again).   
00303  *
00304  ****************************************************************************/
00305 static void callFetchmap(void)
00306 {
00307   MapParamType *        map_param;              /* map parameters */
00308   LocalID               dbID;                   /* local DB ID of FetchMap */
00309   Err                   err;                    /* error code */
00310   
00311   map_param = MemPtrNew(sizeof(MapParamType));
00312   map_param->lat    = gGPSData.lat;
00313   map_param->lon    = gGPSData.lon;
00314   map_param->scale  = gPrefs.mapprefs.scale;    /* from Preferences */
00315   if (gHdFtrSet) {
00316     map_param->width  = 320;
00317 //    map_param->height = 480; /* (fs) ich will die grossen: sollte "option" fetchmap werden */
00318     map_param->height = 320;
00319   } else {
00320     map_param->width  = 160;
00321     map_param->height = 160; 
00322   }
00323 
00324 
00325   dbID = DmFindDatabase(0, "FetchMap");
00326   if ( !dbID ) {
00327     FrmAlert(FetchMapAlert);
00328   } else {
00329     MemPtrSetOwner(map_param, 0);
00330     
00331     /* close serial port before leaving application */
00332     if (gPortID) {
00333       /* restore the default buffer before closing the serial port */
00334       DoSetReceiveBuffer(gPortID, NULL, 0);
00335       DoClose(gPortID);
00336     }
00337     sermux_enable(false);
00338 
00339     /* Set Application Preferences (unsaved) */
00340     PrefSetAppPreferences(kCreatorId, kPrefsId, kVersion, &gPrefs,
00341        sizeof(PrefsType), false);
00342 
00343    /* Invoke FetchMap to download map */
00344    /* Note: Execution actually does not return from SysUIAppSwitch */
00345    err = SysUIAppSwitch(0,                           /* cardNo */
00346                         dbID,                        /* Database ID */
00347                         sysAppLaunchCmdNormalLaunch, /* cmd */
00348                         map_param);                  /* cmdPBP */
00349 
00350     sermux_enable(true);
00351   }
00352 }
00353 
00354 /*****************************************************************************
00355  * FUNCTION:    updateCross
00356  *
00357  * DESCRIPTION: Display/Move crosshair if map is new or position has changed.
00358  *
00359  * RETURNS:     True if updated, else false.
00360  *
00361  ****************************************************************************/
00362 
00363 static void updateCross(Int32 x, Int32 y, Int32 *xo, Int32 *yo,
00364                            double map_lat, double map_lon, UInt32 map_scale,
00365                            int mag, UInt32 deep)
00366 {
00367   Int32         x_old = *xo;            /* previous x-coordinate */
00368   Int32         y_old = *yo;            /* previous y-coordinate */
00369   Int32     cr_x, cr_y;     /* length of cross for 16bit depth - const CROSS_X -_Y too small */
00370 
00371 #ifdef DEBUG
00372   Char          s[20];                  /* string buffer */
00373   Coord         y_top = 110;            /* y-coordinate of text */
00374   Coord         y_dst = 10;             /* y-distance for text lines */
00375 #endif
00376 
00377 
00378   if (gFtrSet35) {
00379     WinPushDrawState();
00380     /* restore default colors */
00381     WinSetForeColor(UIColorGetTableEntryIndex(UIObjectForeground));
00382     WinSetBackColor(UIColorGetTableEntryIndex(UIFieldBackground));
00383     WinSetTextColor(UIColorGetTableEntryIndex(UIFieldText));
00384   }
00385   
00386   if (gHdFtrSet) {
00387     WinSetCoordinateSystem(kCoordinatesNative);
00388   }
00389 
00390   if (deep < 16)
00391   {
00392     cr_x = CROSS_X;
00393     cr_y = CROSS_Y;
00394   }
00395   else cr_y = cr_x = 8;
00396 
00397   /* redraw map at old crosshair position */
00398   dobitmap(x_old-cr_x, y_old-cr_y, mag, x_old-cr_x, y_old-cr_y, 
00399     2*cr_x+1, 2*cr_y+1, deep);
00400   
00401   /* draw new crosshair */ 
00402   WinDrawLine(x-cr_x, y, x+cr_x, y);
00403   WinDrawLine(x, y-cr_y, x, y+cr_y);
00404 
00405 #ifdef DEBUG
00406   if (gHdFtrSet) {
00407     y_top = WinScaleCoord(y_top, false /* ceiling */);
00408     y_dst = WinScaleCoord(y_dst, false /* ceiling */);
00409   }
00410     
00411   /* TBD: debug only, remove later or create proper text overlay */
00412   StrPrintF(s, "%lu", map_scale);
00413   WinDrawChars(s, StrLen(s), 0, y_top);
00414   y_top += y_dst;
00415   format_number(map_lat, 7, s);
00416   WinDrawChars(s, StrLen(s), 0, y_top);
00417   y_top += y_dst;
00418   format_number(map_lon, 7, s);
00419   WinDrawChars(s, StrLen(s), 0, y_top);
00420   y_top += y_dst;
00421   format_number(gGPSData.lat, 7, s);
00422   WinDrawChars(s, StrLen(s), 0, y_top);
00423   y_top += y_dst;
00424   format_number(gGPSData.lon, 7, s);
00425   WinDrawChars(s, StrLen(s), 0, y_top);
00426 #endif
00427 
00428   if (gFtrSet35) {
00429     WinPopDrawState();
00430   }
00431 }
00432 
00433 
00434 /****************************************************************************/
00435 /**
00436  * \brief       Clear screen and display message "No map available!"
00437  *
00438  ****************************************************************************/
00439 void noMap()
00440 {
00441   RectangleType r;                              /* rectangle */
00442   Coord         maxx, maxy;                     /* max. display extent */
00443   MemHandle     strH;                           /* string handle */
00444   MemPtr        strP;                           /* string ptr */
00445 
00446   /*----------------------------------------------------
00447    * No map available
00448    *   The hopeless case - either we tried and failed or
00449    *   we are not even allowed to try! So we just have
00450    *   to inform the user... too bad!
00451    *  
00452    *----------------------------------------------------*/
00453 
00454   if (gFtrSet35) {
00455     WinPushDrawState();
00456     
00457     /* restore default colors */
00458     WinSetForeColor(UIColorGetTableEntryIndex(UIObjectForeground));
00459     WinSetBackColor(UIColorGetTableEntryIndex(UIFieldBackground));
00460     WinSetTextColor(UIColorGetTableEntryIndex(UIFieldText));
00461   }
00462 
00463   if (gHdFtrSet) {
00464     WinSetCoordinateSystem(kCoordinatesNative);
00465   }
00466 
00467   WinGetDisplayExtent(&maxx, &maxy);
00468   r.topLeft.x = r.topLeft.y = 0;
00469   r.extent.x = maxx;
00470   r.extent.y = maxy;
00471   WinEraseRectangle(&r, 0);
00472 
00473   /* get string from resource */
00474   strH = DmGetResource(strRsc, NoMapStr);
00475 
00476   if (strH != NULL) {
00477     /* string handle valid, lock it */
00478     strP = MemHandleLock(strH);
00479 
00480     WinDrawChars(strP, StrLen(strP), (maxx-FntCharsWidth(strP, StrLen(strP))) / 2, (maxy-FntCharHeight()) / 2);
00481 
00482     /* unlock string handle */
00483     MemHandleUnlock(strH);
00484 
00485     /* release string resource */
00486     DmReleaseResource(strH);
00487   } /* if (strH != NULL) */
00488 
00489   if (gFtrSet35) {
00490     WinPopDrawState();
00491   }  
00492 }
00493 
00494 
00495 /****************************************************************************/
00496 /**
00497  * \brief       Map Form event handler
00498  *
00499  * \param       eventP          pointer to event structure
00500  *
00501  * \return      event handled flag
00502  ****************************************************************************/
00503 Boolean MapFormHandleEvent(EventPtr eventP)
00504 {
00505   static FileDescrType  fd;                     /* File Descriptor */
00506   static UInt32         deep, odeep;            /* orig./curr. display depth */
00507   EventType             event;                  /* event to queue */
00508   static int            xo, yo;                 /* image offset (img coords) */
00509   static int            mag;                    /* magnification (1..8) */
00510   static Coord          dm;                     /* magnification (1..8) */
00511   static int            refresh;                /* refresh flag (0..2) */
00512   Char                  tbuf[4];                /* character buffer */
00513   static RectangleType  r;                      /* rectangle */
00514   static Coord          dx, dy;
00515   static Coord          maxx, maxy;             /* max. display extent */
00516   Err                   err;                    /* error code */
00517   Boolean               handled = false;        /* event handled flag */
00518   Boolean               updatedDisplay;         /* updated display flag */
00519   static double         map_lat;                /* Lat. at map center */
00520   static double         map_lon;                /* Lon. at map center */
00521   static UInt32         map_scale;              /* Map scale */
00522   static Int32          x_old = CROSS_X;        /* x (saved crosshair pos.) */ 
00523   static Int32          y_old = CROSS_Y;        /* y (saved crosshair pos.) */
00524   Int32                 x;                      /* x (new crosshair pos.) */
00525   Int32                 y;                      /* y (new crosshair pos.) */
00526   static Int32          dw;                     /* draw region width */
00527   static Int32          dh;                     /* draw region height */
00528   static Boolean        decode_ok = false;      /* image file decoded flag */
00529   static Boolean        map_valid;              /* map valid flag */
00530   static UInt8          fiveway_mode = FW_ZOOM; /* 5-Way Controller mode */
00531   static Boolean        cross_visible = false;  /* crosshair visible flag */
00532   
00533   dm = mag;
00534   
00535   switch (eventP->eType) {
00536     case frmOpenEvent:
00537     
00538       /* init form */
00539       MapFormInit();
00540       
00541       /* init map file status */
00542       map_valid = false;
00543       decode_ok = false;
00544 
00545       /* save current form in application prefs */
00546       gPrefs.form = MapForm;
00547       
00548       /* Erase Form */
00549       WinEraseWindow();
00550       
00551       UpdateStatus(STAT_REDRAW);
00552       
00553       if (StrCompare(gPrefs.filename, "") == 0) {
00554         /* No file selected (yet) */
00555         
00556         if (gPrefs.mapprefs.select == SEL_AUTO) {
00557           /* Auto map selection */ 
00558           noMap();
00559           
00560         } else {
00561           /* User Map selection */
00562           FrmGotoForm(FileSelForm);
00563           
00564         }
00565         break;
00566       
00567       }
00568             
00569       {
00570          Char   tmp[] = "Decoding";
00571          WinDrawChars(tmp, strlen(tmp), 0, 0);
00572       }
00573     
00574       fd.fh = NULL;
00575       fd.fr = 0;
00576         
00577       if (!(gPrefs.filecard & VFS_FLAG)) {      
00578         Char    tmp[] = "File Stream Database";
00579         
00580         /* use file streaming API */
00581         WinDrawChars(gPrefs.filename, strlen(gPrefs.filename), 0, 12);
00582         WinDrawChars(tmp, StrLen(tmp), 0, 36);
00583 
00584         fd.fh = FileOpen( gPrefs.filecard, /* card nr */
00585                           gPrefs.filename,
00586                           'DATA',  /* type */
00587                           'BOXR',  /* creator */
00588                           fileModeReadOnly | fileModeAnyTypeCreator, /* mode */
00589                           &err);   /* err */
00590 
00591         /*
00592          * Show alert and open file browser if file cannot be opened!
00593          * This can happen in both SEL_AUTO and SEL_USER mode, e.g. if
00594          * a file is broken or has been removed (while still set as default
00595          * in application preferences).
00596          */
00597         if ((fd.fh == 0) || (err != 0)) {
00598           FrmCustomAlert(NoFileAlert, gPrefs.filename, NULL, NULL);
00599           
00600           if (gPrefs.mapprefs.select == SEL_USER) { 
00601             /* let user select another map */
00602             FrmGotoForm(FileSelForm);
00603             eraseFilename(gPrefs.filename);
00604           }
00605           
00606           /* clear filename */
00607           StrCopy(gPrefs.filename, "");
00608           
00609           break;
00610         }
00611       } else {
00612         Char            tmp[] = "File on Virtual File System";
00613         MemPtr          pathName;
00614         UInt32          vfs_vol = gPrefs.filecard & ~VFS_FLAG;
00615         
00616         /* use VFS API */
00617         WinDrawChars(gPrefs.filename, strlen(gPrefs.filename), 0, 12);
00618         WinDrawChars(tmp, StrLen(tmp), 0, 36);
00619         
00620         /* generate absolute file path */
00621         pathName = MemPtrNew(sizeof(FILEDIR) + StrLen(gPrefs.filename) + 2);
00622         StrCopy(pathName, FILEDIR);
00623         StrCat(pathName, "/");
00624         StrCat(pathName, gPrefs.filename);
00625 
00626         err = VFSFileOpen(vfs_vol, pathName, vfsModeRead, &fd.fr);
00627         MemPtrFree(pathName);
00628       }
00629 
00630       if (!fd.fh && !fd.fr) {
00631         /* Error: neither File Streaming nor VFS API could open file */ 
00632         FrmCustomAlert(NoFileAlert, gPrefs.filename, NULL, NULL);
00633         
00634         if (gPrefs.mapprefs.select == SEL_USER) {
00635 
00636           /* let user select another map */
00637           FrmGotoForm(FileSelForm);
00638           eraseFilename(gPrefs.filename);
00639         
00640         } else {
00641           noMap();
00642           
00643         }
00644 
00645         /* clear filename */
00646         StrCopy(gPrefs.filename, "");
00647 
00648         break;
00649       }
00650     
00651       /*
00652        * At this point, we have a valid file handle!
00653        */
00654       
00655       deep = 1;
00656       ScrDisplayMode(scrDisplayModeGetSupportedDepths, NULL, NULL,
00657                         &odeep, NULL);
00658       ScrDisplayMode(scrDisplayModeGetSupportsColor, NULL, NULL,
00659                         NULL, &color);
00660 
00661 
00662 // fs Support for 16 bit Display
00663       if (odeep & 0x8000)
00664         deep = 16; // pixel selection for Palm TX
00665       else 
00666       if (odeep & 0x80)
00667         deep = 8;
00668       else if (odeep & 8)
00669         deep = 4;
00670       else if (odeep & 2)
00671         deep = 2;
00672 
00673       ScrDisplayMode(scrDisplayModeGet, NULL, NULL, &odeep, NULL);
00674 
00675 /*********************/
00676 /* **TEST**** T3 *** */
00677 /* * TX works too ** */
00678 /*********************/
00679 // use the current bpp of screen, overwrite the max possible bpp above
00680 deep = odeep;
00681 // hope we can use the calculation of the possible bpp for a device
00682 // later in an option dialog, to allow selection by user
00683 
00684       /* read first 4 characters from file to determine file type */
00685       fread(fd, tbuf, 4);
00686       rewind(fd);
00687 
00688       if (!strncmp(tbuf, "\211PNG", 4)) {
00689         /* map file is a PNG */ 
00690         /* check if ZLib is installed */
00691         if (DmFindDatabase (0, /* card no. */ "ZLib") == 0) {
00692           FrmAlert(NoZLibAlert);
00693           if (gPrefs.mapprefs.select == SEL_USER) {
00694             FrmGotoForm(FileSelForm);
00695           } else {
00696             gPrefs.mapprefs.fetch = FETCH_STOP;
00697             StrCopy(gPrefs.filename, "");
00698           }
00699           eraseFilename(gPrefs.filename);
00700           return true;
00701         }
00702 
00703         if (doPNG(fd)) {
00704           FrmAlert(AbortPNGAlert);
00705           eraseFilename(gPrefs.filename);
00706           if (gPrefs.mapprefs.select == SEL_USER) {
00707             FrmGotoForm(FileSelForm);
00708           } else {
00709             gPrefs.mapprefs.fetch = FETCH_STOP;
00710             noMap();
00711           }         
00712           return true;
00713         }
00714       
00715       } else if (!strncmp(tbuf, "GIF8", 4)) {
00716         /* map file is a GIF */
00717         if (doGIF(fd)) {
00718           cleanGIF();
00719           FrmAlert(AbortGIFAlert);
00720           eraseFilename(gPrefs.filename);
00721           if (gPrefs.mapprefs.select == SEL_USER) {
00722             FrmGotoForm(FileSelForm);
00723           } else {
00724             gPrefs.mapprefs.fetch = FETCH_STOP;
00725             noMap();
00726           }
00727           return true; 
00728         }
00729       
00730       } else {
00731         /* map file is neither PNG nor GIF */
00732         FrmAlert(WrongFileAlert);
00733         eraseFilename(gPrefs.filename); 
00734         if (gPrefs.mapprefs.select == SEL_USER) {
00735           FrmGotoForm(FileSelForm);
00736         } else {
00737           gPrefs.mapprefs.fetch = FETCH_STOP;
00738           noMap();
00739         }
00740         return true;
00741       }
00742       decode_ok = true;
00743       
00744 #ifdef VERBOSE
00745 {
00746   Char          tmp[60];        /* temporary string buffer for debugging */
00747   
00748   StrPrintF(tmp, "decode ok");
00749   WinDrawChars(tmp, StrLen(tmp), 0, 0);
00750   SysTaskDelay(50);
00751 }
00752 #endif
00753       /* determine map parameters */
00754       map_valid = georef_filename(gPrefs.filename, &map_lat, &map_lon, &map_scale);
00755       
00756 #ifdef VERBOSE
00757 {
00758   Char          tmp[60];        /* temporary string buffer for debugging */
00759   
00760   StrPrintF(tmp, "map valid ok");
00761   WinDrawChars(tmp, StrLen(tmp), 0, 0);
00762   SysTaskDelay(50);
00763 }
00764 #endif      /* allow fetching of new map if required */
00765       gPrefs.mapprefs.fetch = FETCH_READY;
00766 
00767 #ifdef VERBOSE
00768 {
00769   Char          tmp[60];        /* temporary string buffer for debugging */
00770   
00771   StrPrintF(tmp, "mappref fetch ok");
00772   WinDrawChars(tmp, StrLen(tmp), 0, 0);
00773   SysTaskDelay(50);
00774 }
00775 #endif      /* save draw state (if color mode) */
00776       if (color) {
00777         WinPushDrawState();
00778       }
00779 #ifdef VERBOSE
00780 {
00781   Char          tmp[60];        /* temporary string buffer for debugging */
00782   
00783   StrPrintF(tmp, "push draw ok");
00784   WinDrawChars(tmp, StrLen(tmp), 0, 0);
00785   SysTaskDelay(50);
00786 }
00787 #endif
00788       if (gHdFtrSet) {
00789         WinSetCoordinateSystem(kCoordinatesNative);
00790 #ifdef VERBOSE
00791 {
00792   Char          tmp[60];        /* temporary string buffer for debugging */
00793   
00794   StrPrintF(tmp, "Hd coordsys ok");
00795   WinDrawChars(tmp, StrLen(tmp), 0, 0);
00796   SysTaskDelay(50);
00797 // (fs) next the Palm TX resets, special coding for 16bit display.
00798 // Err
00799 }
00800 #endif
00801       } 
00802 
00803 // TX resets at this block every time!
00804 // so don't do ScrDisplayMode for 16bpp screen - could be a Palm TX
00805 // this is only a work around
00806 if (deep < 16) /* (fs) don't reset my TX with this */
00807 {
00808 
00809       /* set new display depth */
00810       // next line resets the Palm TX, every bpp does this!!!! (fs 2007)
00811       ScrDisplayMode(scrDisplayModeSet, NULL, NULL, &deep, NULL);
00812 #ifdef VERBOSE
00813 {
00814   Char          tmp[60];
00815   
00816   StrPrintF(tmp, "newdepth ok - not for Palm TX");
00817   WinDrawChars(tmp, StrLen(tmp), 0, 0);
00818   SysTaskDelay(250);
00819 }
00820 #endif
00821 } /* (fs) now the Palm TX is still alive */
00822 
00823 
00824 
00825       WinEraseWindow();
00826 
00827 #ifdef VERBOSE
00828 {
00829   Char          tmp[60];        /* temporary string buffer for debugging */
00830   
00831   StrPrintF(tmp, "erase ok");
00832   WinDrawChars(tmp, StrLen(tmp), 0, 0);
00833   SysTaskDelay(50);
00834 }
00835 #endif
00836 
00837 // (fs) TX in 16bit does not like a pallete, many resets - but not always, can't figure out what happens
00838 // check deep first, and set palette for displaydepth < 16 bits
00839 // err
00840   if (deep < 16)
00841   {
00842       /* set custom color palette */
00843       if (color) 
00844       {
00845         WinPalette(winPaletteSet, 0, mapmax, map);
00846 #ifdef VERBOSE
00847 {
00848   Char          tmp[60];        
00849   
00850   StrPrintF(tmp, "palette ok - no 16 bit mode");
00851   WinDrawChars(tmp, StrLen(tmp), 0, 0);
00852   SysTaskDelay(150);
00853 }
00854 #endif
00855       } // if (color)
00856   } // if (deep < 16)
00857 
00858 else
00859 {
00860 
00861 /* (fs) test with a palette, can't use it in 16bit mode */
00862 /********************************************************
00863 {
00864 
00865 RGBColorType col [256];
00866 int i;
00867 // col = (RGBColorType*)malloc(sizeof(RGBColorType) * 256);
00868 // Set color palette to match BGR233 /
00869 for (i = 0; i < 256; i++)
00870 {
00871 col[i].index = 0;
00872 col[i].r = (((i >> 0) & 0x7) << 5) | (((i >> 0) & 0x7)
00873 << 2) | (((i >> 0) & 0x7) >> 1);
00874 col[i].g = (((i >> 3) & 0x7) << 5) | (((i >> 3) & 0x7)
00875 << 2) | (((i >> 3) & 0x7) >> 1);
00876 col[i].b = (((i >> 6) & 0x3) << 6) | (((i >> 6) & 0x3)
00877 << 4) | (((i >> 6) & 0x3) << 2) | ((i >> 6) & 0x3);
00878 }
00879 WinPalette(winPaletteSet, 0,256, col);
00880 WinSetForeColorRGB(NULL,col); 
00881 
00882 }
00883 ***********************************************************   switched  OFF */
00884 
00885 
00886 
00887 
00888 /***********************************************************   switched  OFF
00889 
00890 // (fs) set palette to default
00891 // set default color palette works, but has no effect
00892 
00893         WinPalette(winPaletteSetToDefault, 0, 255, NULL);
00894 
00895 #ifdef VERBOSE
00896 {
00897   Char          tmp[60];        
00898   
00899   StrPrintF(tmp, "default palette in 16 bit mode");
00900   WinDrawChars(tmp, StrLen(tmp), 0, 0);
00901   SysTaskDelay(150);
00902 }
00903 #endif
00904 
00905 ***********************************************************   switched  OFF */
00906 
00907 
00908 
00909 } // else deep < 16
00910 
00911       WinGetDisplayExtent(&maxx, &maxy);
00912 
00913       /*
00914        * Image size is set by doGIF/doPNG
00915        * w: image width
00916        * h: image height
00917        *
00918        * The image offset (xo, yo) is calculated to center the
00919        * image on the display. 
00920        */
00921       xo = w / 2 - maxx / 2;
00922       yo = h / 2 - maxy / 2;
00923       dx = 0;
00924       dy = 0;
00925       mag = 0;
00926       refresh = 1;
00927       dm = mag;
00928             
00929       if (color) {
00930         WinPopDrawState();
00931       }
00932 
00933       handled = true;
00934       /* frmOpenEvent */
00935       break;
00936    
00937     case keyDownEvent:
00938       if ( gFiveWayAvail ) {
00939         if (FiveWayCenterPressed(eventP)) {
00940           /* toggle FiveWay-Mode */
00941           fiveway_mode = (fiveway_mode == FW_ZOOM) ? FW_PAN : FW_ZOOM;
00942           handled = true;
00943 
00944         } if (FiveWayKeyPressed(eventP, Left) && fiveway_mode == FW_PAN) {
00945           /* Pan Left */
00946           xo -= maxx / 2;
00947           refresh = 1;
00948           handled = true;
00949 
00950         } else if (FiveWayKeyPressed(eventP, Right) && fiveway_mode == FW_PAN) {
00951           /* Pan Right */
00952           xo += maxx / 2;
00953           refresh = 1;
00954           handled = true;
00955 
00956         } else if (FiveWayKeyPressed(eventP, Up) && fiveway_mode == FW_PAN) {
00957           /* Pan Up */
00958           yo -= maxx / 2;
00959           refresh = 1;
00960           handled = true;
00961 
00962         } else if (FiveWayKeyPressed(eventP, Down) && fiveway_mode == FW_PAN) {
00963           /* Pan Down */
00964           yo += maxx / 2;
00965           refresh = 1;
00966           handled = true;
00967 
00968         }
00969       }
00970 
00971       if (!handled && TxtGlueCharIsVirtual(eventP->data.keyDown.modifiers,
00972                                            eventP->data.keyDown.chr)) {
00973         switch (eventP->data.keyDown.chr) {
00974           /* Zoom Display */
00975           case '1'...'8':
00976             mag = event.data.keyDown.chr - '0';
00977             refresh = 2;
00978             break;
00979           case pageUpChr:
00980             mag++;
00981             refresh = 2;
00982             break;
00983           case pageDownChr:
00984             mag--;
00985             refresh = 2;
00986             break;
00987 
00988           case vchrLaunch:
00989             event.eType = appStopEvent;
00990             EvtAddEventToQueue(&event);
00991             break;
00992 
00993         } /* switch (eventP->data.keyDown.chr) */
00994         handled = true;
00995       }
00996       break;
00997 
00998     
00999     /* Pan Display */
01000     case penDownEvent:
01001       {
01002         Coord   px = eventP->screenX;
01003         Coord   py = eventP->screenY;
01004 
01005         /*
01006          * Scale Standard screen coordinates to Native coordinates
01007          * if using High-Density Display.
01008          */
01009         if (color && gHdFtrSet) {
01010           WinPushDrawState();
01011           WinSetCoordinateSystem(kCoordinatesNative);
01012           px = WinScaleCoord(px, false /* ceiling */);
01013           py = WinScaleCoord(py, false /* ceiling */);
01014           WinPopDrawState();
01015         }
01016         
01017         if (py > maxy) {
01018           handled = true;
01019           break;
01020         }
01021 
01022         xo += px - maxx / 2;
01023         yo += py - maxy / 2;
01024         refresh = 1;
01025       }
01026       handled = true;
01027       break;
01028 
01029     case menuEvent:
01030       switch (eventP->data.menu.itemID) {
01031         case PositionMenu:
01032           FrmGotoForm(GPSMainForm);
01033           handled = true;
01034           break;
01035 
01036         case SkyviewMenu:
01037           FrmGotoForm(SkyviewForm);
01038           handled = true;
01039           break;
01040 
01041         case NavigationMenu:
01042           FrmGotoForm(NavigationForm);
01043           handled = true;
01044           break;
01045 
01046         case MiscOptsMenu:
01047           FrmGotoForm(MiscOptsForm);
01048           handled = true;
01049           break;
01050                
01051         case MapOptsMenu:
01052           FrmGotoForm(MapOptsForm);
01053           handled = true;
01054           break;
01055 
01056         case PortsMenu:
01057           if (gNewSerialManager) {
01058             FrmGotoForm(GPSPortForm);
01059           }
01060           handled = true;
01061           break;
01062             
01063         case WaypointMenu:
01064           FrmGotoForm(WaypointForm);
01065           handled = true;
01066           break;
01067                
01068         case RouteMenu:
01069           FrmGotoForm(RouteForm);
01070           handled = true;
01071           break;
01072 
01073         case TrackMenu:
01074           FrmGotoForm(TrackForm);
01075           handled = true;
01076           break;
01077                        
01078         case PosclipMenu:
01079           handled = Position2Clipboard(gGPSData, gPrefs.units);
01080           break;
01081 
01082         case PosgeodbMenu:
01083           handled = Position2Geodb(gGPSData);
01084           break;
01085 
01086         case AboutMenu:
01087           FrmGotoForm(AboutForm);
01088           handled = true;
01089           break;
01090                        
01091 #ifdef DEBUG_FORM
01092         case DebugMenu:
01093           FrmGotoForm(DebugForm);
01094           handled = true;
01095           break;
01096 #endif
01097 
01098         case FileOpenMenu:
01099           FrmGotoForm(FileSelForm);
01100           handled = true;
01101           break;
01102       
01103         case FetchMapMenu:
01104           /* allow fetching of new map as soon as position is available */
01105           gPrefs.mapprefs.fetch = FETCH_READY;
01106 
01107           /* force searching for new map (see nilEvent) */
01108           StrCopy(gPrefs.filename, "");
01109 
01110           handled = true;
01111           break;          
01112           
01113       } /* switch (eventP->data.menu.itemID) */
01114       break;
01115 
01116     case nilEvent:
01117       handled = true;
01118       
01119       /* throw away anything in the buffer-- we want fresh data */
01120       DoReceiveFlush(gPortID, 1);
01121 
01122       /* read data from GPS */
01123       updatedDisplay = ReadFromGPS();
01124 
01125       if (gGPSData.valid && gPrefs.act_rte.valid && gPrefs.auto_wpt) {
01126         /* update active waypoint */
01127         UpdateActWpt(gGPSData.lat, gGPSData.lon, false /* init */);
01128       }
01129 
01130       /* Active Waypoint approach detection and display */
01131       NotifyApproach();
01132       
01133       /* Track Logging */
01134       if (gPrefs.act_trk.log_state) {
01135         Boolean new_trk;
01136 
01137         if (TrackIntervalCheck(false /* init */, &new_trk)) {
01138           TrackWriteLog(new_trk);
01139         }
01140       }         
01141 
01142       if (map_valid && decode_ok) {
01143         /* map parameters o.k. and map decoded */ 
01144         
01145         /* calculate crosshair offset from map center */
01146         calcxy(&x, &y, gGPSData.lon, gGPSData.lat, map_lon, map_lat, map_scale);
01147 
01148         /* calculate screen coordinates from offset */
01149         x = dx + dw/2 + x/mag;
01150         y = dy + dh/2 - y/mag;
01151       }
01152 
01153       /*----------------------------------------------------
01154        * Map has been decoded successfully
01155        *----------------------------------------------------*/
01156       if (decode_ok) {
01157       
01158         /*----------------------------------------------------
01159          * Hide Crosshair
01160          *  - if GPS Status is not o.k.
01161          *  - if map parameters are unknown
01162          *  - if crosshair is off the map
01163          *  - if map is no longer in use
01164          *----------------------------------------------------*/
01165         if (!gGPSData.valid || !map_valid || !ON_MAP(x, y) || (*gPrefs.filename == 0)) {
01166 
01167           if (cross_visible) {
01168             if (color && gHdFtrSet) {
01169               WinPushDrawState();
01170               WinSetCoordinateSystem(kCoordinatesNative);
01171 #ifdef VERBOSE
01172 {
01173   Char          tmp[60];        /* temporary string buffer for debugging */
01174   
01175   StrPrintF(tmp, "pushdraw before do");
01176   WinDrawChars(tmp, StrLen(tmp), 0, 0);
01177   SysTaskDelay(250);
01178 }
01179 #endif      }
01180 
01181             /* redraw map at old crosshair position */
01182             dobitmap(x_old-CROSS_X, y_old-CROSS_Y, mag,
01183                      x_old-CROSS_X, y_old-CROSS_Y, 
01184                      2*CROSS_X+1, 2*CROSS_Y+1, deep);
01185 
01186 #ifdef VERBOSE
01187 {
01188   Char          tmp[60];        /* temporary string buffer for debugging */
01189   
01190   StrPrintF(tmp, "redraw ok");
01191   WinDrawChars(tmp, StrLen(tmp), 0, 0);
01192   SysTaskDelay(250);
01193 }
01194 #endif      if (color && gHdFtrSet) {
01195               WinPopDrawState();
01196             }
01197 
01198             cross_visible = false;
01199           } /* if (cross_visible) */
01200           
01201         } else {
01202           /*----------------------------------------------------
01203            * Update Crosshair
01204            *  - if GPS Fix Status is o.k.
01205            *  - if map parameters are valid
01206            *  - if crosshair is on the map
01207            *----------------------------------------------------*/
01208           updateCross(x, y, &x_old, &y_old, map_lat, map_lon, map_scale, 
01209                       mag, deep);
01210 
01211           /* save current crosshair position */ 
01212           x_old = x;
01213           y_old = y;
01214           cross_visible = true;
01215 
01216         } /* if (<hide_crosshair_conditions>) */
01217       } /* if (decode_ok) */
01218       
01219       /*----------------------------------------------------
01220        *
01221        * If current map is selcted by user,
01222        * keep it -- no matter if it shows
01223        * the current position or not.
01224        *
01225        *----------------------------------------------------*/
01226       if (gPrefs.mapprefs.select == SEL_USER)
01227         break; 
01228       
01229       /*----------------------------------------------------
01230        *
01231        * If the current position is unknown,
01232        * do neither search nor download map.
01233        *
01234        *----------------------------------------------------*/  
01235       if (!gGPSData.valid)
01236         break;
01237 
01238       switch (gPrefs.mapprefs.fetch) {
01239         case FETCH_READY:
01240           /*------------------------------------------------
01241            * Search map if position not on current map or
01242            * current map scale does not match preferences
01243            * any more or no map selected at all.
01244            *------------------------------------------------*/
01245           if ((map_valid && 
01246                (!ON_MAP(x, y) || gPrefs.mapprefs.scale != map_scale)) ||
01247               (StrCompare(gPrefs.filename, "") == 0)) {
01248                     
01249             if (search_map(gPrefs.filename, &gPrefs.filecard,
01250                 gGPSData.lon, gGPSData.lat, maxx, maxy)) {
01251               /* suitable map found */
01252               gPrefs.mapprefs.fetch = FETCH_READY;
01253               FrmGotoForm(MapForm);
01254               
01255             } else {
01256               /* no suitable map found */
01257               switch (gPrefs.mapprefs.download) {
01258                 case DLD_O:
01259                   /* download off - keep current map */
01260                   break;
01261                 
01262                 case DLD_A:
01263                   /* download auto - fetch new map */
01264                   gPrefs.mapprefs.fetch = FETCH_START;
01265                   callFetchmap();
01266                   break;
01267                 
01268                 case DLD_Q:
01269                   /* download query - user has to allow/deny download */
01270                   if ( FrmAlert(QueryDldAlert) == 0 ) {
01271                     /* download allowed - fetch map */
01272                     gPrefs.mapprefs.fetch = FETCH_START;
01273                     callFetchmap();
01274 
01275                   } else {
01276                     /* download denied - don't ask again, keep current map */
01277                     gPrefs.mapprefs.fetch = FETCH_STOP;
01278 
01279                   }
01280                   break;
01281               } /* switch (gPrefs.mapprefs.download) */
01282             } /* if ( search_map() ) */
01283           } /* if (other map needed) */
01284           
01285           /* FETCH_READY */
01286           break;
01287           
01288         case FETCH_START:
01289           /*------------------------------------------------
01290            * A new map should just have been downloaded
01291            * and has to be searched for.
01292            *------------------------------------------------*/
01293            if (search_map(gPrefs.filename, &gPrefs.filecard,
01294                 gGPSData.lon, gGPSData.lat, maxx, maxy)) {
01295              /* suitable map found - change to new map */
01296              gPrefs.mapprefs.fetch = FETCH_READY;
01297              FrmGotoForm(MapForm);
01298              
01299            } else {
01300              /*
01301               * No suitable map has been found.
01302               * This means download failed or
01303               * a different map is needed now
01304               * (position or scale changed).
01305               * In either case, fetching is stopped now
01306               * and the current map is kept.
01307               */
01308              gPrefs.mapprefs.fetch = FETCH_STOP;
01309            
01310           }
01311           /* FETCH_START */
01312           break;
01313           
01314         case FETCH_STOP:
01315           /*------------------------------------------------
01316            * Search, but do not fetch map.
01317            * To leave this state, the user has to select
01318            * the menu entries Map->Fetch or Map->Select.
01319            *------------------------------------------------*/
01320           if (search_map(gPrefs.filename, &gPrefs.filecard,
01321                 gGPSData.lon, gGPSData.lat, maxx, maxy)) {
01322             /* suitable map found - change to new map */
01323             gPrefs.mapprefs.fetch = FETCH_READY;
01324             FrmGotoForm(MapForm);
01325             
01326           }
01327           /* FETCH_STOP */
01328           break;
01329       
01330       } /* switch (gPrefs.mapprefs.fetch) */
01331         
01332       /* nilEvent */
01333       break;
01334    
01335     case frmCloseEvent:
01336       /* close file */
01337       fclose(fd);
01338       
01339       /* restore color palette (if color mode) */
01340       if (color) {
01341         WinPalette(winPaletteSetToDefault, 0, 256, NULL);
01342       }
01343       /* restore original display depth */
01344       ScrDisplayMode(scrDisplayModeSet, NULL, NULL, &odeep, NULL);
01345 
01346       /* restore draw state */
01347       if (color) {
01348         WinPopDrawState();
01349       }
01350       if (decode_ok) {
01351         cleanPNG();                   /* works for both PNG & GIF */
01352         decode_ok = false;
01353       }
01354       MapFormDeinit(FrmGetActiveForm());
01355       FrmEraseForm(FrmGetActiveForm());
01356       handled = false;
01357       break;
01358   
01359   } /* switch (eventP->eType) */
01360 
01361 
01362   /*----------------------------------------------------------------*/
01363   /* Refresh Display                                                */
01364   /*----------------------------------------------------------------*/
01365   if (refresh) {
01366     /* save draw state (if color mode) */
01367     if (color) {
01368       WinPushDrawState();
01369     }
01370     if (gHdFtrSet) {
01371       WinSetCoordinateSystem(kCoordinatesNative);
01372     }
01373 
01374     /* limit magnification to valid range */
01375     if (mag < 1)
01376       mag = 1;
01377     if (mag > 8)
01378       mag = 8;
01379 
01380     /* limit offset of visible region within image to valid range */
01381     if (xo < 0)
01382       xo = 0;
01383     if (yo < 0)
01384       yo = 0;
01385     if (xo + maxx * mag > w)
01386       xo = w - (maxx + 1) * mag + 1;
01387     if (yo + maxy * mag > h)
01388       yo = h - (maxy + 1) * mag + 1;
01389     if (xo < 0)
01390       xo = 0;
01391     if (yo < 0)
01392       yo = 0;
01393 
01394     /* restore default background color */
01395     if (gFtrSet35) {
01396       WinPushDrawState();
01397       WinSetBackColor(UIColorGetTableEntryIndex(UIFormFill));
01398     }
01399 
01400     /* clear image display area */
01401     r.topLeft.x = r.topLeft.y = 0;
01402     r.extent.x = maxx;
01403     r.extent.y = maxy;
01404     WinEraseRectangle(&r, 0);
01405 
01406     if (gFtrSet35) {
01407       WinPopDrawState();
01408     }
01409 
01410     refresh = 0;
01411 
01412 #ifdef VERBOSE
01413     WinDrawChars("Redrawing...", 12, 0, 0);
01414     {
01415       char tmp[20];
01416 
01417       StrPrintF(tmp, "%d;%d", xo, yo);
01418       WinDrawChars(tmp, StrLen(tmp), 0, 15);
01419     }
01420     SysTaskDelay(100);
01421 #endif
01422 
01423     /* center small images on display */
01424     if (maxx > w/mag) {
01425       dx = (maxx - w/mag) / 2;
01426     } else {
01427       dx = 0;
01428     }
01429 
01430     if (maxy > h/mag) {
01431       dy = (maxy - h/mag) / 2;
01432     } else {
01433       dy = 0;
01434     }
01435 
01436     dw = (maxx > w / mag) ? w / mag : maxx;
01437     dh = (maxy > h / mag) ? h / mag : maxy;
01438 
01439     /* do full redraw */
01440     dobitmap(xo,        /* x-offset of draw region within image */
01441              yo,        /* y-offset of draw region within image */
01442              mag,       /* sub-sampling factor */
01443              dx,        /* x-offset of drawing area on screen */
01444              dy,        /* y-offset of drawing area on screen */
01445              dw,        /* x-extent of drawing area */
01446              dh,        /* y-extent of drawing area */
01447              deep       /* color depth */
01448     );
01449 
01450     if (color) {
01451       WinPopDrawState();
01452     }
01453   }
01454 
01455   return handled;
01456 } /* MapFormHandleEvent(EventPtr eventP) */

Created: Mon, 08 Oct 2007 22:33:16 +0200
Copyright ©2004 M. Prinke