[comp.sys.amiga] Mouse Pointer Help Required

zmacv91@doc.ic.ac.uk (Peter Walkley) (01/29/88)

I'm posting this for a friend who needs help.  I'm also not sure how far
out of this site messages I post will get.  Should be interesting to
find out.  Enough of this digression .

My friend wants a CLEAN way of getting rid of the mouse pointer, and
then being able to restore it again.  He's writing a demo that grabs
the display (i.e Ignores intuition), and wants the MP out of the way.

i.e.

	GetRidOfThePointer() ;

	.....
	hack() ;
	morehack() ;

	.....

	PutThe MousePointerBack() ;

can anyone help ?

P. Walkley

hsgj@batcomputer.tn.cornell.edu (Dan Green) (02/01/88)

In article <168@gould.doc.ic.ac.uk> zmacv91@doc.ic.ac.uk (Peter Walkley) writes:
>My friend wants a CLEAN way of getting rid of the mouse pointer, and
>then being able to restore it again.  He's writing a demo that grabs
>the display (i.e Ignores intuition), and wants the MP out of the way.
>  P. Walkley

Here is a method I clipped out from a program of mine.  It works, and I
sure HOPE its "approved", but I don't know for sure.  Note that this
example replaces the arrow with another image -- for your purposes, just
set this image to all 0's, or don't even bother with the image and in
the for() loop just jam 0's into the array.  But I am getting ahead of
myself...  By the way, make sure "intuition.library" is opened, and that
you include stuff, at least intuition.h, preferences.h (v1.2), and 
types.h.  Since you are not using intuition, make sure that you run
pointer_new BEFORE your hack, and pointer_old AFTER you hack and when
intuition is back in action.  Otherwise, you'll be in hot water...

------ code -----

/* Sprite Image data used when replacing pointer with image */
USHORT	pointer_image[] = {
	0,	0,		/* Don't touch these two words */
	0x7FFF, 0x0000,	/* NEW POINTER IMAGE STARTS HERE */
	0x6083, 0x1FFC,
	0x4081, 0x3FFE,
	0x4E39, 0x3FFE,
	0x4E39, 0x3FFE,
	0x4E39, 0x3FFE,
	0x4E39, 0x3FFE,
	0x4E39, 0x3FFE,
	0x4001, 0x3FFE,
	0x4001, 0x3FFE,
	0x4001, 0x3FFE,
	0x4001, 0x3FFE,
	0x4001, 0x3FFE,
	0x6003, 0x1FFC,
	0x7007, 0x0FF8,
	0x7FFF, 0x0000, /* NEW POINTER IMAGE ENDS HERE */
	0,	0		/* Don't touch these two words */
};

USHORT	OldPointer[POINTERSIZE];	/* Saves old mouse pointer */

/*
 * pointer_new()
 *	Replace pointer with the new image.
 */
void	pointer_new()
{
	struct	Preferences	prefs;
	int	i;

	/* Save mouse pointer and fill pointer with new image */
	GetPrefs(&prefs,sizeof(struct Preferences));
	for (i = 0; i < POINTERSIZE; i++) {
		OldPointer[i] = prefs.PointerMatrix[i];
		prefs.PointerMatrix[i] = pointer_image[i];
	}
	SetPrefs(&prefs,sizeof(struct Preferences),TRUE);
}

/*
 * pointer_old()
 *	Turn pointer from the new image back to its original form
 */
void	pointer_old()
{
	struct	Preferences	prefs;
	int	i;

	/* Restore mouse image */
	GetPrefs(&prefs,sizeof(struct Preferences));
	for (i = 0; i < POINTERSIZE; i++)
		prefs.PointerMatrix[i] = OldPointer[i];
	SetPrefs(&prefs,sizeof(struct Preferences),TRUE);
}

--- end code ---

-- Dan Green
-- 
ARPA:  hsgj@tcgould.tn.cornell.edu
UUCP:  ihnp4!cornell!batcomputer!hsgj   BITNET:  hsgj@cornella

phils@tekigm2.TEK.COM (Philip E Staub) (02/02/88)

In article <168@gould.doc.ic.ac.uk> zmacv91@doc.ic.ac.uk (Peter Walkley) writes:
>My friend wants a CLEAN way of getting rid of the mouse pointer, and
>then being able to restore it again.  He's writing a demo that grabs
>the display (i.e Ignores intuition), and wants the MP out of the way.
>
>i.e.
>
>	GetRidOfThePointer() ;
>
>	.....
>	hack() ;
>	morehack() ;
>
>	.....
>
>	PutThe MousePointerBack() ;
>
>can anyone help ?
>
>P. Walkley

