Indirected icon data
GavinWraith (26) 1563 posts |
I have read the PRMs (Wimp_LoadTemplate p3-170, and Template Files p4-455) but find them rather inexplicit when it comes to identifying where the indirected data for a given icon in a given window is supposed to be. I had presumed that Wimp_LoadTemplate simply sweeps through the template file moving indirected data to the work buffer as it encounters it. But I have a template file containing a single window with two icons. The first (number 0) does not have indirected data. The second, an indirected text icon, (number 1) does. I would have presumed that the latter’s text would have begun at the start of the work buffer, but in fact it starts 4 bytes further on. Am I overlooking something? |
Rick Murray (539) 13840 posts |
What are these four bytes? It could be a null word for an empty indirected icon validation string, perhaps? [ if icon+20 points to the text, where does icon+24 point to? ] |
Steve Drain (222) 1620 posts |
Why do you need to know this? If it is not documented, surely you cannot rely on anything you do discover about how the data is organised at present. The actual address of the buffer is simple to find from Wimp_GetIconState. |
GavinWraith (26) 1563 posts |
So that I can update the icons. When I load a window from a template my code returns two things: the address b of a buffer containing the window data, ready for Wimp_CreateWindow, and the address indir of a buffer for the indirected sprite data. I need to calculate the offset f(i) into indir of the indirected data of the i -th sprite. Then I can poke new values there and use Wimp_SetIcon to refresh the screen. The point is, what is the algorithm for f ? My template file was created using WinED. Icon 0 is a sprite icon, and WinEd’s indirected box is unticked; hence my presumption that it makes no contribution to the indir buffer. But icon 1 is an indirected text icon, with validation string R2. I am puzzled why its name starts at indir+4 rather than at indir.
Yes, that is what I had been using. But I found that other tasks were going mysteriously wrong, and I traced this back to my code that was poking stuff into that address. Evidently I had made some nasty error, but poking into the indir buffer seems to be a bit safer. At least I know it is in my task’s address space, not another task’s. |
Steve Drain (222) 1620 posts |
Wimp_LoadTemplate does not return the address of the buffer for indirected data – you supply that in R2 and it returns the address of the unused space. Some Template editors will give you the combined length of the indirected data of all the windows, which you can use to claim the buffer. The icon block returned by Wimp_GetIconState gives you the address of the text buffer at +28 and its length at +36. Could you be writing beyond the buffer? |
Rick Murray (539) 13840 posts |
You know, the Template file does not necessarily represent what happens when the Templates are loaded into memory. For instance, the offsets of Indirected data in the file are offsets from the start of the current entry; however in memory these are pointers to where the data is located. The Template file is fairly clear. There is a short header. Then there is an index of entries (each window is an entry); this window index will contain an offset. Add the relevant window data offset to the Indirected icon offset, and the result will be the location in the file where the Indirected data is stored. Note, this applies only to the file. Not to a loaded template. I have a short function to change the text of an indirected icon. The only caveat is the length of the string written must be smaller than the indirected space, or else it’ll overrun.
Don’t make assumptions. Ask the Wimp for the relevant addresses, use those. |
GavinWraith (26) 1563 posts |
No, but but my (RiscLua) template.load procedure does. But I have discovered why the icon’s text data is at indir+4. It is because the window title data is indirected too, and this happens to be a string of 3 characters plus the terminating &D. I had forgotten that windows can have indirected data that does not come from sprites. Yes, I think I was writing beyond the buffer. A perilous business. But clearly reading the address of the text buffer at +28 and the length at +36 is the right way to go. I shall just have to do it more carefully. |
GavinWraith (26) 1563 posts |
This is all very useful to me. I note that items of indirected data do not necessarily start at word boundaries. I take it that once Wimp_CreateWindow has been called those pointers to indirected data are situated somewhere in the Wimp’s address space, where the user may not change them. So one should update the pointers to point at buffers in one’s own workspace after Wimp_LoadTemplate but before calling Wimp_CreateWindow. No that cannot be right, else Rick’s PROCIcon_SetText would not work. |
Jeff Doggett (257) 234 posts |
I have a generic function that returns the address of the text for an icon irrespective of whether it’s indirected or not. It’s not quite so well written as above, but I’m sure you’ll work it out.
Edit: Actually it’s not very well written at all! I’m sure you can spot the optimisations! |
Steve Drain (222) 1620 posts |
That would be possible, but pointless. You claim a block of memory in your own workspace for all the indirected data in a Template file, pass a pointer to it to Wimp_LoadTemplate and use the returned pointer for the next Wimp_LoadTemplate. The SWI does all the data shifting and updating of pointers before you then call Wimp_CreateWindow. You use Wimp_GetIconData to determine where the indirected data has actually been put. As a rider to this, a similar topic arose in the newsgroups about the pointer to a user sprite control block for an indirected sprite-only icon. In that case, a template editor will have set all the pointers to 1, the wimp pool, so you do have to go through through the template date and set the value you want before using Wimp_CreateWindow. FormEd certainly tells you to do this and expect other editors do, too. I probably have not done this in this century, but it all comes flooding back. The Toolbox makes it so much simpler, and in Basalt with its OOP syntax I only have to do:
;-) |
Steve Drain (222) 1620 posts |
You cannot change data that is not indirected unless you delete and recreate the icon. Wimp_GetIconState puts a copy of the icon block into the buffer you supply, so writing to the un-indirected address returned by your function will not change the icon itself. Wimp_SetIconState will only change the flags. |