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) */