1 /***************************************************
3 ** $VER: Macros.c 1.0 (15.8.2001) **
4 ** Record sequence of keystrokes **
6 ** © T.Pierron, C.Guilaume. Free software **
7 ** under terms of GNU public license. **
9 ***************************************************/
11 #include <intuition/intuition.h>
12 #include <intuition/screens.h>
13 #include <exec/memory.h>
21 #include "ProtoTypes.h"
23 #define CATCOMP_NUMBERS
26 extern STRPTR InfoTmpl
;
29 static STRPTR OldInfo
= NULL
;
31 UBYTE NewTmpl
[20], TmplLen
, TmplWid
;
33 /** Manage a set of macros **/
34 Macro MainMacro
= NULL
, MacCur
= NULL
, LastChunk
;
37 sizeof( *(ActChar
)0L ),
38 sizeof( *(ActMenu
)0L ),
39 sizeof( *(ActShortcut
)0L )
42 /*** Setup some variables ***/
43 void init_macros( void )
46 strcpy(NewTmpl
, ErrMsg(WARN_REC
)));
47 strcat(NewTmpl
, " "); TmplLen
+= 2;
48 strcat(NewTmpl
, InfoTmpl
);
51 /*** Free memory used by a macro ***/
52 void free_macro( Macro m
)
55 for(; m
; next
= m
->next
, FreeVec(m
), m
= next
);
57 void free_macros( void )
59 free_macro(MainMacro
);
63 /*** Start recording keystrokes ***/
64 void start_macro( void )
68 /* Show a special msg in info template to show reccording state */
72 TmplWid
= TextLength(prefs
.backdrop
? &Scr
->RastPort
: &RPT
, NewTmpl
, TmplLen
);
74 MacCur
= LastChunk
= NULL
;
76 ThrowError(Wnd
, ErrMsg(WARN_RECORD
));
81 void stop_macro( void )
85 InfoTmpl
= OldInfo
; OldInfo
= NULL
;
88 /* Do not save something if nothing has been recorded */
90 free_macro( MainMacro
); MainMacro
= MacCur
; MacCur
= NULL
;
91 ThrowError(Wnd
, ErrMsg(WARN_RECORDED
));
93 else SetTitle(Wnd
, Wnd
->UserData
);
98 /** Alloc a new chunk for recording keystroke **/
99 void *new_action( UWORD size
)
101 if(LastChunk
== NULL
|| LastChunk
->usage
+ size
> SZ_MACRO
)
104 /* Alloc a new chunk, not enough room */
105 if(NULL
== (new = (Macro
) AllocVec(sizeof(*new), MEMF_CLEAR
)))
108 if(LastChunk
) LastChunk
->next
= new;
109 else MacCur
= new; LastChunk
= new;
113 else /* Still some place in current chunk */
115 STRPTR
new = LastChunk
->data
+ LastChunk
->usage
;
116 LastChunk
->usage
+= size
;
121 /** Register actions **/
122 void reg_act_addchar( UBYTE code
)
125 if( ( new = new_action( sizeof(*new) ) ) )
126 new->Type
= MAC_ACT_ADD_CHAR
, new->Char
= code
;
128 void reg_act_com( UBYTE type
, UWORD code
, UWORD qual
)
131 if( ( new = new_action( sizeof(*new) ) ) )
132 new->Type
= type
, new->Code
= code
, new->Qual
= qual
;
135 /** Play current macro **/
136 void play_macro( int nb_times
)
138 extern struct IntuiMessage msgbuf
;
139 WORD selmask
, txtmask
;
142 if(MainMacro
== NULL
) return;
144 /* Disconnect display, just to be clean, not for performance */
145 inv_curs(edit
, FALSE
);
146 RP
->Mask
= 0; RPT
.Mask
= 0;
147 selmask
= gui
.selmask
; gui
.selmask
= 0;
148 txtmask
= gui
.txtmask
; gui
.txtmask
= 0;
153 for(m
= MainMacro
; m
; m
= m
->next
)
156 for(eoc
= (op
= m
->data
) + m
->usage
; op
< eoc
; op
+= SzOp
[*op
])
159 case MAC_ACT_ADD_CHAR
:
160 if( add_char(&edit
->undo
, edit
->edited
, edit
->nbc
, ((ActChar
)op
)->Char
) )
162 REDRAW_CURLINE(edit
);
163 curs_right(edit
, FALSE
);
165 case MAC_ACT_COM_MENU
:
166 msgbuf
.Qualifier
= ((ActMenu
)op
)->Qual
;
167 handle_menu( ((ActMenu
)op
)->Code
); break;
168 case MAC_ACT_SHORTCUT
:
169 msgbuf
.Qualifier
= ((ActShortcut
)op
)->Qual
;
170 msgbuf
.Code
= ((ActShortcut
)op
)->Code
;
171 handle_kbd(edit
); break;
175 /* Now we can show changes */
176 gui
.selmask
= selmask
;
177 gui
.txtmask
= txtmask
;
178 RP
->Mask
= (edit
->ccp
.select
? selmask
: txtmask
);
181 redraw_content(edit
, edit
->show
, gui
.topcurs
, gui
.nbline
);
186 void repeat_macro( Project p
)
190 if( MainMacro
&& get_number(p
, GetMenuText(404), &nb
) )
195 /** Select other slot **/
196 void new_slot( BYTE dir
)
198 Macro
*m
= MacTable
+ CurInd
- 1, *last
= m
;
201 if(dir
< 0) m
--; else m
++;
202 if(m
< MacTable
) m
= MacTable
+ MAX_MAC
;
203 if(m
>= MacTable
+MAX_MAC
) m
= MacTable
;
204 if(last
== m
|| *m
!= NULL
) break;
206 CurInd
= m
- MacTable
+ 1;
208 ThrowError(Wnd
, my_SPrintf(*m
? ErrMsg(WARN_SLOT
) : ErrMsg(WARN_EMPTYSLOT
), &CurInd
));