]> asedeno.scripts.mit.edu Git - pssh.git/blob - forms/resize.c
Greg Parker's 2005-06-23 release.
[pssh.git] / forms / resize.c
1 /* $Id: resize.c,v 1.1 2005/05/15 09:06:04 admin Exp $ */
2 /*******************************************************************************
3     Copyright (c) 2004, Alexander R. Pruss
4     All rights reserved.
5
6     Redistribution and use in source and binary forms, with or without modification,
7     are permitted provided that the following conditions are met:
8
9         Redistributions of source code must retain the above copyright notice, this
10         list of conditions and the following disclaimer.
11
12         Redistributions in binary form must reproduce the above copyright notice, this
13         list of conditions and the following disclaimer in the documentation and/or
14         other materials provided with the distribution.
15
16         Neither the name of the PalmResize Project nor the names of its
17         contributors may be used to endorse or promote products derived from this
18         software without specific prior written permission.
19
20     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27     ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *******************************************************************************/
31
32 #include <PalmOS.h>
33 #include <LstGlue.h>
34 #include <PalmOSGlue.h>
35 //#include "util.h"
36 #include "DIA.h"
37 #ifdef SUPPORT_DIA_HANDERA
38 #include <Vga.h>
39 #endif
40
41 #include "includes.h"
42 #include "rsrc/rsrc.h"
43
44 static void DebugInfo(const char *format, ...)
45 {
46     /*    va_list args;
47     char buf[500];
48     int len;
49
50     len = snprintf(buf, sizeof(buf), "%lu ", TimGetTicks());
51
52     va_start(args, format);
53     vsnprintf(buf+len, sizeof(buf)-len, format, args);
54     va_end(args);
55
56     ClipboardAppendItem(clipboardText, buf, StrLen(buf));
57     */
58 }
59
60         
61 typedef struct {
62     UInt16    formID;
63     FormType* formPtr;
64     UInt16    index;
65     UInt16    flags;
66     DIAFormEntryType* entry;
67 } ResizeTemporaryData;
68
69
70 static DIAFormEntryType* formList = NULL;
71 static DIAStateType*     bins;
72 static UInt16            numBins;
73 static UInt16            formCount = 0;
74 static ResizeTemporaryData active;
75 static Boolean           haveWinDisplayChangedEvent = false;
76
77
78
79 RESIZE_SECTION static UInt16 StandardExtent( void )
80 {
81 #ifdef SUPPORT_DIA_HANDERA
82     if ( GetDIAHardware() == DIA_HARDWARE_HANDERA )
83         return 240;
84     else
85 #endif
86         return 160;
87 }
88
89
90
91 /* Update form, but only once */
92 RESIZE_SECTION static void UniqueUpdateForm( UInt16 formID, UInt16 code )
93 {
94     EventType e;
95     MemSet( &e, sizeof(EventType), 0 );
96     e.eType                     = frmUpdateEvent;
97     e.data.frmUpdate.formID     = formID;
98     e.data.frmUpdate.updateCode = code;
99     EvtAddUniqueEventToQueue( &e, 0, true );
100     DebugInfo("Queuing frmUpdateForm");
101 }
102
103
104
105 /* Same as FrmGetObjectIndex() but works with GSI_OBJECT_ID, too */
106 RESIZE_SECTION static UInt16 MyFrmGetObjectIndex( FormPtr formPtr, UInt16 id )
107 {
108     UInt16 i;
109     if ( id != GSI_OBJECT_ID )
110         return FrmGetObjectIndex( formPtr, id );
111     for ( i = FrmGetNumberOfObjects( formPtr ) - 1 ; 0 < i ; i -- ) {
112         if ( FrmGetObjectType( formPtr, i ) == frmGraffitiStateObj ) {
113             return i;
114         }
115     }
116     return 0;
117 }
118
119
120
121 RESIZE_SECTION static void WinGlueGetBounds( WinHandle winH, RectangleType* rect )
122 {
123     Err     err;
124     UInt32  version;
125     err = FtrGet( sysFtrCreator, sysFtrNumROMVersion, &version );
126     if ( err == errNone && 0x04003000 <= version ) {
127         WinGetBounds( winH, rect );
128     }
129     else {
130         WinHandle oldH;
131         oldH = WinSetDrawWindow( winH );
132         WinGetDrawWindowBounds( rect );
133         WinSetDrawWindow( oldH );
134     }
135 }
136
137
138
139 RESIZE_SECTION static void SafeFrmGetObjectBounds
140     (
141     const FormType* formPtr,
142     UInt16 objectIndex,
143     RectangleType* rect
144     )
145 {
146     WinHandle oldWin;
147
148     oldWin = WinSetDrawWindow( FrmGetWindowHandle( formPtr ) );
149
150     FrmGetObjectBounds( formPtr, objectIndex, rect );
151
152     if ( NULL != oldWin )
153         WinSetDrawWindow( oldWin );
154 }
155
156
157
158 RESIZE_SECTION static void SafeFrmSetObjectBounds
159     (
160     FormType* formPtr,
161     UInt16 objectIndex,
162     RectangleType* rect
163     )
164 {
165     WinHandle oldWin;
166
167     oldWin = WinSetDrawWindow( FrmGetWindowHandle( formPtr ) );
168
169     FrmSetObjectBounds( formPtr, objectIndex, rect );
170
171     if ( NULL != oldWin )
172         WinSetDrawWindow( oldWin );
173 }
174
175
176
177 RESIZE_SECTION static void AddForm( UInt16 indexInList, MemHandle handle, UInt16 formID )
178 {
179     UInt16         numObjects;
180     DIAConfigType* config;
181
182     formList[ indexInList ].configHandle = handle;
183     if ( handle == NULL ) {
184         return;
185     }
186
187     config          = ( DIAConfigType* )MemHandleLock( handle );
188     numObjects      = ( ( config->sizeInWords + 1 ) * sizeof( UInt16 ) -
189                         sizeof( DIAConfigType ) ) /
190                           sizeof( DIAConfigEntryType );
191
192     formList[ indexInList ].formID         = formID;
193     formList[ indexInList ].config         = config;
194     formList[ indexInList ].numObjects     = numObjects;
195     formList[ indexInList ].open           = false;
196     formList[ indexInList ].callback       = NULL;
197
198     if ( config->flags & DIA_FORM_USE_BIN &&
199          numBins < 1 + config->bin )
200         numBins = 1 + config->bin;
201 }
202
203
204
205 /* This sets up the original bounds array as needed */
206 RESIZE_SECTION static void InitialSetupForm( UInt16 indexInList ) 
207 {
208     RectangleType* originalBounds;
209     FormType*      formPtr;
210     UInt16         numObjects;
211     UInt16         i;
212
213     numObjects = formList[ indexInList ].numObjects;
214     if ( numObjects == 0 )
215         return;
216     if ( formList[ indexInList ].originalBounds != NULL )
217         return;
218     formPtr = FrmGetFormPtr( formList[ indexInList ].formID );
219     if ( formPtr == NULL )
220         return;
221
222     originalBounds = ( RectangleType* )SafeMemPtrNew( numObjects * 
223                                            sizeof( RectangleType ) );
224     formList[ indexInList ].originalBounds = originalBounds;
225
226     /* First object is the form itself */
227     WinGlueGetBounds( FrmGetWindowHandle( formPtr ), &( originalBounds[ 0 ] ) );
228
229     /* Now on to the other objects */
230     for ( i = 1 ; i < numObjects ; i++ ) {
231          UInt16 objectIndex;
232          objectIndex = MyFrmGetObjectIndex( formPtr,
233                      formList[ indexInList ].config->objectList[ i ].objectID );
234          SafeFrmGetObjectBounds( formPtr, objectIndex, &( originalBounds[ i ] ) );
235     }
236 }
237
238
239
240 /* Adjust one coordinate */
241 RESIZE_SECTION static Coord Adjust
242     (
243     Coord value,            /* old value to adjust */
244     Coord oldObjectExtent,  /* old extent if relevant */
245     Coord newObjectExtent,  /* already adjusted extent if relevant */
246     Coord oldExtent,        /* old form/screen extent */
247     Coord newExtent,        /* new form/screen extent */
248     UInt16 shiftedFlag      /* adjustment flag, shifted down as needed */
249     )
250 {
251     Coord delta;
252     
253     delta = newExtent - oldExtent;
254
255     switch ( shiftedFlag ) {
256         case DIA_X_FIX >> DIA_SHIFT_X:
257             return value;
258         case DIA_X_RATIO >> DIA_SHIFT_X:
259             return value * ( Int32 )newExtent / oldExtent;
260         case DIA_X_RIGHT >> DIA_SHIFT_X:
261             return newExtent - ( oldExtent - value - oldObjectExtent ) - newObjectExtent;
262         case DIA_X_PLUS_DW >> DIA_SHIFT_X:
263             return value + delta;
264         case DIA_X_PLUS_1_2_DW >> DIA_SHIFT_X:
265             return value + delta / 2;
266         case DIA_X_PLUS_1_3_DW >> DIA_SHIFT_X:
267             return value + delta / 3;
268         case DIA_X_PLUS_2_3_DW >> DIA_SHIFT_X:
269             return value + 2 * delta / 3;
270         case DIA_X_PLUS_1_4_DW >> DIA_SHIFT_X:
271             return value + delta / 4;
272         case DIA_X_PLUS_3_4_DW >> DIA_SHIFT_X:
273             return value + 3 * delta / 4;
274         default: /* should not happen */
275             return value;
276     }
277 }
278
279
280
281 /* Get new bounds for an object, adjusted for DIA */
282 RESIZE_SECTION static void GetNewBounds( UInt16 displayExtentX, UInt16 displayExtentY,
283     UInt16 stdFormExtentX, UInt16 stdFormExtentY,
284     RectangleType* oldBounds, RectangleType* newBounds,
285     DIAConfigEntryType* configEntry )
286 {
287     UInt16 flags;
288     flags = configEntry->flags;
289
290     if ( flags & DIA_MASK_W ) {
291         newBounds->extent.x  = Adjust( oldBounds->extent.x, 0, 0, 
292                                    stdFormExtentX,
293                                    displayExtentX,
294                                    ( flags & DIA_MASK_W ) >> DIA_SHIFT_W );
295     }
296     if ( flags & DIA_MASK_H ) {
297         newBounds->extent.y  = Adjust( oldBounds->extent.y, 0, 0,
298                                    stdFormExtentY,
299                                    displayExtentY,
300                                    ( flags & DIA_MASK_H ) >> DIA_SHIFT_H );
301     }
302     newBounds->topLeft.x = Adjust( oldBounds->topLeft.x, oldBounds->extent.x,
303                                newBounds->extent.x,
304                                stdFormExtentX, displayExtentX,
305                                ( flags & DIA_MASK_X ) >> DIA_SHIFT_X );
306     newBounds->topLeft.y = Adjust( oldBounds->topLeft.y, oldBounds->extent.y,
307                                newBounds->extent.y,
308                                stdFormExtentY, displayExtentY,
309                                ( flags & DIA_MASK_Y ) >> DIA_SHIFT_Y );
310 }
311
312
313
314 /* This compares two rectangles.  If sonyDoubleSecond is set and the first
315    bounds are exactly double the size of the first and DIA hardware is
316    DIA_HARDWARE_SONY1, then they also match. */
317 RESIZE_SECTION static Boolean SameBounds( RectangleType* a, RectangleType* b,
318     Boolean sonyDoubleSecond )
319 {
320     Boolean compare;
321     compare = ( a->extent.y == b->extent.y && a->extent.x == b->extent.x &&
322                 a->topLeft.y == b->topLeft.y && a->topLeft.x == b->topLeft.x );
323 #ifdef SUPPORT_DIA_SONY
324     if ( ! compare && GetDIAHardware() == DIA_HARDWARE_SONY1 ) {
325         return a->extent.y == 2 * b->extent.y &&
326                a->extent.x == 2 * b->extent.x &&
327                a->topLeft.y == 2 * b->topLeft.y &&
328                a->topLeft.x == 2 * b->topLeft.x;
329     }
330 #endif
331     return compare;
332 }
333
334
335
336 /* Returns true if there is moving done */
337 RESIZE_SECTION static Boolean MoveObjectsInForm( UInt16 indexInList ) 
338 {
339     Coord     extentX;
340     Coord     extentY;
341     UInt16    i;
342     UInt16    focus;
343     FormType* formPtr;
344     DIAFormEntryType* entry;
345     Int16 dw, dh;
346
347     RectangleType  newBounds;
348     RectangleType  curBounds;
349     
350     entry = &( formList[ indexInList ] );
351
352     formPtr = FrmGetFormPtr( entry->formID );
353     if ( formPtr == NULL )
354         return false;
355     InitialSetupForm( indexInList );
356     WinGetDisplayExtent( &extentX, &extentY );
357
358     /* First object is the form itself */
359     WinGlueGetBounds( FrmGetWindowHandle( formPtr ), &curBounds );
360     newBounds = curBounds;
361     GetNewBounds( extentX, extentY, StandardExtent(), StandardExtent(),
362          &( formList[ indexInList ].originalBounds[ 0 ] ),
363          &newBounds, &( entry->config->objectList[ 0 ] ) );
364
365 /* { Char ss[55]; StrPrintF(ss, " %d x %d ", extentX, extentY ); DebugInfo(ss); DebugInfo("abc"); } DebugInfo("def"); */
366
367     if ( ( SameBounds( &curBounds, &newBounds, true ) ||
368            ( formList[ indexInList ].open &&
369            SameBounds( &newBounds, &( formList[ indexInList ].lastBounds ), false ) ) ) &&
370            extentX == entry->lastExtentX && extentY == entry->lastExtentY ) {
371         DebugInfo( "skipping resize" );
372         return false;
373     }
374
375     dw = newBounds.extent.x - curBounds.extent.x;
376     dh = newBounds.extent.y - curBounds.extent.y;
377
378     if ( GetDIAHardware() == DIA_HARDWARE_SONY1 || 
379          GetDIAHardware() == DIA_HARDWARE_HANDERA ) {
380          /* Sony OS4 and Handera work differently from everybody else */
381         FrmEraseForm( formPtr );
382     }
383
384     entry->lastBounds  = newBounds;
385     entry->lastExtentX = extentX;
386     entry->lastExtentY = extentY;
387     WinSetBounds( FrmGetWindowHandle(formPtr), &newBounds );
388
389     /* The rest is resized relative to the form itself */
390     extentX = newBounds.extent.x;
391     extentY = newBounds.extent.y;
392     focus   = FrmGetFocus( formPtr );
393
394     for ( i = 1 ; i < entry->numObjects ; i++ ) {
395          UInt16  objectIndex;
396
397          objectIndex = MyFrmGetObjectIndex( formPtr,
398                      entry->config->objectList[ i ].objectID );
399          SafeFrmGetObjectBounds( formPtr, objectIndex, &curBounds );
400          newBounds = curBounds;
401          GetNewBounds( extentX, extentY,
402              entry->originalBounds[ 0 ].extent.x,
403              entry->originalBounds[ 0 ].extent.y,
404              &( entry->originalBounds[ i ] ),
405              &newBounds, &( entry->config->objectList[ i ] ) );
406
407          if ( ! SameBounds( &curBounds, &newBounds, false ) ) {
408              SafeFrmSetObjectBounds( formPtr, objectIndex, &newBounds );
409              
410              switch ( FrmGetObjectType( formPtr, objectIndex ) ) {
411                  case frmFieldObj:
412     /*             case frmScrollBarObj: */
413                  {
414                      FieldType* field;
415                      UInt16     insPt;
416
417                      field   = ( FieldType* ) FrmGetObjectPtr( formPtr, objectIndex );
418
419                      if ( entry->config->objectList[ i ].flags & DIA_H_GRANULAR ) {
420                          FontID oldFont;
421                          Coord  newHeight;
422
423                          oldFont   = FntSetFont( FldGetFont( field ) );
424
425                          newHeight = newBounds.extent.y / FntLineHeight() *
426                                          FntLineHeight();
427                                          
428                          FntSetFont( oldFont );
429
430                          if ( 0 < newHeight ) {
431                              newBounds.extent.y = newHeight;
432                              SafeFrmSetObjectBounds( formPtr, objectIndex, &newBounds );
433                          }
434                      }
435                      insPt   = FldGetInsPtPosition( field );
436                      FldRecalculateField( field, true );
437                      FldSetInsPtPosition( field, insPt );
438                      FldSendChangeNotification( field );
439                      break;
440                  }
441                  case frmListObj:
442                      if ( entry->config->objectList[ i ].flags & DIA_H_GRANULAR ) {
443                          ListType* list;
444                          FontID oldFont;
445                          Coord  newHeight;
446
447                          list   = ( ListType* ) FrmGetObjectPtr( formPtr, objectIndex );
448
449                          oldFont   = FntSetFont( LstGlueGetFont( list ) );
450
451                          newHeight = newBounds.extent.y / FntLineHeight() *
452                                          FntLineHeight();
453
454                          FntSetFont( oldFont );
455
456                          if ( 0 < newHeight ) {
457                              newBounds.extent.y = newHeight;
458                              SafeFrmSetObjectBounds( formPtr, objectIndex, &newBounds );
459                          }
460                      }
461                      break;
462
463                  default:
464                      break;
465              }
466          }
467     }
468
469     if ( formList[ indexInList ].callback ) {
470         (*formList[ indexInList ].callback)(formPtr, dw, dh);
471     }
472
473     if ( FrmGetFocus( formPtr ) != focus )
474         FrmSetFocus( formPtr, focus );
475
476     return true;
477 }
478
479
480
481 void InitializeResizeSupport( UInt16 formMapId )
482 {
483     MemHandle     indexHandle;
484     DIAIndexType* index;
485     UInt16        i;
486
487     if ( formList != NULL ) {
488         return;
489     }
490     indexHandle = DmGetResource( WORD_LIST_TYPE, formMapId );
491     if ( indexHandle == NULL ) {
492         return;
493     }
494
495     if ( DIA_HARDWARE_NONE == InitializeDIA() ) {
496         return;
497     }
498
499     index     = ( DIAIndexType* )MemHandleLock( indexHandle );
500     numBins   = 0;
501     formCount = index->count * sizeof( UInt16 ) /
502                     sizeof( DIAIndexEntryType );
503
504     if ( formCount == 0 ) {
505         numBins = 0;
506         return;
507     }
508
509     formList  = ( DIAFormEntryType* ) SafeMemPtrNew( formCount * 
510                                           sizeof( DIAFormEntryType ) );
511     MemSet( formList, formCount * sizeof( DIAFormEntryType ), 0 );
512
513     for ( i = 0 ; i < formCount ; i++ ) {
514          AddForm( i, DmGetResource( WORD_LIST_TYPE, index->mapList[ i ].to ),
515              index->mapList[ i ].from );
516     }
517
518     MemHandleUnlock( indexHandle );
519     DmReleaseResource( indexHandle );
520
521     if ( 0 < numBins ) {
522         bins = ( DIAStateType* ) SafeMemPtrNew( numBins * 
523                                      sizeof( DIAStateType ) );
524         for ( i = 0 ; i < numBins ; i++ )
525              bins[ i ] = DIA_STATE_UNDEFINED;
526     }
527 }
528
529
530
531
532 void TerminateResizeSupport( void )
533 {
534      UInt16  i;
535
536      if ( formList == NULL )
537          return;
538      TerminateDIA();
539      for ( i = 0 ; i < formCount ; i++ ) {
540           if ( NULL != formList[ i ].configHandle ) {
541               MemHandleUnlock( formList[ i ].configHandle );
542               DmReleaseResource( formList[ i ].configHandle );
543               if ( formList[ i ].originalBounds != NULL )
544                   SafeMemPtrFree( formList[ i ].originalBounds );
545           }
546      }
547      SafeMemPtrFree( formList );
548      formCount = 0;
549      if ( 0 < numBins ) {
550          SafeMemPtrFree( bins );
551      }
552 }
553
554
555
556
557 void LoadResizePrefs( UInt32 appID, UInt16 prefID )
558 {
559     UInt16 size;
560
561     size = 0;
562
563     if ( formList == NULL || numBins == 0 ||
564          noPreferenceFound ==
565              PrefGetAppPreferences( appID, prefID, NULL, &size, true ) ) {
566         return;
567     }
568
569     if ( numBins * sizeof( DIAStateType ) < size ) {
570         size = numBins * sizeof( DIAStateType );
571     }
572
573     PrefGetAppPreferences( appID, prefID, bins, &size, true );
574 }
575
576
577
578 void SaveResizePrefs( UInt32 appID, UInt16 prefID, Int16 version )
579 {
580     if ( formList == NULL || numBins == 0 )
581         return;
582
583     PrefSetAppPreferences( appID, prefID, version, bins,
584         numBins * sizeof( DIAStateType ), true );
585 }
586
587
588
589 RESIZE_SECTION static UInt16 GetFormIndex( UInt16 formID ) 
590 {
591     UInt16 i;
592
593     if ( formList == NULL )
594         return 0;
595
596     for ( i = 0 ; i < formCount ; i++ )
597         if ( formList[ i ].formID == formID )
598             break;
599
600     return i;
601 }
602
603
604
605 void SetResizePolicy( UInt16 formID )
606 {
607     if ( GetFormIndex( formID ) < formCount ) {
608         SetCustomDIAPolicy( formID );
609     }
610 }
611
612
613 void SetResizeCallback( UInt16 formID, DIAResizeCallback fn )
614 {
615     UInt16 i;
616     i = GetFormIndex( formID );
617     if ( i < formCount ) {
618         formList[ i ].callback = fn;
619     }
620 }
621
622
623
624 RESIZE_SECTION static Boolean GetFormInfo( void ) 
625 {
626     active.formID  = FrmGetActiveFormID();
627     active.formPtr = FrmGetActiveForm();
628     active.index   = GetFormIndex( active.formID );
629
630     if ( active.index < formCount ) {
631         active.entry = &( formList[ active.index ] );
632         active.flags = active.entry->config->flags;
633         return true;
634     }
635     else {
636         return false;
637     }
638 }
639
640
641
642
643
644 RESIZE_SECTION static Boolean PrepareForm( void ) 
645 {
646     if ( active.index == formCount ) {
647         SetDIAState( DIA_STATE_MAX );
648         SetDIAAllowResize( false );
649         return false;
650     }
651
652     return MoveObjectsInForm( active.index );
653 }
654
655
656
657 RESIZE_SECTION static void SaveDIAState( void ) 
658 {
659     if ( active.index == formCount )
660         return;
661
662     if ( active.entry->config->flags & DIA_FORM_USE_BIN ) {
663         bins[ active.entry->config->bin ] = GetDIAState();
664     }
665 }
666
667
668
669
670 RESIZE_SECTION static Boolean FormStartup( void )
671 {
672     DIAStateType newState;
673     Boolean   big;
674     Boolean   allowBig;
675     Boolean   changed;
676     Boolean   allowResize;
677
678     if ( active.index == formCount ) {
679         SetDIAState( DIA_STATE_MAX );
680         SetDIAAllowResize( false );
681         SetDIAConstraints( FrmGetWindowHandle( active.formPtr ), false, false );
682         return false;
683     }
684
685     newState = GetDIAState();
686
687     if ( ( active.flags & DIA_FORM_USE_BIN ) &&
688          ( bins[ active.entry->config->bin ] != DIA_STATE_UNDEFINED ) ) {
689         newState = bins[ active.entry->config->bin ];
690 /*        if ( newState == DIA_STATE_MIN ) DebugInfo("bin = min");
691         if ( newState == DIA_STATE_MAX ) DebugInfo("bin = max"); */
692     }
693     else if ( ! ( active.flags & DIA_FORM_KEEP_LAST ) ) {
694         newState = active.entry->config->preferredState;
695     }
696
697     if ( active.flags & DIA_FORM_NO_RESIZE ) {
698         allowResize = false;
699         allowBig = false;
700     }
701     else {
702         allowResize = true;
703         allowBig = true;
704     }
705
706     big      = ( newState == DIA_STATE_MIN || newState == DIA_STATE_NO_STATUS_BAR );
707     allowBig = allowBig || big;
708
709     SetDIAConstraints( FrmGetWindowHandle( active.formPtr ), allowBig, allowBig );
710
711     SetDIAState( newState );
712
713     SetDIAAllowResize( allowResize );
714
715     changed = PrepareForm();
716
717 /*    if ( changed ) DebugInfo("Changed in FormStartup"); */
718
719     SaveDIAState();
720
721     return changed;
722 }
723
724
725 RESIZE_SECTION static void ForceRedrawAll( void )
726 {
727     UInt16 i;
728     for ( i = 0 ; i < formCount ; i++ ) {
729         if ( formList[ i ].open )
730             formList[ i ].forceRedraw = true;
731     }
732 }
733
734
735
736 Boolean ResizeHandleFrmOpenEvent( void )
737 {
738     GetFormInfo();
739 #ifdef SUPPORT_DIA_HANDERA
740     if ( GetDIAHardware() == DIA_HARDWARE_HANDERA &&
741          ( active.index == formCount || ! ( active.flags & DIA_FORM_HANDERA ) )
742        ) {
743         VgaFormModify( active.formPtr, vgaFormModify160To240 );
744     }
745 #endif
746     if ( active.index < formCount ) {
747         MemSet( &( active.entry->lastBounds ), sizeof( RectangleType ), 0 );
748         active.entry->lastExtentX = -1;
749         active.entry->lastExtentY = -1;
750         active.entry->forceRedraw = false;
751     }
752     DebugInfo("FrmOpen");
753     PushCoordinateSystemToStandard();
754     FormStartup();
755     if ( active.index < formCount ) {
756         active.entry->open = true;
757     }
758     PopCoordinateSystem();
759     haveWinDisplayChangedEvent = false;
760     return true;
761 }
762
763
764
765 Boolean ResizeHandleFrmCloseEvent( void )
766 {
767     if ( GetFormInfo() ) {
768         DebugInfo("FrmClose");
769         active.entry->open        = false;
770         active.entry->forceRedraw = false;
771         SaveDIAState();
772     }
773     return true;
774 }
775
776
777
778 Boolean ResizeHandleWinDisplayChangedEvent( void )
779 {
780     haveWinDisplayChangedEvent = false;
781     if ( ! GetFormInfo() )
782         return true;
783
784     PushCoordinateSystemToStandard();
785
786     DebugInfo("WinDisplayChanged");
787     if ( PrepareForm() || active.entry->forceRedraw ) {
788         UniqueUpdateForm( active.formID, frmRedrawUpdateCode );
789         active.entry->forceRedraw = false;
790     }
791     SaveDIAState();
792
793     PopCoordinateSystem();
794
795     return true;
796 }
797
798
799
800 Boolean ResizeHandleWinExitEvent( void )
801 {
802     DebugInfo("WinExit");
803
804     return true;
805 }
806
807
808
809 Boolean ResizeHandleFrmRedrawUpdateCode( void )
810 {
811     GetFormInfo();
812     DebugInfo("FrmUpdate");
813     if ( active.index < formCount )
814         active.entry->forceRedraw = false;
815     return true;
816 }
817
818
819
820 Boolean ResizeHandleWinEnterEvent( void )
821 {
822     GetFormInfo();
823     DebugInfo("WinEnter");
824     if ( active.index == formCount ) {
825         return true;
826     }
827
828     PushCoordinateSystemToStandard();
829
830     /* If the last form we have record of being in is this one, then
831        we may have missed what happened on a form. */
832
833     if ( active.entry->open && ( FormStartup() ||
834          active.entry->forceRedraw ) )
835        {
836         EventType e;
837         DebugInfo("WinEnter: Possibly missed winDisplayChangedEvent");
838         MemSet( &e, sizeof( EventType ), 0 );
839         e.eType = winDisplayChangedEvent;
840         EvtAddUniqueEventToQueue( &e, 0, true );
841         DebugInfo("Queuing display change");
842         active.entry->forceRedraw = true;
843     }
844
845     PopCoordinateSystem();
846
847     return true;
848 }
849
850
851
852
853 void SetHaveWinDisplayChangedEvent( Boolean value )
854 {
855     DebugInfo("SetHaveWinDisplayChangedEvent()");
856     haveWinDisplayChangedEvent = value;
857     ForceRedrawAll();
858 }
859
860
861
862
863 void ResizeRefreshCurrentForm( void )
864 {
865     GetFormInfo();
866     if ( active.index == formCount )
867         return;
868
869     PushCoordinateSystemToStandard();
870
871     FormStartup();
872     SaveDIAState();
873     UniqueUpdateForm( active.formID, frmRedrawUpdateCode );
874
875     PopCoordinateSystem();
876 }
877
878
879
880
881 Boolean ResizeHandleEvent( EventType* event )
882 {
883     Boolean handled = false;
884     ResizeTemporaryData old;
885
886     switch ( event->eType ) {
887         case nilEvent:
888             return false;
889         case frmOpenEvent: {
890             old = active;
891             ResizeHandleFrmOpenEvent();
892             active = old;
893             break;
894         }
895         case frmCloseEvent: {
896             old = active;
897             ResizeHandleFrmCloseEvent();
898             active = old;
899             break;
900         }
901         case winEnterEvent: {
902             old = active;
903             ResizeHandleWinEnterEvent();
904             active = old;
905             break;
906         }
907         case winExitEvent: {
908             old = active;
909             ResizeHandleWinExitEvent();
910             active = old;
911             break;
912         }
913         case winDisplayChangedEvent: {
914             old = active;
915             ResizeHandleWinDisplayChangedEvent();
916             active = old;
917             break;
918         }
919         case frmUpdateEvent:
920             if ( event->data.frmUpdate.updateCode == frmRedrawUpdateCode ) {
921                 old = active;
922                 ResizeHandleFrmRedrawUpdateCode();
923                 active = old;
924             }
925             break;
926         default:
927             break;
928     }
929
930     return handled;
931 }
932