disable warnings about unused local typedefs
[AROS-Contrib.git] / Misc / SWitch / SWitch.c
blob38349015e77be88acdf5c535a7479b8ee4cef354
1 /*
2 * SWitch (C) 1996 John M Haubrich Jr
3 * All Rights Under Copyright Reserved
5 * Version 1.0
7 * Written using SAS/C 6.56
9 * PROGRAM AND SOURCE CODE ARE FREELY (RE)DISTRIBUTABLE.
11 * By John M. Haubrich, Jr.
14 #include <aros/oldprograms.h>
16 #include <exec/types.h>
17 #include <exec/memory.h>
18 #include <exec/nodes.h>
19 #include <exec/libraries.h>
20 #include <libraries/commodities.h>
21 #include <intuition/intuition.h>
22 #include <intuition/intuitionbase.h>
23 #include <intuition/gadgetclass.h>
24 #include <libraries/gadtools.h>
25 #include <dos/dos.h>
26 #include <dos/rdargs.h>
28 #include <proto/dos.h>
29 #include <proto/exec.h>
30 #include <proto/alib.h>
31 #include <proto/graphics.h>
32 #include <proto/commodities.h>
33 #include <proto/intuition.h>
34 #include <proto/gadtools.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdio.h>
40 #ifdef LATTICE
41 int CXBRK(void) { return(0); }
42 int chkabort(void) { return(0); }
43 #endif
46 * VERSION STRING ===================================
48 char *vers="$VER: SWitch 1.0 (15.05.96)";
52 * DEFINES ------------------------------------------
54 #define BASENAME "SWitch"
55 #define EVT_HOTKEY 1L
56 #define GAD_LISTVIEW 101L
57 #define ID_MENU_HIDE 201L
58 #define ID_MENU_QUIT 202L
59 #define ID_MENU_SAVESETTINGS 203L
61 #define MAXINFOCHARS 128 // 'Information...' allows 128 chars max
62 // in string gadget.
66 * STRUCTURE DEFINITIONS ----------------------------
68 struct NewBroker newbroker = {
69 NB_VERSION,
70 "SWitch",
71 "Pops up a screen/window list.",
72 "User selects which to activate.",
73 NBU_UNIQUE | NBU_NOTIFY,
74 0, 0, NULL, 0
77 struct MyGlobals {
78 struct MsgPort *broker_mp;
79 CxObj *broker;
80 ULONG cxsigflag; // our combined message port signal FLAG
82 BOOL fRunFromWB;
83 BOOL fBeQuiet;
85 struct Gadget *listview;
86 struct List list;
87 UWORD uwNumItems;
89 char szHotkeyDesc[MAXINFOCHARS];
90 WORD wLeftEdge;
91 WORD wTopEdge;
92 WORD wWidth;
93 WORD wHeight;
94 BOOL fPointerRel;
95 SHORT sJumpClicks;
98 struct SWNode
100 struct Node node;
101 struct Screen *scr;
102 struct Window *wdw;
107 * GLOBAL VARIABLES ---------------------------------
109 struct MyGlobals MG;
110 struct Gadget *glist = NULL;
111 struct Window *mywin = NULL;
112 struct Menu *menu = NULL;
113 void *vi = NULL;
115 struct NewMenu mynewmenu[] =
117 { NM_TITLE, "Project", 0 , 0, 0, NULL },
118 { NM_ITEM, "Hide", "H", 0, 0, (APTR)ID_MENU_HIDE },
119 { NM_ITEM, "Quit", "Q", 0, 0, (APTR)ID_MENU_QUIT },
121 // { NM_TITLE, "Prefs", 0 , 0, 0, NULL },
122 // { NM_ITEM, "Save Settings", 0 , 0, 0, (APTR)ID_MENU_SAVESETTINGS },
124 { NM_END, NULL, 0 , 0, 0, NULL }
129 * FUNCTION PROTOTYPES ------------------------------
131 void ProcessMsg(void);
132 int JMH_EasyReq( char *, char *, char *);
133 void JMH_Complain(char *);
134 void JMH_Info(char *);
135 int JMH_Query(char *, char *);
136 void JMH_Quit(char *);
137 VOID JMH_InitVars(void);
138 void JumpToIt( UWORD, struct Screen * );
139 BOOL HandleEvents( void );
140 BOOL fnPopupJumpList( void );
141 struct Gadget *CreateAllGadgets( struct Gadget **, void *, WORD, WORD, WORD, WORD );
145 * LIBRARY VARIABLES --------------------------------
147 struct Library *CxBase = NULL;
148 struct IntuitionBase *IntuitionBase = NULL;
149 struct Library *IconBase = NULL;
150 struct DosBase *DosBase = NULL;
151 struct GfxBase *GfxBase = NULL;
152 struct Library *GadToolsBase = NULL;
156 * FUNCTIONS ----------------------------------------
160 * JMH_EasyReq(): pop up JMH_EasyRequest() with a custom title bar, message and
161 * response buttons.
162 -------------------------------------------------------------------------*/
163 int JMH_EasyReq( char *title, char *text, char *resp ) {
164 static struct EasyStruct es = {
165 sizeof(struct EasyStruct),
167 NULL,
168 NULL,
169 NULL
171 int stat = 0;
174 if ( MG.fBeQuiet == FALSE )
176 if ( MG.fRunFromWB == TRUE )
178 es.es_Title = title;
179 es.es_TextFormat = text;
180 es.es_GadgetFormat = resp;
182 stat = EasyRequest(NULL, &es, NULL, TAG_DONE);
184 else
186 printf( "%s\n", text );
187 stat = -1;
190 return( stat );
194 * JMH_Complain(): pop up JMH_EasyRequest() with a JMH_Complaint message
195 -------------------------------------------------------------------------*/
196 void JMH_Complain(char *t)
198 char buf[100];
201 if (t) {
202 sprintf( buf, "%s Complaint...", BASENAME );
203 JMH_EasyReq( buf, t, "OK" );
208 * JMH_Info(): pop up JMH_EasyRequest() with a (nice) informative message
209 * if WB flag set else send output to stderr
210 -------------------------------------------------------------------------*/
211 void JMH_Info(char *t)
213 char buf[100];
216 if (t) {
217 sprintf( buf, "%s Information...", BASENAME );
218 JMH_EasyReq( buf, t, "OK" );
223 * JMH_Query(): are you sure... ? (1=yes, 0=no)
224 -------------------------------------------------------------------------*/
225 int JMH_Query(char *t, char *response) {
226 char buf[100];
227 char *resp;
228 int stat;
231 if (t) {
232 sprintf( buf, "%s Request...", BASENAME );
234 if (response)
235 resp = response;
236 else
237 resp = "Yes|No";
238 stat = JMH_EasyReq( buf, t, resp );
239 return(stat);
242 return 0;
246 * JMH_Quit(): close down everything we've opened and JMH_Quit
247 -------------------------------------------------------------------------*/
248 void JMH_Quit( char *t )
250 char szQuitBuf[256+20];
253 if ( mywin )
255 ClearMenuStrip( mywin );
256 CloseWindow( mywin );
257 mywin = NULL;
260 if ( t )
262 sprintf( szQuitBuf, "%s\nExiting...", t );
263 JMH_Complain( szQuitBuf );
266 if ( MG.broker ) DeleteCxObjAll( MG.broker );
267 if ( MG.broker_mp ) DeletePort( MG.broker_mp );
269 if ( GfxBase ) CloseLibrary( (struct Library *)GfxBase );
270 if ( GadToolsBase )
272 if ( menu ) FreeMenus( menu );
275 // Free list nodes, if any
276 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
277 if ( MG.list.lh_Head->ln_Succ )
279 struct SWNode *swworknode, *swnode;
282 swworknode = (struct SWNode *)MG.list.lh_Head;
283 while (( swnode = (struct SWNode *)( swworknode->node.ln_Succ ) ))
285 FreeVec( swworknode );
286 swworknode = swnode;
288 NewList( &MG.list );
291 if ( vi )
293 FreeVisualInfo( vi );
294 vi = NULL;
296 if ( glist )
298 FreeGadgets( glist );
299 glist = NULL;
301 CloseLibrary(GadToolsBase);
303 if ( DosBase ) CloseLibrary( (struct Library *)DosBase );
304 if ( CxBase ) CloseLibrary( CxBase );
305 if ( IconBase ) CloseLibrary( (struct Library *)IconBase );
306 if ( IntuitionBase ) CloseLibrary( (struct Library *)IntuitionBase );
308 exit( ( t ? TRUE : FALSE ) );
313 * JMH_InitVars(): initialize variables to default values
314 -------------------------------------------------------------------------*/
315 VOID JMH_InitVars()
318 // initialize variables...
319 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
320 memset( &MG, 0, sizeof( MG ) );
322 MG.broker = NULL;
323 MG.broker_mp = NULL;
324 MG.fRunFromWB = TRUE;
325 MG.fBeQuiet = FALSE;
327 NewList( &MG.list );
330 menu = CreateMenus( mynewmenu, TAG_DONE );
335 ** M A I N P R O G R A M -----------------------
337 int main( int argc, char *argv[] )
339 UBYTE **ttypes,
340 *temp;
341 CxMsg *msg;
342 CxObj *filter;
343 LONG errorcode;
347 // open libraries
348 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
349 IntuitionBase = (struct IntuitionBase *)
350 OpenLibrary("intuition.library",37L);
351 if (!IntuitionBase) JMH_Quit("Cannot open intuition.library 37+");
353 IconBase = OpenLibrary("icon.library",37L);
354 if (!IconBase) JMH_Quit("Cannot open icon.library 37+");
356 CxBase = OpenLibrary("commodities.library",37L);
357 if (!CxBase) JMH_Quit("Cannot open commodities.library 37+");
359 DosBase = (struct DosBase *)OpenLibrary("dos.library",37L);
360 if (!DosBase) JMH_Quit("Cannot open dos.library 37+");
362 GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37L);
363 if (!GfxBase) JMH_Quit("Cannot open graphics.library 37+");
365 GadToolsBase = OpenLibrary("gadtools.library",37L);
366 if (!GadToolsBase) JMH_Quit("Cannot open gadtools.library 37+");
369 // initialize variables
370 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
371 JMH_InitVars();
373 if (!(MG.broker_mp = CreateMsgPort()))
374 JMH_Quit( "Cannot create broker message port." );
377 // user may only run from Workbench
378 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
379 MG.fRunFromWB = TRUE;
381 // get opts from TOOLTYPES in icon
382 ttypes = ArgArrayInit( argc, (STRPTR *)argv );
384 // user-specified priority for the commodity
385 newbroker.nb_Pri = (BYTE)ArgInt( ttypes, "CX_PRIORITY", 0 );
387 // report errors?
388 temp = ArgString( ttypes, "QUIET", "FALSE" );
389 if ( stricmp( temp, "TRUE" ) == 0 )
391 MG.fBeQuiet = TRUE;
393 else
395 MG.fBeQuiet = FALSE;
398 // read hotkey
399 temp = ArgString( ttypes, "HOTKEY", "rawkey lalt esc" );
400 strcpy( MG.szHotkeyDesc, temp );
402 // read left/top/width/height
403 temp = ArgString( ttypes, "LEFTEDGE", "0" ); MG.wLeftEdge = atoi( temp );
404 temp = ArgString( ttypes, "TOPEDGE" , "20" ); MG.wTopEdge = atoi( temp );
405 temp = ArgString( ttypes, "WIDTH" , "300" ); MG.wWidth = atoi( temp );
406 MG.wWidth = ( MG.wWidth < 100 ? 100 : MG.wWidth );
407 temp = ArgString( ttypes, "HEIGHT" , "150" ); MG.wHeight = atoi( temp );
408 MG.wHeight = ( MG.wHeight < 80 ? 80 : MG.wHeight );
410 // popup jump window relative to mouse pointer?
411 temp = ArgString( ttypes, "POINTERRELATIVE", NULL );
412 if ( temp )
413 MG.fPointerRel = TRUE;
414 else
415 MG.fPointerRel = FALSE;
417 // read number of clicks to jump
418 temp = ArgString( ttypes, "JUMPCLICKS", "1" );
419 MG.sJumpClicks = atoi( temp );
420 if ( MG.sJumpClicks < 1 ) MG.sJumpClicks = 1;
421 else if ( MG.sJumpClicks > 2 ) MG.sJumpClicks = 2;
423 ArgArrayDone();
425 newbroker.nb_Port = MG.broker_mp;
426 MG.cxsigflag = 1L << MG.broker_mp->mp_SigBit;
428 if (( MG.broker = CxBroker(&newbroker, &errorcode) ))
431 // Establish hotkey filter
432 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
433 if (( filter = HotKey( MG.szHotkeyDesc, MG.broker_mp, EVT_HOTKEY ) ))
435 AttachCxObj( MG.broker, filter );
437 if ( CxObjError( filter ) )
439 JMH_Quit( "Error creating filter for hotkey." );
441 else
443 ActivateCxObj( MG.broker, TRUE );
444 ProcessMsg(); // process msgs until user quits...
447 else
450 // an error has occured.. show user!
451 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
452 switch ( errorcode )
454 case CBERR_SYSERR:
455 JMH_Quit( "Broker SYSTEM error.\nNo memory?" );
456 break;
457 case CBERR_DUP:
459 // this message is shown in ProcessMsg(): 'already running...'
460 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
461 break;
462 case CBERR_VERSION:
463 JMH_Quit( "Broker VERSION error." );
464 break;
469 // Empty message port of all remaining messages
470 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
471 while (( msg = (CxMsg *)GetMsg( MG.broker_mp ) ))
472 ReplyMsg( (struct Message *)msg );
474 JMH_Quit( NULL );
476 return 0;
479 void ProcessMsg()
481 CxMsg *msg;
482 ULONG sigrcvd;
483 ULONG msgid;
484 ULONG msgtype;
485 BOOL fKeepGoing = TRUE;
488 while ( fKeepGoing == TRUE )
490 sigrcvd = Wait( SIGBREAKF_CTRL_C | MG.cxsigflag );
492 while (( msg = (CxMsg *)GetMsg( MG.broker_mp ) ))
494 msgid = CxMsgID( msg );
495 msgtype = CxMsgType( msg );
496 ReplyMsg( (struct Message *)msg );
498 switch ( msgtype )
500 case CXM_IEVENT:
501 if ( msgid == EVT_HOTKEY )
503 ActivateCxObj( MG.broker, FALSE );
504 fKeepGoing = ( fnPopupJumpList() ? FALSE : TRUE );
505 ActivateCxObj( MG.broker, TRUE );
507 break;
509 case CXM_COMMAND:
510 switch ( msgid )
512 case CXCMD_DISABLE:
513 ActivateCxObj( MG.broker, FALSE );
514 break;
516 case CXCMD_ENABLE:
517 ActivateCxObj( MG.broker, TRUE );
518 break;
520 case CXCMD_KILL:
521 fKeepGoing = FALSE;
522 break;
524 case CXCMD_UNIQUE:
525 JMH_Complain( "SWitch is already running!" );
526 break;
528 break;
530 if ( fKeepGoing == FALSE ) break;
532 if ( sigrcvd & SIGBREAKF_CTRL_C )
534 fKeepGoing = FALSE;
539 // -----------------------------------------------------------------------
540 // fnPopupJumpList(): prepare jump list and launch window
541 // -----------------------------------------------------------------------
542 BOOL fnPopupJumpList( void )
544 BOOL fQuitCX = FALSE; // FALSE = keep going; TRUE = quit program
545 struct Screen *scr;
546 struct Window *wdw;
547 char *pszTitle;
548 UBYTE szTitle[80];
549 struct SWNode *swnode;
550 struct SWNode *swworknode;
551 LONG lIBLock;
554 // Free list nodes, if any
555 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
556 if ( MG.list.lh_Head->ln_Succ )
558 swworknode = (struct SWNode *)MG.list.lh_Head;
559 while (( swnode = (struct SWNode *)( swworknode->node.ln_Succ ) ))
561 FreeVec( swworknode );
562 swworknode = swnode;
564 NewList( &MG.list );
568 // Fill the screen/window list
569 // scan screenlist...
570 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
571 lIBLock = LockIBase(0);
572 MG.uwNumItems = 0;
573 for ( scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen )
575 // use Default Title if there's no on-screen title
576 if ( scr->Title == NULL ) pszTitle = scr->DefaultTitle;
577 else pszTitle = scr->Title;
579 swnode = (struct SWNode *)AllocVec( sizeof( struct SWNode ) + strlen( pszTitle ) + 1, MEMF_PUBLIC | MEMF_CLEAR );
580 if ( swnode )
582 swnode->scr = scr;
583 swnode->wdw = NULL; // no window yet...
584 pszTitle = ( pszTitle ? pszTitle : "Unnamed Screen" );
585 strcpy( (char *)( swnode + 1 ), pszTitle ); // copy screen name to ln_Name
586 swnode->node.ln_Name = (char *)( swnode + 1 );
587 AddTail( &MG.list, (struct Node *)swnode );
588 MG.uwNumItems++;
592 // ...then windowlist
593 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
594 for ( wdw = scr->FirstWindow; wdw; wdw = wdw->NextWindow )
596 if ( wdw->Title )
598 pszTitle = wdw->Title;
600 else
602 sprintf( szTitle, "Unnamed Window at (%d,%d)", wdw->LeftEdge, wdw->TopEdge );
603 pszTitle = szTitle;
605 swnode = (struct SWNode *)AllocVec( sizeof( struct SWNode ) + 3 + strlen( pszTitle ) + 1, MEMF_PUBLIC | MEMF_CLEAR );
606 if ( swnode )
608 swnode->scr = scr;
609 swnode->wdw = wdw;
610 sprintf( (char *)( swnode + 1 ), " %s", pszTitle ); // copy window name to ln_Name (indented)
611 swnode->node.ln_Name = (char *)( swnode + 1 );
612 AddTail( &MG.list, (struct Node *)swnode );
613 MG.uwNumItems++;
617 UnlockIBase( lIBLock );
620 // Open the window and drop into the window event loop
621 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
622 fQuitCX = HandleEvents();
624 return( fQuitCX );
628 void JumpToIt( UWORD imsgCode, struct Screen *currscr )
630 struct Window *wdw;
631 struct SWNode *swnode;
632 int i;
636 // imsgCode contains index of selection
637 // walk thru LL for nth item
638 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
639 for ( swnode = (struct SWNode *)MG.list.lh_Head, i = 0;
640 i < imsgCode;
641 i++, swnode = (struct SWNode *)swnode->node.ln_Succ );
643 // jump to screen/window
644 ScreenToFront( swnode->scr );
645 wdw = ( swnode->wdw ? swnode->wdw : swnode->scr->FirstWindow );
646 WindowToFront( wdw );
647 ActivateWindow( wdw );
648 if ( IntuitionBase->LibNode.lib_Version >= 39 )
650 ScreenPosition( currscr,
651 SPOS_MAKEVISIBLE | SPOS_FORCEDRAG,
652 wdw->LeftEdge,
653 wdw->TopEdge,
654 wdw->LeftEdge + wdw->Width,
655 wdw->TopEdge + wdw->Height );
660 BOOL HandleEvents( void )
662 BOOL fQuitCX = FALSE; // FALSE = keep going; TRUE = quit program
663 struct IntuiMessage *imsg;
664 struct Gadget *gad;
665 struct Screen *currscr = NULL;
666 ULONG imsgClass;
667 UWORD imsgCode;
668 UWORD uwCode = 0xFFFF;
669 UWORD uwListItem = 0;
670 ULONG imsgSeconds = 0;
671 ULONG imsgMicros = 0;
672 ULONG ulSeconds = 0;
673 ULONG ulMicros = 0;
674 WORD topborder;
675 struct MenuItem *mitem;
676 WORD wLeftEdge;
677 WORD wTopEdge;
678 WORD wWidth;
679 WORD wHeight;
680 BOOL fTerminated = FALSE;
681 BOOL fShift = FALSE;
682 BOOL fAlt = FALSE;
683 BOOL fFound;
684 struct SWNode *swnode;
685 UWORD i;
688 currscr = IntuitionBase->ActiveScreen;
690 if ( !( vi = GetVisualInfo( currscr, TAG_DONE ) ) )
692 // can't get visual info... bail out!
693 DisplayBeep( NULL );
694 goto endrtn;
698 // How tall is window's title bar?
699 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
700 topborder = currscr->WBorTop + (currscr->Font->ta_YSize + 1);
702 wWidth = ( MG.wWidth > currscr->Width ? currscr->Width : MG.wWidth );
703 wHeight = ( MG.wHeight > currscr->Height ? currscr->Height : MG.wHeight );
704 wLeftEdge = ( MG.wLeftEdge > currscr->Width ? currscr->Width - wWidth : MG.wLeftEdge );
705 wTopEdge = ( MG.wTopEdge > currscr->Height ? currscr->Height - wHeight - topborder : MG.wTopEdge );
708 // override left/top if POINTERRELATIVE mode is being used
709 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
710 if ( MG.fPointerRel )
712 wLeftEdge = currscr->MouseX;
713 wTopEdge = currscr->MouseY;
716 if ( !( mywin = OpenWindowTags( NULL,
717 WA_CustomScreen , currscr,
718 WA_Left , wLeftEdge,
719 WA_Top , wTopEdge,
720 WA_InnerWidth , wWidth,
721 WA_InnerHeight , wHeight,
722 WA_MinWidth , 100,
723 WA_MinHeight , 80,
724 WA_MaxWidth , 32767,
725 WA_MaxHeight , 32767,
726 WA_AutoAdjust , TRUE,
727 WA_Activate , TRUE,
728 WA_DragBar , TRUE,
729 WA_DepthGadget , TRUE,
730 WA_CloseGadget , TRUE,
731 WA_SizeGadget , TRUE,
732 WA_SizeBBottom , TRUE,
733 WA_SimpleRefresh, TRUE,
734 WA_IDCMP , CLOSEWINDOW | REFRESHWINDOW | MENUPICK | IDCMP_NEWSIZE |
735 IDCMP_RAWKEY | IDCMP_INACTIVEWINDOW | LISTVIEWIDCMP,
736 WA_Title , "SWitch List",
737 TAG_DONE ) ) )
739 DisplayBeep( NULL );
740 goto endrtn;
743 if ( !CreateAllGadgets( &glist, vi, mywin->BorderLeft, topborder,
744 mywin->Width - mywin->BorderLeft - mywin->BorderRight,
745 mywin->Height - mywin->BorderTop - mywin->BorderBottom ) )
747 DisplayBeep( NULL );
748 goto endrtn;
750 AddGList( mywin, glist, -1, -1, NULL );
751 RefreshGList( glist, mywin, NULL, -1 );
752 GT_RefreshWindow( mywin, NULL );
753 LayoutMenus( menu, vi,
754 GTMN_NewLookMenus, TRUE,
755 TAG_DONE );
756 SetMenuStrip( mywin, menu );
758 while ( !fTerminated )
760 Wait ( 1 << mywin->UserPort->mp_SigBit );
761 while ( ( !fTerminated ) && ( imsg = GT_GetIMsg( mywin->UserPort ) ) )
763 imsgClass = imsg->Class;
764 imsgCode = imsg->Code;
765 imsgSeconds = imsg->Seconds;
766 imsgMicros = imsg->Micros;
767 gad = (struct Gadget *)imsg->IAddress;
768 GT_ReplyIMsg( imsg );
769 switch ( imsgClass )
771 case IDCMP_NEWSIZE:
772 RemoveGList( mywin, glist, -1 );
773 FreeGadgets( glist );
774 glist = NULL;
775 if ( !CreateAllGadgets( &glist, vi, mywin->BorderLeft, topborder,
776 mywin->Width - mywin->BorderLeft - mywin->BorderRight,
777 mywin->Height - mywin->BorderTop - mywin->BorderBottom ) )
779 DisplayBeep( NULL );
781 else
783 AddGList( mywin, glist, -1, -1, NULL );
784 SetRast( mywin->RPort, 0 );
785 RefreshWindowFrame( mywin );
786 RefreshGList( glist, mywin, NULL, -1 );
787 GT_RefreshWindow( mywin, NULL );
789 break;
790 case IDCMP_RAWKEY:
791 switch( imsgCode )
793 case 0x60:
794 case 0x61:
795 // LEFT or RIGHT SHIFT pressed
796 fShift = TRUE;
797 break;
798 case 0xE0:
799 case 0xE1:
800 // LEFT or RIGHT SHIFT released
801 fShift = FALSE;
802 break;
803 case 0x64:
804 case 0x65:
805 // LEFT or RIGHT ALT pressed
806 fAlt = TRUE;
807 break;
808 case 0xE4:
809 case 0xE5:
810 // LEFT or RIGHT ALT released
811 fAlt = FALSE;
812 break;
813 case 0x43:
814 case 0x44:
815 // ENTER/RETURN
816 JumpToIt( uwListItem, currscr );
818 // close jump window and exit...
819 fTerminated = TRUE;
820 break;
821 case 0x45:
822 // ESC
823 if ( fAlt == FALSE && fShift == FALSE )
825 fTerminated = TRUE;
827 break;
828 case 0x4C:
829 // Up cursor
830 if ( uwListItem <= 0 ) break;
832 if ( fShift == TRUE )
834 for ( swnode = (struct SWNode *)MG.list.lh_Head, i = 0;
835 ( ( i < uwListItem-1 ) && ( swnode->node.ln_Succ ) );
836 i++, swnode = (struct SWNode *)swnode->node.ln_Succ );
837 for ( fFound = FALSE; swnode->node.ln_Pred; i--, swnode = (struct SWNode *)swnode->node.ln_Pred )
839 if ( swnode->wdw == NULL )
841 fFound = TRUE;
842 break;
845 if ( fFound )
847 uwListItem = i;
848 GT_SetGadgetAttrs( MG.listview, mywin, NULL, GTLV_Selected , uwListItem,
849 GTLV_MakeVisible, uwListItem,
850 ( GadToolsBase->lib_Version < 39 ? GTLV_Top : TAG_SKIP ), uwListItem,
851 TAG_DONE, TAG_DONE );
854 else if ( fAlt == TRUE )
856 uwListItem = 0;
857 GT_SetGadgetAttrs( MG.listview, mywin, NULL, GTLV_Selected , uwListItem,
858 GTLV_MakeVisible, uwListItem,
859 ( GadToolsBase->lib_Version < 39 ? GTLV_Top : TAG_SKIP ), uwListItem,
860 TAG_DONE, TAG_DONE );
862 else
864 uwListItem = ( uwListItem-1 >= 0 ? uwListItem-1 : 0 );
865 GT_SetGadgetAttrs( MG.listview, mywin, NULL, GTLV_Selected , uwListItem,
866 GTLV_MakeVisible, uwListItem,
867 ( GadToolsBase->lib_Version < 39 ? GTLV_Top : TAG_SKIP ), uwListItem,
868 TAG_DONE, TAG_DONE );
870 break;
871 case 0x4D:
872 // Down cursor
873 if ( uwListItem >= MG.uwNumItems-1 ) break;
875 if ( fShift == TRUE )
877 for ( swnode = (struct SWNode *)MG.list.lh_Head, i = 0;
878 ( ( i < uwListItem+1 ) && ( swnode->node.ln_Succ ) );
879 i++, swnode = (struct SWNode *)swnode->node.ln_Succ );
880 for ( fFound = FALSE; swnode->node.ln_Succ; i++, swnode = (struct SWNode *)swnode->node.ln_Succ )
882 if ( swnode->wdw == NULL )
884 fFound = TRUE;
885 break;
888 if ( fFound )
890 uwListItem = i;
891 GT_SetGadgetAttrs( MG.listview, mywin, NULL, GTLV_Selected , uwListItem,
892 GTLV_MakeVisible, uwListItem,
893 ( GadToolsBase->lib_Version < 39 ? GTLV_Top : TAG_SKIP ), uwListItem,
894 TAG_DONE, TAG_DONE );
897 else if ( fAlt == TRUE )
899 uwListItem = MG.uwNumItems - 1;
900 GT_SetGadgetAttrs( MG.listview, mywin, NULL, GTLV_Selected , uwListItem,
901 GTLV_MakeVisible, uwListItem,
902 ( GadToolsBase->lib_Version < 39 ? GTLV_Top : TAG_SKIP ), uwListItem,
903 TAG_DONE, TAG_DONE );
905 else
907 uwListItem = ( uwListItem+1 < MG.uwNumItems ? uwListItem+1 : MG.uwNumItems-1 );
908 GT_SetGadgetAttrs( MG.listview, mywin, NULL, GTLV_Selected , uwListItem,
909 GTLV_MakeVisible, uwListItem,
910 ( GadToolsBase->lib_Version < 39 ? GTLV_Top : TAG_SKIP ), uwListItem,
911 TAG_DONE, TAG_DONE );
913 break;
915 break;
917 case MENUPICK:
918 while ( ( imsgCode != MENUNULL ) && ( !fTerminated ) )
920 mitem = ItemAddress( menu, imsgCode );
921 switch( (IPTR)GTMENUITEM_USERDATA( mitem ) )
923 case ID_MENU_HIDE:
924 fTerminated = TRUE;
925 break;
926 case ID_MENU_QUIT:
927 fTerminated = TRUE;
928 fQuitCX = TRUE;
929 break;
930 case ID_MENU_SAVESETTINGS:
931 // save settings here -- how replace existing tool types
932 break;
934 imsgCode = mitem->NextSelect;
936 break;
938 case GADGETUP:
939 if ( gad->GadgetID == GAD_LISTVIEW )
941 uwListItem = imsgCode;
942 if ( ( MG.sJumpClicks == 1 ) ||
943 ( ( MG.sJumpClicks == 2 ) &&
944 DoubleClick( ulSeconds, ulMicros, imsgSeconds, imsgMicros ) &&
945 ( imsgCode == uwCode ) ) )
947 JumpToIt( imsgCode, currscr );
950 // close jump window and exit...
951 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
952 fTerminated = TRUE;
954 ulSeconds = imsgSeconds;
955 ulMicros = imsgMicros;
956 uwCode = imsgCode;
958 break;
959 case CLOSEWINDOW:
960 case IDCMP_INACTIVEWINDOW:
961 fTerminated = TRUE;
962 break;
963 case REFRESHWINDOW:
964 GT_BeginRefresh( mywin );
965 GT_EndRefresh( mywin, TRUE );
966 break;
972 // Close the window and cleanup
973 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
974 endrtn:
975 if ( mywin )
977 ClearMenuStrip( mywin );
978 CloseWindow( mywin );
979 mywin = NULL;
981 if ( vi )
983 FreeVisualInfo( vi );
984 vi = NULL;
986 if ( glist )
988 FreeGadgets( glist );
989 glist = NULL;
993 // Send back return code
994 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
995 return( fQuitCX );
998 struct Gadget *CreateAllGadgets( struct Gadget **glistptr, void *vi,
999 WORD wLeft, WORD topborder, WORD wWidth, WORD wHeight )
1001 struct NewGadget ng;
1002 struct Gadget *gad;
1005 memset( &ng, 0, sizeof( struct NewGadget ) );
1007 gad = CreateContext(glistptr);
1009 ng.ng_LeftEdge = wLeft + 1;
1010 ng.ng_TopEdge = topborder + 1;
1011 ng.ng_Width = wWidth - 2;
1012 ng.ng_Height = wHeight;
1013 ng.ng_TextAttr = NULL;
1014 ng.ng_VisualInfo = vi;
1015 ng.ng_GadgetID = GAD_LISTVIEW;
1016 ng.ng_Flags = 0;
1017 MG.listview = gad = CreateGadget( LISTVIEW_KIND, gad, &ng,
1018 GTLV_Labels , &MG.list,
1019 GTLV_Selected , 0,
1020 GTLV_ShowSelected, NULL,
1021 LAYOUTA_Spacing , 2,
1022 TAG_DONE );
1024 return( gad );