home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d9xx / d998 / screenselect.lha / ScreenSelect / StickySelect / StickySelect.c < prev    next >
C/C++ Source or Header  |  1994-04-05  |  11KB  |  462 lines

  1. /** ** *** MakeRev Header *** **
  2. **
  3. **    ** StickySelect - Selector for ScreenSelect. **
  4. **
  5. **    Copyright © 1993,1994  Markus Aalto
  6. **
  7. **    Creation date: 27-Jul-93
  8. **
  9. **    ------------------------------------------------------------------
  10. **    $Filename: StickySelect.c $
  11. **    $Revision: 1.1 $
  12. **    $Date: 22-Jan-94 $
  13. **
  14. **    $Author: Markus_Aalto $
  15. **    $Comment: Freely Distributable. Use to create your own interfaces. $
  16. **
  17. */
  18.  
  19.  
  20. #include "StickySelect.h"
  21.  
  22. extern UBYTE version[] = "$VER: StickySelect 1.1 (30-Jan-94)";
  23.  
  24. void CleanUp( void );
  25. void ProcessSignals( void );
  26. void RemoveSemaphoreHook( void );
  27. BOOL InstallSemaphoreHook( void );
  28. BOOL OpenInterface( void );
  29. BOOL UpdateList( void );
  30. void SignalScreenSelect( ULONG code );
  31. BOOL ReadParameters( void );
  32.  
  33. extern struct IntuitionBase *IntuitionBase;
  34. extern struct GfxBase *GfxBase;
  35. extern struct Library *GadToolsBase;
  36. extern struct Library *UtilitiesBase;
  37.  
  38. struct List         screenname_list;
  39. struct Window         *sticky_window = NULL;
  40. struct Gadget        *listview;
  41. struct Gadget        *gadg_context = NULL;
  42. LONG                  update_signal = -1;
  43. SignalUpdateNode    *update_node = NULL;
  44. LONG                TopX = 0, TopY = 0;
  45. LONG                Width = 150, Height = 100;
  46. char                *pubscreen_name = NULL;
  47. APTR                vi = NULL;
  48. struct TextAttr        my_font;
  49. ULONG                ARGS[ARG_COUNT] = { NULL, NULL, NULL, NULL, NULL };
  50.  
  51. int main( int argc, char **argv )
  52. {
  53.  
  54.     NewList(&screenname_list);
  55.  
  56.  
  57.     if( ReadParameters() ) {
  58.         if( InstallSemaphoreHook() ) {
  59.             if( UpdateList() ) {
  60.  
  61.                 ProcessSignals();
  62.             }
  63.  
  64.             RemoveSemaphoreHook();
  65.         }
  66.     }
  67.  
  68.     CleanUp();
  69.  
  70.        return(0);
  71. }
  72.  
  73.  
  74. /* Clean up most of the allocated stuff. */
  75. void CleanUp()
  76. {
  77.     struct Node *screennode;
  78.  
  79.     if( sticky_window ) CloseWindow( sticky_window );
  80.  
  81.     if( gadg_context ) FreeGadgets(gadg_context);
  82.  
  83.     if( vi ) FreeVisualInfo( vi );
  84.  
  85.     if( pubscreen_name ) FreeVec((void *)pubscreen_name);
  86.  
  87.     if( update_node ) FreeVec((void *)update_node);
  88.  
  89.     if( update_signal != -1 ) FreeSignal( update_signal );
  90.  
  91.     while( screennode = RemHead(&screenname_list) ) {
  92.         if( screennode->ln_Name ) FreeVec((void *)screennode->ln_Name);
  93.         FreeVec((void *)screennode);
  94.     }
  95. }
  96.  
  97.  
  98. /* Install a SignalUpdateNode to TaskList in "ScreenSelect" public semaphore.
  99. ** And infrom ScreenSelect about it. */
  100. BOOL InstallSemaphoreHook()
  101. {
  102.     BOOL retval = FALSE;
  103.     UpdateDataSemaphore *uds;
  104.  
  105.     update_signal = AllocSignal(-1);
  106.     if( update_signal != -1 ) {
  107.         update_node = (SignalUpdateNode *)AllocVec(sizeof(SignalUpdateNode),
  108.                 MEMF_PUBLIC|MEMF_CLEAR);
  109.         if( update_node ) {
  110.             update_node->su_Task = FindTask(NULL);
  111.             update_node->su_Signal = update_signal;
  112.  
  113.             Forbid();
  114.             if( uds = (UpdateDataSemaphore *)FindSemaphore(SEMAPHORE_NAME) ) {
  115.                   ObtainSemaphore( (struct SignalSemaphore *)uds );
  116.  
  117.                 Permit();
  118.  
  119.                 AddTail(&uds->ud_TaskList, update_node);
  120.  
  121.                 if( uds->ud_ScreenSelectTask ) {
  122.                     /* Notify about new client. */
  123.                      uds->ud_code = CODE_NEWCLIENT;
  124.                      Signal(uds->ud_ScreenSelectTask,
  125.                              1 << uds->ud_ScreenSelectSignal);
  126.                 }
  127.  
  128.                 ReleaseSemaphore( (struct SignalSemaphore *)uds );
  129.  
  130.                 retval = TRUE;
  131.             }
  132.             else Permit();
  133.         }
  134.     }
  135.  
  136.     return(retval);
  137. }
  138.  
  139.  
  140. /* Release the SignalUpdateNode from the ScreenSelect sempahore. */
  141. void RemoveSemaphoreHook()
  142. {
  143.     UpdateDataSemaphore *uds;
  144.  
  145.     Forbid();
  146.     if( uds = (UpdateDataSemaphore *)FindSemaphore(SEMAPHORE_NAME) ) {
  147.         ObtainSemaphore( (struct SignalSemaphore *)uds );
  148.         Permit();
  149.  
  150.         Remove(update_node);
  151.  
  152.         ReleaseSemaphore( (struct SignalSemaphore *)uds );
  153.     }
  154.     else Permit();
  155. }
  156.  
  157.  
  158. void ProcessSignals()
  159. {
  160.     ULONG signal, signalmask, stickymask;
  161.     BOOL END;
  162.     ULONG class;
  163.     UWORD code;
  164.     ULONG old_secs = 0, old_mics = 0;
  165.     struct IntuiMessage *imsg;
  166.  
  167.  
  168.     END = OpenInterface();
  169.  
  170.     while( !END ) {
  171.         stickymask = (1 << sticky_window->UserPort->mp_SigBit);
  172.            signalmask = (1 << update_signal) | SIGBREAKF_CTRL_C | stickymask;
  173.  
  174.            signal = Wait( signalmask );
  175.  
  176.            if( signal & SIGBREAKF_CTRL_C ) {
  177.                END = TRUE;
  178.            }
  179.            else if( signal & (1 << update_signal) ) {
  180.             GT_SetGadgetAttrs(listview, sticky_window, NULL,
  181.                     GTLV_Labels,    ~0,
  182.                     TAG_END);
  183.  
  184.             END = !UpdateList();
  185.  
  186.             GT_SetGadgetAttrs(listview, sticky_window, NULL,
  187.                     GTLV_Labels,    &screenname_list,
  188.                     TAG_END);
  189.            }
  190.            else if( signal & stickymask ) {
  191.             while( (!END) && (imsg = GT_GetIMsg(sticky_window->UserPort)) ) {
  192.                 class = imsg->Class;
  193.                 code = imsg->Code;
  194.  
  195.                 switch(class)
  196.                 {
  197.                 case IDCMP_CLOSEWINDOW:
  198.                     END = TRUE;
  199.                     break;
  200.                 case IDCMP_REFRESHWINDOW:
  201.                     GT_BeginRefresh(sticky_window);
  202.                     GT_EndRefresh(sticky_window,TRUE);
  203.                     break;
  204.                 case IDCMP_GADGETUP:
  205.                     if( DoubleClick( old_secs, old_mics, imsg->Seconds,
  206.                             imsg->Micros) ) {
  207.                         SignalScreenSelect(code);
  208.                     }
  209.                     old_secs = imsg->Seconds;
  210.                     old_mics = imsg->Micros;
  211.                     break;
  212.                 }
  213.  
  214.                 GT_ReplyIMsg(imsg);
  215.                }
  216.            }
  217.     }
  218. }
  219.  
  220. BOOL OpenInterface()
  221. {
  222.     BOOL END = TRUE;
  223.     struct Screen *pub_screen;
  224.     struct NewGadget ng;
  225.     struct Gadget *gad;
  226.     struct DrawInfo *dri;
  227.  
  228.     if( pub_screen = LockPubScreen(pubscreen_name) ) {
  229.         dri = GetScreenDrawInfo(pub_screen);
  230.         if( dri ) {
  231.             sticky_window = OpenWindowTags(NULL,
  232.                 WA_Left,            TopX,
  233.                 WA_Top,                TopY,
  234.                 WA_Width,            Width,
  235.                 WA_Height,            Height,
  236.                 WA_IDCMP,            MY_IDCMP_FLAGS,
  237.                 WA_Title,            "StickySelect",
  238.                 WA_ScreenTitle,        "StickySelect 1.1 © (1993) by Markus Aalto",
  239.                 WA_PubScreen,        pub_screen,
  240.                 WA_DragBar,            TRUE,
  241.                 WA_DepthGadget,        TRUE,
  242.                 WA_CloseGadget,        TRUE,
  243.                 WA_SimpleRefresh,    TRUE,
  244.                 WA_AutoAdjust,        TRUE,
  245.                 WA_NewLookMenus,    TRUE,
  246.                 TAG_END);
  247.  
  248.             if( sticky_window ) {
  249.                 vi = GetVisualInfo( pub_screen, TAG_END);
  250.  
  251.                 if( vi ) {
  252.                     SetFont(sticky_window->RPort, dri->dri_Font);
  253.                     AskFont(sticky_window->RPort, &my_font);
  254.  
  255.                     gad = CreateContext(&gadg_context);
  256.  
  257.                     ng.ng_LeftEdge = INTERWIDTH + sticky_window->BorderLeft;
  258.                     ng.ng_TopEdge = INTERHEIGHT + sticky_window->BorderTop;
  259.                     ng.ng_Width = sticky_window->Width - (2*INTERWIDTH
  260.                             + sticky_window->BorderLeft + sticky_window->BorderRight);
  261.                     ng.ng_Height = sticky_window->Height - (2*INTERHEIGHT
  262.                             + sticky_window->BorderTop + sticky_window->BorderBottom);
  263.                     ng.ng_GadgetText = NULL;
  264.                     ng.ng_TextAttr = &my_font;
  265.                     ng.ng_Flags = NG_HIGHLABEL;
  266.                     ng.ng_GadgetID = 0;
  267.                     ng.ng_UserData = NULL;
  268.                     ng.ng_VisualInfo = vi;
  269.  
  270.                     listview = gad = CreateGadget(LISTVIEW_KIND, gad, &ng,
  271.                             GTLV_Labels,        &screenname_list,
  272.                             GTLV_ShowSelected,     NULL,
  273.                             GTLV_Selected,        0,
  274.                             TAG_END);
  275.  
  276.                     if( gad == NULL ) {
  277.                         FreeGadgets(gadg_context);
  278.                     }
  279.                     else {
  280.                         END = FALSE;
  281.                         AddGList(sticky_window, gadg_context, -1, -1, NULL);
  282.                         RefreshGList(gadg_context, sticky_window, NULL, -1);
  283.                         GT_RefreshWindow(sticky_window,NULL);
  284.                     }
  285.                 }
  286.             }
  287.  
  288.             FreeScreenDrawInfo(pub_screen, dri);
  289.         }
  290.  
  291.         UnlockPubScreen(NULL,pub_screen);
  292.     }
  293.  
  294.     return(END);
  295. }
  296.  
  297.  
  298. /* Recreate the ScreenList for StickySelect. */
  299. BOOL UpdateList()
  300. {
  301.     struct Node *screennode;
  302.     struct Node *namenode;
  303.     UpdateDataSemaphore *uds;
  304.     BOOL fine = TRUE;
  305.  
  306.     while( screennode = RemHead(&screenname_list) ) {
  307.         if( screennode->ln_Name ) FreeVec((void *)screennode->ln_Name);
  308.         FreeVec((void *)screennode);
  309.     }
  310.  
  311.     Forbid();
  312.     if( uds = (UpdateDataSemaphore *)FindSemaphore(SEMAPHORE_NAME) ) {
  313.         ObtainSemaphoreShared( (struct SignalSemaphore *)uds );
  314.  
  315.         Permit();
  316.  
  317.         for(namenode = uds->ud_NameList.lh_Head; (namenode->ln_Succ) && fine;
  318.                     namenode = namenode->ln_Succ) {
  319.             screennode = (struct Node *)AllocVec(sizeof(struct Node),
  320.                     MEMF_ANY|MEMF_CLEAR);
  321.             if( screennode ) {
  322.                 screennode->ln_Name = (UBYTE *)AllocVec(
  323.                         1 + strlen(namenode->ln_Name), MEMF_ANY);
  324.                 if( screennode->ln_Name ) {
  325.                     strcpy( screennode->ln_Name, namenode->ln_Name );
  326.                     AddTail(&screenname_list,screennode);
  327.                 }
  328.                 else {
  329.                     fine = FALSE;
  330.                     FreeVec((void *)screennode);
  331.                 }
  332.             }
  333.             else fine = FALSE;
  334.         }
  335.  
  336.         ReleaseSemaphore( (struct SignalSemaphore *)uds );
  337.     }
  338.     else Permit();
  339.  
  340.     return(fine);
  341. }
  342.  
  343. /* Signal ScreenSelect that User have selected new item. */
  344. void SignalScreenSelect( ULONG code )
  345. {
  346.     UpdateDataSemaphore *uds;
  347.  
  348.     Forbid();
  349.     if( uds = (UpdateDataSemaphore *)FindSemaphore(SEMAPHORE_NAME) ) {
  350.         ObtainSemaphore( (struct SignalSemaphore *)uds );
  351.         Permit();
  352.  
  353.          /* Check if semaphore is active. This means that ScreenSelect
  354.          ** is around and waiting. */
  355.          if( uds->ud_ScreenSelectTask ) {
  356.              /* Notify about new selection. */
  357.             uds->ud_code = code;
  358.             Signal(uds->ud_ScreenSelectTask, 1 << uds->ud_ScreenSelectSignal);
  359.         }
  360.  
  361.         ReleaseSemaphore( (struct SignalSemaphore *)uds );
  362.     }
  363.     else Permit();
  364. }
  365.  
  366.  
  367. BOOL ReadParameters()
  368. {
  369.     UBYTE *TTString;
  370.     BOOL retval = TRUE;
  371.  
  372.     if( Cli() == NULL ) {
  373.         extern struct WBStartup *_WBenchMsg;
  374.         struct WBStartup *wb_msg;
  375.         struct WBArg *wb_arg;
  376.         BPTR old_dir;
  377.         struct DiskObject *disk_obj;
  378.         char **tools;
  379.  
  380.         wb_msg = _WBenchMsg;
  381.         wb_arg = wb_msg->sm_ArgList;
  382.  
  383.         if(wb_arg->wa_Lock) {
  384.             old_dir = CurrentDir(wb_arg->wa_Lock);
  385.  
  386.             disk_obj = GetDiskObjectNew(wb_arg->wa_Name);
  387.             if( disk_obj ) {
  388.                 tools = (char **)disk_obj->do_ToolTypes;
  389.  
  390.                 TTString = FindToolType(tools,"PUBSCREEN");
  391.                 if( TTString ) {
  392.                     pubscreen_name = AllocVec(1+ strlen(TTString),
  393.                         MEMF_ANY);
  394.                     if( pubscreen_name ) {
  395.                         strcpy(pubscreen_name,TTString);
  396.                     }
  397.                     else retval = FALSE;
  398.                 }
  399.  
  400.                 TTString = FindToolType(tools,"LEFT");
  401.                 if( TTString ) {
  402.                     StrToLong(TTString,&TopX);
  403.                 }
  404.  
  405.                 TTString = FindToolType(tools,"TOP");
  406.                 if( TTString ) {
  407.                     StrToLong(TTString,&TopY);
  408.                 }
  409.  
  410.                 TTString = FindToolType(tools,"WIDTH");
  411.                 if( TTString ) {
  412.                     if( StrToLong(TTString,&Width) == -1 ) Width = 150;
  413.                 }
  414.  
  415.                 TTString = FindToolType(tools,"HEIGHT");
  416.                 if( TTString ) {
  417.                     if( StrToLong(TTString,&Height) == -1 ) Height = 100;
  418.                 }
  419.  
  420.                 FreeDiskObject(disk_obj);
  421.             }
  422.             (void)CurrentDir(old_dir);
  423.         }
  424.  
  425.     }
  426.     else {
  427.         struct RDArgs *my_rda;
  428.  
  429.         my_rda = ReadArgs(TEMPLATE,(LONG *)ARGS,NULL);
  430.         if( my_rda ) {
  431.             if(ARGS[ARG_PUBSCREEN] != 0) {
  432.                 TTString = (char *)ARGS[ARG_PUBSCREEN];
  433.                 pubscreen_name = (char *)AllocVec(1+strlen(TTString),MEMF_ANY);
  434.                 if(pubscreen_name) {
  435.                     strcpy(pubscreen_name,TTString);
  436.                 }
  437.                 else retval = FALSE;
  438.             }
  439.  
  440.             if(ARGS[ARG_LEFT] != 0) {
  441.                 TopX = *(ULONG *)ARGS[ARG_LEFT];
  442.             }
  443.  
  444.             if(ARGS[ARG_TOP] != 0) {
  445.                 TopY = *(ULONG *)ARGS[ARG_TOP];
  446.             }
  447.  
  448.             if(ARGS[ARG_WIDTH] != 0) {
  449.                 Width = *(ULONG *)ARGS[ARG_WIDTH];
  450.             }
  451.  
  452.             if(ARGS[ARG_HEIGHT] != 0) {
  453.                 Height = *(ULONG *)ARGS[ARG_HEIGHT];
  454.             }
  455.  
  456.             FreeArgs(my_rda);
  457.         }
  458.     }
  459.  
  460.     return(retval);
  461. }
  462.