I don't know how "clean" you would consider this, but in the include file
"gfxmacros.h" there is a pair of macros OFF_SPRITE and ON_SPRITE which will
achieve what you asked for, (of course, as long as you're not using sprites).

So using your above example:

	OFF_SPRITE;
	...
	hack();
	morehack();
	...
	ON_SPRITE;


I found this when attempting to do the same thing you describe, and I knew I
wouldn't be using sprites in my hacks.

I strongly suspect there is a more "official" way to do this. I can think of 
at least two possibilities: a) a call which moves the mouse pointer off the
visible display area, and b) one which simply disables sprite 0 (I think
that's the one the mouse pointer uses. It's been a long time and my memory
is not too good right now). But in cases which aren't going to use sprites,
this is quick and effective.

Hope this helps.
Phil
-- 
------------------------------------------------------------------------------
Phil Staub                     "I do NOT approve. I merely said I UNDERSTAND."
tektronix!tekigm2!phils                                              - Spock
phils@tekigm2.TEK.COM

ali@rocky.STANFORD.EDU (Ali Ozer) (02/02/88)

In article <168@gould.doc.ic.ac.uk> Peter Walkley writes:
>My friend wants a CLEAN way of getting rid of the mouse pointer, and
>then being able to restore it again.  He's writing a demo that grabs
>the display (i.e Ignores intuition), and wants the MP out of the way.

Among the answers posted so far, one involved using ON_SPRITE/OFF_SPRITE,
and the other involved changing Preferences image --- as long as there
is any chance the user might be interacting with any other tasks at the
same time, I think both of these methods run into problems... The
approved way to change the mouse pointer under Intuition is 
SetPointer/ClearPointer, which allows you to have a different mouse
pointer image for every window without having to do any shuffling of images.

Of course, without Intuition, you don't have a window or screen, and this is
not possible. So then you might want to use one of the above methods... 

I should add that in my opinion, people should make every effort to 
use Intuition before they give up --- I hope your friend didn't just 
discard Intuition aside without trying to use it. No matter what
program you are running, demo or game, I think being able to pull the
screen down and show the stuff going on the back adds a lot to the
impressiveness and wow-factor. That is one reason why I like Amoeba
as much as most of my commercial arcade-style games. Or look at
The Director --- it is Intuition-friendly, and it runs ANIMs almost as fast
as ShowAnim... It's sure wild to be able to pull screens up and down while
an animation is going on!

Ali Ozer, ali@rocky.stanford.edu

scott@applix.UUCP (Scott Evernden) (02/03/88)

In article <168@gould.doc.ic.ac.uk> zmacv91@doc.ic.ac.uk (Peter Walkley) writes:
>	GetRidOfThePointer() ;
>	.....
>	hack() ;
>	morehack() ;
>
>	PutThe MousePointerBack() ;

