1 /*
2    Copyright (C) 1998,1999,2000,2001,2002,2003,2004
3    T. Scott Dattalo and Ralf Forsberg
4 
5 This file is part of gpsim.
6 
7 gpsim is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11 
12 gpsim is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with gpsim; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21 
22 #ifndef __GUI_SRC_H__
23 #define __GUI_SRC_H__
24 
25 #include "../src/modules.h"
26 #include "gui_object.h"
27 
28 #include <gdk-pixbuf/gdk-pixbuf.h>
29 #include <gdk/gdk.h>
30 #include <glib.h>
31 #include <gtk/gtk.h>
32 
33 #include <map>
34 #include <string>
35 #include <vector>
36 
37 // forward references
38 class SourceBrowserParent_Window;
39 class StatusBar_Window;
40 class Value;
41 class SourceWindow;
42 class FileContext;
43 class GUI_Processor;
44 class ProgramMemoryAccess;
45 
46 //========================================================================
47 class SourceBuffer
48 {
49 public:
50   SourceBuffer(GtkTextTagTable *,FileContext *,SourceBrowserParent_Window *);
51   void parseLine(const char*, int parseStyle);
52 
53   void addTagRange(const char *pStyle, int start_index, int end_index);
54 
55   GtkTextBuffer *getBuffer();
56   SourceBrowserParent_Window *m_pParent;
57   FileContext   *m_pFC;
58 
59   bool IsParsed();
60   void parse();
61 private:
62   bool m_bParsed;
63   GtkTextBuffer *m_buffer;
64 };
65 
66 
67 //========================================================================
68 // The SourcePageMargin holds configuration information for the left margin
69 // of a SourcePage. The left margin is where line numbers, addresses, opcodes,
70 // breakpoints, and current program counter are all shown.
71 class SourcePageMargin
72 {
73 public:
74   SourcePageMargin();
75 
enableLineNumbers(bool b)76   void enableLineNumbers(bool b)
77   {
78     m_bShowLineNumbers = b;
79   }
enableAddresses(bool b)80   void enableAddresses(bool b)
81   {
82     m_bShowAddresses = b;
83   }
enableOpcodes(bool b)84   void enableOpcodes(bool b)
85   {
86     m_bShowOpcodes = b;
87   }
88 
89   bool formatMargin(char *,int, int line,int addr,int opcode,bool bBreak);
bLineNumbers()90   bool bLineNumbers() { return m_bShowLineNumbers; }
bAddresses()91   bool bAddresses()   { return m_bShowAddresses; }
bOpcodes()92   bool bOpcodes()     { return m_bShowOpcodes; }
93 private:
94   bool m_bShowLineNumbers;
95   bool m_bShowAddresses;
96   bool m_bShowOpcodes;
97 };
98 
99 //========================================================================
100 // SourcePage
101 // A single source file.
102 //
103 // The SourcePage class associates a single file with a single GtkTextBuffer.
104 // manages
105 class NSourcePage
106 {
107 public:
108   NSourcePage(SourceWindow *, SourceBuffer  *, int file_id, GtkWidget *);
109 
110   GtkTextBuffer *buffer();
111   GtkTextView   *getView();
112   SourceWindow  *getParent();
113 
114   void invalidateView();
115   void updateMargin(int y1, int y2);
116 
117   void Close();
118   void setFont(const char *);
119 
120   FileContext *getFC();
121 
get_file_id()122   unsigned int get_file_id() { return m_fileid; }
get_margin_width()123   int get_margin_width() { return m_marginWidth; }
124 
125 private:
126   // callbacks
127   static gboolean KeyPressHandler(GtkTextView *pView, GdkEventKey *key,
128     NSourcePage *page);
129   static gint ButtonPressHandler(GtkTextView *pView, GdkEventButton *pButton,
130     NSourcePage *pPage);
131   static gint ViewExposeEventHandler(GtkTextView *pView, GdkEventExpose *pEvent,
132     NSourcePage *pPage);
133 
134   GtkTextView   *m_view;
135   SourceBuffer  *m_pBuffer;
136   SourceWindow  *m_Parent;
137   unsigned int   m_fileid;
138   int            m_marginWidth;
139   std::string    m_cpFont;
140 };
141 
142 class SearchDialog;
143 
144 class SourceWindow : public GUI_Object
145 {
146 public:
147   SourceWindow(GUI_Processor *gp,
148                SourceBrowserParent_Window *,
149                bool bUseConfig,
150                const char *newName=0);
151 
152   virtual void Build();
153   virtual void SetTitle();
154 
155   void set_pma(ProgramMemoryAccess *new_pma);
156 
157   virtual void SelectAddress(int address);
158   virtual void SelectAddress(Value *);
159   virtual void Update();
160   virtual void UpdateLine(int address);
161   virtual void SetPC(int address);
162   virtual void CloseSource(void);
163   virtual void NewSource(GUI_Processor *gp);
164 
165   virtual int getPCLine(int page);
166   virtual int getAddress(NSourcePage *pPage, int line);
167   virtual bool bAddressHasBreak(int address);
168   virtual int getOpcode(int address);
169   int  AddPage(SourceBuffer *pSourceBuffer, const std::string &fName);
170   void step(int n=1);
171   void step_over();
172   void stop();
173   void run();
174   void finish();
175   void reset();
176   void toggleBreak(NSourcePage *pPage, int line);
177   void movePC(int line);
bSourceLoaded()178   bool bSourceLoaded() { return m_bSourceLoaded; }
179   void findText();
180   int  findText(const char *, int, bool bDir, bool bCase);
181 
182   GtkTextTagTable *getTagTable();
183 
184   SourcePageMargin &margin();
185   const char *getFont();
186   gint switch_page_cb(guint newPage);
187 
188   // do we need this:
189   bool m_bLoadSource;
190   bool m_bSourceLoaded;
191   int  m_LineAtButtonClick;
192 
193 private:
194   int AddPage(SourceBuffer *pSourceBuffer);
195 
196   ProgramMemoryAccess *pma;      // pointer to the processor's pma.
197   StatusBar_Window *status_bar;  // display's PC, status, etc.
198   SIMULATION_MODES last_simulation_mode;
199   std::string sLastPmaName;
200   unsigned int m_currentPage;          // Notebook page currently displayed.
201 
202   struct _PC {
203     bool bIsActive;
204     int  page;                // Notebook page containing the source
205     int  line;                // Line within the page.
206     GtkTextBuffer *pBuffer;   // Buffer containing the Program Counter
207     GtkTextIter   iBegin;     // Start of where highlight begins
208     GtkTextIter   iEnd;       // End of highlight
209   } mProgramCounter;
210 
211   // Popup Menu
212   SearchDialog *stPSearchDialog;
213   GtkWidget * BuildPopupMenu();
214   static void PopupMenuHandler(GtkWidget *widget,
215                                gpointer data);
216 
217   // Callbacks
218   static gboolean KeyPressHandler(GtkWidget *widget,
219                 GdkEventKey *key,
220                 SourceWindow *pSW);
221   static int DeleteEventHandler(GtkWidget *widget,
222                 GdkEvent  *event,
223                 SourceWindow *sw);
224   static void cb_notebook_switchpage(GtkNotebook    *notebook,
225                                     gpointer         page,
226                                     guint            page_num,
227                                     SourceWindow     *pSW);
228 
229   std::string m_name;
230 
231 protected:
232   std::map<int, NSourcePage *> pages;
233   GtkWidget *m_Notebook;
234   GtkPositionType m_TabPosition;
235   SourceBrowserParent_Window *m_pParent;
236 
237 public:
name_pub()238   const char *name_pub() {return name();}
239 };
240 
241 class SourceBrowser_Window : public GUI_Object {
242  public:
243   explicit SourceBrowser_Window(const char *name);
244 
245   GtkWidget *vbox;               // for children to put widgets in
246 
247   ProgramMemoryAccess *pma;      // pointer to the processor's pma.
248   SIMULATION_MODES last_simulation_mode;
249   std::string sLastPmaName;
250 
251   void set_pma(ProgramMemoryAccess *new_pma);
252 
253   void Create();
254   virtual void NewProcessor(GUI_Processor *gp) = 0;
255   virtual void SetTitle();
256   virtual void SelectAddress(int address) = 0;
257   virtual void SelectAddress(Value *);
258   virtual void Update();
259   virtual void UpdateLine(int address) = 0;
260   virtual void SetPC(int address) = 0;
CloseSource()261   virtual void CloseSource() {};
NewSource(GUI_Processor *)262   virtual void NewSource(GUI_Processor *) {};
263 };
264 
265 //
266 // The Source Opcode Browser Data
267 //
268 class SourceBrowserOpcode_Window : public SourceBrowser_Window
269 {
270  public:
271   explicit SourceBrowserOpcode_Window(GUI_Processor *gp);
272   ~SourceBrowserOpcode_Window();
273   virtual void Build();
274   virtual void NewProcessor(GUI_Processor *gp);
275   virtual void SelectAddress(int address);
276   virtual void SetPC(int address);
277   virtual void NewSource(GUI_Processor *gp);
278   virtual void UpdateLine(int address);
279   virtual void Fill();
280 
281   void update_ascii(gint row);
282   void load_styles();
283   void settings_dialog();
284 
285 private:
286   GtkWidget *build_menu_for_sheet();
287   GtkWidget *build_menu_for_list();
288 
289   void update_values(int address);
290   void update_styles(int address);
291   void update(int address);
292   void update_label(int address);
293 
294   void do_popup_menu(GtkWidget *my_widget, GdkEventButton *event);
295 
296   static void popup_activated(GtkWidget *widget, SourceBrowserOpcode_Window *sbow);
297   static void cell_renderer(GtkTreeViewColumn *tree_column,
298     GtkCellRenderer *cell, GtkTreeModel *tree_model,
299     GtkTreeIter *iter, gpointer data);
300   static void show_entry(GtkWidget *widget, SourceBrowserOpcode_Window *sbow);
301   static gint activate_sheet_cell(GtkWidget *widget,
302     gint row, gint column, SourceBrowserOpcode_Window *sbow);
303   static gint button_press(GtkWidget *widget, GdkEventButton *event,
304     SourceBrowserOpcode_Window *sbow);
305   static gboolean popup_menu_handler(GtkWidget *widget,
306     SourceBrowserOpcode_Window *sbw);
307   static void row_selected(GtkTreeView *tree_view, GtkTreePath *path,
308     GtkTreeViewColumn *column, SourceBrowserOpcode_Window *sbow);
309 
310   GtkListStore *list;
311   GtkWidget *tree;
312 
313   unsigned int current_address;   // current PC
314 
315   std::string normalfont_string;
316   PangoFontDescription *normalPFD;
317 
318   GtkWidget *notebook;
319   GtkWidget *sheet;
320   GtkWidget *entry;
321   GtkWidget *label;
322 
323   GtkWidget *sheet_popup_menu;
324   GtkWidget *list_popup_menu;
325 
326   GdkPixbuf *break_pix;
327   GdkPixbuf *pc_pix;
328 
329   unsigned int *memory;
330 };
331 
332 //
333 // The Source Browser Child window.
334 //
335 // The gui supports "context" debugging, where a context
336 // may be code written for interrupt routines, non-interrupt
337 // routines, high versus low interrupt priorities, etc. Each
338 // context has a dedicated source browser. The SourceBrowserChild_Window
339 // class manages this.
340 
341 class SourceBrowserParent_Window : public GUI_Object
342 {
343  public:
344   explicit SourceBrowserParent_Window(GUI_Processor *gp);
345 
346   virtual void Build();
347   virtual void NewProcessor(GUI_Processor *gp);
348   virtual void SelectAddress(int address);
349   virtual void SelectAddress(Value *);
350   virtual void Update();
351   virtual void UpdateLine(int address);
352   virtual void SetPC(int address);
353   virtual void CloseSource();
354   virtual void NewSource(GUI_Processor *gp);
355   virtual void ChangeView(int view_state);
356   virtual int set_config();
357 
getTagTable()358   GtkTextTagTable *getTagTable() { return mpTagTable; }
359   void CreateSourceBuffers(GUI_Processor *gp);
360 
361   void parseSource(SourceBuffer *pBuffer,FileContext *pFC);
362   SourcePageMargin &margin();
363   void setTabPosition(int tt);
getTabPosition()364   int getTabPosition() { return m_TabType; }
365   void setFont(const char *);
366   const char *getFont();
367 
368 private:
369   gchar *get_color_string(const char *tag_name);
370 
371   GtkTextTagTable *mpTagTable;
372   std::vector<SourceWindow *> children;
373 
374   ProgramMemoryAccess *pma;      // pointer to the processor's pma.
375 
376 private:
377   SourcePageMargin m_margin;
378   int m_TabType;
379   std::string m_FontDescription;
380 
381 public:
382   std::vector<SourceBuffer *> ppSourceBuffers;
383 };
384 
385 #endif // __GUI_SRC_H__
386