home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / desklib / examples / DeskLib / Examples / Widget5 / !Widget5 / c / ProcessWin < prev    next >
Encoding:
Text File  |  1995-05-05  |  31.1 KB  |  1,294 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *        File: ProcessWin.c                                            *
  4.  *                                                                      *
  5.  *     Purpose: Provides user interface to image processing functions   *
  6.  *                                                                      *
  7.  ************************************************************************/
  8.  
  9. #include "DeskLib:WimpSWIs.h"          /* Low-level WIMP commands         */
  10. #include "DeskLib:Window.h"            /* Window handling automation      */
  11. #include "DeskLib:Core.h"              /* usefull core functions          */
  12. #include "DeskLib:Error.h"             /* Error despatcher                */
  13. #include "DeskLib:Event.h"             /* Event despatcher                */
  14. #include "DeskLib:EventMsg.h"          /* Wimp Message event dispatcher   */
  15. #include "DeskLib:File.h"              /* Low level file handling         */
  16. #include "DeskLib:Msgs.h"              /* Message translation code        */
  17. #include "DeskLib:Resource.h"          /* Handles finding resource files  */
  18. #include "DeskLib:Sound.h"             /* Beep!                           */
  19. #include "DeskLib:Template.h"          /* Template loading and caching    */
  20. #include "DeskLib:Icon.h"              /* Icon handling automation        */
  21. #include "DeskLib:Screen.h"            /* Caching screen info             */
  22. #include "DeskLib:Sprite.h"            /* Sprite handling routines        */
  23. #include "DeskLib:File.h"              /* OS file IO                      */
  24. #include "DeskLib:KeyCodes.h"          /* Codes for wimp returned keys    */
  25. #include "DeskLib:Hourglass.h"         /* control hourglass               */
  26.  
  27. #include "SpriteWin.h"
  28. #include "CheckBanks.h"
  29. #include "Process.h"
  30. #include "Filter.h"
  31. #include "MixWin.h"
  32. #include "GreyEdWin.h"
  33. #include "Misc.h"
  34.  
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37.  
  38. extern window_handle db;
  39.  
  40. typedef struct {
  41.    iconrange_block source2range;
  42.    iconrange_block destrange;
  43. } common2_block;
  44.  
  45. /* definitions for 'process' */
  46. #define process_COPY        0
  47. #define process_ADD         1
  48. #define process_AVERAGE     2
  49. #define process_MIX         3
  50. #define process_CONVOLUTION 4
  51. #define process_MEDIAN      5
  52. #define process_GREYEDIT    6
  53. #define process_SCALE       7
  54.  
  55.  
  56. /* icon block for dest images */
  57. #define image_MIN 8
  58. #define image_MAX 13
  59.  
  60. /* icon blocks for twin source windows */
  61. #define sourceimage2_MIN 8
  62. #define sourceimage2_MAX 13
  63. #define desttwinimage_MIN 16
  64. #define desttwinimage_MAX 21
  65.  
  66. /* icon block for size radios in scale window */
  67. #define size_MIN 16
  68. #define size_MAX 21
  69.  
  70. /* default values for scale window */
  71. static wimp_point tofit;
  72. static sprite_scalefactors custom;
  73. static int selectedsize;
  74.  
  75. void NoMemProc(void);
  76. void InvAnchor(void);
  77.  
  78. void open_copy(int sourceimage);
  79. void open_add(int sourceimage);
  80. void open_average(int sourceimage);
  81. void open_convolution(int sourceimage);
  82. void open_median(int sourceimage);
  83. void open_greyedit(int sourceimage);
  84. void open_scale(int sourceimage);
  85. void open_mix(int sourceimage);
  86.  
  87. void prepare_processwin(iconrange_block *range);
  88.  
  89. static BOOL Click_common(event_pollblock *event, void *reference);
  90. static BOOL Click_common2(event_pollblock *event, void *reference);
  91. static BOOL Click_convolution(event_pollblock *event, void *reference);
  92. static BOOL Click_scale(event_pollblock *event, void *reference);
  93.  
  94. static BOOL Key_convolution(event_pollblock *event, void *reference);
  95. static BOOL Key_scale(event_pollblock *event, void *reference);
  96.  
  97. static void close_copy(BOOL ok, BOOL keepopen, iconrange_block *range);
  98. static void close_add(BOOL ok, BOOL keepopen, iconrange_block *range);
  99. static void close_average(BOOL ok, BOOL keepopen, iconrange_block *range);
  100. static void close_convolution(BOOL ok, BOOL keepopen, iconrange_block *range);
  101. static void close_median(BOOL ok, BOOL keepopen, iconrange_block *range);
  102. static void close_greyedit(BOOL ok, BOOL keepopen, iconrange_block *range);
  103. static void close_scale(BOOL ok, BOOL keepopen, iconrange_block *range);
  104. static void close_mix(BOOL ok, BOOL keepopen, common2_block *block);
  105.  
  106. static BOOL Close_window(event_pollblock *event, void *reference);
  107. static BOOL Close_window2(event_pollblock *event, void *reference);
  108.  
  109. static BOOL Null_closecommon2(event_pollblock *event, void *reference);
  110.  
  111. /******************************************************************************
  112.  *                            extern routines                                 *
  113.  ******************************************************************************/
  114.  
  115. extern void ProcessWin_Init(void)
  116. {
  117.  /*
  118.   * initialisation to be done on startup
  119.   */
  120.  
  121.  /*
  122.   * setup default vaules for scale window
  123.   */
  124.   tofit.x = 1280;
  125.   tofit.y = 1024;
  126.  
  127.   custom.multiply.x = 1;
  128.   custom.divide.x = 1;
  129.   custom.multiply.y = 1;
  130.   custom.divide.y = 2;
  131.  
  132.   selectedsize = 17;
  133.  
  134. }
  135.  
  136. /******************************************************************************/
  137.  
  138. extern void ProcessWin_Start(int process, int sourceimage)
  139. {
  140.  
  141.   switch(process)
  142.   {
  143.     case process_COPY:
  144.       open_copy(sourceimage);
  145.       break;
  146.  
  147.     case process_ADD:
  148.       open_add(sourceimage);
  149.       break;
  150.  
  151.     case process_AVERAGE:
  152.       open_average(sourceimage);
  153.       break;
  154.  
  155.     case process_MIX:
  156.       open_mix(sourceimage);
  157.       break;
  158.  
  159.     case process_CONVOLUTION:
  160.       open_convolution(sourceimage);
  161.       break;
  162.  
  163.     case process_MEDIAN:
  164.       open_median(sourceimage);
  165.       break;
  166.  
  167.     case process_GREYEDIT:
  168.       open_greyedit(sourceimage);
  169.       break;
  170.       
  171.     case process_SCALE:
  172.       open_scale(sourceimage);
  173.       break;
  174.  
  175.     default:
  176.       Error_Report(1, "sel %i   image %i", process, sourceimage);
  177.       break;
  178.   }
  179.  
  180. }
  181.  
  182. /******************************************************************************
  183.  *                              Click handlers                                *
  184.  ******************************************************************************/
  185.  
  186. static BOOL Click_common2(event_pollblock *event, void *reference)
  187. {
  188.   common2_block *block = reference;
  189.  
  190.   switch(event->data.mouse.icon)
  191.   {
  192.     
  193.     case 22: /* Cancel */
  194.        (block->source2range.close)(FALSE, FALSE, block);
  195.        break;
  196.  
  197.     case 23: /* Action */
  198.        (block->source2range.close)(TRUE, event->data.mouse.button.data.adjust, block);
  199.        break;
  200.       
  201.   }
  202.   return(TRUE);
  203. }
  204.  
  205. /******************************************************************************/
  206.  
  207. static BOOL Click_common(event_pollblock *event, void *reference)
  208. {
  209.   iconrange_block *range = reference;
  210.  
  211.   switch(event->data.mouse.icon)
  212.   {
  213.     
  214.     case 14: /* Cancel */
  215.        (range->close)(FALSE, FALSE, range);
  216.        break;
  217.  
  218.     case 15: /* Action */
  219.        (range->close)(TRUE, event->data.mouse.button.data.adjust, range);
  220.        break;
  221.       
  222.   }
  223.   return(TRUE);
  224. }
  225.  
  226. /******************************************************************************/
  227.  
  228. static BOOL Click_convolution(event_pollblock *event, void *reference)
  229. {
  230.   iconrange_block *range = reference;
  231.  
  232.   switch(event->data.mouse.icon)
  233.   {
  234.     
  235.     case 32: /* Cancel */
  236.        close_convolution(FALSE, FALSE, range);
  237.        break;
  238.  
  239.     case 33: /* Filter */
  240.        close_convolution(TRUE, event->data.mouse.button.data.adjust, range);
  241.        break;
  242.       
  243.   }
  244.   return(TRUE);
  245. }
  246.  
  247. /******************************************************************************/
  248.  
  249. static BOOL Click_scale(event_pollblock *event, void *reference)
  250. {
  251.   iconrange_block *range = reference;
  252.  
  253.   if( (event->data.mouse.icon >= size_MIN) && (event->data.mouse.icon <= size_MAX) ){
  254.      Icon_Select(range->window, event->data.mouse.icon);
  255.      return(TRUE);
  256.   }
  257.  
  258.   switch(event->data.mouse.icon)
  259.   {
  260.     
  261.     case 31: /* Cancel */
  262.        close_scale(FALSE, FALSE, range);
  263.        break;
  264.  
  265.     case 32: /* Scale */
  266.        close_scale(TRUE, event->data.mouse.button.data.adjust, range);
  267.        break;
  268.       
  269.   }
  270.   return(TRUE);
  271. }
  272.  
  273. /******************************************************************************
  274.  *                             keypress handlers                              *
  275.  ******************************************************************************/
  276.  
  277. static BOOL Key_convolution(event_pollblock *event, void *reference)
  278. {
  279.   iconrange_block *range = reference;
  280.  
  281.   if(event->data.key.caret.icon == 31){
  282.  
  283.      if(event->data.key.code == keycode_RETURN){
  284.         close_convolution(TRUE, FALSE, range);
  285.         return(TRUE);
  286.      }
  287.  
  288.   }
  289.  
  290.   return(FALSE);
  291.  
  292. }
  293.  
  294. /******************************************************************************/
  295.  
  296. static BOOL Key_scale(event_pollblock *event, void *reference)
  297. {
  298.   iconrange_block *range = reference;
  299.  
  300.   if(event->data.key.caret.icon == 30){
  301.  
  302.      if(event->data.key.code == keycode_RETURN){
  303.         close_scale(TRUE, FALSE, range);
  304.         return(TRUE);
  305.      }
  306.  
  307.   }
  308.  
  309.   return(FALSE);
  310.  
  311. }
  312.  
  313. /******************************************************************************
  314.  *                                open handlers                               *
  315.  ******************************************************************************/
  316.  
  317. void prepare_processwin(iconrange_block *range)
  318. {
  319.  /*
  320.   * set text in window and start destination bank scanning
  321.   */
  322.   wimp_point *sourcesize;
  323.   char text[20];
  324.  
  325.  /*
  326.   * imagebank number
  327.   */
  328.   Msgs_Lookup("txt.imbank", text, 19);
  329.   Icon_printf(range->window, 2, "%s %i", text, range->sourceimage);
  330.  
  331.  /*
  332.   * image bank size
  333.   */
  334.   sourcesize = SpriteWin_GetSize(range->sourceimage);
  335.   Icon_SetInteger(range->window, 3, sourcesize->x);
  336.   Icon_SetInteger(range->window, 5, sourcesize->y);
  337.  
  338.  /*
  339.   * initialise the available banks and start the scanning procedure
  340.   */
  341.   range->size.x = sourcesize->x;
  342.   range->size.y = sourcesize->y;
  343.   range->min = image_MIN;
  344.   range->max = image_MAX;
  345.   CheckBanks_InstallScanDestination(range);
  346.  
  347. }
  348.  
  349. /******************************************************************************/
  350.  
  351. void prepare_processwin2(common2_block *block)
  352. {
  353.  /*
  354.   * set text in window and start destination bank scanning
  355.   */
  356.   wimp_point *sourcesize;
  357.   char text[20];
  358.  
  359.  /*
  360.   * imagebank number
  361.   */
  362.   Msgs_Lookup("txt.imbank", text, 19);
  363.   Icon_printf(block->destrange.window, 2, "%s %i", text, block->destrange.sourceimage);
  364.  
  365.  /*
  366.   * image bank size
  367.   */
  368.   sourcesize = SpriteWin_GetSize(block->destrange.sourceimage);
  369.   Icon_SetInteger(block->destrange.window, 3, sourcesize->x);
  370.   Icon_SetInteger(block->destrange.window, 5, sourcesize->y);
  371.  
  372.  /*
  373.   * initialise the available banks and start the scanning procedure
  374.   */
  375.   block->source2range.size.x = sourcesize->x;
  376.   block->source2range.size.y = sourcesize->y;
  377.   block->source2range.min = sourceimage2_MIN;
  378.   block->source2range.max = sourceimage2_MAX;
  379.   CheckBanks_InstallScanSource(&(block->source2range));
  380.  
  381.   block->destrange.size.x = sourcesize->x;
  382.   block->destrange.size.y = sourcesize->y;
  383.   block->destrange.min = desttwinimage_MIN;
  384.   block->destrange.max = desttwinimage_MAX;
  385.   CheckBanks_InstallScanDestination(&(block->destrange));
  386.  
  387.   Event_Claim(event_NULL, event_ANY, event_ANY, Null_closecommon2, block);
  388.  
  389. }
  390.  
  391. /******************************************************************************/
  392.  
  393. void open_copy(int sourceimage)
  394. {
  395.  /*
  396.   * open copy image window on screen
  397.   */
  398.   iconrange_block *range;
  399.   char text[40];
  400.  
  401.  /*
  402.   * allocate memory for range info block and return if fails
  403.   */
  404.   range = malloc(sizeof(iconrange_block));
  405.   if(range == NULL){
  406.      NoMemProc();
  407.      return;
  408.   }
  409.  
  410.  /*
  411.   * create the window
  412.   */
  413.   range->window = Window_Create("Common", template_TITLEMIN);
  414.   Msgs_Lookup("txt.copyt", text, 39);
  415.   Window_SetTitle(range->window, text);
  416.   Msgs_Lookup("txt.copy", text, 39);
  417.   Icon_SetText(range->window, 15, text);
  418.  
  419.  /*
  420.   * set routine that closes window when source bank is closed
  421.   */
  422.   range->sourceimage = sourceimage;
  423.   range->close = (closewindow_routine)close_copy;
  424.  
  425.  /*
  426.   * initialise source and destination image frames
  427.   */
  428.   prepare_processwin(range);
  429.  
  430.  /*
  431.   * install event handlers
  432.   */
  433.   Event_Claim(event_CLICK, range->window, event_ANY, Click_common, range);
  434.  
  435.   Event_Claim(event_CLOSE, range->window, event_ANY, Close_window, range);
  436.   
  437.   Window_Show(range->window, open_UNDERPOINTER);
  438.  
  439. }
  440.  
  441. /******************************************************************************/
  442.  
  443. void open_add(int sourceimage)
  444. {
  445.  /*
  446.   * open add new image window on screen
  447.   */
  448.   iconrange_block *range;
  449.   char text[40];
  450.  
  451.  /*
  452.   * allocate memory for range info block and return if fails
  453.   */
  454.   range = malloc(sizeof(iconrange_block));
  455.   if(range == NULL){
  456.      NoMemProc();
  457.      return;
  458.   }
  459.  
  460.  /*
  461.   * create the window
  462.   */
  463.   range->window = Window_Create("Common", template_TITLEMIN);
  464.   Msgs_Lookup("txt.addt", text, 39);
  465.   Window_SetTitle(range->window, text);
  466.   Msgs_Lookup("txt.add", text, 39);
  467.   Icon_SetText(range->window, 15, text);
  468.  
  469.  /*
  470.   * set routine that closes window when source bank is closed
  471.   */
  472.   range->sourceimage = sourceimage;
  473.   range->close = (closewindow_routine)close_add;
  474.  
  475.  /*
  476.   * initialise source and destination image frames
  477.   */
  478.   prepare_processwin(range);
  479.  
  480.  /*
  481.   * install event handlers
  482.   */
  483.   Event_Claim(event_CLICK, range->window, event_ANY, Click_common, range);
  484.  
  485.   Event_Claim(event_CLOSE, range->window, event_ANY, Close_window, range);
  486.   
  487.   Window_Show(range->window, open_UNDERPOINTER);
  488.  
  489. }
  490.  
  491. /******************************************************************************/
  492.  
  493. void open_average(int sourceimage)
  494. {
  495.  /*
  496.   * open average image window on screen
  497.   */
  498.   iconrange_block *range;
  499.   char text[40];
  500.  
  501.  /*
  502.   * allocate memory for range info block and return if fails
  503.   */
  504.   range = malloc(sizeof(iconrange_block));
  505.   if(range == NULL){
  506.      NoMemProc();
  507.      return;
  508.   }
  509.  
  510.  /*
  511.   * create the window
  512.   */
  513.   range->window = Window_Create("Common", template_TITLEMIN);
  514.   Msgs_Lookup("txt.avrt", text, 39);
  515.   Window_SetTitle(range->window, text);
  516.   Msgs_Lookup("txt.avr", text, 39);
  517.   Icon_SetText(range->window, 15, text);
  518.  
  519.  /*
  520.   * set routine that closes window when source bank is closed
  521.   */
  522.   range->sourceimage = sourceimage;
  523.   range->close = (closewindow_routine)close_average;
  524.  
  525.  /*
  526.   * initialise source and destination image frames
  527.   */
  528.   prepare_processwin(range);
  529.  
  530.  /*
  531.   * install event handlers
  532.   */
  533.   Event_Claim(event_CLICK, range->window, event_ANY, Click_common, range);
  534.  
  535.   Event_Claim(event_CLOSE, range->window, event_ANY, Close_window, range);
  536.   
  537.   Window_Show(range->window, open_UNDERPOINTER);
  538.  
  539. }
  540.  
  541. /******************************************************************************/
  542.  
  543. void open_convolution(int sourceimage)
  544. {
  545.  /*
  546.   * open convolute image window on screen
  547.   */
  548.   iconrange_block *range;
  549.  
  550.  /*
  551.   * allocate memory for range info block and return if fails
  552.   */
  553.   range = malloc(sizeof(iconrange_block));
  554.   if(range == NULL){
  555.      NoMemProc();
  556.      return;
  557.   }
  558.  
  559.  /*
  560.   * create the window
  561.   */
  562.   range->window = Window_Create("Convolution", template_TITLEMIN);
  563.  
  564.  /*
  565.   * set routine that closes window when source bank is closed
  566.   */
  567.   range->sourceimage = sourceimage;
  568.   range->close = (closewindow_routine)close_convolution;
  569.  
  570.  /*
  571.   * initialise source and destination image frames
  572.   */
  573.   prepare_processwin(range);
  574.  
  575.  /*
  576.   * install filter menu
  577.   */
  578.   Filter_InstallMenu(range->window);
  579.  
  580.  /*
  581.   * install event handlers
  582.   */
  583.   Event_Claim(event_CLICK, range->window, event_ANY, Click_convolution, range);
  584.  
  585.   Event_Claim(event_KEY, range->window, event_ANY, Key_convolution, range);
  586.  
  587.   Event_Claim(event_CLOSE, range->window, event_ANY, Close_window, range);
  588.   
  589.   Window_Show(range->window, open_UNDERPOINTER);
  590.  
  591.  /*
  592.   * put caret into first number of matrix
  593.   */
  594.   Icon_SetCaret(range->window, 16);
  595.  
  596. }
  597.  
  598. /******************************************************************************/
  599.  
  600. void open_median(int sourceimage)
  601. {
  602.  /*
  603.   * open median filter window on screen
  604.   */
  605.   iconrange_block *range;
  606.   char text[40];
  607.  
  608.  /*
  609.   * allocate memory for range info block and return if fails
  610.   */
  611.   range = malloc(sizeof(iconrange_block));
  612.   if(range == NULL){
  613.      NoMemProc();
  614.      return;
  615.   }
  616.  
  617.  /*
  618.   * create the window
  619.   */
  620.   range->window = Window_Create("Common", template_TITLEMIN);
  621.   Msgs_Lookup("txt.medt", text, 39);
  622.   Window_SetTitle(range->window, text);
  623.   Msgs_Lookup("txt.filter", text, 39);
  624.   Icon_SetText(range->window, 15, text);
  625.  
  626.  /*
  627.   * set routine that closes window when source bank is closed
  628.   */
  629.   range->sourceimage = sourceimage;
  630.   range->close = (closewindow_routine)close_median;
  631.  
  632.  /*
  633.   * initialise source and destination image frames
  634.   */
  635.   prepare_processwin(range);
  636.  
  637.  /*
  638.   * install event handlers
  639.   */
  640.   Event_Claim(event_CLICK, range->window, event_ANY, Click_common, range);
  641.  
  642.   Event_Claim(event_CLOSE, range->window, event_ANY, Close_window, range);
  643.   
  644.   Window_Show(range->window, open_UNDERPOINTER);
  645.  
  646. }
  647.  
  648. /******************************************************************************/
  649.  
  650. void open_greyedit(int sourceimage)
  651. {
  652.  /*
  653.   * open edit image greylevels window
  654.   */
  655.   iconrange_block *range;
  656.   char text[40];
  657.  
  658.  /*
  659.   * allocate memory for range info block and return if fails
  660.   */
  661.   range = malloc(sizeof(iconrange_block));
  662.   if(range == NULL){
  663.      NoMemProc();
  664.      return;
  665.   }
  666.  
  667.  /*
  668.   * create the window
  669.   */
  670.   range->window = Window_Create("Common", template_TITLEMIN);
  671.   Msgs_Lookup("txt.greyedt", text, 39);
  672.   Window_SetTitle(range->window, text);
  673.   Msgs_Lookup("txt.start", text, 39);
  674.   Icon_SetText(range->window, 15, text);
  675.  
  676.  /*
  677.   * set routine that closes window when source bank is closed
  678.   */
  679.   range->sourceimage = sourceimage;
  680.   range->close = (closewindow_routine)close_greyedit;
  681.  
  682.  /*
  683.   * initialise source and destination image frames
  684.   */
  685.   prepare_processwin(range);
  686.  
  687.  /*
  688.   * install event handlers
  689.   */
  690.   Event_Claim(event_CLICK, range->window, event_ANY, Click_common, range);
  691.  
  692.   Event_Claim(event_CLOSE, range->window, event_ANY, Close_window, range);
  693.   
  694.   Window_Show(range->window, open_UNDERPOINTER);
  695.  
  696. }
  697.  
  698. /******************************************************************************/
  699.  
  700. void open_scale(int sourceimage)
  701. {
  702.  /*
  703.   * open scale image window on screen
  704.   */
  705.   iconrange_block *range;
  706.  
  707.  /*
  708.   * allocate memory for range info block and return if fails
  709.   */
  710.   range = malloc(sizeof(iconrange_block));
  711.   if(range == NULL){
  712.      NoMemProc();
  713.      return;
  714.   }
  715.  
  716.  /*
  717.   * create the window
  718.   */
  719.   range->window = Window_Create("Scale", template_TITLEMIN);
  720.  
  721.  /*
  722.   * set routine that closes window when source bank is closed
  723.   */
  724.   range->sourceimage = sourceimage;
  725.   range->close = (closewindow_routine)close_convolution;
  726.  
  727.  /*
  728.   * initialise source and destination image frames
  729.   */
  730.   prepare_processwin(range);
  731.  
  732.  /*
  733.   * set destination size to -1x-1 so that it cannot find windows of the same size
  734.   */
  735.   range->size.x = -1;
  736.   range->size.y = -1;
  737.  
  738.  /*
  739.   * initialise the default values
  740.   */
  741.   Icon_SetRadios(range->window, size_MIN, size_MAX, selectedsize);
  742.   Icon_SetInteger(range->window, 22, tofit.x);
  743.   Icon_SetInteger(range->window, 24, tofit.y);
  744.   Icon_SetInteger(range->window, 25, custom.multiply.x);
  745.   Icon_SetInteger(range->window, 27, custom.divide.x);
  746.   Icon_SetInteger(range->window, 28, custom.multiply.y);
  747.   Icon_SetInteger(range->window, 30, custom.divide.x);
  748.  
  749.  
  750.  /*
  751.   * install event handlers
  752.   */
  753.   Event_Claim(event_CLICK, range->window, event_ANY, Click_scale, range);
  754.  
  755.   Event_Claim(event_KEY, range->window, event_ANY, Key_scale, range);
  756.  
  757.   Event_Claim(event_CLOSE, range->window, event_ANY, Close_window, range);
  758.   
  759.   Window_Show(range->window, open_UNDERPOINTER);
  760.  
  761.  /*
  762.   * put caret into first icon
  763.   */
  764.   Icon_SetCaret(range->window, 22);
  765.  
  766. }
  767.  
  768. /******************************************************************************/
  769.  
  770. void open_mix(int sourceimage)
  771. {
  772.  /*
  773.   * open grey edit image window on screen
  774.   */
  775.   common2_block *block;
  776.   char text[40];
  777.  
  778.  /*
  779.   * allocate memory for range info block and return if fails
  780.   */
  781.   block = malloc(sizeof(common2_block));
  782.   if(block == NULL){
  783.      NoMemProc();
  784.      return;
  785.   }
  786.  
  787.  /*
  788.   * create the window
  789.   */
  790.   block->source2range.window = Window_Create("Common2", template_TITLEMIN);
  791.   block->destrange.window = block->source2range.window;
  792.   Msgs_Lookup("txt.mixt", text, 39);
  793.   Window_SetTitle(block->destrange.window, text);
  794.   Msgs_Lookup("txt.start", text, 39);
  795.   Icon_SetText(block->destrange.window, 23, text);
  796.  
  797.  /*
  798.   * set routine that closes window when source bank is closed
  799.   */
  800.   block->source2range.sourceimage = sourceimage;
  801.   block->destrange.sourceimage = sourceimage;
  802.   block->source2range.close = (closewindow_routine)close_mix;
  803.   block->destrange.close = NULL; /*(closewindow_routine)close_mix;*/
  804.  
  805.  /*
  806.   * initialise source 1 + 2 and destination image frames
  807.   */
  808.   prepare_processwin2(block);
  809.  
  810.  /*
  811.   * install event handlers
  812.   */
  813.   Event_Claim(event_CLICK, block->destrange.window, event_ANY, Click_common2, block);
  814.  
  815.   Event_Claim(event_CLOSE, block->destrange.window, event_ANY, Close_window2, block);
  816.   
  817.   Window_Show(block->destrange.window, open_UNDERPOINTER);
  818.  
  819. }
  820.  
  821. /******************************************************************************
  822.  *                               close handlers                               *
  823.  ******************************************************************************/
  824.  
  825. static void close_copy(BOOL ok, BOOL keepopen, iconrange_block *range)
  826. {
  827.   int destimage;
  828.   wimp_point *size;
  829.  
  830.   if(ok == TRUE){
  831.  
  832.      destimage = image_getselect(range);
  833.  
  834.     /*
  835.      * process the image
  836.      */
  837.      if(destimage != -1){
  838.         size = SpriteWin_GetSize(range->sourceimage);
  839.  
  840.        /*
  841.         * create destination if not created and return if creation fails
  842.         */
  843.         if( SpriteWin_FreeImage(destimage) ){
  844.  
  845.            if( !SpriteWin_Create(size, destimage) )
  846.               return;
  847.         }
  848.  
  849.         Process_Copy(range->sourceimage, destimage, size);
  850.  
  851.        /*
  852.         * refresh destination image
  853.         */
  854.         SpriteWin_RefreshWin(destimage);
  855.      }
  856.   
  857.   }
  858.  
  859.   if(keepopen == FALSE){
  860.  
  861.      CheckBanks_RemoveScanDestination(range);
  862.      Window_Delete(range->window);
  863.      free(range);
  864.   }
  865.  
  866. }
  867.  
  868. /******************************************************************************/
  869.  
  870. static void close_add(BOOL ok, BOOL keepopen, iconrange_block *range)
  871. {
  872.   int destimage;
  873.   wimp_point *size;
  874.  
  875.   if(ok == TRUE){
  876.  
  877.      destimage = image_getselect(range);
  878.  
  879.     /*
  880.      * process the image
  881.      */
  882.      if(destimage != -1){
  883.         size = SpriteWin_GetSize(range->sourceimage);
  884.  
  885.        /*
  886.         * create destination if not created and return if creation fails
  887.         */
  888.         if( SpriteWin_FreeImage(destimage) ){
  889.  
  890.            if( !SpriteWin_Create(size, destimage) )
  891.               return;
  892.         }
  893.  
  894.         Process_Add(range->sourceimage, destimage, size);
  895.  
  896.        /*
  897.         * refresh destination image
  898.         */
  899.         SpriteWin_RefreshWin(destimage);
  900.      }
  901.   
  902.   }
  903.  
  904.   if(keepopen == FALSE){
  905.  
  906.      CheckBanks_RemoveScanDestination(range);
  907.      Window_Delete(range->window);
  908.      free(range);
  909.   }
  910.  
  911. }
  912.  
  913. /******************************************************************************/
  914.  
  915. static void close_average(BOOL ok, BOOL keepopen, iconrange_block *range)
  916. {
  917.   int destimage;
  918.   wimp_point *size;
  919.  
  920.   if(ok == TRUE){
  921.  
  922.      destimage = image_getselect(range);
  923.  
  924.     /*
  925.      * process the image
  926.      */
  927.      if(destimage != -1){
  928.         size = SpriteWin_GetSize(range->sourceimage);
  929.  
  930.        /*
  931.         * create destination if not created and return if creation fails
  932.         */
  933.         if( SpriteWin_FreeImage(destimage) ){
  934.  
  935.            if( !SpriteWin_Create(size, destimage) )
  936.               return;
  937.         }
  938.  
  939.         Process_Average(range->sourceimage, destimage, size);
  940.  
  941.        /*
  942.         * refresh destination image
  943.         */
  944.         SpriteWin_RefreshWin(destimage);
  945.      }
  946.   
  947.   }
  948.  
  949.   if(keepopen == FALSE){
  950.  
  951.      CheckBanks_RemoveScanDestination(range);
  952.      Window_Delete(range->window);
  953.      free(range);
  954.   }
  955.  
  956. }
  957.  
  958. /******************************************************************************/
  959.  
  960. static void close_convolution(BOOL ok, BOOL keepopen, iconrange_block *range)
  961. {
  962.   int destimage;
  963.   wimp_point *size;
  964.   wimp_point anchor;
  965.   int filter[3][3];
  966.  
  967.   if(ok == TRUE){
  968.  
  969.      destimage = image_getselect(range);
  970.  
  971.     /*
  972.      * process the image
  973.      */
  974.      if(destimage != -1){
  975.         size = SpriteWin_GetSize(range->sourceimage);
  976.  
  977.         Filter_GetMatrix(range->window, &anchor, &filter);
  978.  
  979.        /*
  980.         * check anchor point is valid
  981.         */
  982.         if( (anchor.x < -1) || (anchor.x > 1) || (anchor.y < -1) || (anchor.y > 1) ){
  983.            InvAnchor();
  984.            return;
  985.         }
  986.  
  987.        /*
  988.         * create destination if not created and return if creation fails
  989.         */
  990.         if( SpriteWin_FreeImage(destimage) ){
  991.  
  992.            if( !SpriteWin_Create(size, destimage) )
  993.               return;
  994.         }
  995.         
  996.         Process_Convolve(range->sourceimage, destimage, size, &anchor, &filter, TRUE);
  997.  
  998.        /*
  999.         * refresh destination image
  1000.         */
  1001.         SpriteWin_RefreshWin(destimage);
  1002.      }
  1003.   
  1004.   }
  1005.  
  1006.   if(keepopen == FALSE){
  1007.  
  1008.      CheckBanks_RemoveScanDestination(range);
  1009.      Window_Delete(range->window);
  1010.      free(range);
  1011.   }
  1012.  
  1013. }
  1014.  
  1015. /******************************************************************************/
  1016.  
  1017. static void close_median(BOOL ok, BOOL keepopen, iconrange_block *range)
  1018. {
  1019.   int destimage;
  1020.   wimp_point *size;
  1021.  
  1022.   if(ok == TRUE){
  1023.  
  1024.      destimage = image_getselect(range);
  1025.  
  1026.     /*
  1027.      * process the image
  1028.      */
  1029.      if(destimage != -1){
  1030.         size = SpriteWin_GetSize(range->sourceimage);
  1031.  
  1032.        /*
  1033.         * create destination if not created and return if creation fails
  1034.         */
  1035.         if( SpriteWin_FreeImage(destimage) ){
  1036.  
  1037.            if( !SpriteWin_Create(size, destimage) )
  1038.               return;
  1039.         }
  1040.  
  1041.         Process_Median(range->sourceimage, destimage, size);
  1042.  
  1043.        /*
  1044.         * refresh destination image
  1045.         */
  1046.         SpriteWin_RefreshWin(destimage);
  1047.      }
  1048.   
  1049.   }
  1050.  
  1051.   if(keepopen == FALSE){
  1052.  
  1053.      CheckBanks_RemoveScanDestination(range);
  1054.      Window_Delete(range->window);
  1055.      free(range);
  1056.   }
  1057.  
  1058. }
  1059.  
  1060. /******************************************************************************/
  1061.  
  1062. static void close_greyedit(BOOL ok, BOOL keepopen, iconrange_block *range)
  1063. {
  1064.   int destimage;
  1065.   wimp_point openpos;
  1066.  
  1067.   if(ok == TRUE){
  1068.  
  1069.      destimage = image_getselect(range);
  1070.  
  1071.     /*
  1072.      * process the image
  1073.      */
  1074.      if(destimage != -1){
  1075.  
  1076.        /*
  1077.         * open process window
  1078.         */
  1079.  
  1080.         Window_GetPos(range->window, &openpos);
  1081.         GreyEdWin_Open(range->sourceimage, destimage, &openpos);
  1082.  
  1083.      }
  1084.   
  1085.   }
  1086.  
  1087.   if(keepopen == FALSE){
  1088.  
  1089.      CheckBanks_RemoveScanDestination(range);
  1090.      Window_Delete(range->window);
  1091.      free(range);
  1092.   }
  1093.  
  1094. }
  1095.  
  1096. /******************************************************************************/
  1097.  
  1098. static void close_scale(BOOL ok, BOOL keepopen, iconrange_block *range)
  1099. {
  1100.   int destimage;
  1101.   wimp_point *sourcesize;
  1102.   wimp_point destsize;
  1103.   wimp_point *actdestsize;
  1104.  
  1105.  /*
  1106.   * update the default values
  1107.   */
  1108.   selectedsize = Icon_WhichRadio(range->window, size_MIN, size_MAX);
  1109.   tofit.x = Icon_GetInteger(range->window, 22);
  1110.   tofit.y = Icon_GetInteger(range->window, 24);
  1111.   custom.multiply.x = Icon_GetInteger(range->window, 25); 
  1112.   custom.divide.x = Icon_GetInteger(range->window, 27);
  1113.   custom.multiply.y = Icon_GetInteger(range->window, 28);
  1114.   custom.divide.y = Icon_GetInteger(range->window, 30);
  1115.  
  1116.   if(ok == TRUE){
  1117.  
  1118.      destimage = image_getselect(range);
  1119.  
  1120.     /*
  1121.      * process the image
  1122.      */
  1123.      if(destimage != -1){
  1124.         sourcesize = SpriteWin_GetSize(range->sourceimage);
  1125.  
  1126.        /*
  1127.         * calculate the size of the destination image
  1128.         */
  1129.         switch( Icon_WhichRadio(range->window, size_MIN, size_MAX) - size_MIN)
  1130.         {
  1131.           case 0: /* 400% */    
  1132.             destsize.x = sourcesize->x * 4;
  1133.             destsize.y = sourcesize->y * 4;
  1134.             break;
  1135.  
  1136.           case 1: /* 200% */     
  1137.             destsize.x = sourcesize->x * 2;
  1138.             destsize.y = sourcesize->y * 2;
  1139.             break;
  1140.  
  1141.           case 2: /* 50% */     
  1142.             destsize.x = sourcesize->x / 2;
  1143.             destsize.y = sourcesize->y / 2;
  1144.             break;
  1145.  
  1146.           case 3: /* 25% */    
  1147.             destsize.x = sourcesize->x / 4;
  1148.             destsize.y = sourcesize->y / 4;
  1149.             break;
  1150.  
  1151.           case 4: /* to fit */  
  1152.             destsize.x = tofit.x;
  1153.             destsize.y = tofit.y;
  1154.             break;
  1155.  
  1156.           case 5: /* custom */  
  1157.             destsize.x = (sourcesize->x * custom.multiply.x) / custom.divide.x;
  1158.             destsize.y = (sourcesize->y * custom.multiply.y) / custom.divide.y;
  1159.             break;
  1160.         }
  1161.             
  1162.        /*
  1163.         * create destination and return if creation fails
  1164.         */
  1165.         if( SpriteWin_FreeImage(destimage) ){
  1166.  
  1167.            if( !SpriteWin_Create(&destsize, destimage) )
  1168.               return;
  1169.         }
  1170.         actdestsize = SpriteWin_GetSize(destimage);
  1171.         Process_Scale(range->sourceimage, destimage, sourcesize, actdestsize);
  1172.  
  1173.        /*
  1174.         * refresh destination image
  1175.         */
  1176.         SpriteWin_RefreshWin(destimage);
  1177.      }
  1178.   
  1179.   }
  1180.  
  1181.   if(keepopen == FALSE){
  1182.  
  1183.      CheckBanks_RemoveScanDestination(range);
  1184.      Window_Delete(range->window);
  1185.      free(range);
  1186.   }
  1187.  
  1188. }
  1189.  
  1190. /******************************************************************************/
  1191.  
  1192. static void close_mix(BOOL ok, BOOL keepopen, common2_block *block)
  1193. {
  1194.   int source2image;
  1195.   int destimage;
  1196.   BOOL oktokill;
  1197.   wimp_point openpos;
  1198.  
  1199.   oktokill = TRUE;
  1200.  
  1201.   if(ok == TRUE){
  1202.  
  1203.      source2image = image_getselect(&(block->source2range));
  1204.      destimage = image_getselect(&(block->destrange));
  1205.  
  1206.      if( (source2image != -1) && (destimage != -1) ){
  1207.  
  1208.        /*
  1209.         * open process window
  1210.         */
  1211.  
  1212.         Window_GetPos(block->destrange.window, &openpos);
  1213.         MixWin_Open(block->destrange.sourceimage, source2image, destimage, &openpos);
  1214.      }
  1215.      else
  1216.         oktokill = FALSE;
  1217.  
  1218.   }
  1219.  
  1220.  /*
  1221.   * kill window
  1222.   */
  1223.  
  1224.   if(oktokill){
  1225.  
  1226.      CheckBanks_RemoveScanSource(&(block->source2range));
  1227.      CheckBanks_RemoveScanDestination(&(block->destrange));
  1228.      Event_Release(event_NULL, event_ANY, event_ANY, Null_closecommon2, block);
  1229.      Window_Delete(block->destrange.window);
  1230.      free(block);
  1231.   }
  1232.  
  1233. }
  1234.  
  1235. /******************************************************************************/
  1236.  
  1237. static BOOL Close_window(event_pollblock *event, void *reference)
  1238. {
  1239.   iconrange_block *range = reference;
  1240.  
  1241.   (range->close)(FALSE, FALSE, range);
  1242.  
  1243.   return(FALSE);
  1244. }
  1245.  
  1246. /******************************************************************************/
  1247.  
  1248. static BOOL Close_window2(event_pollblock *event, void *reference)
  1249. {
  1250.   common2_block *block = reference;
  1251.  
  1252.   (block->source2range.close)(FALSE, FALSE, block);
  1253.  
  1254.   return(FALSE);
  1255. }
  1256.  
  1257. /******************************************************************************
  1258.  *                             Null handlers                                  *
  1259.  ******************************************************************************/
  1260.  
  1261. static BOOL Null_closecommon2(event_pollblock *event, void *reference)
  1262. {
  1263.   common2_block *block = reference;
  1264.   
  1265.   if(SpriteWin_FreeImage(block->source2range.sourceimage))
  1266.      (block->source2range.close)(FALSE, FALSE, block);
  1267.  
  1268.   return(FALSE);
  1269. }
  1270.  
  1271. /******************************************************************************
  1272.  *                             misc routines                                  *
  1273.  ******************************************************************************/
  1274.  
  1275. void NoMemProc(void)
  1276. {
  1277.   char err_msg[128];
  1278.  
  1279.   Msgs_Lookup("err.nomemproc", err_msg, 127);
  1280.   Error_Report(1,err_msg);
  1281.  
  1282. }
  1283.  
  1284. /******************************************************************************/
  1285.  
  1286. void InvAnchor(void)
  1287. {
  1288.   char err_msg[128];
  1289.  
  1290.   Msgs_Lookup("err.invanch", err_msg, 127);
  1291.   Error_Report(1,err_msg);
  1292.  
  1293. }
  1294.