home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / System / Swatch / Development / swatch 1.7 / content.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-09  |  12.7 KB  |  601 lines  |  [TEXT/KAHL]

  1. /**
  2.  
  3.     content.c
  4.     Copyright (c) 1990-1992, joe holt
  5.  
  6.  **/
  7.  
  8.  
  9. /**-----------------------------------------------------------------------------
  10.  **
  11.  **    Headers
  12.  **
  13.  **/
  14.  
  15. #ifndef __content__
  16. #include "content.h"
  17. #endif
  18. #ifndef __ctypes__
  19. #include "ctypes.h"
  20. #endif
  21. #ifndef __display__
  22. #include "display.h"
  23. #endif
  24. #ifndef __heap_list__
  25. #include "heap_list.h"
  26. #endif
  27. #ifndef __info__
  28. #include "info.h"
  29. #endif
  30. #ifndef __prefs__
  31. #include "prefs.h"
  32. #endif
  33. #ifndef __pstring__
  34. #include "pstring.h"
  35. #endif
  36. #ifndef __resources__
  37. #include "resources.h"
  38. #endif
  39. #ifndef __swatch__
  40. #include "swatch.h"
  41. #endif
  42. #ifndef __window__
  43. #include "window.h"
  44. #endif
  45.  
  46.  
  47. /**-----------------------------------------------------------------------------
  48.  **
  49.  ** Private Variables
  50.  **
  51.  **/
  52.  
  53. static int16 heap_cursor;
  54. static int16 num_display_lines;        // number of whole rows visible in current window
  55. static int16 partial_display_line;    // partial row at bottom also visible
  56.  
  57. static int32 display_heap_bytes,    // number of heap bytes visible in current window
  58.         horiz_scroll_scale,
  59.         heap_offset_pixels,
  60.         heap_right_pixels;
  61. static int16 heap_cursor;
  62.  
  63.  
  64. /**-----------------------------------------------------------------------------
  65.  **
  66.  ** Private Functions
  67.  **
  68.  **/
  69.  
  70. static void mousedown_in_updating( EventRecord *the_event, Heap_info_handle_t h );
  71. static void mousedown_in_name( EventRecord *the_event, Heap_info_handle_t h );
  72. static void mousedown_in_heap( EventRecord *the_event, Heap_info_handle_t h );
  73. static void mousedown_move_border( EventRecord *the_event );
  74. static void mousedown_in_border( EventRecord *the_event );
  75. static void mousedown_in_bomb( EventRecord *the_event );
  76.  
  77. static void swatch( unsigned char *str );
  78.  
  79.  
  80. /*******************************************************************************
  81.  **
  82.  **    Public Variables
  83.  **
  84.  **/
  85.  
  86. int16 mbox_type = 0;
  87. unsigned char mbox_heap_appname[32];
  88. THz mbox_heap_zone;
  89. Ptr mbox_heap_current_selection_logical_start;
  90.  
  91.  
  92. /*******************************************************************************
  93.  **
  94.  **    Public Functions
  95.  **
  96.  **/
  97.  
  98. void Content_init( void )
  99. {
  100. }
  101.  
  102.  
  103. Boolean Content_find_point( Point where, Heap_info_handle_t *hp, int16 *type )
  104. {
  105.     Heap_info_handle_t h;
  106.     Heap_info_t *hi;
  107.     column_t *col;
  108.     int i;
  109.     Boolean found;
  110.     Rect contents_rect;
  111.  
  112.     contents_rect = App_window->portRect;
  113.     contents_rect.right -= 15;
  114.     contents_rect.bottom -= 15;
  115.     if ( !PtInRect( where, &contents_rect ) ) return false;
  116.  
  117.     h = nil;
  118.     found = false;
  119.     while ( !found && (h = l_next( heaps, h )) ) {
  120.  
  121.          hi = l_access( h );
  122.  
  123.         if ( where.v >= hi->row.top && where.v <= hi->row.bottom ) {
  124.  
  125.             for ( i = hi->row.max_columns, col = &hi->row.column[i]; i >= 0; --i, --col ) {
  126.                 if ( where.h >= col->left &&
  127.                      where.h <= col->right ) {
  128.  
  129.                     if ( hp ) *hp = h;
  130.                     if ( type ) *type = col->cell->type;
  131.                     found = true;
  132.                     break;
  133.  
  134.                 }
  135.  
  136.             }
  137.  
  138.         }
  139.  
  140.         l_release( h );
  141.     }
  142.  
  143.     return found;
  144. }
  145.  
  146.  
  147. void Content_mousedown( EventRecord *the_event )
  148. {
  149.     Heap_info_handle_t h;
  150.     int16 type;
  151.  
  152.     if ( Content_find_point( the_event->where, &h, &type ) ) {
  153.  
  154.         if ( type == colUpdating ) mousedown_in_updating( the_event, h );
  155.         else if ( type == colName ) mousedown_in_name( the_event, h );
  156.         else if ( type == colHeap ) mousedown_in_heap( the_event, h );
  157.  
  158.     }
  159.     else if ( heap_cursor == MOVE_BORDER_CURS ) mousedown_move_border( the_event );
  160.     else if ( the_event->where.v <= BORDER_BOTTOM ) mousedown_in_border( the_event );
  161.     else if ( Debugger_installed &&
  162.               the_event->where.v >= App_window->portRect.bottom - 15 &&
  163.               the_event->where.h < 19 ) mousedown_in_bomb( the_event );
  164. }
  165.  
  166.  
  167. void Content_set_cursor( EventRecord *the_event )
  168. {
  169.     Heap_info_handle_t h;
  170.     int16 type;
  171.     Rect r;
  172.     int16 new_cursor;
  173.  
  174.     new_cursor = ARROW_CURS;
  175.  
  176.     if ( the_event->where.h >= MBox_right - 1 &&
  177.          the_event->where.h <= MBox_right + 1 ) new_cursor = MOVE_BORDER_CURS;
  178.  
  179.     else if ( Content_find_point( the_event->where, &h, &type ) ) {
  180.  
  181.         if ( type == colHeap ) {
  182.  
  183.             if ( the_event->modifiers & optionKey )
  184.  
  185.                 new_cursor = (Prefs.heap_scale < MAX_HEAP_SCALE) ?
  186.                     ZOOM_OUT_CURS : NO_ZOOM_CURS;
  187.     
  188.             else if ( the_event->modifiers & cmdKey )
  189.  
  190.                 new_cursor = INFO_CURS;
  191.  
  192.             else new_cursor = (Prefs.heap_scale > MIN_HEAP_SCALE) ?
  193.                         ZOOM_IN_CURS : NO_ZOOM_CURS;
  194.  
  195.         }
  196.  
  197.     }
  198.  
  199.  
  200.     if ( new_cursor != heap_cursor ) {
  201.  
  202.         heap_cursor = new_cursor;
  203.  
  204.         if ( heap_cursor == ARROW_CURS ) InitCursor();
  205.  
  206.         else {
  207.             Handle cursor_h;
  208.  
  209.             cursor_h = GetResource( 'CURS', new_cursor );
  210.             assert( cursor_h, "\p Content_set_cursor(): couldn't get cursor" );
  211.  
  212.             HLock( cursor_h );
  213.             SetCursor( (Cursor *) *cursor_h );
  214.             HUnlock( cursor_h );
  215.             HPurge( cursor_h );
  216.  
  217.         }
  218.     }
  219. }
  220.  
  221.  
  222. int16 Content_rows( void )
  223. {
  224.     return num_display_lines;
  225. }
  226.  
  227.  
  228. int16 Content_partial_row( void )
  229. {
  230.     return partial_display_line;
  231. }
  232.  
  233.  
  234. void Content_reset_vert( void )
  235. {
  236.     int16 i;
  237.  
  238.     i = App_window->portRect.bottom - 15 - BORDER_BOTTOM;
  239.     partial_display_line = (i % CELL_HEIGHT) != 0;
  240.     num_display_lines = i / CELL_HEIGHT;
  241. }
  242.  
  243.  
  244. void Content_scroll_horiz( ControlHandle the_control, int16 part, int16 unit_delta )
  245. {
  246.     int32 delta, old_heap_offset_pixels;
  247.  
  248.     if ( !part )
  249.         return;
  250.  
  251.     old_heap_offset_pixels = heap_offset_pixels;
  252.     if ( part == inUpButton )
  253.         delta = -unit_delta;
  254.     else if ( part == inDownButton )
  255.         delta = unit_delta;
  256.     else {
  257.         delta = (display_heap_bytes >> Prefs.heap_scale_2n) - unit_delta;
  258.         if ( part == inPageUp )
  259.         delta = -delta;
  260.     }
  261.  
  262.     heap_offset_pixels += delta;
  263.     if ( heap_offset_pixels < 0 )
  264.         heap_offset_pixels = 0;
  265.     else if ( heap_offset_pixels > heap_right_pixels )
  266.         heap_offset_pixels = heap_right_pixels;
  267.     
  268.     if ( heap_offset_pixels != old_heap_offset_pixels ) {
  269.         SetCtlValue( the_control, heap_offset_pixels / horiz_scroll_scale );
  270.         Display_lines( UPDATE_HEAP | UPDATE_SELECTION, DISPLAY_ALL, DISPLAY_ALL );
  271.     }
  272. }
  273.  
  274.  
  275. void Content_horiz_scrolled( int cvalue )
  276. {
  277.     heap_offset_pixels = (int32) cvalue * horiz_scroll_scale;
  278. }
  279.  
  280.  
  281. Boolean Content_reset_horiz( ControlHandle the_control )
  282. {
  283.     int32 i, largest_heap_size;
  284.     Heap_info_t *hi;
  285.     int16 first_heap_pixel;
  286.     Heap_info_handle_t h;
  287.     int16 max, value;
  288.  
  289.     h = l_next( heaps, nil );
  290.     hi = l_access( h );
  291.  
  292.     largest_heap_size = Heap_list_largest_heap_size();
  293.     first_heap_pixel = hi->row.column[hi->row.max_columns].left;
  294.  
  295.     l_release( h );
  296.  
  297.     display_heap_bytes = (int32) (App_window->portRect.right - 15 - first_heap_pixel) *
  298.             Prefs.heap_scale;
  299.     i = largest_heap_size - display_heap_bytes;
  300.     if ( i > 0 ) {
  301.         heap_right_pixels = ( i >> Prefs.heap_scale_2n ) +
  302.                 ( (i & (Prefs.heap_scale-1)) ? 1 : 0 ) + 20;
  303.         horiz_scroll_scale = heap_right_pixels / 32768L + 1;
  304.     }
  305.     else {
  306.         heap_right_pixels = 0;
  307.         horiz_scroll_scale = 1;
  308.     }
  309.  
  310.     max = heap_right_pixels / horiz_scroll_scale +
  311.             ((heap_right_pixels % horiz_scroll_scale) ? 1 : 0);
  312.  
  313.     value = GetCtlValue( the_control );
  314.     SetCtlMax( the_control, max );
  315.     if ( value > max ) {
  316.         Content_horiz_scrolled( max );  // scroll position changed
  317.         return true;
  318.     }
  319.     return false;
  320. }
  321.  
  322.  
  323. int32 Content_heap_offset_pixels( void )
  324. {
  325.     return heap_offset_pixels;
  326. }
  327.  
  328.  
  329. void *Content_pixel_to_address( Heap_info_t *hi, int32 pixel_h )
  330. {
  331.     int32 pixel;
  332.     int16 first_heap_pixel;
  333.  
  334.     first_heap_pixel = hi->row.column[hi->row.max_columns].left;
  335.  
  336.     pixel = heap_offset_pixels + pixel_h - (first_heap_pixel);
  337.     return (void *)((pixel << Prefs.heap_scale_2n) + (int32)&hi->zone->heapData);
  338. }
  339.  
  340.  
  341. int32 Content_address_to_pixel( Heap_info_t *hi, void *address )
  342. {
  343.     int32 pixel;
  344.     int16 first_heap_pixel;
  345.  
  346.     first_heap_pixel = hi->row.column[hi->row.max_columns].left;
  347.  
  348.     pixel = ((int32)address - (int32)&hi->zone->heapData) >> Prefs.heap_scale_2n;
  349.     return pixel - heap_offset_pixels + first_heap_pixel;
  350. }
  351.  
  352.  
  353. /*--------*/
  354.  
  355. #ifdef __IGNORE__
  356.     colUpdating        = 1 << 0,
  357.     colName            = 1 << 1,
  358.     colSize            = 1 << 2,
  359.     colFree            = 1 << 3,
  360.     colIslands        = 1 << 4,
  361.     colHeap            = 1 << 5
  362.  
  363. if one column:
  364.   Heap Size  -->  Free  -->  Islands  -->  Heap Size
  365.  
  366. if two columns:
  367.   Heap Size / Free  -->  Heap Size / Islands  -->  Free / Heap Size  -->  Free / Islands
  368.   -->  Islands / Heap Size  --> Islands / Free  -->  Heap Size / Free
  369.  
  370. if three columns:
  371.   Heap Size / Free / Islands  -->  Heap Size / Islands / Free
  372.   -->  Free / Heap Size / Islands  -->  Free / Islands / Heap Size
  373.   -->  Islands / Heap Size / Free  -->  Islands / Free / Heap Size
  374.   -->  Heap Size / Free / Islands
  375.  
  376. #endif
  377.  
  378. static void mousedown_move_border( EventRecord *the_event )
  379. {
  380.     while ( StillDown() ) {
  381.  
  382.         GetMouse( &the_event->where );
  383.         
  384.     }
  385. }
  386.  
  387.  
  388. static void mousedown_in_border( EventRecord *the_event )
  389. {
  390. }
  391.  
  392.  
  393. static void mousedown_in_bomb( EventRecord *the_event )
  394. {
  395.     Boolean in_bomb, mouse_in_bomb;
  396.     Rect r;
  397.  
  398.     SetRect( &r, 0, App_window->portRect.bottom - 14, 20, App_window->portRect.bottom );
  399.  
  400.     in_bomb = false;
  401.     while ( StillDown() ) {
  402.  
  403.         GetMouse( &the_event->where );
  404.         mouse_in_bomb = PtInRect( the_event->where, &r );
  405.         if ( ( mouse_in_bomb && !in_bomb ) || ( !mouse_in_bomb && in_bomb ) ) {
  406.             in_bomb ^= 1;
  407.             InvertRect( &r );
  408.         }
  409.  
  410.     }
  411.  
  412.     if ( in_bomb ) {
  413.         unsigned char str[256];
  414.  
  415.         if ( mbox_type == MBOX_HEAP_ADDRESS ) {
  416.             pstrcopy( pstr(MacsBug_Looking_at_STR_x), str );
  417.             pstrappend( mbox_heap_appname, str );
  418.             pstrappend( pstr(MacsBug_hx_STR_x), str );
  419.             phexappend( (int32) mbox_heap_zone, 8, str );
  420.         }
  421.  
  422.         else if ( mbox_type == MBOX_ADDRESS ) {
  423.             pstrcopy( pstr(MacsBug_Looking_at_STR_x), str );
  424.             pstrappend( mbox_heap_appname, str );
  425.             pstrappend( pstr(MacsBug_hx_STR_x), str );
  426.             phexappend( (int32) mbox_heap_zone, 8, str );
  427.             pstrappend( pstr(MacsBug_wh_STR_x), str );
  428.             phexappend( (int32) mbox_heap_current_selection_logical_start, 8, str );
  429.         }
  430.  
  431.         else str[0] = 0;
  432.  
  433.         swatch( str );
  434.         InvertRect( &r );
  435.  
  436.     }
  437. }
  438.  
  439.  
  440. static void mousedown_in_updating( EventRecord *the_event, Heap_info_handle_t h )
  441. {
  442.     unsigned char *mbox_text;
  443.     Heap_info_t *hi;
  444.     int16 i, j;
  445.     unsigned char str[256];
  446.     Boolean scrolled;
  447.  
  448.     mbox_text = MBox_text();
  449.  
  450.     hi = l_access( h );
  451.     hi->updating ^= 1;
  452.     l_release( h );
  453.  
  454.  
  455.     scrolled = Window_reset_horiz_scroll();  // may've turned on/off longest heap
  456.  
  457.     if ( Heap_list_resort() )
  458.         Display_lines( UPDATE_COLUMNS | FORCE_UPDATE, DISPLAY_ALL, DISPLAY_ALL );
  459.     else {
  460.         if ( scrolled )
  461.             Display_lines( UPDATE_HEAP | UPDATE_SELECTION | FORCE_UPDATE, DISPLAY_ALL,
  462.                     DISPLAY_ALL );  // also erases row just turned off
  463.         else
  464.             Display_row( UPDATE_COLUMNS | FORCE_UPDATE, h );
  465.     }
  466.  
  467.     while ( StillDown() );
  468. }
  469.  
  470.  
  471. static void mousedown_in_name( EventRecord *the_event, Heap_info_handle_t h )
  472. {
  473.     unsigned char *mbox_text;
  474.     Heap_info_t *hi;
  475.     int16 i, j;
  476.     unsigned char str[256];
  477.  
  478.     hi = l_access( h );
  479.  
  480.     if ( hi->updating ) {
  481.         THz save_zone, compact_zone;
  482.  
  483.         mbox_text = MBox_text();
  484.  
  485.         mbox_type = MBOX_HEAP_ADDRESS;
  486.         record_for_mbox( hi );
  487.         pstrcopy( "\pHeap is at $", mbox_text );
  488.         phexappend( (int32) hi->zone, 8, mbox_text );
  489.         pstrappend( "\p (", mbox_text );
  490.         pstrappend( hi->appname, mbox_text );
  491.         pchappend( ')', mbox_text );
  492.         Window_update_mbox();
  493.  
  494.         {
  495.             Rect r;
  496.             uns32 ticker;
  497.     
  498.             ticker = TickCount() + 2;
  499.             r.top = hi->row.top;
  500.             r.bottom = hi->row.bottom;
  501.             r.left = hi->row.column[1].left;
  502.             r.right = hi->row.column[1].right;
  503.             InvertRoundRect( &r, 4, 4 );
  504.     
  505.             compact_zone = hi->zone;
  506.             l_release( h );    // so block can move, if this is the block's heap
  507.     
  508.             save_zone = TheZone;
  509.             TheZone = compact_zone;
  510.             PurgeMem( 0x7FFFFFFF );
  511.             CompactMem( 0x7FFFFFFF );
  512.             TheZone = save_zone;
  513.     
  514.             hi = l_access( h );
  515.     
  516.             while ( ticker > TickCount() );
  517.             InvertRoundRect( &r, 4, 4 );
  518.         }
  519.  
  520.         Display_row( UPDATE_COLUMNS, h );
  521.     }
  522.  
  523.     l_release( h );
  524.  
  525.     while ( StillDown() );
  526. }
  527.  
  528.  
  529. static void swatch( unsigned char *str )
  530. {
  531.     DebugStr( str );
  532. }
  533.  
  534.  
  535. static void mousedown_in_heap( EventRecord *the_event, Heap_info_handle_t h )
  536. {
  537.     Heap_info_t *hi;
  538.     int16 first_heap_pixel;
  539.  
  540.     hi = l_access( h );
  541.  
  542.     switch ( heap_cursor ) {
  543.  
  544.     case ZOOM_IN_CURS:
  545.     case ZOOM_OUT_CURS:
  546.  
  547.         if ( heap_cursor == ZOOM_IN_CURS ) {
  548.  
  549.             Prefs.heap_scale >>= 1;
  550.             --Prefs.heap_scale_2n;
  551.  
  552.         }
  553.         else {
  554.  
  555.             Prefs.heap_scale <<= 1;
  556.             ++Prefs.heap_scale_2n;
  557.  
  558.         }
  559.         Prefs.dirty = true;
  560.  
  561.         Window_reset_horiz_scroll();
  562.  
  563.  
  564. // adjust offset so that we stay centered on the click location
  565.  
  566.         first_heap_pixel = hi->row.column[hi->row.max_columns].left;
  567.  
  568.         if ( (the_event->where.h - first_heap_pixel > 35) || heap_offset_pixels ) {
  569.  
  570.             heap_offset_pixels = ( heap_cursor == ZOOM_IN_CURS ) ?
  571.                     (heap_offset_pixels << 1) + the_event->where.h - first_heap_pixel :
  572.                     (heap_offset_pixels - (the_event->where.h - first_heap_pixel)) >> 1;
  573.  
  574.         }
  575.  
  576.  
  577.         if ( heap_offset_pixels < 0 ) heap_offset_pixels = 0;
  578.         else if ( heap_offset_pixels > heap_right_pixels )
  579.             heap_offset_pixels = heap_right_pixels;
  580.  
  581.         SetCtlValue( Window_horiz_scroll(), heap_offset_pixels / horiz_scroll_scale );
  582.         Display_lines( UPDATE_HEAP | UPDATE_HEAP_SCALE, DISPLAY_ALL, DISPLAY_ALL );
  583.         break;
  584.  
  585.  
  586.     case INFO_CURS:
  587.         Info_track_heap( the_event, h );
  588.         break;
  589.  
  590.     }
  591.  
  592.     l_release( h );
  593. }
  594.  
  595.  
  596. void record_for_mbox( Heap_info_t *hi )
  597. {
  598.     pstrcopy( hi->appname, mbox_heap_appname );
  599.     mbox_heap_zone = hi->zone;
  600.     mbox_heap_current_selection_logical_start = hi->current_selection.logical_start;
  601. }