1 /**
2 * @namespace biew
3 * @file editors.c
4 * @brief This file contains low level editor implementation of BIEW project.
5 * @version -
6 * @remark this source file is part of Binary vIEW project (BIEW).
7 * The Binary vIEW (BIEW) is copyright (C) 1995 Nickols_K.
8 * All rights reserved. This software is redistributable under the
9 * licence given in the file "Licence.en" ("Licence.ru" in russian
10 * translation) distributed in the BIEW archive.
11 * @note Requires POSIX compatible development system
12 *
13 * @author Nickols_K
14 * @since 1995
15 * @note Development, fixes and improvements
16 **/
17 #include <string.h>
18 #include <errno.h>
19
20 #include "colorset.h"
21 #include "bmfile.h"
22 #include "tstrings.h"
23 #include "plugins/disasm.h"
24 #include "bconsole.h"
25 #include "biewutil.h"
26 #include "biewhelp.h"
27 #include "editor.h"
28 #include "biewlib/biewlib.h"
29 #include "biewlib/kbd_code.h"
30 #include "biewlib/pmalloc.h"
31
32 __fileoff_t edit_cp = 0;
33 struct tag_emem EditorMem;
34
35 int edit_x,edit_y;
36 unsigned char edit_XX = 0;
37
ExtHelp(void)38 void ExtHelp( void )
39 {
40 TWindow * using = twUsedWin();
41 hlpDisplay(2);
42 twUseWin(using);
43 }
44
PaintETitle(int shift,tBool use_shift)45 void __FASTCALL__ PaintETitle( int shift,tBool use_shift )
46 {
47 TWindow * using = twUsedWin();
48 unsigned eidx;
49 char byte,obyte;
50 twUseWin(TitleWnd);
51 twFreezeWin(TitleWnd);
52 twGotoXY(1,1);
53 twClrEOL();
54 twPrintF("%08lX: ",edit_cp + shift);
55 eidx = use_shift ? (unsigned)shift : edit_y*EditorMem.width+edit_x;
56 byte = EditorMem.buff[eidx];
57 obyte = EditorMem.save[eidx];
58 if(byte != obyte) twSetColorAttr(title_cset.change);
59 twPrintF("%c %02XH %sH %sB "
60 ,byte ? byte : ' '
61 ,byte & 0x00FF
62 ,Get2SignDig(byte)
63 ,GetBinary(byte));
64 twSetColorAttr(title_cset.main);
65 if(byte != obyte)
66 {
67 twPrintF("ORIGINAL: %c %02XH %sH %sB "
68 ,obyte ? obyte : ' '
69 ,obyte & 0x00FF
70 ,Get2SignDig(obyte)
71 ,GetBinary(obyte));
72 }
73 else
74 twPrintF(" ");
75 twPrintF("MASK: %sH"
76 ,Get2Digit(edit_XX));
77 twRefreshWin(TitleWnd);
78 twUseWin(using);
79 }
80
editInitBuffs(unsigned width,unsigned char * buff,unsigned size)81 tBool __FASTCALL__ editInitBuffs(unsigned width,unsigned char *buff,unsigned size)
82 {
83 __filesize_t flen,cfp,ssize;
84 unsigned i,msize;
85 msize = tvioWidth*tvioHeight;
86 EditorMem.buff = PMalloc(msize);
87 EditorMem.save = PMalloc(msize);
88 EditorMem.alen = PMalloc(tvioHeight);
89 if((!EditorMem.buff) || (!EditorMem.save) || (!EditorMem.alen))
90 {
91 if(EditorMem.buff) PFREE(EditorMem.buff);
92 if(EditorMem.save) PFREE(EditorMem.save);
93 if(EditorMem.alen) PFREE(EditorMem.alen);
94 MemOutBox("Editor initialization");
95 return False;
96 }
97 memset(EditorMem.buff,TWC_DEF_FILLER,msize);
98 memset(EditorMem.save,TWC_DEF_FILLER,msize);
99 flen = BMGetFLength();
100 edit_cp = cfp = BMGetCurrFilePos();
101 EditorMem.width = width;
102 if(buff)
103 {
104 EditorMem.size = size;
105 memcpy(EditorMem.buff,buff,size);
106 }
107 else
108 {
109 EditorMem.size = (unsigned)((__filesize_t)msize > (flen-cfp) ? (flen-cfp) : msize);
110 BMReadBufferEx(EditorMem.buff,EditorMem.size,cfp,BM_SEEK_SET);
111 BMSeek(cfp,BM_SEEK_SET);
112 }
113 memcpy(EditorMem.save,EditorMem.buff,EditorMem.size);
114 /** initialize EditorMem.alen */
115 ssize = flen-cfp;
116 for(i = 0;i < tvioHeight;i++)
117 {
118 EditorMem.alen[i] = ssize >= width ? width : ssize;
119 ssize -= min(ssize,width);
120 }
121 return True;
122 }
123
editDestroyBuffs(void)124 void __FASTCALL__ editDestroyBuffs( void )
125 {
126 PFREE(EditorMem.buff);
127 PFREE(EditorMem.save);
128 PFREE(EditorMem.alen);
129 }
130
CheckBounds(void)131 void __FASTCALL__ CheckBounds( void )
132 {
133 tAbsCoord height = twGetClientHeight(MainWnd);
134 if(edit_y < 0) edit_y = 0;
135 if((unsigned)edit_y > height - 1) edit_y = height - 1;
136 if(!EditorMem.alen[edit_y]) edit_y--;
137 if(edit_x >= EditorMem.alen[edit_y]) edit_x = EditorMem.alen[edit_y] - 1;
138 }
139
CheckYBounds(void)140 void __FASTCALL__ CheckYBounds( void )
141 {
142 tAbsCoord height = twGetClientHeight(MainWnd);
143 if(edit_y < 0) edit_y = 0;
144 if((unsigned)edit_y > height - 1) edit_y = height - 1;
145 while(!EditorMem.alen[edit_y]) edit_y--;
146 }
147
CheckXYBounds(void)148 void __FASTCALL__ CheckXYBounds( void )
149 {
150 CheckYBounds();
151 if(edit_x < 0) edit_x = EditorMem.alen[--edit_y]*2;
152 if(edit_x >= EditorMem.alen[edit_y]*2) { edit_x = 0; edit_y++; }
153 CheckYBounds();
154 }
155
editSaveContest(void)156 void __FASTCALL__ editSaveContest( void )
157 {
158 BGLOBAL bHandle;
159 char *fname;
160 fname = BMName();
161 bHandle = biewOpenRW(fname,BBIO_SMALL_CACHE_SIZE);
162 if(bHandle == &bNull)
163 {
164 err:
165 errnoMessageBox(WRITE_FAIL,NULL,errno);
166 return;
167 }
168 bioSeek(bHandle,edit_cp,BIO_SEEK_SET);
169 if(!bioWriteBuffer(bHandle,(void *)EditorMem.buff,EditorMem.size)) goto err;
170 bioClose(bHandle);
171 BMReRead();
172 }
173
edit_defaction(int _lastbyte)174 tBool __FASTCALL__ edit_defaction(int _lastbyte)
175 {
176 tBool redraw;
177 redraw = False;
178 switch(_lastbyte)
179 {
180 case KE_UPARROW : edit_y--; break;
181 case KE_DOWNARROW: edit_y++; break;
182 case KE_ENTER:
183 case KE_LEFTARROW:
184 case KE_RIGHTARROW: break;
185 case KE_F(3) :
186 Get2DigitDlg(INIT_MASK,INPUT_MASK,&edit_XX);
187 break;
188 default: redraw = True; break;
189 }
190 return redraw;
191 }
192
editDefAction(int _lastbyte)193 tBool __FASTCALL__ editDefAction(int _lastbyte)
194 {
195 tBool redraw = True;
196 int eidx;
197 eidx = edit_y*EditorMem.width+edit_x;
198 switch(_lastbyte)
199 {
200 case KE_F(4) : EditorMem.buff[eidx] = ~EditorMem.buff[eidx]; break;
201 case KE_F(5) : EditorMem.buff[eidx] |= edit_XX; break;
202 case KE_F(6) : EditorMem.buff[eidx] &= edit_XX; break;
203 case KE_F(7) : EditorMem.buff[eidx] ^= edit_XX; break;
204 case KE_F(8) : EditorMem.buff[eidx] = edit_XX; break;
205 case KE_F(9) : EditorMem.buff[eidx] = EditorMem.save[eidx]; break;
206 default : redraw = edit_defaction(_lastbyte); edit_x--; break;
207 }
208 edit_x++;
209 return redraw;
210 }
211
FullEdit(TWindow * txtwnd,void (* save_func)(unsigned char *,unsigned))212 int __FASTCALL__ FullEdit(TWindow * txtwnd,void (*save_func)(unsigned char *,unsigned))
213 {
214 size_t i,j;
215 unsigned mlen;
216 unsigned int _lastbyte;
217 unsigned flags;
218 tAbsCoord height = twGetClientHeight(MainWnd);
219 tBool redraw;
220 char attr = __ESS_HARDEDIT | __ESS_WANTRETURN;
221 twSetColorAttr(browser_cset.edit.main);
222 __MsSetState(False);
223 for(i = 0;i < height;i++)
224 {
225 for(j = 0;j < EditorMem.alen[i];j++)
226 {
227 unsigned eidx;
228 eidx = i*EditorMem.width+j;
229 twSetColorAttr(EditorMem.buff[eidx] == EditorMem.save[eidx] ? browser_cset.edit.main : browser_cset.edit.change);
230 twDirectWrite(j + 1,i + 1,&EditorMem.buff[eidx],1);
231 }
232 if((unsigned)EditorMem.alen[i] + 1 < EditorMem.width)
233 {
234 twGotoXY(EditorMem.alen[i] + 1,i + 1); twClrEOL();
235 }
236 }
237 __MsSetState(True);
238 PaintETitle(edit_y*EditorMem.width + edit_x,0);
239 twShowWin(twUsedWin());
240 twSetCursorType(TW_CUR_NORM);
241 redraw = True;
242 if(txtwnd)
243 {
244 char work[__TVIO_MAXSCREENWIDTH];
245 int len;
246 TWindow * using = twUsedWin();
247 twUseWin(txtwnd);
248 twSetColorAttr(browser_cset.main);
249 twFreezeWin(txtwnd);
250 for(i = 0;i < height;i++)
251 {
252 mlen = EditorMem.alen[i];
253 len = ExpandHex(work,&EditorMem.buff[i*EditorMem.width],mlen,2);
254 twDirectWrite(11,i + 1,work,len);
255 if((unsigned)EditorMem.alen[i] + 1 < EditorMem.width)
256 {
257 twGotoXY(11+len,i + 1); twClrEOL();
258 }
259 }
260 twRefreshWin(txtwnd);
261 twUseWin(using);
262 }
263 while(1)
264 {
265 unsigned eidx;
266 eidx = edit_y*EditorMem.width;
267 mlen = EditorMem.alen[edit_y];
268 flags = attr;
269 if(!redraw) flags |= __ESS_NOREDRAW;
270 _lastbyte = eeditstring((char *)&EditorMem.buff[eidx],NULL,&mlen,(unsigned)(edit_y + 1),
271 (unsigned *)&edit_x,flags,(char *)&EditorMem.save[eidx], NULL);
272 switch(_lastbyte)
273 {
274 case KE_F(1) : ExtHelp(); continue;
275 case KE_F(2) : save_func?save_func(EditorMem.buff,EditorMem.size):editSaveContest();
276 case KE_F(10) :
277 case KE_ESCAPE : goto bye;
278 case KE_TAB : if(txtwnd) goto bye;
279 default : redraw = editDefAction(_lastbyte); break;
280 }
281 CheckBounds();
282 if(redraw)
283 {
284 if(txtwnd)
285 {
286 char work[__TVIO_MAXSCREENWIDTH];
287 int len;
288 TWindow * using = twUsedWin();
289 twUseWin(txtwnd);
290 len = ExpandHex(work,&EditorMem.buff[edit_y*EditorMem.width],mlen,2);
291 twDirectWrite(11,edit_y + 1,work,len);
292 twUseWin(using);
293 }
294 }
295 PaintETitle(edit_y*EditorMem.width + edit_x,0);
296 }
297 bye:
298 twSetCursorType(TW_CUR_OFF);
299 return _lastbyte;
300 }
301