Experiment:
[AROS-Contrib.git] / bgui / commodityclass.c
blobd44f0d8fea4db7bf55b03378c7cc352e534b54ba
1 /*
2 * @(#) $Header$
4 * BGUI library
5 * commodityclass.c
7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
13 * $Log$
14 * Revision 42.5 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.4 2003/01/18 19:09:56 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.3 2000/05/29 00:40:23 bergers
21 * Update to compile with AROS now. Should also still compile with SASC etc since I only made changes that test the define __AROS__. The compilation is still very noisy but it does the trick for the main directory. Maybe members of the BGUI team should also have a look at the compiler warnings because some could also cause problems on other systems... (Comparison always TRUE due to datatype (or something like that)). And please compile it on an Amiga to see whether it still works... Thanks.
23 * Revision 42.2 2000/05/15 19:27:01 stegerg
24 * another hundreds of REG() macro replacements in func headers/protos.
26 * Revision 42.1 2000/05/14 23:32:47 stegerg
27 * changed over 200 function headers which all use register
28 * parameters (oh boy ...), because the simple REG() macro
29 * doesn't work with AROS. And there are still hundreds
30 * of headers left to be fixed :(
32 * Many of these functions would also work with stack
33 * params, but since i have fixed every single one
34 * I encountered up to now, I guess will have to do
35 * the same for the rest.
37 * Revision 42.0 2000/05/09 22:08:41 mlemos
38 * Bumped to revision 42.0 before handing BGUI to AROS team
40 * Revision 41.11 2000/05/09 19:54:06 mlemos
41 * Merged with the branch Manuel_Lemos_fixes.
43 * Revision 41.10 1998/02/25 21:11:50 mlemos
44 * Bumping to 41.10
46 * Revision 1.1 1998/02/25 17:07:55 mlemos
47 * Ian sources
52 #include "include/classdefs.h"
55 * Internal storage of the Hotkeys.
57 typedef struct Key {
58 struct Key *k_Next; /* next key */
59 struct Key *k_Prev; /* previous key */
60 CxObj *k_Object; /* The CxObj */
61 ULONG k_KeyID; /* key ID */
62 ULONG k_Flags; /* control flags */
63 } KEY;
65 typedef struct {
66 KEY *kl_First; /* first key */
67 KEY *kl_EndMark; /* end marker */
68 KEY *kl_Last; /* last key */
69 } KEYLIST;
72 * Object instance data.
74 typedef struct {
75 KEYLIST cd_Hotkeys; /* list of keys */
76 struct NewBroker cd_Broker; /* NewBroker structure */
77 CxObj *cd_BrokerPtr; /* points to broker */
78 ULONG cd_ErrorCode; /* error code */
79 ULONG cd_Flags; /* control flags */
80 } CD;
82 #define CDF_BROKERON (1<<0) /* broker is active */
85 * For PackBoolTags().
87 STATIC struct TagItem BoolTags[] = {
88 COMM_Unique, NBU_UNIQUE,
89 COMM_Notify, NBU_NOTIFY,
90 TAG_DONE
94 * Module prototypes.
98 STATIC ASM ULONG CommClassNew( REG(a0) Class *, REG(a2) Object *, REG(a1) struct opSet * );
99 STATIC ASM ULONG CommClassDispose( REG(a0) Class *, REG(a2) Object *, REG(a1) Msg );
100 STATIC ASM ULONG CommClassGet( REG(a0) Class *, REG(a2) Object *, REG(a1) struct opGet * );
101 STATIC ASM ULONG CommClassAddHotkey( REG(a0) Class *, REG(a2) Object *, REG(a1) struct cmAddHotkey * );
102 STATIC ASM ULONG CommClassRemHotkey( REG(a0) Class *, REG(a2) Object *, REG(a1) struct cmDoKeyCommand * );
103 STATIC ASM ULONG CommClassDisableHotkey( REG(a0) Class *, REG(a2) Object *, REG(a1) struct cmDoKeyCommand * );
104 STATIC ASM ULONG CommClassEnableHotkey( REG(a0) Class *, REG(a2) Object *, REG(a1) struct cmDoKeyCommand * );
105 STATIC ASM ULONG CommClassEnableBroker( REG(a0) Class *, REG(a2) Object *, REG(a1) Msg );
106 STATIC ASM ULONG CommClassDisableBroker( REG(a0) Class *, REG(a2) Object *, REG(a1) Msg );
107 STATIC ASM ULONG CommClassMsgInfo( REG(a0) Class *, REG(a2) Object *, REG(a1) struct cmMsgInfo * );
110 STATIC ASM REGFUNCPROTO3(ULONG, CommClassNew, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, struct opSet *, ops));
111 STATIC ASM REGFUNCPROTO3(ULONG, CommClassDispose, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, Msg, msg));
112 STATIC ASM REGFUNCPROTO3(ULONG, CommClassGet, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, struct opGet *, opg));
113 STATIC ASM REGFUNCPROTO3(ULONG, CommClassAddHotkey, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, struct cmAddHotkey *, cah));
114 STATIC ASM REGFUNCPROTO3(ULONG, CommClassRemHotkey, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, struct cmDoKeyCommand *, com));
115 STATIC ASM REGFUNCPROTO3(ULONG, CommClassDisableHotkey, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, struct cmDoKeyCommand *, com));
116 STATIC ASM REGFUNCPROTO3(ULONG, CommClassEnableHotkey, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, struct cmDoKeyCommand *, com));
117 STATIC ASM REGFUNCPROTO3(ULONG, CommClassEnableBroker, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, Msg, msg));
118 STATIC ASM REGFUNCPROTO3(ULONG, CommClassDisableBroker, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, Msg, msg));
119 STATIC ASM REGFUNCPROTO3(ULONG, CommClassMsgInfo, REGPARAM(A0, Class *, cl), REGPARAM(A2, Object *, obj), REGPARAM(A1, struct cmMsgInfo*, cmi));
122 * Class function table.
124 STATIC DPFUNC ClassFunc[] = {
125 OM_NEW, (FUNCPTR)CommClassNew,
126 OM_GET, (FUNCPTR)CommClassGet,
127 OM_DISPOSE, (FUNCPTR)CommClassDispose,
128 CM_ADDHOTKEY, (FUNCPTR)CommClassAddHotkey,
129 CM_REMHOTKEY, (FUNCPTR)CommClassRemHotkey,
130 CM_DISABLEHOTKEY, (FUNCPTR)CommClassDisableHotkey,
131 CM_ENABLEHOTKEY, (FUNCPTR)CommClassEnableHotkey,
132 CM_DISABLEBROKER, (FUNCPTR)CommClassDisableBroker,
133 CM_ENABLEBROKER, (FUNCPTR)CommClassEnableBroker,
134 CM_MSGINFO, (FUNCPTR)CommClassMsgInfo,
135 DF_END, NULL
139 * Simple class initialization.
141 makeproto Class *InitCxClass(void)
143 return BGUI_MakeClass(CLASS_ObjectSize, sizeof(CD),
144 CLASS_DFTable, ClassFunc,
145 TAG_DONE);
149 * Create a shiny new object.
151 METHOD(CommClassNew, struct opSet *, ops)
153 CD *cd;
154 struct TagItem *tstate = ops->ops_AttrList, *tag;
155 ULONG rc, un = NBU_UNIQUE | NBU_NOTIFY, data;
158 * First we let the superclass
159 * setup an object.
161 if (rc = AsmDoSuperMethodA(cl, obj, (Msg)ops))
164 * Get the instance data.
166 cd = INST_DATA(cl, rc);
169 * Initialize Hotkey list.
171 NewList((struct List *)&cd->cd_Hotkeys);
174 * Get us a message port.
176 if (cd->cd_Broker.nb_Port = CreateMsgPort())
179 * Initialize the broker.
181 cd->cd_Broker.nb_Version = NB_VERSION;
183 while (tag = NextTagItem(&tstate))
185 data = tag->ti_Data;
186 switch (tag->ti_Tag)
188 case COMM_Name:
189 cd->cd_Broker.nb_Name = (BYTE *)data;
190 break;
192 case COMM_Title:
193 cd->cd_Broker.nb_Title = (BYTE *)data;
194 break;
196 case COMM_Description:
197 cd->cd_Broker.nb_Descr = (BYTE *)data;
198 break;
200 case COMM_Priority:
201 cd->cd_Broker.nb_Pri = (BYTE)data;
202 break;
204 case COMM_ShowHide:
205 if (data)
206 cd->cd_Broker.nb_Flags = COF_SHOW_HIDE;
207 break;
212 * Setup broker flags.
214 cd->cd_Broker.nb_Unique = PackBoolTags(un, ops->ops_AttrList, BoolTags);
217 * Setup broker.
219 if (cd->cd_BrokerPtr = CxBroker(&cd->cd_Broker, NULL))
220 return rc;
223 * Major screwup.
225 AsmCoerceMethod(cl, (Object *)rc, OM_DISPOSE);
227 return NULL;
229 METHOD_END
232 * Get rid of an object.
234 METHOD(CommClassDispose, Msg, msg)
236 CD *cd = INST_DATA( cl, obj );
237 struct MsgPort *mp;
238 struct Message *tmp;
239 KEY *key;
242 * Scan through the list of keys.
244 while ( key = ( KEY * )RemHead(( struct List * )&cd->cd_Hotkeys )) {
246 * Enabled?
248 if ( ! ( key->k_Flags & CAHF_DISABLED ))
250 * Yes. Remove it.
252 RemoveCxObj( key->k_Object );
254 * Delete the CxObj.
256 DeleteCxObjAll( key->k_Object );
259 * Deallocate the KEY structure.
261 BGUI_FreePoolMem( key );
265 * De-activate and delete the broker.
267 if ( cd->cd_BrokerPtr ) {
268 if ( cd->cd_Flags & CDF_BROKERON )
269 ActivateCxObj( cd->cd_BrokerPtr, FALSE );
270 DeleteCxObjAll( cd->cd_BrokerPtr );
274 * Strip the remaining messages.
276 if ( mp = cd->cd_Broker.nb_Port ) {
277 while ( tmp = GetMsg( mp )) ReplyMsg( tmp );
278 DeleteMsgPort( mp );
282 * The superclass takes care of the rest.
284 return( AsmDoSuperMethodA( cl, obj, msg ));
286 METHOD_END
289 * They want something.
292 //STATIC ASM ULONG CommClassGet( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct opGet *opg )
293 STATIC ASM REGFUNC3(ULONG, CommClassGet,
294 REGPARAM(A0, Class *, cl),
295 REGPARAM(A2, Object *, obj),
296 REGPARAM(A1, struct opGet *, opg))
298 CD *cd = ( CD * )INST_DATA( cl, obj );
299 ULONG rc = 1L, *store = opg->opg_Storage;
301 switch ( opg->opg_AttrID ) {
303 case COMM_SigMask:
304 *store = ( ULONG )( 1L << cd->cd_Broker.nb_Port->mp_SigBit );
305 break;
307 case COMM_ErrorCode:
308 *store = cd->cd_ErrorCode;
309 break;
311 default:
312 rc = AsmDoSuperMethodA( cl, obj, ( Msg )opg );
313 break;
315 return( rc );
317 REGFUNC_END
320 * Search for a key by it's ID.
322 //STATIC ASM KEY *FindKey( REG(a0) KEYLIST *kl, REG(d0) ULONG keyID )
323 STATIC ASM REGFUNC2(KEY *, FindKey,
324 REGPARAM(A0, KEYLIST *, kl),
325 REGPARAM(D0, ULONG, keyID))
327 KEY *key;
329 for ( key = kl->kl_First; key->k_Next; key = key->k_Next ) {
330 if ( keyID == key->k_KeyID )
331 return( key );
333 return( NULL );
335 REGFUNC_END
338 * Add a hotkey to the list.
341 //STATIC ASM ULONG CommClassAddHotkey( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct cmAddHotkey *cah )
342 STATIC ASM REGFUNC3(ULONG, CommClassAddHotkey,
343 REGPARAM(A0, Class *, cl),
344 REGPARAM(A2, Object *, obj),
345 REGPARAM(A1, struct cmAddHotkey *, cah))
347 CD *cd = ( CD * )INST_DATA( cl, obj );
348 KEY *key;
351 * Deactivate the broker if active.
353 if ( cd->cd_Flags & CDF_BROKERON )
354 ActivateCxObj( cd->cd_BrokerPtr, FALSE );
357 * Key ID's must be unique.
359 if ( ! FindKey( &cd->cd_Hotkeys, cah->cah_KeyID )) {
361 * Allocate a KEY structure.
363 if ( key = ( KEY * )BGUI_AllocPoolMem( sizeof( KEY ))) {
365 * Setup the key.
367 if ( key->k_Object = HotKey( cah->cah_InputDescription, cd->cd_Broker.nb_Port, cah->cah_KeyID )) {
369 * Initialize the KEY structure.
371 key->k_Flags = cah->cah_Flags;
372 key->k_KeyID = cah->cah_KeyID;
375 * Add the key when necessary.
377 if ( ! ( key->k_Flags & CAHF_DISABLED ))
378 AttachCxObj( cd->cd_BrokerPtr, key->k_Object );
381 * An error occured?
383 if ( ! CxObjError( key->k_Object )) {
385 * No. Add the key to the list.
387 AddTail(( struct List * )&cd->cd_Hotkeys, ( struct Node * )key );
390 * Clear the error code.
392 cd->cd_ErrorCode = CMERR_OK;
395 * Activate the broker if necessary.
397 if ( cd->cd_Flags & CDF_BROKERON )
398 ActivateCxObj( cd->cd_BrokerPtr, TRUE );
399 return 1;
400 } else
402 * Error from CxObjError();
404 cd->cd_ErrorCode = CMERR_CXOBJERROR;
406 * Remove and dispose of the Cx
407 * object.
409 if ( ! ( key->k_Flags & CAHF_DISABLED ))
410 RemoveCxObj( key->k_Object );
411 DeleteCxObjAll( key->k_Object );
412 } else
413 cd->cd_ErrorCode = CMERR_KEY_CREATION;
415 * Free memory.
417 BGUI_FreePoolMem( key );
418 } else
419 cd->cd_ErrorCode = CMERR_NO_MEMORY;
420 } else
421 cd->cd_ErrorCode = CMERR_KEYID_IN_USE;
424 * Re-activate the broker if necessary.
426 if ( cd->cd_Flags & CDF_BROKERON )
427 ActivateCxObj( cd->cd_BrokerPtr, TRUE );
429 return 0;
431 REGFUNC_END
434 * Remove a hotkey from the list.
436 //STATIC ASM ULONG CommClassRemHotkey( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct cmDoKeyCommand *com )
437 STATIC ASM REGFUNC3(ULONG, CommClassRemHotkey,
438 REGPARAM(A0, Class *, cl),
439 REGPARAM(A2, Object *, obj),
440 REGPARAM(A1, struct cmDoKeyCommand *, com))
442 CD *cd = ( CD * )INST_DATA( cl, obj );
443 KEY *key;
444 ULONG rc = 0L;
447 * Deactivate the broker if necessary.
449 if ( cd->cd_Flags & CDF_BROKERON )
450 ActivateCxObj( cd->cd_BrokerPtr, FALSE );
453 * Locate the key.
455 if ( key = FindKey( &cd->cd_Hotkeys, com->cdkc_KeyID )) {
457 * Remove it from the list.
459 Remove(( struct Node * )key );
462 * Remove the CxObj when necessary.
464 if ( ! ( key->k_Flags & CAHF_DISABLED ))
465 RemoveCxObj( key->k_Object );
468 * Delete the CxObj.
470 DeleteCxObjAll( key->k_Object );
473 * Deallocate the KEY structure.
475 BGUI_FreePoolMem( key );
476 rc = 1L;
480 * Activate the broker if necessary.
482 if ( cd->cd_Flags & CDF_BROKERON )
483 ActivateCxObj( cd->cd_BrokerPtr, TRUE );
485 return( rc );
487 REGFUNC_END
490 * Disable a hotkey.
492 //STATIC ASM ULONG CommClassDisableHotkey( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct cmDoKeyCommand *com )
493 STATIC ASM REGFUNC3(ULONG, CommClassDisableHotkey,
494 REGPARAM(A0, Class *, cl),
495 REGPARAM(A2, Object *, obj),
496 REGPARAM(A1, struct cmDoKeyCommand *, com))
498 CD *cd = ( CD * )INST_DATA( cl, obj );
499 KEY *key;
500 ULONG rc = 0L;
503 * Deactivate the broker if necessary.
505 if ( cd->cd_Flags & CDF_BROKERON )
506 ActivateCxObj( cd->cd_BrokerPtr, FALSE );
509 * Locate the key.
511 if ( key = FindKey( &cd->cd_Hotkeys, com->cdkc_KeyID )) {
513 * Only disable when the key is enabled.
515 if ( ! ( key->k_Flags & CAHF_DISABLED )) {
517 * Remove the key.
519 RemoveCxObj( key->k_Object );
522 * Mark it as disabled.
524 key->k_Flags |= CAHF_DISABLED;
525 rc = 1;
530 * Activate the broker if necessary.
532 if ( cd->cd_Flags & CDF_BROKERON )
533 ActivateCxObj( cd->cd_BrokerPtr, TRUE );
535 return( rc );
537 REGFUNC_END
540 * Enable a hotkey.
543 //STATIC ASM ULONG CommClassEnableHotkey( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct cmDoKeyCommand *com )
544 STATIC ASM REGFUNC3(ULONG, CommClassEnableHotkey,
545 REGPARAM(A0, Class *, cl),
546 REGPARAM(A2, Object *, obj),
547 REGPARAM(A1, struct cmDoKeyCommand *, com))
549 CD *cd = ( CD * )INST_DATA( cl, obj );
550 KEY *key;
551 ULONG rc = 0L;
554 * Deactivate the broker if necessary.
556 if ( cd->cd_Flags & CDF_BROKERON )
557 ActivateCxObj( cd->cd_BrokerPtr, FALSE );
560 * Locate the key.
562 if ( key = FindKey( &cd->cd_Hotkeys, com->cdkc_KeyID )) {
564 * Only enable when the key is disabled.
566 if ( key->k_Flags & CAHF_DISABLED ) {
568 * Add the key.
570 AttachCxObj( cd->cd_BrokerPtr, key->k_Object );
573 * Clear the disabled bit.
575 key->k_Flags &= ~CAHF_DISABLED;
576 rc = 1L;
581 * Activate the broker if necessary.
583 if ( cd->cd_Flags & CDF_BROKERON )
584 ActivateCxObj( cd->cd_BrokerPtr, TRUE );
586 return( rc );
588 REGFUNC_END
591 * Enable the broker.
593 //STATIC ASM ULONG CommClassEnableBroker( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) Msg msg )
594 STATIC ASM REGFUNC3(ULONG, CommClassEnableBroker,
595 REGPARAM(A0, Class *, cl),
596 REGPARAM(A2, Object *, obj),
597 REGPARAM(A1, Msg, msg))
599 CD *cd = ( CD * )INST_DATA( cl, obj );
600 ULONG rc = 0L;
603 * Only enable when the broker is disabled.
605 if ( ! ( cd->cd_Flags & CDF_BROKERON )) {
607 * Activate the broker.
609 ActivateCxObj( cd->cd_BrokerPtr, TRUE );
612 * Mark us as active.
614 cd->cd_Flags |= CDF_BROKERON;
615 rc = 1L;
617 return( rc );
619 REGFUNC_END
622 * Disable the broker.
624 //STATIC ASM ULONG CommClassDisableBroker( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) Msg msg )
625 STATIC ASM REGFUNC3(ULONG, CommClassDisableBroker,
626 REGPARAM(A0, Class *, cl),
627 REGPARAM(A2, Object *, obj),
628 REGPARAM(A1, Msg, msg))
630 CD *cd = ( CD * )INST_DATA( cl, obj );
631 ULONG rc = 0L;
634 * Only disable when the broker is enabled.
636 if ( cd->cd_Flags & CDF_BROKERON ) {
638 * Deactivate the broker.
640 ActivateCxObj( cd->cd_BrokerPtr, FALSE );
643 * Clear the enabled bit.
645 cd->cd_Flags &= ~CDF_BROKERON;
646 rc = 1L;
648 return( rc );
650 REGFUNC_END
653 * Poll broker port.
655 //STATIC ASM ULONG CommClassMsgInfo( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct cmMsgInfo *cmi )
656 STATIC ASM REGFUNC3(ULONG, CommClassMsgInfo,
657 REGPARAM(A0, Class *, cl),
658 REGPARAM(A2, Object *, obj),
659 REGPARAM(A1, struct cmMsgInfo*, cmi))
661 CD *cd = ( CD * )INST_DATA( cl, obj );
662 CxMsg *msg;
663 ULONG rc = 0, type, id, data;
666 * Get a message from the port.
668 if ( msg = ( CxMsg * )GetMsg( cd->cd_Broker.nb_Port )) {
670 * Get message data.
672 type = CxMsgType(msg);
673 id = CxMsgID(msg);
674 data = (ULONG)CxMsgData(msg);
677 * Save data where ever possible.
679 if ( cmi->cmi_Info.Type ) *( cmi->cmi_Info.Type ) = type;
680 if ( cmi->cmi_Info.ID ) *( cmi->cmi_Info.ID ) = id;
681 if ( cmi->cmi_Info.Data ) *( cmi->cmi_Info.Data ) = data;
684 * Setup V40 return codes.
686 switch (type)
688 case CXM_IEVENT:
689 rc = id;
690 break;
692 case CXM_COMMAND:
693 switch(id)
695 case CXCMD_KILL:
696 rc = CMMI_KILL;
697 break;
699 case CXCMD_DISABLE:
700 AsmDoMethod(obj, CM_DISABLEBROKER);
701 rc = CMMI_DISABLE;
702 break;
704 case CXCMD_ENABLE:
705 AsmDoMethod(obj, CM_ENABLEBROKER);
706 rc = CMMI_ENABLE;
707 break;
709 case CXCMD_UNIQUE:
710 rc = CMMI_UNIQUE;
711 break;
713 case CXCMD_APPEAR:
714 rc = CMMI_APPEAR;
715 break;
717 case CXCMD_DISAPPEAR:
718 rc = CMMI_DISAPPEAR;
719 break;
721 break;
725 * Reply the message.
727 ReplyMsg(( struct Message *)msg );
728 } else
730 * No more messages.
732 rc = CMMI_NOMORE;
734 return( rc );
736 REGFUNC_END