Can't you simply SetPointer() the cursor to be something which is all
color 0 (i.e., transparent)?   Alternatively, (and I've never tried this)
couldn't you SetPointer() a 0 sized sprite image?

	like: SetPointer(window, junkptr(?), 0L, 0L, 0L, 0L);
                                             ^   ^
                                             |   |
		           i.e., nothing ----+---+

Natch, the other restoring call is ClearPointer(window).

-scott

cmcmanis%pepper@Sun.COM (Chuck McManis) (02/03/88)

In article <3542@batcomputer.tn.cornell.edu> (Dan Green) writes:
>In article <168@gould.doc.ic.ac.uk> (Peter Walkley) originally wrote:
>>My friend wants a CLEAN way of getting rid of the mouse pointer, and
>>then being able to restore it again.  He's writing a demo that grabs
>>the display (i.e Ignores intuition), and wants the MP out of the way.
>>  P. Walkley
>
>Here is a method I clipped out from a program of mine.  It works, and I
>sure HOPE its "approved", but I don't know for sure.

AAAAAAAAAAAAAAAAAAARRRRRRRRRRRRRRRRRRRRRGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHH!
So close, and yet so far away. The 'clean' approved way of changing your
pointer to ANYTHING, including 'nothing' is to use the Intuition 
SetPointer call. To restore it to the original preferences set pointer
you can use the Intuition ClearPointer() call. BUT THERE IS A GOTCHA!
And a very important one it is. The data you pass to SetPointer(), and
read my lips here, MUST BE IN CHIP RAM OR YOU WILL GET AN UGLY SMEAR
ON SYSTEMS WITH FAST RAM.

So, the appropriate code would be something like ...

UWORD	*Newpointer = NULL;

GoAwayPointer()
{
  if (!NewPointer) NewPointer = AllocMem(2*sizeof(UWORD),MEMF_CHIP+MEMF_CLEAR);
  SetPointer(NewPointer,1,1,1,1);
}

ComeBackPointer()
{
  ClearPointer();
}

Note also that the pointer is a sprite and follows the rules for sprite 
images, meaning that each plane is represented by "n" UWORDs where n is
the number of lines high the new image is, and that you have to have 
2 planes because a sprite is 3 colors (plus transparent). So 1 * 2 = 2
UWORDs. Finally, set the hotspot to 1,1 because if you set it to 0,0
SetPointer sometimes activates sprite 1 (for no apparent reason).


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.

scott@applix.UUCP (Scott Evernden) (02/03/88)

In article <644@applix.UUCP> scott@applix.UUCP (Scott Evernden) writes:
>Can't you simply SetPointer() the cursor to be something which is all
>color 0 (i.e., transparent)?   Alternatively, (and I've never tried this)
>couldn't you SetPointer() a 0 sized sprite image?

You dummy; he said he wasn't using Intuition, so this is pretty worthless
information.  (Maybe I should actually READ the messages I reply to).

>-scott

-scott

cmcmanis%pepper@Sun.COM (Chuck McManis) (02/04/88)

In article <645@applix.UUCP> scott@applix.UUCP (Scott Evernden) writes:
>You dummy; he said he wasn't using Intuition, so this is pretty worthless
>information.  (Maybe I should actually READ the messages I reply to).
>-scott

(This is Scott correcting himself by the way.) I too said, "Oops, he said
he is 'ignoring' Intuition." but then it became clear that it doesn't 
really matter in this case. Because 'ignoring Intuition' does not make it
go away! If you can move the mouse around, then Intuition is being called
by the input.device to move the mouse, if you can hit LeftAmiga-M and 
bring the workbench to the front then Intuition is there. And even if
neither of these cases is true, Intuition is ALWAYS in the ROM patiently
waiting for you. And if you call SetPointer() all it is *Really* doing
is fixing up the sprite data! So think of the code like this :

main()
    ... initializing some variables what have you.
    GoAwayPointer(); /* tell Intuition to make sprite 0 invisible */
    ...
    Stomp(); 	/* do you're worst, the pointer will still be gone */
    Stomp(); 
    Hack(); 
    Slash();
    ...
    Patch();
    Patch();
    Restore();
    UnStomp();
    ClearPointer();	/* Poof! The mouse reappears */
    exit(0);
}

The point is that you can use little pieces of Intuition with out buying into
the whole window system. And it is really just some code that lies around 
dormant until someone talks to it, you can't really make it go away.

If you are totally ignoring Intuition (you know makeing your own screens 
by stuffing values in to the copper list) then you just make the screen
to be 'sprite less'. But that is not necessary. 


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.

hsgj@batcomputer.tn.cornell.edu (Dan Green) (02/04/88)

In article <40779@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes:
>In article <3542@batcomputer.tn.cornell.edu> (Dan Green) writes:
>>In article <168@gould.doc.ic.ac.uk> (Peter Walkley) originally wrote:
>>>My friend wants a CLEAN way of getting rid of the mouse pointer, and
>>>then being able to restore it again.  He's writing a demo that grabs
>>>the display (i.e Ignores intuition), and wants the MP out of the way.
>>>  P. Walkley
>>
>>Here is a method I clipped out from a program of mine.  It works, and I
>>sure HOPE its "approved", but I don't know for sure.
>
>AAAAAAAAAAAAAAAAAAARRRRRRRRRRRRRRRRRRRRRGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHH!
>So close, and yet so far away. The 'clean' approved way of changing your
>pointer to ANYTHING, including 'nothing' is to use the Intuition 
>SetPointer call. To restore it to the original preferences set pointer
>you can use the Intuition ClearPointer() call. [...]

There is a reason that I recommend the Preferences method instead of
the Intuition "SetPointer" command.
	The SetPointer command changes the mouse pointer image only
in the window that you specify.  While you could repeatedly call
SetPointer for every window existing in the system, if someone were
to click outside of any window, I believe the original pointer image
would return.
	On the other hand, Preferences is global, and if you change
the pointer image with the SetPrefs command, the mouse pointer will
be your new image in EVERY window of EVERY screen on the system.
For many folks, this is an extremely bad thing to do, as other tasks
will look funny with the wrong pointer.
	Please recall, however, that for the application that was
originally mentioned (a demo that takes over the system) the
SetPrefs is a well-behaved command that will function even if Intuition
windows are not being used.  (Whether it will work if you CloseLibrary
intuition is something that I don't know...).

Lastly, and here I repeat Chuck McManis, if you only want the pointer
to change for your window, be well behaved and use SetPointer.

-- Dan Green

-- 
ARPA:  hsgj@tcgould.tn.cornell.edu
UUCP:  ihnp4!cornell!batcomputer!hsgj   BITNET:  hsgj@cornella

zmacv91@doc.ic.ac.uk (Peter Walkley) (02/09/88)

In article <168@gould.doc.ic.ac.uk>, zmacv91@doc.ic.ac.uk (Peter Walkley) writes:
> (Bits deleted)
>
> My friend wants a CLEAN way of getting rid of the mouse pointer, and
> then being able to restore it again.  He's writing a demo that grabs
> the display (i.e Ignores intuition), and wants the MP out of the way.
> 
> (More bits deleted)

Many thanks for all the help recieved.  The answers fell into three
categories :-

1).  Use SPRITE_OFF and SPRITE_ON macros.  This would be fine, but my friend
     is using sprites that I didn't tell you about (sorry).

2).  Use SetPointer() to set the pointer to either a null, or an invisible
     image and then ClearPointer() to restore it again.

