2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
5 AutoPoint commodity -- activates the window under the mouse pointer.
8 /******************************************************************************
16 CX_PRIORITY/N/K, LAG/S
24 Automatically activates the window under the mouse pointer.
28 CX_PRIORITY -- The priority of the commodity
30 LAG -- Wait for the next timer event to activate the window
32 MIDMOUSEPREVENTSACTIVATION -- Don't activate the window under the
33 mouse if middle mouse button is pressed
49 05.03.2000 SDuvan implemented
51 ******************************************************************************/
53 #include <aros/symbolsets.h>
54 #include <intuition/intuition.h>
55 #include <intuition/intuitionbase.h>
56 #include <libraries/commodities.h>
57 #include <libraries/locale.h>
58 #include <proto/exec.h>
59 #include <proto/dos.h>
60 #include <proto/intuition.h>
61 #include <proto/layers.h>
62 #include <proto/commodities.h>
63 #include <proto/locale.h>
64 #include <proto/alib.h>
70 #include <aros/debug.h>
75 #define CATALOG_NAME "System/Tools/Commodities.catalog"
76 #define CATALOG_VERSION 3
79 /***************************************************************************/
81 UBYTE version
[] = "\0$VER: AutoPoint 0.4 (17.10.2012)";
83 #define ARG_TEMPLATE "CX_PRIORITY=PRI/N/K,LAG/S,MIDMOUSEPREVENTSACTIVATION=MMPA/S"
91 static struct NewBroker nb
=
97 NBU_NOTIFY
| NBU_UNIQUE
,
105 typedef struct _APState
108 struct MsgPort
*as_msgPort
;
114 struct Window
*ai_thisWindow
;
115 struct Window
*ai_lastActivatedWindow
;
116 BOOL ai_mouseHasMoved
;
117 BOOL ai_leftButtonDown
;
118 BOOL ai_rightButtonDown
;
119 BOOL ai_middleButtonDown
;
120 BOOL ai_midMousePreventsActivation
;
135 static struct Catalog
*catalog
;
137 /************************************************************************************/
139 static void freeResources(APState
*as
);
140 static BOOL
initiate(int argc
, char **argv
, APState
*as
);
141 static void autoActivateLag(CxMsg
*msg
, CxObj
*co
);
142 static void autoActivate(CxMsg
*msg
, CxObj
*co
);
143 static CONST_STRPTR
_(ULONG id
);
144 static BOOL
Locale_Initialize(VOID
);
145 static VOID
Locale_Deinitialize(VOID
);
146 static void showSimpleMessage(CONST_STRPTR msgString
);
148 /************************************************************************************/
150 static CONST_STRPTR
_(ULONG id
)
152 if (LocaleBase
!= NULL
&& catalog
!= NULL
)
154 return GetCatalogStr(catalog
, id
, CatCompArray
[id
].cca_Str
);
158 return CatCompArray
[id
].cca_Str
;
162 /************************************************************************************/
164 static BOOL
Locale_Initialize(VOID
)
166 if (LocaleBase
!= NULL
)
168 catalog
= OpenCatalog
170 NULL
, CATALOG_NAME
, OC_Version
, CATALOG_VERSION
, TAG_DONE
181 /************************************************************************************/
183 static VOID
Locale_Deinitialize(VOID
)
185 if(LocaleBase
!= NULL
&& catalog
!= NULL
) CloseCatalog(catalog
);
188 /************************************************************************************/
190 static void showSimpleMessage(CONST_STRPTR msgString
)
192 struct EasyStruct easyStruct
;
194 easyStruct
.es_StructSize
= sizeof(easyStruct
);
195 easyStruct
.es_Flags
= 0;
196 easyStruct
.es_Title
= _(MSG_AUTOPOINT_CXNAME
);
197 easyStruct
.es_TextFormat
= msgString
;
198 easyStruct
.es_GadgetFormat
= _(MSG_OK
);
200 if (IntuitionBase
!= NULL
&& !Cli() )
202 EasyRequestArgs(NULL
, &easyStruct
, NULL
, NULL
);
210 /************************************************************************************/
212 static BOOL
initiate(int argc
, char **argv
, APState
*as
)
215 void (*activateFunc
)(CxMsg
*msg
, CxObj
*co
);
217 memset(as
, 0, sizeof(APState
));
219 activateFunc
= autoActivate
;
224 IPTR
*args
[] = { NULL
, (IPTR
)FALSE
, (IPTR
)FALSE
};
226 rda
= ReadArgs(ARG_TEMPLATE
, (IPTR
*)args
, NULL
);
230 if (args
[ARG_PRI
] != NULL
)
232 nb
.nb_Pri
= *args
[ARG_PRI
];
236 activateFunc
= autoActivateLag
;
240 apInfo
.ai_midMousePreventsActivation
= TRUE
;
247 UBYTE
**array
= ArgArrayInit(argc
, (UBYTE
**)argv
);
249 nb
.nb_Pri
= ArgInt(array
, "CX_PRIORITY", 0);
251 if (ArgString(array
, "LAG", 0))
253 activateFunc
= autoActivateLag
;
255 if (ArgString(array
, "MIDMOUSEPREVENTSACTIVATION", 0))
257 apInfo
.ai_midMousePreventsActivation
= TRUE
;
263 nb
.nb_Name
= _(MSG_AUTOPOINT_CXNAME
);
264 nb
.nb_Title
= _(MSG_AUTOPOINT_CXTITLE
);
265 nb
.nb_Descr
= _(MSG_AUTOPOINT_CXDESCR
);
267 as
->as_msgPort
= CreateMsgPort();
269 if (as
->as_msgPort
== NULL
)
271 showSimpleMessage(_(MSG_CANT_CREATE_MSGPORT
));
276 nb
.nb_Port
= as
->as_msgPort
;
278 as
->as_broker
= CxBroker(&nb
, 0);
280 if (as
->as_broker
== NULL
)
285 customObj
= CxCustom(activateFunc
, 0);
287 if (customObj
== NULL
)
289 showSimpleMessage(_(MSG_CANT_CREATE_CUSTOM
));
294 AttachCxObj(as
->as_broker
, customObj
);
295 ActivateCxObj(as
->as_broker
, TRUE
);
297 apInfo
.ai_thisWindow
= IntuitionBase
->ActiveWindow
;
302 /************************************************************************************/
304 static void freeResources(APState
*as
)
310 if (as
->as_broker
!= NULL
)
312 DeleteCxObjAll(as
->as_broker
);
316 if (as
->as_msgPort
!= NULL
)
318 while ((cxm
= GetMsg(as
->as_msgPort
)))
323 DeleteMsgPort(as
->as_msgPort
);
327 /************************************************************************************/
329 /* Our CxCustom() function that is invoked everytime an imputevent is
330 routed to our broker */
331 static void autoActivateLag(CxMsg
*msg
, CxObj
*co
)
333 struct InputEvent
*ie
= (struct InputEvent
*)CxMsgData(msg
);
335 if (ie
->ie_Class
== IECLASS_TIMER
)
337 struct Screen
*screen
;
340 if (apInfo
.ai_leftButtonDown
||
341 apInfo
.ai_rightButtonDown
||
342 apInfo
.ai_middleButtonDown
)
345 if (IntuitionBase
->ActiveWindow
!= NULL
)
347 screen
= IntuitionBase
->ActiveWindow
->WScreen
;
351 screen
= IntuitionBase
->ActiveScreen
;
358 LockLayerInfo(&screen
->LayerInfo
);
359 layer
= WhichLayer(&screen
->LayerInfo
, screen
->MouseX
, screen
->MouseY
);
360 UnlockLayerInfo(&screen
->LayerInfo
);
363 apInfo
.ai_thisWindow
= (layer
!= NULL
) ?
364 (struct Window
*)layer
->Window
: NULL
;
366 if (apInfo
.ai_mouseHasMoved
||
367 (IntuitionBase
->ActiveWindow
== apInfo
.ai_thisWindow
) ||
368 (apInfo
.ai_lastActivatedWindow
== apInfo
.ai_thisWindow
))
370 apInfo
.ai_mouseHasMoved
= FALSE
;
374 /* Two timer events and mouse hasn't moved in between. */
376 apInfo
.ai_mouseHasMoved
= FALSE
;
378 /* Should be possible to use ActivateWindow(NULL)? Else, we must
380 if (apInfo
.ai_thisWindow
!= NULL
)
382 apInfo
.ai_lastActivatedWindow
= apInfo
.ai_thisWindow
;
383 ActivateWindow(apInfo
.ai_thisWindow
);
386 if (apInfo
.ai_thisWindow
!= NULL
)
388 D(bug("Activated window %s\n", apInfo
.ai_thisWindow
->Title
));
392 D(bug("No window active. %s\n",
393 IntuitionBase
->ActiveWindow
->Title
));
399 if (ie
->ie_Class
== IECLASS_RAWMOUSE
)
401 apInfo
.ai_mouseHasMoved
= FALSE
;
404 case IECODE_NOBUTTON
:
405 apInfo
.ai_mouseHasMoved
= TRUE
;
408 if (apInfo
.ai_midMousePreventsActivation
)
409 apInfo
.ai_middleButtonDown
= TRUE
;
412 apInfo
.ai_leftButtonDown
= TRUE
;
415 apInfo
.ai_rightButtonDown
= TRUE
;
418 apInfo
.ai_middleButtonDown
= FALSE
;
421 apInfo
.ai_leftButtonDown
= FALSE
;
424 apInfo
.ai_rightButtonDown
= FALSE
;
430 /************************************************************************************/
432 static void autoActivate(CxMsg
*msg
, CxObj
*co
)
434 struct InputEvent
*ie
= (struct InputEvent
*)CxMsgData(msg
);
436 if (ie
->ie_Class
== IECLASS_RAWMOUSE
)
438 struct Screen
*screen
;
441 if (ie
->ie_Code
!= IECODE_NOBUTTON
)
446 if (apInfo
.ai_midMousePreventsActivation
)
447 apInfo
.ai_middleButtonDown
= TRUE
;
450 apInfo
.ai_leftButtonDown
= TRUE
;
453 apInfo
.ai_rightButtonDown
= TRUE
;
456 apInfo
.ai_middleButtonDown
= FALSE
;
459 apInfo
.ai_leftButtonDown
= FALSE
;
462 apInfo
.ai_rightButtonDown
= FALSE
;
468 if (apInfo
.ai_leftButtonDown
||
469 apInfo
.ai_rightButtonDown
||
470 apInfo
.ai_middleButtonDown
)
473 if (IntuitionBase
->ActiveWindow
!= NULL
)
475 screen
= IntuitionBase
->ActiveWindow
->WScreen
;
479 screen
= IntuitionBase
->ActiveScreen
;
486 LockLayerInfo(&screen
->LayerInfo
);
487 layer
= WhichLayer(&screen
->LayerInfo
, screen
->MouseX
, screen
->MouseY
);
488 UnlockLayerInfo(&screen
->LayerInfo
);
491 apInfo
.ai_thisWindow
= (layer
!= NULL
) ?
492 (struct Window
*)layer
->Window
: NULL
;
494 if (apInfo
.ai_thisWindow
!= NULL
&&
495 apInfo
.ai_thisWindow
!= IntuitionBase
->ActiveWindow
)
497 ActivateWindow(apInfo
.ai_thisWindow
);
498 D(bug("Activated window %s\n", apInfo
.ai_thisWindow
->Title
));
505 /************************************************************************************/
507 /* React on command messages sent by commodities.library */
508 static void handleCx(APState
*as
)
516 signals
= Wait((1 << nb
.nb_Port
->mp_SigBit
) | SIGBREAKF_CTRL_C
);
518 if (signals
& (1 << nb
.nb_Port
->mp_SigBit
))
520 while ((msg
= (CxMsg
*)GetMsg(as
->as_msgPort
)))
522 switch (CxMsgType(msg
))
525 switch (CxMsgID(msg
))
528 ActivateCxObj(as
->as_broker
, FALSE
);
532 ActivateCxObj(as
->as_broker
, TRUE
);
536 /* Running the program twice <=> quit */
543 } /* switch(CxMsgID(msg)) */
546 } /* switch (CxMsgType(msg))*/
548 ReplyMsg((struct Message
*)msg
);
550 } /* while((msg = (CxMsg *)GetMsg(cs->cs_msgPort))) */
553 if (signals
& SIGBREAKF_CTRL_C
)
558 } /* while (!quit) */
561 /************************************************************************************/
563 int main(int argc
, char **argv
)
566 int error
= RETURN_OK
;
568 if (initiate(argc
, argv
, &aState
))
577 freeResources(&aState
);
582 /************************************************************************************/
584 ADD2INIT(Locale_Initialize
, 90);
585 ADD2EXIT(Locale_Deinitialize
, 90);