Jump to content
PB170

Macintosh Toolbox programming questions

Recommended Posts

Having worked as an intern at Apple in the late ‘90s where part of my job was writing example code (for OpenDoc, but never mind that), sadly, I would not necessarily have complete faith that Apple’s example code is sacrosanct. :) 

 

If you can provide your entire source code somewhere, I would be happy to browse it more carefully.

 

Good point, yes, since you’re writing a code resource, THINK C’s debugger won’t help.  You’d want to use Macsbug.  In Macsbug, once your control strip loads, I would hit the interrupt switch and enter “ATB _ControlStripDispatch”.  This should break any time a control strip call Iike SBTrackSlider() is called.  Then, mouse down on your slider, “S” to step into the SBTrackSlider code, and see what’s going on in there and exactly what got passed to it on the stack.   You’d need to learn a bit of 68k assembly to be able to follow along if you haven’t already.  Apple’s original Macsbug Reference and Debugging Guide is terrific and may tell you most of what you’d need to know.

Share this post


Link to post
Share on other sites

Wow, cool to hear that you worked at Apple in the 90's! Must have been fascinating.

 

Well… all I can do at this point is trust the examples provided :) although I try my best to fully understand how they work.

 

Thank you for the instructions on Macsbug. Very helpful, once I get started with it (have yet to install it :)). I'm a little bit familiar with assembly and the inner workings of CPU's in general (on a broad level – haven't done any actual coding), so that shouldn't be too difficult to learn I think.

 

I included the full project in my post earlier ;)

 

Thank you for helping out!

Edited by PB170

Share this post


Link to post
Share on other sites

Sorry had missed that - just looked at your code now.

 

I see that sliderSetting is indeed not initialized anywhere and that feels quite problematic to me, would suggest triple-checking that this problem indeed recurs once that's set properly, or even just set to 0 in the SBTrackSlider() call for test purposes.

 

One thing that makes me a bit uncomfortable is in main(), if you somehow get handed NIL in globs on an sdevMouseClick, you don't do any error checking -- you'll call HandleMouseClick with an uninitialized pointer in gb, then pass random stuff to SBTrackSlider().  I realize that feels unlikely and is probably not what's happening, but I would add an error check there and alert/fail gracefully somehow if that happens.

Share this post


Link to post
Share on other sites

Like I said, I just missed it when I went back to Apple's example for my post here – it's been initialized properly throughout all my tests :) It's initialized to 0 during the initialization call to the module after the global variables are allocated.

 

Regarding the globals, is this level of error checking necessary? Isn't it enough to check if the allocation was successful, like it's done in the program, as long as the values are initialized properly?

 

Would you mind having a look at what happens when SBTrackSlider() is called while the code is running? If so, I can upload a version with the proper initialization included. Otherwise, I guess this could be a good point for me to get familiar with Macsbug :) (Though I still lean towards this being a bug in the Control Strip software.)

 

By the way, I have had the initial value for the slider continuously set to 0 during all of my testing, since the slider won't appear when the value is less than 0.

Share this post


Link to post
Share on other sites

Yeah I can probably try to debug it this weekend.

 

Personally when writing a CODE resource that's handed a pointer when the system invokes it, I would always check to ensure it's not NIL before dereferencing it just in case something weird happened somewhere outside my code (or in case I allocated it in my Init... routine but then forgot to return it in some edge cases, or something!), just to prevent having to chase down weird cases where my variables hold random nonsense.  Again though I think it's unlikely this is happening.

Edited by Crutch

Share this post


Link to post
Share on other sites

Oh, it's buggy alright :) After having a first look at MacsBug, I played around a bit with a version of the control strip module that sets the initial value to "0" if the previously returned value is out of range (not using of MacsBug at this point) and discovered that if the module is just clicked on very quickly (without bringing up the slider (not possible every time) ), it returns the value "2". After that the slider works properly one time (positive values in the range specified). Bringing the slider up again a second time (now with a positive value passed as the initial value) makes the handle on the slider appear outside of the slider (makes sense, I guess…). Setting it to a new value makes it go back to negative values. However, if no new setting is made, the value returned appears to decrease by 2 and 3 alternately for each click, until it reaches "0". That is, unless the starting value is odd, in which case it appears to decrease by 4 the first time…

 

Also, if it's clicked on again after "2" is returned, it returns "−1" and then does so for all of the following clicks.

 

All of this seem to occur only when the initial value is positive.

 

Getting around this would involve patching the Control Strip software, I imagine. So odd that this bug isn't mentioned anywhere in the developer documentation… Surely, I can't be the first one to try out the slider function…?

 

Here's a version of the module that displays the value of the sliderSetting variable in place of the icon in Apple's example, and works as described above.

Module2.sit

Edited by PB170

Share this post


Link to post
Share on other sites
16 hours ago, PB170 said:

Oh, it's buggy alright :) After having a first look at MacsBug, I played around a bit with a version of the control strip module that sets the initial value to "0" if the previously returned value is out of range (not using of MacsBug at this point) and discovered that if the module is just clicked on very quickly (without bringing up the slider (not possible every time) ), it returns the value "2". After that the slider works properly one time (positive values in the range specified). Bringing the slider up again a second time (now with a positive value passed as the initial value) makes the handle on the slider appear outside of the slider (makes sense, I guess…). Setting it to a new value makes it go back to negative values. However, if no new setting is made, the value returned appears to decrease by 2 and 3 alternately for each click, until it reaches "0". That is, unless the starting value is odd, in which case it appears to decrease by 4 the first time…

 

Also, if it's clicked on again after "2" is returned, it returns "−1" and then does so for all of the following clicks.

 

All of this seem to occur only when the initial value is positive.

 

Getting around this would involve patching the Control Strip software, I imagine. So odd that this bug isn't mentioned anywhere in the developer documentation… Surely, I can't be the first one to try out the slider function…?

 

Here's a version of the module that displays the value of the sliderSetting variable in place of the icon in Apple's example, and works as described above.

Module2.sit

Would be fun to raise a ticket at Apples support site and report this as a software bug :lol:

Interesting to see if there is anyone left with a sense of humour at Apple or if all those guys are retired by now..

 

Anyway, keep reporting! It's a very interesting and fun read 8-)

Share this post


Link to post
Share on other sites
17 hours ago, John_A said:

Would be fun to raise a ticket at Apples support site and report this as a software bug :lol:

Interesting to see if there is anyone left with a sense of humour at Apple or if all those guys are retired by now..

 

Anyway, keep reporting! It's a very interesting and fun read 8-)

Haha :lol: Well, while I like the thought of it, the company that brags about having having 90-ish percent of their users on their latest OS and do all they can get away with to improve that number, would probably ditch bug reports about anything older than the second latest version unless it's critical. And you know, if it's humor, it's got to be market oriented. :wink: Anyone with any thoughts about the the past in their head are probably not retired, but fired :) But maybe I'm being too pessimistic.

 

Anyway, glad to hear you enjoy the thread! I had a feeling maybe it was getting a bit too specific to be of general interest :)

Share this post


Link to post
Share on other sites

It looks like my suspicion was correct and your statusRect is somehow getting nuked. SBTrackControl has no idea what to do with the nonsense Rect so pukes back a negative value. Here’s the statusRect Macsbug shows you passing in. I got this by noticing that you are putting the Rect at an offset of $000C to A6 on the stack for SBTrackControl, and doing “DM A6+C Rect” in Macsbug. I’ll look at your code again later and try to figure out what’s causing this. 
 

62D25396-DF2B-49FF-BDE4-AAEA24BFEA0E.jpeg

Share this post


Link to post
Share on other sites

OK I'm pretty sure the problem is in this weird implementation of DrawCurrentIcon.  Is this really Apple sample code?

 

This writes over the statusRect that was passed in by MacOS.  That seems weird.  I think this code should allocate a new Rect on the stack, set its coordinates, and call PlotIconSuite/DrawPicture with that.  What happens if you try your control strip module with all the lines after "arrowHeight = ..." commented out?  I think you should avoid every modifying the statusRect that gets passed in by the system and if you need to draw things elsewhere, set up a separate Rect on the stack or that.

 

From the Macsbug screen above, it looks like statusRect->top is good, and everything else is nonsense.  When I run this multiple times, statusRect->left and bottom are random nonsense values; statusRect->right is always -256.

Quote

 

void DrawCurrentIcon(Globals *gb, Rect *statusRect) {
    short            arrowHeight;

//    draw the current icon

    statusRect->right = statusRect->left + IconWidth;
    (void) PlotIconSuite(statusRect, atNone, ttNone, gb->lastIcon);

//    draw an ‘up arrow’ to show that the module has a popup menu

    arrowHeight = (**gb->popupArrowPicture).picFrame.bottom - (**gb->popupArrowPicture).picFrame.top;
    statusRect->left = statusRect->right;
    statusRect->right += (**gb->popupArrowPicture).picFrame.right - (**gb->popupArrowPicture).picFrame.left;
    statusRect->top = (statusRect->top + statusRect->bottom - arrowHeight) >> 1;
    statusRect->bottom = statusRect->top + arrowHeight;
    DrawPicture(gb->popupArrowPicture, statusRect);
}

 

 

Share this post


Link to post
Share on other sites

Typo in the Macsbug command above, should have been "DM (A6+C)^ Rect" with the caret.

 

Anyway, pretty sure that was the issue.  I rebuilt your sdev with the attached code that just manipulated a new Rect on the stack instead of messing with the one pointed to by statusRect.  Seems to work in my tests?

 

Hope this helps!

ControlStripSample.c

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×