revert between 56095 -> 55830 in arch
[AROS.git] / workbench / tools / Edit / Macros.c
blobf818c36a8ee504a41c2418de7c185edba4c55acd
1 /***************************************************
2 ** **
3 ** $VER: Macros.c 1.0 (15.8.2001) **
4 ** Record sequence of keystrokes **
5 ** **
6 ** © T.Pierron, C.Guilaume. Free software **
7 ** under terms of GNU public license. **
8 ** **
9 ***************************************************/
11 #include <intuition/intuition.h>
12 #include <intuition/screens.h>
13 #include <exec/memory.h>
14 #include "Project.h"
15 #include "Macros.h"
16 #include "Gui.h"
17 #include "Utility.h"
18 #include "Cursor.h"
19 #include "Jed.h"
20 #include "Events.h"
21 #include "ProtoTypes.h"
23 #define CATCOMP_NUMBERS
24 #include "strings.h"
26 extern STRPTR InfoTmpl;
27 extern UBYTE record;
28 extern Project edit;
29 static STRPTR OldInfo = NULL;
31 UBYTE NewTmpl[40], TmplLen, TmplWid;
33 /** Manage a set of macros **/
34 Macro MainMacro = NULL, MacCur = NULL, LastChunk;
36 UBYTE SzOp[] = {
37 sizeof( *(ActChar)0L ),
38 sizeof( *(ActMenu)0L ),
39 sizeof( *(ActShortcut)0L )
42 /*** Setup some variables ***/
43 void init_macros( void )
45 TmplLen = strlen(
46 /* "FIXME: Missing buffer overflow check!" */
47 strcpy(NewTmpl, ErrMsg(WARN_REC)));
48 strcat(NewTmpl, " "); TmplLen += 2;
49 strcat(NewTmpl, InfoTmpl);
52 /*** Free memory used by a macro ***/
53 void free_macro( Macro m )
55 Macro next;
56 for(; m ; next = m->next, FreeVec(m), m = next);
58 void free_macros( void )
60 free_macro(MainMacro);
61 free_macro(MacCur);
64 /*** Start recording keystrokes ***/
65 void start_macro( void )
67 if(OldInfo == NULL)
69 /* Show a special msg in info template to show reccording state */
70 free_macro(MacCur);
71 OldInfo = InfoTmpl;
72 InfoTmpl = NewTmpl;
73 TmplWid = TextLength(prefs.backdrop ? &Scr->RastPort : &RPT, NewTmpl, TmplLen);
74 record = 0x81;
75 MacCur = LastChunk = NULL;
76 gui.xinfo -= TmplWid;
77 ThrowError(Wnd, ErrMsg(WARN_RECORD));
78 draw_info( edit );
82 void stop_macro( void )
84 if(OldInfo != NULL)
86 InfoTmpl = OldInfo; OldInfo = NULL;
87 record = FALSE;
88 gui.xinfo += TmplWid;
89 /* Do not save something if nothing has been recorded */
90 if(MacCur != NULL) {
91 free_macro( MainMacro ); MainMacro = MacCur; MacCur = NULL;
92 ThrowError(Wnd, ErrMsg(WARN_RECORDED));
94 else UpdateTitle(Wnd, edit);
98 /** Alloc a new chunk for recording keystroke **/
99 void *new_action( UWORD size )
101 if(LastChunk == NULL || LastChunk->usage + size > SZ_MACRO)
103 Macro new;
104 /* Alloc a new chunk, not enough room */
105 if(NULL == (new = (Macro) AllocVec(sizeof(*new), MEMF_CLEAR)))
106 return NULL;
108 if(LastChunk)
109 LastChunk->next = new;
110 else
111 MacCur = new;
112 LastChunk = new;
113 new->usage = size;
114 return new->data;
116 else /* Still some place in current chunk */
118 STRPTR new = LastChunk->data + LastChunk->usage;
119 LastChunk->usage += size;
120 return new;
124 /** Register actions **/
125 void reg_act_addchar( UBYTE code )
127 ActChar new;
128 if( ( new = new_action( sizeof(*new) ) ) )
129 new->Type = MAC_ACT_ADD_CHAR, new->Char = code;
131 void reg_act_com( UBYTE type, UWORD code, UWORD qual )
133 ActMenu new;
134 if( ( new = new_action( sizeof(*new) ) ) )
135 new->Type = type, new->Code = code, new->Qual = qual;
138 /** Play current macro **/
139 void play_macro( int nb_times )
141 extern struct IntuiMessage msgbuf;
142 WORD selmask, txtmask;
143 Macro m;
145 if(MainMacro == NULL) return;
147 /* Disconnect display, just to be clean, not for performance */
148 inv_curs(edit, FALSE);
149 RP->Mask = 0; RPT.Mask = 0;
150 selmask = gui.selmask; gui.selmask = 0;
151 txtmask = gui.txtmask; gui.txtmask = 0;
152 record = 2;
154 while( nb_times -- )
156 for(m = MainMacro; m; m = m->next)
158 STRPTR op, eoc;
159 for(eoc = (op = m->data) + m->usage; op < eoc; op += SzOp[*op])
160 switch( *op )
162 case MAC_ACT_ADD_CHAR:
163 if( add_char(&edit->undo, edit->edited, edit->nbc, ((ActChar)op)->Char) )
165 REDRAW_CURLINE(edit);
166 curs_right(edit, FALSE);
167 } break;
168 case MAC_ACT_COM_MENU:
169 msgbuf.Qualifier = ((ActMenu)op)->Qual;
170 handle_menu( ((ActMenu)op)->Code ); break;
171 case MAC_ACT_SHORTCUT:
172 msgbuf.Qualifier = ((ActShortcut)op)->Qual;
173 msgbuf.Code = ((ActShortcut)op)->Code;
174 handle_kbd(edit); break;
178 /* Now we can show changes */
179 gui.selmask = selmask;
180 gui.txtmask = txtmask;
181 RP->Mask = (edit->ccp.select ? selmask : txtmask);
182 RPT.Mask = 0xff;
183 record = 0;
184 redraw_content(edit, edit->show, gui.topcurs, gui.nbline);
185 prop_adj( edit );
186 inv_curs(edit,TRUE);
189 void repeat_macro( Project p )
191 LONG nb;
193 if( MainMacro && get_number(p, GetMenuText(404), &nb) )
194 play_macro( nb );
197 #if 0
198 /** Select other slot **/
199 void new_slot( BYTE dir )
201 Macro *m = MacTable + CurInd - 1, *last = m;
203 for(;;) {
204 if(dir < 0) m--; else m++;
205 if(m < MacTable) m = MacTable + MAX_MAC;
206 if(m >= MacTable+MAX_MAC) m = MacTable;
207 if(last == m || *m != NULL) break;
209 CurInd = m - MacTable + 1;
211 ThrowError(Wnd, my_SPrintf(*m ? ErrMsg(WARN_SLOT) : ErrMsg(WARN_EMPTYSLOT), (RAWARG)&CurInd));
213 #endif