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 UpdateTitle(Wnd
, edit
);
97 /** Alloc a new chunk for recording keystroke **/
98 void *new_action( UWORD size
)
100 if(LastChunk
== NULL
|| LastChunk
->usage
+ size
> SZ_MACRO
)
103 /* Alloc a new chunk, not enough room */
104 if(NULL
== (new = (Macro
) AllocVec(sizeof(*new), MEMF_CLEAR
)))
107 if(LastChunk
) LastChunk
->next
= new;
108 else MacCur
= new; LastChunk
= new;
112 else /* Still some place in current chunk */
114 STRPTR
new = LastChunk
->data
+ LastChunk
->usage
;
115 LastChunk
->usage
+= size
;
120 /** Register actions **/
121 void reg_act_addchar( UBYTE code
)
124 if( ( new = new_action( sizeof(*new) ) ) )
125 new->Type
= MAC_ACT_ADD_CHAR
, new->Char
= code
;
127 void reg_act_com( UBYTE type
, UWORD code
, UWORD qual
)
130 if( ( new = new_action( sizeof(*new) ) ) )
131 new->Type
= type
, new->Code
= code
, new->Qual
= qual
;
134 /** Play current macro **/
135 void play_macro( int nb_times
)
137 extern struct IntuiMessage msgbuf
;
138 WORD selmask
, txtmask
;
141 if(MainMacro
== NULL
) return;
143 /* Disconnect display, just to be clean, not for performance */
144 inv_curs(edit
, FALSE
);
145 RP
->Mask
= 0; RPT
.Mask
= 0;
146 selmask
= gui
.selmask
; gui
.selmask
= 0;
147 txtmask
= gui
.txtmask
; gui
.txtmask
= 0;
152 for(m
= MainMacro
; m
; m
= m
->next
)
155 for(eoc
= (op
= m
->data
) + m
->usage
; op
< eoc
; op
+= SzOp
[*op
])
158 case MAC_ACT_ADD_CHAR
:
159 if( add_char(&edit
->undo
, edit
->edited
, edit
->nbc
, ((ActChar
)op
)->Char
) )
161 REDRAW_CURLINE(edit
);
162 curs_right(edit
, FALSE
);
164 case MAC_ACT_COM_MENU
:
165 msgbuf
.Qualifier
= ((ActMenu
)op
)->Qual
;
166 handle_menu( ((ActMenu
)op
)->Code
); break;
167 case MAC_ACT_SHORTCUT
:
168 msgbuf
.Qualifier
= ((ActShortcut
)op
)->Qual
;
169 msgbuf
.Code
= ((ActShortcut
)op
)->Code
;
170 handle_kbd(edit
); break;
174 /* Now we can show changes */
175 gui
.selmask
= selmask
;
176 gui
.txtmask
= txtmask
;
177 RP
->Mask
= (edit
->ccp
.select
? selmask
: txtmask
);
180 redraw_content(edit
, edit
->show
, gui
.topcurs
, gui
.nbline
);
185 void repeat_macro( Project p
)
189 if( MainMacro
&& get_number(p
, GetMenuText(404), &nb
) )
194 /** Select other slot **/
195 void new_slot( BYTE dir
)
197 Macro
*m
= MacTable
+ CurInd
- 1, *last
= m
;
200 if(dir
< 0) m
--; else m
++;
201 if(m
< MacTable
) m
= MacTable
+ MAX_MAC
;
202 if(m
>= MacTable
+MAX_MAC
) m
= MacTable
;
203 if(last
== m
|| *m
!= NULL
) break;
205 CurInd
= m
- MacTable
+ 1;
207 ThrowError(Wnd
, my_SPrintf(*m
? ErrMsg(WARN_SLOT
) : ErrMsg(WARN_EMPTYSLOT
), &CurInd
));