Une compilation de code de chez TalmsPalm:
Determining if your app runs on a ZodiacJohn Wilund, TamsPalm reader and Programmer extraordinaire, felt like sharing the following bit of code with all of you:
CODE
#ifdef __OBC__
#define sysFtrNumOEMCompanyID 20
#endif
#define twCreatorID 'Tpwv' // from TwDefs.h
Boolean isTapwave(void){
Err err;
UInt32 manufacturer;
if(FtrGet(sysFileCSystem, sysFtrNumOEMCompanyID, &manufacturer)== errNone)
return(manufacturer == twCreatorID);
return false;
}
It returns true if the device your program runs on is a TapWave Zodiac PDA. Feel free to use the source code in your programs!
Runs unsigned app on a ZodiacTo avoid the protection, just copy this little code on your source and call the TwGfxOpen() by this one:
CODE
static asm char TwGfxOpenNoSign (void *p, void *q)
{
stmfd sp!, {r4-r11,lr}
ldr r9, [r9]
ldr r9, [r9]
sub sp, sp, #0x24
mov r6, r0
mov r7, r1
ldr pc, =0x200995F0
}
Detecting vibrators and alarm leds programmaticallySometimes, you really need to know if the handheld that your app runs on has a vibrator or a alert LED. These routines can help you:
Boolean hasLED()
{
UInt32 capabilities;
FtrGet(kAttnFtrCreator, kAttnFtrCapabilities, &capabilities);
if (capabilities & kAttnFlagsHasLED)
{
return true;
}
else
{
return false;
}
}
Boolean hasVibration()
{
UInt32 capabilities;
FtrGet(kAttnFtrCreator, kAttnFtrCapabilities, &capabilities);
if (capabilities & kAttnFlagsHasVibrate)
{
return true;
}
else
{
return false;
}
}
These routines worked in both PODS 1.1 and OnBoardC. Feel free to use them in your own apps!
Tapwave Rumble effectsCODE
TwDeviceHandle rumblerH;
typedef struct
{
void * data; // Volume & duration pairs.
Int32 size;
} EffectInfo;
void HostPlayRumble(short int effect);
void HostPlayRumble(short int effect)
{
// A real scheme would important data from resources.
// A single, short bump.
UInt8 EffectBump[] =
{
255,20,0,5,255,10
};
EffectInfo EffectData[1];
EffectData[0].data = EffectBump;
EffectData[0].size = sizeof(EffectBump);
// Send to the rumbler
TwDeviceControl(rumblerH, 'play',
EffectData[effect].data,
EffectData[effect].size);
}
In appstart
TwDeviceOpen(&rumblerH, "vibrator0", "w");
and in appstop
TwDeviceClose(rumblerH);
and play rumble with
CODE
HostPlayRumble(0);
Detecting color screens programaticallySometimes, you will need to determine if your application is running on a device with a color screen. This ultra-sleek C routine returns true if your app runs on a handheld with a color screen:
CODE
Boolean hasColorCrt()
{
Boolean enableColor;
WinScreenMode(winScreenModeGet, NULL,NULL, NULL,&enableColor );
return enableColor;
}
It was tested on a OS4 Palm V, a Tungsten T3 and a Tungsten E2. It compiled perfectly in PODS 1.1 and OnBoardC. Feel free to use it in your apps!
Debugging with decoy printfsMost people make mistakes when programming. Today, I had an interesting debug session with Mr. Stuttner(he still does good LAN parties) today. Since the stuff we looked at may be interestinf for more of you, here is a brain-dump of what we did!
The program was designed to convert characters without using library functions(just macros), but it didnt work. It always converted to lower. Anyways, we decided to trace the program by intersting a few decoy alerts into the program:
CODE
#include "stdafx.h"
#define Upper(c)((c>='a'&&c< ='z')?(c-'a'+'A'):(c))
#define Lower(c)((c>=’A'&&c< ='Z')?(c-'A'+'a'):(c))
int _tmain(int argc, _TCHAR* argv[])
{
char c;
printf("Buchstabe Eingeben der Gros geschreiben werden soll:\n");
scanf("%c",&c);
printf("Ihre Eingabe: %c\n",c);
if ((c<=65) && (c>=90))
{ printf(”If”);
c=Upper(c);
}
else
{ printf(”Else”);
c=Lower(c);
}
printf(”Auswertung: %c”,c);
scanf(”%d”,c);
return 0;
}
Now, we knew what happened. And indeed, the condition of the loop was erroneously formulated. This led to the following program:
CODE
#include "stdafx.h"
#define Upper(c)((c>='a'&&c< ='z')?(c-'a'+'A'):(c))
#define Lower(c)((c>=’A'&&c< ='Z')?(c-'A'+'a'):(c))
int _tmain(int argc, _TCHAR* argv[])
{
char c;
printf("Buchstabe Eingeben der Gros geschreiben werden soll:\n");
scanf("%c",&c);
printf("Ihre Eingabe: %c\n",c);
if ((c>=65) && (c< =90))
{
c=Upper(c);
}
else
{
c=Lower(c);
}
printf("Auswertung: %c",c);
scanf("%d",c);
return 0;
}
This program worked better, but still was unreliable. It now simply returned the character given. SO, we fed in decoys yet again!
CODE
#include "stdafx.h"
#define Upper(c)((c>='a'&&c< ='z')?(c-'a'+'A'):(c))
#define Lower(c)((c>=’A'&&c< ='Z')?(c-'A'+'a'):(c))
int _tmain(int argc, _TCHAR* argv[])
{
char c;
printf("Buchstabe Eingeben der Gros geschreiben werden soll:\n");
scanf("%c",&c);
printf("Ihre Eingabe: %c\n",c);
if ((c>=65) && (c< =90))
{ printf("Converting to upper");
c=Upper(c);
}
else
{ printf("Converting to lower");
c=Lower(c);
}
printf("Auswertung: %c",c);
scanf("%d",c);
return 0;
}
We now saw that the statements need to be exchanged! And so, finally, we exchanged the upper and lower macros to get a nice and working routine!
CODE
#include "stdafx.h"
#define Upper(c)((c>='a'&&c< ='z')?(c-'a'+'A'):(c))
#define Lower(c)((c>=’A'&&c< ='Z')?(c-'A'+'a'):(c))
int _tmain(int argc, _TCHAR* argv[])
{
char c;
printf("Buchstabe Eingeben der Gros geschreiben werden soll:\n");
scanf("%c",&c);
printf("Ihre Eingabe: %c\n",c);
if ((c>=65) && (c< =90))
{
c=Lower(c);
}
else
{
c=Upper(c);
}
printf("Auswertung: %c",c);
scanf("%d",c);
return 0;
}
So, overall, this was funky! Indeed, debugging gets much easier if you insert decoy alerts into your program. This is much easier than using breakpoints,… . For the Palm OS, FrmAlert and FrmCustomAlert may be suitable decoys!
malloc and free for Palm OS
This code was posted by Estêvão Samuel Procópio to the OnBoardC newsgroup. It replaces the malloc and free functions of regular C compilers, this can be useful when using code from books. Altough these two functions can easily be replaced by calls to MemPtrNew and MemPtrFree(with other functions, the parameters need to be switched), this code is very interesting and thus is beeing posted here. You know, one never reads enough code…
CODE
MemPtr malloc(UInt16 size) {
MemHandle h = MemHandleNew(size);
if (!h) return NULL;
return (MemPtr) MemHandleLock(h);
}
void free(MemPtr ptr) {
MemHandle h = MemPtrRecoverHandle(ptr);
if(!h) return;
MemHandleUnlock(h);
MemHandleFree(h);
ptr = NULL;
}
Determining if a handheld has a rectangular screenEver since BinaryClock 2.0 was released, users were annoyed about how the fullscreen mode option was shown on all handhelds with Palm’s new Pen Input Manager.
However, I now found a new routine that accurately determines if a handheld has a “retractable DIA”. In fact, on a TUngsten T3, it even offers Fullscreen mode when the slider is closed(hides the status bar then).
CODE
Boolean PlmsDia()
{
Err err;
UInt32 version;
//dont ask why-obc wants null here or fatal alert
err=FtrGet(pinCreator, pinFtrAPIVersion, &version);
if(!err)
{
return true;
}
else
{
return false;
}
}
if(PlmsDia() && PINGetInputAreaState()!=2)//Works bc PlmsDia gets evaluated first
{
MenuShowItem(MenuFullscreen);
}
else
{
MenuHideItem(MenuFullscreen);
}
break;
PlmsDia is a security function, all it does is make sure that the call doesn’t “kill” handhelds without the latest version of the Pen Input Manager.
You can play around with this code in a few hours, as a golden beta of BinaryClock 2.1 will be released soon!