A Bit of RB Trivia

March 31st, 2008 by Joe Ranieri

There’s a free license to CalendarKit 2 to the first person who can answer this question:

Name a situation when the global App object is nil (while executing user code).

* Offer not applicable to Norman Palardy or past or present REAL Software employees.

Update: We have posted the answers.


Demangling C++ Names

March 26th, 2008 by Joe Ranieri

RuntimeException.stack is one of the most useful things to be added to REALbasic. However, we can make it a bit better by demangling any C++ function names that might be in the stack trace.

Function CPPDemangle(name as string) As string
  //! Demangles a C++ function name. Returns an empty string on failure.
  //! Only works on Mac OS X.
 
  #if targetMacOS
      declare function __cxa_demangle lib "/usr/lib/libstdc++.6.dylib" ( name as CString, _
      outBuffer as ptr, outLength as ptr, byref outState as integer ) as CString
    declare sub free lib "System" ( value as CString )
    const kStateSuccess = 0
 
    dim state as integer
    dim demangledString as CString = __cxa_demangle( name, nil, nil, state )
 
    if state = kStateSuccess then
      // create our RB string, then free the string demangle gave us
      dim result as string = demangledString
      free( demangledString )
 
      return result
    end if
  #endif
End Function

Then you can apply this function to the exception’s stack like so:

Function GetErrorStack(err as RuntimeException) As string()
  //! Gets the stack trace for our exception. This differs from
 //! RuntimeException.stack in that it demangles C++ names.
 
  // this can crash in some cases, giving us a completely useless crash log
  // <rb-feedback://keeqghwg>, hopefully this will be fixed someday...
  dim stack() as string = err.stack
  dim cleanedStack() as string
 
  // the order of RB's "for each" isn't defined <rb-feedback://hdcdbgfi>, so we have
  // to use a normal loop
  for i as integer = 0 to stack.ubound
    dim name as string = stack( i )
    dim demangledName as string = cppDemangle( name )
 
    if demangledName <> "" then
      cleanedStack.append( demangledName )
    else
      cleanedStack.append( name )
    end if
  next
 
  return cleanedStack
End Function

So, instead of seeing “__ZN14RuntimeListbox7GetTextE15getTextSelectorll” in an exception trace, you will see “RuntimeListbox::GetText(getTextSelector, long, long)“. Much, much easier on the eyes. :)


CalendarKit 2.0 beta, integrates with Outlook on Windows

March 24th, 2008 by Alacatia Labs, Inc.

We are pleased to announce a beta of CalendarKit 2.0! The major new feature in this release is support for Outlook calendars under Microsoft Windows. Without any code changes, existing REALbasic applications using CalendarKit are now able to manipulate calendars on both Mac OS X 10.5 “Leopard” and Microsoft Windows.

The only known issue is that notifications of external changes to calendars are not yet working. We will address this in an update in the near future.

If you have purchased CalendarKit, your account page will give you the option of downloading the latest version. If you are interested in learning more about CalendarKit and what it can bring to your applications, please visit http://alacatialabs.com/products/calendarkit/ and download a demo.


Programatically Controlling Spaces

March 22nd, 2008 by Joe Ranieri

There’s been a lot of questions on mailing lists about how to control Spaces programatically. So far, there’s been no results from these discussions. Well, fortunately accomplishing this is quite simple, if you’re comfortable using private APIs.

Functions to query the current settings:

CGError CGSGetWorkspace(CGSConnectionID cid, CGSWorkspaceID *outWorkspace);
extern bool CoreDockGetWorkspacesEnabled();
extern void CoreDockGetWorkspacesCount(int *rows, int *columns);

You’ll probably also want to switch spaces. You can accomplish this by using a distributed notification. This tells the Dock to switch spaces, giving you all of the normal animations:

- (void)switchToSpace:(CGSWorkspaceID)spaceNumber {
  // note that the notification is 1 based, but CGSWorkspaceID is zero based!
  [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.switchSpaces"
                                                                 object:[NSString stringWithFormat:@"%i", spaceNumber + 1]];
}

And lastly, you’ll probably want to get notified when things change:

//! Gets called when the current space changes.
void SpaceChangedCallback(CGSNotificationType type, CGSWorkspaceID *workspace, unsigned int dataLength, Controller *self) {
  if(*workspace != kCGSTransitioningWorkspaceID) {
    // do something
  }
}
 
//! Gets called when the user enables or disables Spaces.
- (void)spacesEnabledChanged:(NSNotification *)notification {
  // do something
}
 
//! Start listening for workspace related changes.
- (void)registerForNotifications {
  // listen for when Spaces is enabled or disabled
  [[NSDistributedNotificationCenter defaultCenter] addObserver:self
                                                      selector:@selector(spacesEnabledChanged:)
                                                          name:@"SpacesEnableChange"
                                                        object:nil
                                            suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];
 
  // listen for when the current space changes
  CGSRegisterNotifyProc((CGSNotifyProcPtr)SpaceChangedCallback, kCGSNotificationWorkspaceChanged, self);
}

You can find a full code example in the CGSInternal svn repository under Examples/SpacesSwitchingMenu, which mimics the Spaces menu extra.

Happy hacking!


Review of Vista SP 1

March 19th, 2008 by Ryan Govostes

The Internets are abuzz with the news that Microsoft has finally released the first service pack to its widely successful Windows Vista, just one year (plus change) after it first hit retail store shelves.

