Bluetooth in VMWare Fusion

Yesterday I wanted to update the firmware in my Parrot EasyDrive Bluetooth carkit. Seems simple enough to do it using VMWare Fusion. I started up Fusion, chose the option to connect the “Bluetooth USB device” and found that Windows didn’t have the driver. Crap, I remember having to do something with BootCamp to get the drivers, but I couldn’t recall. Now that BootCamp wasn’t a download (it is part of Leopard), I started poking around at the BootCamp Assistant and got no where. I searched online and couldn’t find an answer. Finally, I found a reference to inserting the Leopard DVD while in Windows. I tried this and when I did, the BootCamp driver installer came up and installed my drivers. Perfect; why couldn’t VMWare say something about this on their website?

Oh that brings me to something else, on the Mac, AutoPlaying of a data CD/DVD has been disabled for years, but it seems that Windows still has this on by default (I run Windows XP). Has Microsoft not learned from all the viruses and malware available for Windows? Are they taking that ease of use over security? While I understand there are tradeoffs, I think this is a poor one to make.

TV without violence?

My wife and I realized awhile ago that most of the shows we were watching/recording on TiVo had to do with crime/murder such as CSI: Miami, NCIS, Without a Trace, etc. While the shows are quite engaging, they are violent. I wasn’t sleeping well and my wife suggested that our TV viewing habits could be the cause. So, we decided to change our makeup of shows to shows without violence. Unfortunately we picked a real crappy time to do this because of the writer’s strike. We’ve started watching “chick” shows are there simply aren’t that many comedies and other good shows on TV. While the “chick” shows (i.e. Grey’s Anatomy aren’t my cup of tea, I am sleeping much better. We’ve thrown a few of the crime shows into the mix, although not as often, and I’m still sleeping well.

I’m not sure why we were so attracted to violent shows, but our choice of shows is changing which is a good thing because as our son grows up (and we determine how much TV he’ll be allowed to watch), we don’t want him watching violent shows.

Indie Software Developers

For years, I’ve seen references to “indie” (independent) software developers, but never considered myself one. I’ve never had to rely on sales of my own software as I’ve been an independent contractor without my own products (that brought in any significant amount of income) for almost five years. However, this past year, ReceiptWallet has started to change that; I’m not about to give up my day job, but in an exchange with another developer today, he referred to both of us as “indie” developers. I guess I am an independent developer.

Cool phone tricks

One of the things I “lost” when I shutdown my server and stopped running my Asterisk PBX was the ability to redirect calls to my phone to my computer in case I was out of town or the like. When we travelled back east last month, we stayed with my uncle who had really high speed Internet (Verizon FIOS), but had virtually no cell phone coverage (neither my Sprint PCS nor my AT&T phone could keep a connection). One day I had to take a business call, but didn’t want to hog my uncle’s phone line, so I re-directed my PBX to send my calls over SIP to my Mac (using the Gizmo Project’s SIP client). That was pretty cool, but I can no longer do that.

I’ve had a GrandCentral account for awhile and had read about forwarding to a Gizmo Project account. Today, I decided to play around and low and behold, I can still get work calls on my computer by having people call my GrandCentral number (which I’m now going to start giving out as my work number). Furthermore, I can make outgoing calls by adding people to my GrandCentral phone book and originating the call through the GrandCentral website (Gizmo Project charges for outgoing, but not incoming calls; this method makes the outgoing call actually an incoming call). So not only can I receive calls on my computer, I can now make free calls! I don’t need free calls as I have unlimited long distance on my home phone, I have 100 outgoing minutes per month on my work line, and more than enough minutes on my cell phones. I don’t even talk on the phone all that much!

Broken Idle Time in 10.4/10.5

After fighting with trying to get the amount of time since a user has done something with the system, I’ve determined that CGEventSourceSecondsSinceLastEventType is broken. The documentation indicates that calling it like:

CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType)

will tell me how many seconds since the user last moved the mouse, touched the keyboard, etc. The docs say:

The various system and app defined events do not contribute to this event type’s time.

Unfortunately this just isn’t true. In one app I’m working on, I have a timer that fires every 5 seconds and prints the idle time. It starts going up, but then a notification comes in and it resets back to zero without me touching the keyboard. So, this call is almost useless as I need to know when things are idle in order to perform some tasks. While some of you are saying that I can use a Carbon Event Idle Timer, it turns out that they don’t work in background only apps. My only solution is to make the above call using something like:

+ (double) idleTimeInSeconds
{
	double idleTime = 0;
	double tempIdleTime = 0;
	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventLeftMouseDown);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventLeftMouseUp);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventRightMouseDown);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventRightMouseUp);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventMouseMoved);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventLeftMouseDragged);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventRightMouseDragged);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventKeyDown);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventKeyUp);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventFlagsChanged);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventScrollWheel);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventTabletPointer);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventTabletProximity);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventOtherMouseDown);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventOtherMouseUp);
	if (idleTime == 0 || tempIdleTime < idleTime)
	{
		idleTime = tempIdleTime;
	}

	tempIdleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventOtherMouseDragged);

	return idleTime;
}

Wow, that is freaking ugly, but at least I know exactly when a user event occurred. Feel free to use my code in any way you see fit. I've searched the web and found answers to a lot of my problems, so here's a small contribution back to the community.