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