Palm OS has a nasty little “habit” of forcing code resources to have a defined maximum size – if that size gets exceeded, the code needs to be “swapped out” into another resource(called segmenting). Creating such multi-segment applications in projects that have Managed Make enabled is difficult – but a reader sent me this tutorial some time ago(which works really well):

In case you need it, here is a copy of my notes on going multisegmented
(including some quoted comments from other list subscribers and things
I found on the net — thanks guys, and sorry I didn’t include credits).
My comments are in square brackets.

================== Multisection/Multisegmented Applications =======

1 – Create a “Managed Make 68 C/C++ Project” (only managed project works
with me)
2 – Create a file named “Sections.def” in the root of your project
3 – In the top of “AppMain.c” or equivalent, include the file “Section.h”
4 – Now, edit the file “Sections.def” and “Sections.h” to define what
sections your project will have.

Sample: “Sections.def”
=======================
application { “_temp_” TEMP }
multiple code { “code1″ “code2″ }
=======================
[You must have at least one segment in the 'multiple code' definition.
The names must match those in Sections.h. Try to minimize the number
of sections you define and use, while making sure none of them grow
too big. In place of "_temp_", use your application's name. In place
of "TEMP", use your Creator ID.]

Sample: “Sections.h”
=======================
#ifndef _SECTIONS_H
#define _SECTIONS_H
#define EXTRA_SECTION_ONE __attribute__ ((section
(“code1″)))
#define EXTRA_SECTION_TWO __attribute__ ((section
(“code2″)))
#endif
=======================
[The names (here code1 and code2) can be whatever you want, but must
match those in Sections.def. You can use whatever you want as the
symbol defined. Here, it's EXTRA_SECTION_*, but could be anything.
You will use it again in #5, just below.]

5 – On the function definition specify what section will be used, the non
specified functions will be redirect to default section code.
[Try to group functions together to minimize the jumps between sections.
Be careful not to miss any, because they will default to your first
section, and possibly make it too big.]
Sample:
=======================
// [Here's where the compiler learns where to put the function:]
static void myfunc() EXTRA_SECTION_ONE;
// [Remember to add the macro every time you add a new function to your
// application!]

static void myfunc() {
// `the code`
}
=======================
If your project have a section defined and don’t use it anywhere, you got a
error. So, you need use the sections defined one time at least, or don’t
define it.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

For a managed project, in your project properties, you need to go to the
build panel and choose the prc-tools-68k-compiler->Symbols section and
add a line:

MULTISECTION_BUILD=true

to make the managed project look for your .def file. If you do everything else
in the prior posting it should then work. (The stock Sections.h file said to use
MULTIPLE_CODE_SECTIONS, but that didn’t work. I found the definition above
by looking at the generated objects.mk file.)
[I tried this and it worked; I didn't try MULTIPLE_CODE_SECTIONS - JT]

NB It also seems to require that some function be in each section or it will
complain about the section not existing at link time.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

[Also, it might help after adding the files to the project, right click
on the project's name in the Navigation window and select Refresh,
before building the project.]

Jay Ts

Thank you very much for sending this in(a few months ago…whew, some things take a LOOONG time). All I can add is that you should clean the project whenever you get ld issues at compile time – there seems to be some kind of weird segmenting cache somewhere in PODS!

Creating DIA aware applications(applications that can compact the Grafitti area on handhelds like the Palm Tungsten T3) with OnBoardC has been a difficult task for beginners, as OnBoardC’s header lacks the necessary support information for PenInputManager.h.

I created an OnBoardC-Compatible version of PenInputManager.h that just needs to be installed into the Palm handheld’s RAM and needs to be included like this:

#include "PenInputManager.h"

Download the header here.

John Wilund’s SrcEdit has had problems identifying the Treo 600′s 5way navigator – we managed to fix that a few days ago. John allowed me to share his routine with all of you:

Please have a look:

// From the Handspring headers // HsExtCommon.h
#ifndef hsFtrCreator
#define hsFtrCreator 'hsEx'
#endif
#ifndef hsFtrIDNavigationSupported // HsExtCommon.h
#define hsFtrIDNavigationSupported 14
#endif´
#ifndef sysFtrNumUIHardwareFlags // SystemMgr.h
#define sysFtrNumUIHardwareFlags 27
#endif
#ifndef sysFtrNumUIHardwareHas5Way // HsKeyCommon.h
#define sysFtrNumUIHardwareHas5Way 0x00000001
#endif

UInt32 val;
if (FtrGet (hsFtrCreator, hsFtrIDNavigationSupported, &val) == errNone)
// 5-Way Rocker

if (FtrGet (sysFileCSystem, sysFtrNumUIHardwareFlags, &val) == errNone)
{
if (val & sysFtrNumUIHardwareHas5Way)
// 5-Way Rocker
}

I just wonder what Treos the first and what Treos the second statement will find, respectively...

The Palm OS’s display system had to undergo three mayor overhauls in the last few years – dynamic UI(long time ago), HiRes+ and 5way navigation. The path to dynamic UI was very, very buggy afaik, HiRes+ worked well and 5way nav is, umm, more like dynamic UI to me.

Anyways, I had a nice modal form that reacted to WinDisplayChangedEvents. That form was popped up via FrmPopupForm(the only such form in the entire app…all others worked fine =) ). The resizing didn’t quite work out on Chris Schrinner’s TX:
a Fixing 5way navigation distortion   or   how to prevent the blue ring from fuxating your modal form
b Fixing 5way navigation distortion   or   how to prevent the blue ring from fuxating your modal form

There seems to be some kind of quirk with PalmOne engineers having placed a cache into their 5way nav system that stores whats behind the blue ring. Now, when the form gets resized, this cache somehow screws up and distorts/obfuscates the proximity of the poor control that happened to be selected.

Fixing the problem is rather simple – remove the focus, do the movement and then restore focus. Here is how I did it(no special headers needed btw):

UInt32 buffer;
Err err;
err = FtrGet(sysFtrCreator, sysFtrNumFiveWayNavVersion, &buffer);
if (err == errNone)
{
// One-handed navigation is supported
buffer=FrmGetFocus(pForm);
FrmSetFocus(pForm,noFocus);
FrmNavRemoveFocusRing (pForm);
}

//Party with the controls here

if(err==errNone && buffer!=noFocus)
{
FrmSetFocus(pForm,buffer);
}
FrmDrawForm(pForm);

P.s. I know that this code doesn’t detect the Treo 600 as 5way capable. But since the Treo 600 has no HiRes+ screen, I don’t really care as it will never see this code anyways….

Finding out that a field has changed is not easy on the Palm OS, as it doesnt have a “Field Changed” event like Visual Basic et al have. Since I needed such a snippet in the new AutoSync version, I decided to share it right here:

case keyDownEvent:
//send NilEvent
EvtSetNullEventTick(TimGetTicks()+ 2);
break;
case nilEvent:
//Field MAY have changed
foo();
break;

Basically, this code is straightforward. Whenever an user enters a character, a null event gets added to the queue. Whenever you get a null event, there is a possibility that the field has changed!

This code is here by popular demand(hello, Jonas).


{
MemHandle h=MemHandleNew(60);
MemPtr p=MemHandleLock(h);
StrPrintF(p,"Sync in %ld seconds",integer);
MemHandleUnlock(h);
FldFreeMemory(getObjectPtr(pForm, FldTimeLeft));
FldSetTextHandle(getObjectPtr(pForm, FldTimeLeft),h);
FldDrawField(getObjectPtr(pForm, FldTimeLeft));
}

Understanding how it works is trivial. First, a handle is obtained(size is chosen very big, 1kb doesnt matter nowadays so why care about a few bytes). This handle is then locked to obtain a pointer. Then, StrPrintF – the Palm OS equivalent of printf() is used to write into the handle.

After that, the field is assigned the handle and is redrawn…

I programmed this little ‘gem’ a bit of time ago:


static Int16 asciisort(char* s1, char* s2)
{//recursive ascii sorter for SysQSort
//FIXME: fails if both strs are exactly the same
//0...p1==p2
//-1.p1 < p2
//1...p1 > p2
if(*s1< *s2)
{
return -1;
}
else if(*s1>*s2)
{
return 1;
}
else
{
return asciisort(++s1,++s2);
}
}

Don’t ask me why I did it recursively, but it was the easiest way to code it(imho). The code breaks when two filenames are exactly equal, but well, this rarely happens…

The Fossil WristPDA SDK advices developers to use a FossilIsWristPDADevice call to determine if the device that their application currently runs on is a WristPDA. I tried this, and it didnt work – at all! Both Palm Tungsten T3 and Simulator died producing an error mesage saying (Sys 0505) (0,1092).

Anyways, I can propose you a better solution:

Boolean isWpda()
{
UInt32 foo;
if(WPdaGetVersion(&foo)==errNone)
{
return true;
}
return false;
}

This function works perfectly well on every machine I could get my hands on. So, use that instead of FossilIsWristPDADevice from now on!

Updated to work around WristPDA API bug
Palm handhelds like the Tungsten T3(before the PalmOne 5way one-handed nav stuff I never quite liked) had a nifty feature – you pressed the center button of the 5way nav, and if the form contained a buton called OK, it was tapped automatically. Since Tam Hanna is a creature of habit, I wanted the enter button of the rocker of my WristPDA to do the same thing to open forms in Binary Clock for Palm OS.

After a quick check into the SDK I found out that Fossil has designated the back button for this task – no problem, lets handle both. Here is a bit of code that you can more-less cut and paste into the form handler of all forms where you want this behaviour(attention – you need the WristPDA SDK included and the user cant exit to the launcher from this form):


//This goes somewhere global
Boolean isWpda()
{
UInt32 foo;
if(WPdaGetVersion(&foo)==errNone)
{
return true;
}
return false;
}

//This goes into frmOpenEvent
if(isWpda())
{
FossilBackKeyModeSet(kFossilBackKeyLauncher);
}

//And this goes into the event loop of the form handler
case keyDownEvent:
//For WristPDA
if(pEvent->data.keyDown.chr==vchrHardRockerEnter || pEvent->data.keyDown.chr==vchrHardBack)
{
EventType event;
event.eType=ctlSelectEvent;
event.data.ctlSelect.controlID=OK;
EvtAddEventToQueue(&event);
FossilBackKeyModeSet(kFossilBackKeyStopEvent);
handled=true;
}
break;

There is little to be explained here – enjoy!

Creating text with a transparent background is a problem that’s probably as old as the merry Palm OS function WinDrawChars. Many developers(including me) used abstruse techniques to create it(I used a bitmap lookup table, more on that if anyone is interested) – but I now found the official, PalmSource-approved, Palm TX safe way.

WinPushDrawState();
WinSetDrawMode(winOverlay);
WinPaintChar(char,xpos,ypos);
WinPopDrawState();

Simple, huh…. . And by the way, it really works well – even in the simulator!

Ever 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).


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!

Many times, I reccommended people the PalmOS developer mailing list/newsgroup if they have questions about how to program the Palm OS(especially to those who fill the OnBoardC list with it and wonder about the rather few replies).

accessing the group is a very comfortable process, as a “email interface” is available that either sends you individual emails or a daily digest. You can find out more about that interface here:
http://www.palmos.com/dev/support/forums/help.html#subscribing

You can search the existing ‘archives’ here:
http://news.palmos.com/read/?forum=palm-dev-forum

Starting to program the Patlm OS is a rather difficult task(especially if you don’t know C, altough this can help you). After having overcome the walls of C, however, new skills await you. You need to get a grasp on an entirely new set of API’s, a new aproach to data storage,… .

SDK documentation CAN be helpful, but one always wishes for a tutorial at some point in time. PalmSource has its sample code dump, yeah, but Eric Poncet wrote up a nice bunch of examples on his web site:

http://mobile.eric-poncet.com/palm/tutorial.html

This is definitely a good read!

John Wilund, TamsPalm reader and Programmer extraordinaire, felt like sharing the following bit of code with all of you:

#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!

© 2013 TamsPalm - the Palm OS / web OS Blog Suffusion theme by Sayontan Sinha