As a user of Windows Vista Ultimate, I watched the service pack through its beta period with interest. As I’ve mentioned before, Windows and I don’t always see eye-to-eye, so I decided it best to refrain from installing an unstable, pre-release quality operating system on my production machine — a MacBook Pro.

So, I grabbed the Service Pack 1 updater from Microsoft. Weighing in at over 400 MB, the download took roughly an hour to complete. I giddily started the installation at a quarter past 11 PM; after a few reboots during the install process, I was greeted with a fresh view of Windows:

It isn’t often that a 255 by 139 pixel screenshot conveys so many layers of information. Your eye might first be drawn to the third line of text, suggesting that I have pirated Windows. Not so — in fact, my cell phone shows that I placed a 6 minute, 17 second call to Microsoft’s activation center at 8:50 PM, when I activated Windows for the nth time. The update seems to have deactivated my install; I haven’t tried to activate for the (n + 1)th time to see if it will work.

Second, you might notice that the time is 3:06 AM. That’s right — it took four hours to get me back into Windows. Consider that a fresh Windows Vista install takes around 45 minutes (if I remember correctly); OS X takes around 20. Never mind why I’m up at 3 AM on a school night, four hours is a ridiculous amount of time for a system update.

Third, the well-informed reader will note that the build number in the screenshot, 6000, does not match the build number of Windows Vista SP 1, which is 6001. That’s right. After four excruciating hours, the install failed — with no particularly informative error message. I can’t find the exact error number in my Windows logs, but there are thousands of entries at 3:01:37, all reading

Windows Servicing failed to complete the process of setting package
Package_82_for_KB936330~31bf3856ad364e35~x86~~6.0.1.18000 () into Staged(Staged) state

Finally, we note that the screenshot has a hideous red outline. I couldn’t figure out how the equivalent of print screen on my MacBook Pro keyboard, so I used the “Snipping Tool.”


Not sure of the point of allowing signups then…

March 14th, 2008 by Jonathan Johnson

I received this email a few minutes ago:

Dear Registered iPhone Developer,

Thank you for expressing interest in the iPhone Developer Program. We have received your enrollment request. As this time, the iPhone Developer Program is available to a limited number of developers and we plan to expand during the beta period. We will contact you again regarding your enrollment status at the appropriate time.

It seems to me if they were only opening it up to select people, they should have held off on the signup form until they were actually ready for people to sign up. I guess they have to wait to get our $99.

Update:
It sounds like it was either first-come or random. I guess we fail for now.


Another CKFrameworks Teaser

March 9th, 2008 by Joe Ranieri

I spent a bit of time this weekend working on CKFrameworks, so I figured I’d give another teaser. This time I’ll show off the CFType support…

// load our bundle
dim myFile as FolderItem = desktopFolder.child( "test.ape" )
dim bundle as CFTypeRef = CKFrameworks.CFBundleCreate( myFile )
 
// do some random stuff with it
bundle.loadExecutable()
msgbox( bundle.identifier )

Or perhaps you want to get time zone information:

dim timezone as CFTypeRef = CKFrameworks.CFTimeZoneCreateWithName( "EST", true )
msgbox( timezone.name )

As you can see, this is all pure magic. I’m hoping to have an alpha to show at REAL World, so be there or miss out.


Legally Insane

March 8th, 2008 by Joe Ranieri

You probably all are aware that Apple released the iPhone SDK a couple of days ago.

We’ve played around with it and definitely intend on developing for it. Ryan and I are getting iPod Touches, and Jon already has his iPhone. :)

Sadly, we can’t say too much about the SDK itself, because the whole thing is under NDA. That’s right, even though anyone can download it and use it, nobody is allowed to talk about it.

Oh well, lawyers are such silly things.


REAL World 2008 Agenda Calendar

March 8th, 2008 by Jonathan Johnson

In addition to Norman’s REAL World 2008 Track Calendar, I’ve created an iCal file for the conference agenda itself, excluding the session blocks. Combining his calendars with mine, you can now have the entire REAL World 2008 schedule in iCal. More importantly, it allows me to have everything on my iPhone :)

Subscribe

Download

Also, anyone who’s interested in meeting up with me and discussing any of our products, seek me out on Tuesday night, Wednesday, or Thursday. I’m also giving a talk on Team Development at 1:00 on Wednesday, so be sure to come if that sort of thing interests you.


Moral of the Story (Part 2ish)

March 5th, 2008 by Joe Ranieri

On a somewhat related topic from last time, I thought I’d mention some other nasty hacks I’ve seen passed off as safe.

Pre-emptive Threading

There are several libraries that claim to offer this in REALbasic. The problem is that it can’t be done. The RB runtime simply isn’t thread safe, not to mention the framework itself!

Something as trivial as referencing a string has the potential to bring down your whole application in bizarre and difficult-to-detect ways. Even if your code doesn’t directly touch the runtime, the code the compiler generates might. The rules on when it does so (to yield to another thread, for example) are undocumented and extremely likely to change from version to version.

To make a long story short: it’s a bad idea.

Weak References

Another library implemented weak references in a horrible manner. They simply unlocked the object and returned it, decrementing its reference count.

At first glance this would appear to work - your object goes away even if another object holds a weak reference to it. However, the problem occurs if you attempt to access the “weak reference” after its original object goes away. This will almost certainly crash your program.

The problem is that your “weak reference” still points to the place in memory where the object lived. By the time you use your “weak reference,” REALbasic has most likely already tossed something else in that location.

To make a long story short: it’s a bad idea.