http://fpcamigawiki.alb42.de/index.php?title=Intuition.SetWindowPointerA()&feed=atom&action=historyIntuition.SetWindowPointerA() - Revision history2024-03-29T10:24:51ZRevision history for this page on the wikiMediaWiki 1.35.1http://fpcamigawiki.alb42.de/index.php?title=Intuition.SetWindowPointerA()&diff=205&oldid=prevMolly: Corrected name of image and added some extra line between image and source code2014-08-09T11:16:18Z<p>Corrected name of image and added some extra line between image and source code</p>
<table class="diff diff-contentalign-left diff-editfont-monospace" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 11:16, 9 August 2014</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l13" >Line 13:</td>
<td colspan="2" class="diff-lineno">Line 13:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>First a little picture of a slight variation on the presented code (using 64x64 pointer instead of 32x32)</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>First a little picture of a slight variation on the presented code (using 64x64 pointer instead of 32x32)</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">[[File:MousePointer64x64.jpg]]</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del class="diffchange diffchange-inline">[[File</del>:<del class="diffchange diffchange-inline">Example.jpg]]</del></div></td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline">And the code that made it happen</ins>:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div><source lang="pascal"></div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div><source lang="pascal"></div></td></tr>
<!-- diff cache key db624220369-ntdbjym2gu:diff::1.12:old-203:rev-205 -->
</table>Mollyhttp://fpcamigawiki.alb42.de/index.php?title=Intuition.SetWindowPointerA()&diff=203&oldid=prevMolly: Initial content2014-08-09T11:06:53Z<p>Initial content</p>
<p><b>New page</b></p><div>Unfortunately no real explanation(s) yet, just some piece of code i wanted to 'rescue' out of the aros-exec.org 'haystack'.<br />
<br />
The code is quite self-explanatory though.<br />
<br />
The code was originally presented in [http://aros-exec.org/modules/newbb/viewtopic.php?viewmode=flat&type=&topic_id=8050&forum=1 this thread], [http://aros-exec.org/modules/newbb/viewtopic.php?post_id=79294#forumpost79294 this post] to be exact (2-3-2013).<br />
<br />
Another interesting (related) thread is [http://aros-exec.org/modules/newbb/viewtopic.php?viewmode=flat&type=&topic_id=8081&forum=2 this one], in which i stumbled upon some WritePixelArray() (/Alpha) curiosity (5-3-2013).<br />
<br />
But the 'mother' of all threads is [http://aros-exec.org/modules/newbb/viewtopic.php?viewmode=flat&type=&topic_id=4176&forum=1 this one] (21-1-2010)), in which the author of the new mouse pointer implementation explains how things are suppose to work in practice (don't worry, all the important information is already supplied in the comments of the presented source-code).<br />
<br />
<br />
Unfortunately code is also still in my old stubborn 'use my unts and types'-format, so it won't compile out of the box (hence this example is not situated on the main page from ALB).<br />
<br />
First a little picture of a slight variation on the presented code (using 64x64 pointer instead of 32x32)<br />
<br />
[[File:Example.jpg]]<br />
<br />
<source lang="pascal"><br />
program SinglePointerV2b; <br />
<br />
{$MODE OBJFPC}{$H+} <br />
<br />
uses <br />
aros_types, <br />
aros_exec, <br />
aros_dos, <br />
aros_graphics, <br />
aros_intuition, <br />
aros_cybergraphics, <br />
mytagsarray; <br />
<br />
<br />
(* <br />
author : MaGoRiuM <br />
date : 03-march-2013 <br />
Name : singlepointer revision V2b <br />
Topic : A quick'n'dirty mousepointer changing test <br />
Target : AROS <br />
Usage : Start from shell. No other windows must be open <br />
to ensure the shell-window is the first window <br />
on the screen. If not then the windows that has its <br />
cursor changed needs to be activated before the changes <br />
to the mousepointer are visible. <br />
The name of the window for which the mousepointer <br />
is changed is written in the shell along with <br />
other debug information. <br />
Tested in vesa mode only. Max dimensions tested <br />
64*64*32 (w*h*d) <br />
Disclaimer: Use and abuse at your own risk. <br />
This file is not meant for distribution. Its <br />
purpose is being an example. Bad coding style(tm) <br />
applies. <br />
*) <br />
<br />
<br />
(* <br />
Important notes: <br />
<br />
From Sonic in "New Mouse Pointer" thread on aros-exec.org <br />
<br />
FWIW Sonic is the AROS system developer that implemented the <br />
mousepointerclass. <br />
<br />
- The pointerclass attributes are not settable. You can pass them only <br />
during object creation. <br />
- If you want several different pointers then create several different <br />
objects. Then just switch between them using SetWindowPointer(). <br />
- Dont recreate the bitmap each time. After creating a pointerclass <br />
object you may re-use it. The bitmap is NOT attached to the created <br />
object in any way, data are copied and stored internally. <br />
See rom/intuition/pointerclass.c for more details. <br />
- Pixelformat specifies the order of bytes in RAM, not in a longword. So <br />
they are endianess-dependant. Take this into account if you use longword <br />
to specify your pointer image. <br />
*) <br />
<br />
<br />
(***************************************************************************) <br />
(** **) <br />
(** Routines that are missing from default units **) <br />
(** **) <br />
(***************************************************************************) <br />
<br />
Const <br />
BMF_SPECIALFMT = 1 shl 7; // Missing tag in agraphics unit. <br />
<br />
<br />
function NewObject(classPtr : pIClass; const classID: pChar; const tags : array of const) : Pointer; <br />
begin <br />
// Cast to pointer to avois clas between aros_utility and utility unit. <br />
NewObject := NewObjectA(classPtr, ClassID, Pointer(readinTags(tags))); <br />
end; <br />
<br />
procedure SetWindowPointer(win : pWindow; const tags : array of const); <br />
begin <br />
// Cast to pointer to avoid clash between aros_utility and utility unit. <br />
SetWindowPointerA(win, pointer(readintags(tags))); <br />
end; <br />
<br />
<br />
<br />
(***************************************************************************) <br />
(** **) <br />
(** Actual implementation **) <br />
(** **) <br />
(***************************************************************************) <br />
<br />
Const <br />
TAG_DONE = 0; // for convenience, no need for utility unit. <br />
<br />
RawDataWidth = 16; // The width in pixels of our rawdata <br />
RawDataHeight = 16; // The height in pixels of our rawdata <br />
<br />
<br />
Var <br />
RawData_16x16 : packed array[0..(RawDataWidth*RawDataHeight)-1] of longword = <br />
( <br />
// format AABBGGRR; <br />
$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FF0000, <br />
$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FFFFFF,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00FF0000,$00FF0000, <br />
$000000FF,$000000FF,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00, <br />
$000000FF,$000000FF,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00,$0000FF00 <br />
); <br />
<br />
<br />
<br />
(* <br />
Routine that creates an actual AROS cursor from the raw cursor data. <br />
Width, Height and Depth describes the raw data. <br />
*) <br />
Function AllocAROSPointer(Width, Height, Depth: Integer; RawData: pLongWord): pObject_; <br />
var <br />
px, py, r : Integer; <br />
CursorBM : pBitmap; <br />
CursorRP : pRastPort; <br />
cc : LongWord; <br />
aa,rr,gg,bb : Byte; <br />
AROSCursor : pObject_; <br />
WordWidth : LongInt; <br />
//RawDataAccess : pRawCursorData; <br />
<br />
begin <br />
AROSCursor := nil; <br />
{ <br />
Now we need to actually make real AROS cursor <br />
out of the raw data that is given. <br />
<br />
It is a slow process but luckiliy this could <br />
be execute tbefore a program actually runs so <br />
that it will not take away runtime performance. <br />
} <br />
<br />
{ <br />
Step 1: <br />
allocate an offscreen bitmap to copy the rgb32 pixeldata <br />
into. This creates a bitmap, that is unfortunately needed <br />
by AROS to create a new pointer. <br />
} <br />
CursorBM := AllocBitMap( <br />
Width, // sizeX, pixelwidth desired for bitmapdata <br />
Height, // sizey, pixelheight desired for bitmapdata <br />
Depth, // depth, number of bitplanes tha are at least allocated (32 bit for RGBA32) <br />
BMF_MINPLANES or BMF_SPECIALFMT or (PIXFMT_RGBA32 shl 24), // flags, see documentation <br />
nil // pRastPort(window^.RPort)^.BitMap <br />
); <br />
<br />
if (CursorBM <> nil) <br />
then writeln('allocated bitmap') <br />
else writeln('ERROR: allocating bitmap failed'); <br />
<br />
{ <br />
Step 2: <br />
A rastport to the offscreen-bitmap is needed in order to be able to <br />
actually write anything into the bitmap. <br />
On classic we would use initrastport, but AROS specifically tells use to <br />
use CreateRastPort(). Using inintrastport in this situation will freeze <br />
AROS-OS. <br />
NOTE: the rastport needs to be freed as well. <br />
} <br />
<br />
CursorRP := CreateRastPort; <br />
if (CursorRP <> nil) <br />
then writeln('created rastport for cursor') <br />
else writeln('ERROR: creating rastport for cursor failed'); <br />
<br />
{ <br />
Step 3: <br />
Attach bitmap to rastport to make connection. <br />
} <br />
CursorRP^.Bitmap := CursorBM; <br />
<br />
<br />
{ <br />
Step 4: <br />
The RAW defined pixeldata needs to be: <br />
- copied into the bitmap <br />
- an cursor object needs to be created from this bitmap <br />
} <br />
<br />
begin <br />
{ <br />
Step 4a: <br />
Copy data into the bitmap <br />
} <br />
// initialize the counter used to count the nr of pixels that are <br />
// drawn into the bitmap without any error. <br />
r := 0; <br />
<br />
for py := 0 to Height-1 do <br />
begin <br />
for px := 0 to Width-1 do <br />
begin <br />
// get color asociated with the current pixel <br />
cc := rawdata[py*width+px]; <br />
// break color component of pixel into seperate ARGB colorvalues <br />
rr := cc shr 0 and $FF; <br />
gg := cc shr 8 and $FF; <br />
bb := cc shr 16 and $FF; <br />
aa := cc shr 24 and $FF; <br />
<br />
{ <br />
// Check if the pixel is transparant (RGB=000) <br />
// If pixel is transparent we override alpha channel <br />
// if pixel has alphavalue we need to fill in alphavalue <br />
// for testing purpose only we fill in $FF which mean full color, no alpha <br />
} <br />
if (rr+gg+bb = 0) then aa := $00 else aa := $FF; <br />
// Put back the colors + corrected alpha value into the correct format in order to be able to write a pixel <br />
cc := (aa shl 24) + (rr shl 16) + (gg shl 8) + (bb); <br />
// write the pixel into the bitmap <br />
// cast to pointer because of type conflict between aros_graphics and agraphics unit. <br />
If WriteRGBPixel(Pointer(CursorRp), px, py, cc) = 0 then <br />
begin <br />
// if the pixel is written ok, increase counter so pixelwritecount can be checked <br />
inc(r); <br />
end; <br />
end; // for pixel-coordinates x <br />
end; // for pixel-coordinates y <br />
<br />
// write out the number of pixels that were written into the bitmap <br />
// if it doesn't match px*py then an error occured. <br />
writeln('wrote ', r, ' pixels into bitmap'); <br />
<br />
<br />
{ <br />
Step 4b: <br />
Now that the bitmap is setup correctly we attempt to create a cursor from it. <br />
} <br />
WordWidth := (Width + 15) shr 4; <br />
<br />
<br />
AROSCursor := NewObject(nil,'pointerclass', <br />
[ <br />
POINTERA_BitMap , CursorBM, <br />
POINTERA_WordWidth , WordWidth, // width of cursor in words. <br />
//POINTERA_XResolution, POINTERXRESN_DEFAULT, <br />
//POINTERA_YResolution, POINTERYRESN_DEFAULT, <br />
POINTERA_XResolution, POINTERXRESN_SCREENRES, <br />
POINTERA_YResolution, POINTERYRESN_SCREENRESASPECT, <br />
//POINTERA_XOffset , 0, // Hotspot x <br />
//POINTERA_YOffset , 0, // hotspot y <br />
TAG_DONE <br />
]); <br />
<br />
If (AROSCursor <> nil) <br />
then writeln('allocated new pointer object') <br />
else writeln ('ERROR: could not create new pointer object'); <br />
<br />
// assume object is created <br />
Result := AROSCursor; <br />
end; // done creating mousepointer object <br />
<br />
{ Step 5: <br />
Give back the rastport <br />
} <br />
FreeRastPort(CursorRP); <br />
<br />
{ Step 6: <br />
Give back the bitmap <br />
} <br />
FreeBitMap(CursorBM); <br />
<br />
{ <br />
!!!!! DONE !!!!! <br />
} <br />
<br />
end; <br />
<br />
<br />
(* <br />
Routine that free the AROS cursor and so give back the created object <br />
*) <br />
Procedure FreeAROSPointer(Var AROSCursor: PObject_); <br />
begin <br />
if AROSCursor <> nil then <br />
begin <br />
// we are done with our pointer so we can free the pointerclass <br />
// Actually it is undetermined what happens if a cursor is <br />
// still in use by the AROS system. <br />
DisPoseObject(AROSCursor); <br />
AROSCursor := nil; <br />
writeln('Disposed AROS object'); <br />
end <br />
else writeln('ERROR: AROS pointerObject was not allocated and could therefore not be destroyed'); <br />
end; <br />
<br />
<br />
(* <br />
Routine to test the mousepointer <br />
Delaycount = the nr of milliseconds to change the pointer <br />
AROSPointer = the feshly created mousepointer class that <br />
needs is being shown. <br />
*) <br />
Procedure TestPointer(delaycount: Integer; AROSPointer: pObject_); <br />
var <br />
screen : pScreen; <br />
Window : pWindow; <br />
begin <br />
// A window is needed, so start-out with a screen. <br />
Screen := LockPubScreen(nil); <br />
if (screen <> nil) then <br />
begin <br />
writeln('found screen ', screen^.Title); <br />
<br />
// get the window that is desperately needed <br />
window := Screen^.firstwindow; <br />
if (window <> nil) then <br />
begin <br />
writeln('found window ',window^.title); <br />
<br />
writeln('Starting cursor demo'); <br />
begin <br />
writeln('Attempting to display cursor'); <br />
<br />
// if the given pointer is valid then continue <br />
If AROSPointer <> nil then <br />
begin <br />
// actually link the mousepointer to the window <br />
// so that it becomes visible when the window is <br />
// activated. <br />
SetWindowPointer(Window, [WA_Pointer, AROSPointer, TAG_DONE]); <br />
<br />
writeln('Current cursor is being displayed'); <br />
// Wait some time before returning back. <br />
DOSDelay(DelayCount); <br />
end <br />
else writeln('ERROR: Cursor did not had a valid object'); <br />
<br />
end; <br />
writeln('ending cursor demo'); <br />
<br />
// after fiddling and changing the cursor, the window <br />
// needs back its original cursor. <br />
// Unfortunatly there is no way of knowing if giving <br />
// back the default cursor succeeded or not. <br />
SetWindowPointer(Window, [WA_Pointer, 0, TAG_DONE]); <br />
<br />
end else writeln('CERROR: ould not locate a window'); <br />
<br />
// Albeit a bit late, the locked screen must really be unlocked. <br />
unlockpubscreen(nil, screen); <br />
<br />
end else WriteLn('ERROR: could not locate a screen'); <br />
end; <br />
<br />
<br />
<br />
(* <br />
MAIN <br />
*) <br />
Var <br />
AROSMousePointer : pObject_; <br />
<br />
begin <br />
writeln('enter'); <br />
<br />
// create real AROS mousepointer class from raw data <br />
AROSMousePointer := AllocAROSPointer(16,16,32, @RawData_16x16[0] ); <br />
//AROSMousePointer := AllocAROSPointer(32,32,32, @RawData_32x32[0] ); <br />
//AROSMousePointer := AllocAROSPointer(64,64,32, @RawData_64x64[0] ); <br />
If AROSMousePointer <> nil then <br />
begin <br />
writeln; <br />
// Do some visual mousepointer changing <br />
TestPointer(1000, AROSMousePointer); <br />
writeln; <br />
// Free the AROS mousepointer object. <br />
FreeAROSPointer(AROSMousePointer); <br />
end; <br />
writeln('leave'); <br />
end.<br />
<br />
</source></div>Molly