3).  Use GetPrefs() to get a copy of preferences, SetPrefs() to reset the
     pointer to a null image, and then SetPrefs() at the end to restore the
     original (I hope I got that right).

Methods 2 and 3 were tried, and he decided to use 2.

I did send email to the first two people whose answers I received by private
mail, but don't know if it got through (Chuck McManis & Randy Anderson).

		 - Peter Walkley.

===============================================================================
          One day I'll come up with a decent .signature file
===============================================================================

dmg@ssc-vax.UUCP (David Geary) (02/09/88)

In Article 14707, Chuck McManis writes:

>AAAAAAAAAAAAAAAAAAARRRRRRRRRRRRRRRRRRRRRGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHH!
>So close, and yet so far away. The 'clean' approved way of changing your
>pointer to ANYTHING, including 'nothing' is to use the Intuition 
>SetPointer call. To restore it to the original preferences set pointer
>you can use the Intuition ClearPointer() call. BUT THERE IS A GOTCHA!
>And a very important one it is. The data you pass to SetPointer(), and
>read my lips here, MUST BE IN CHIP RAM OR YOU WILL GET AN UGLY SMEAR
>ON SYSTEMS WITH FAST RAM.

>So, the appropriate code would be something like ...

>UWORD	*Newpointer = NULL;

>GoAwayPointer()
>{
>  if (!NewPointer) NewPointer = AllocMem(2*sizeof(UWORD),MEMF_CHIP+MEMF_CLEAR);
>  SetPointer(NewPointer,1,1,1,1);
>}
>
>ComeBackPointer()
>{
>  ClearPointer();
>}

>Note also that the pointer is a sprite and follows the rules for sprite 
>images, meaning that each plane is represented by "n" UWORDs where n is
>the number of lines high the new image is, and that you have to have 
>2 planes because a sprite is 3 colors (plus transparent). So 1 * 2 = 2
>UWORDs. Finally, set the hotspot to 1,1 because if you set it to 0,0
>SetPointer sometimes activates sprite 1 (for no apparent reason).

Almost...

The call to SetPointer should read:

SetPointer(w, NewPointer,1,1,1,1);  - You must send SetPointer a pointer to
				      the window you want to change the
				      pointer in.

Also, this still leaves you with a pointer - even if it is just one pixel
wide, and one pixel high.  The third and fourth args to SetPointer give
it a new location for the pointer.  However, they are OFFSETS from the
current pointer position, so if you wanted to put the one-pixel ptr
at 0,0, you would:

SetPointer(w, NewPointer,-(s->MouseX),-(s->MouseY),1,1);

You could even try to put it offscreen like so:

SetPointer(w, NewPointer,-(s->MouseX+1),-(s->MouseY+1),1,1);

Note that I have tried the method of putting pointer at 0,0, cause
that's what I want to do for my application.  I've never tried
to put it offscreen, but try it if you want...

BTW, s above is a pointer to the screen your window's in...


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~	"... Who's gonna see that I'm fed,		~
~	     And who's gonna want me in bed,		~
~	     But who'll watch TV instead, 		~
~	     Because I do..."				~
~							~
~		If Not You, Dr. Hook			~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


-- 
***********************************************************
* David Geary, Boeing Aerospace Co., Seattle, WA 	  *
* (206)773-5249.  --I disclaim everything I've ever said--*
***********************************************************