2018-03-23 10:35:30 +01:00
|
|
|
/* Copyright radare2 2014-2018 - Author: pancake, vane11ope */
|
2015-03-05 02:07:53 +01:00
|
|
|
|
2015-03-05 12:18:37 +01:00
|
|
|
// pls move the typedefs into roons and rename it -> RConsPanel
|
|
|
|
|
2015-03-05 02:07:53 +01:00
|
|
|
#include <r_core.h>
|
|
|
|
|
2018-02-20 10:15:17 +09:00
|
|
|
#define LIMIT 256
|
2018-03-11 18:23:44 +09:00
|
|
|
|
2018-02-21 20:31:01 +09:00
|
|
|
#define PANEL_TITLE_SYMBOLS "Symbols"
|
|
|
|
#define PANEL_TITLE_STACK "Stack"
|
|
|
|
#define PANEL_TITLE_REGISTERS "Registers"
|
|
|
|
#define PANEL_TITLE_REGISTERREFS "RegisterRefs"
|
|
|
|
#define PANEL_TITLE_DISASSEMBLY "Disassembly"
|
|
|
|
#define PANEL_TITLE_NEWFILES "New files"
|
|
|
|
#define PANEL_TITLE_INFO "Info"
|
|
|
|
#define PANEL_TITLE_DATABASE "Database"
|
|
|
|
#define PANEL_TITLE_HEXDUMP "Hexdump"
|
|
|
|
#define PANEL_TITLE_FUNCTIONS "Functions"
|
|
|
|
#define PANEL_TITLE_COMMENTS "Comments"
|
|
|
|
#define PANEL_TITLE_ENTROPY "Entropy"
|
|
|
|
#define PANEL_TITLE_DRX "DRX"
|
|
|
|
#define PANEL_TITLE_SECTIONS "Sections"
|
|
|
|
#define PANEL_TITLE_STRINGS "Strings"
|
|
|
|
#define PANEL_TITLE_MAPS "Maps"
|
|
|
|
#define PANEL_TITLE_MODULES "Modules"
|
|
|
|
#define PANEL_TITLE_BACKTRACE "Backtrace"
|
|
|
|
#define PANEL_TITLE_BREAKPOINTS "Breakpoints"
|
|
|
|
#define PANEL_TITLE_IMPORTS "Imports"
|
|
|
|
#define PANEL_TITLE_CLIPBOARD "Clipboard"
|
|
|
|
#define PANEL_TITLE_FCNINFO "FcnInfo"
|
2018-06-15 16:49:25 +09:00
|
|
|
#define PANEL_TITLE_GRAPH "Graph"
|
2018-02-21 20:31:01 +09:00
|
|
|
|
2018-03-11 18:23:44 +09:00
|
|
|
#define PANEL_CMD_SYMBOLS "isq"
|
|
|
|
#define PANEL_CMD_STACK "px 256@r:SP"
|
|
|
|
#define PANEL_CMD_REGISTERS "dr="
|
|
|
|
#define PANEL_CMD_REGISTERREFS "drr"
|
2018-06-12 13:05:47 +02:00
|
|
|
#define PANEL_CMD_DISASSEMBLY "pd $r"
|
2018-06-15 16:49:25 +09:00
|
|
|
#define PANEL_CMD_GRAPH "agf"
|
2018-03-11 18:23:44 +09:00
|
|
|
|
2018-04-07 23:51:25 +09:00
|
|
|
static const int layoutMaxCount = 2;
|
2018-03-28 19:31:08 +09:00
|
|
|
|
|
|
|
enum {
|
|
|
|
LAYOUT_DEFAULT = 0,
|
|
|
|
LAYOUT_BALANCE = 1
|
|
|
|
};
|
|
|
|
|
2015-03-05 02:07:53 +01:00
|
|
|
|
|
|
|
static const char *menus[] = {
|
2015-08-31 11:53:03 +02:00
|
|
|
"File", "Edit", "View", "Tools", "Search", "Debug", "Analyze", "Help",
|
2015-03-05 02:07:53 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *menus_File[] = {
|
2016-11-22 01:58:52 +01:00
|
|
|
"New", "Open", "Close", ".", "Sections", "Strings", "Symbols", "Imports", "Info", "Database", ".", "Quit",
|
2015-03-05 02:07:53 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *menus_Edit[] = {
|
2015-08-31 05:06:01 +02:00
|
|
|
"Copy", "Paste", "Clipboard", "Write String", "Write Hex", "Write Value", "Assemble", "Fill", "io.cache",
|
2015-03-05 02:07:53 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *menus_View[] = {
|
2015-08-31 05:43:38 +02:00
|
|
|
"Hexdump", "Disassembly", "Graph", "FcnInfo", "Functions", "Comments", "Entropy", "Colors",
|
2015-03-05 02:07:53 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *menus_Tools[] = {
|
2015-09-29 04:26:00 +02:00
|
|
|
"Assembler", "Calculator", "R2 Shell", "System Shell",
|
2015-03-05 02:07:53 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2015-08-31 11:53:03 +02:00
|
|
|
static const char *menus_Search[] = {
|
|
|
|
"String", "ROP", "Code", "Hexpairs",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2015-03-05 02:07:53 +01:00
|
|
|
static const char *menus_Debug[] = {
|
2015-10-07 11:32:08 +02:00
|
|
|
"Registers", "RegisterRefs", "DRX", "Breakpoints",
|
2016-11-22 01:58:52 +01:00
|
|
|
"Watchpoints", "Maps", "Modules",
|
2015-08-31 05:06:01 +02:00
|
|
|
"Backtrace",
|
2016-11-22 01:58:52 +01:00
|
|
|
".",
|
|
|
|
"Continue", "Cont until.",
|
|
|
|
"Step", "Step Over",
|
2015-03-05 02:07:53 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *menus_Analyze[] = {
|
2015-08-31 05:06:01 +02:00
|
|
|
"Function", "Program", "Calls", "References",
|
2015-03-05 02:07:53 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *menus_Help[] = {
|
2016-11-22 01:58:52 +01:00
|
|
|
"Fortune", "Commands", "2048", "License", ".", "About",
|
2015-03-05 02:07:53 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char **menus_sub[] = {
|
|
|
|
menus_File,
|
|
|
|
menus_Edit,
|
|
|
|
menus_View,
|
|
|
|
menus_Tools,
|
2015-08-31 11:53:03 +02:00
|
|
|
menus_Search,
|
2015-03-05 02:07:53 +01:00
|
|
|
menus_Debug,
|
|
|
|
menus_Analyze,
|
|
|
|
menus_Help,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2018-06-07 16:34:08 +09:00
|
|
|
static void layoutMenu(RPanel *panel);
|
2018-05-18 17:34:34 +09:00
|
|
|
static void panelPrint(RCore *core, RConsCanvas *can, RPanel *panel, int color);
|
|
|
|
static void addPanelFrame(RCore* core, RPanels* panels, const char *title, const char *cmd);
|
2018-06-13 18:12:18 +09:00
|
|
|
static bool checkFunc(RCore *core);
|
2018-05-11 18:41:22 +09:00
|
|
|
static void cursorLeft(RCore *core);
|
|
|
|
static void cursorRight(RCore *core);
|
|
|
|
static void delCurPanel(RPanels *panels);
|
2018-05-22 15:44:09 +09:00
|
|
|
static void doPanelsRefresh(RCore *core);
|
2018-05-11 18:41:22 +09:00
|
|
|
static bool handleCursorMode(RCore *core, const int key);
|
2018-05-18 17:34:34 +09:00
|
|
|
static void handleUpKey(RCore *core);
|
|
|
|
static void handleDownKey(RCore *core);
|
|
|
|
static void handleLeftKey(RCore *core);
|
|
|
|
static void handleRightKey(RCore *core);
|
|
|
|
static bool handleEnterKey(RCore *core);
|
2018-05-11 18:41:22 +09:00
|
|
|
static int havePanel(RPanels *panels, const char *s);
|
2018-05-18 17:34:34 +09:00
|
|
|
static bool init(RCore *core, RPanels *panels, int w, int h);
|
|
|
|
static bool initPanels(RCore *core, RPanels *panels);
|
2018-05-11 18:41:22 +09:00
|
|
|
static void panelBreakpoint(RCore *core);
|
|
|
|
static void panelContinue(RCore *core);
|
2018-05-21 08:53:39 +09:00
|
|
|
static void panelPrompt(const char *prompt, char *buf, int len);
|
2018-05-11 18:41:22 +09:00
|
|
|
static void panelSingleStepIn(RCore *core);
|
|
|
|
static void panelSingleStepOver(RCore *core);
|
|
|
|
static void setRefreshAll(RPanels *panels);
|
|
|
|
static void setCursor(RCore *core, bool cur);
|
2018-06-15 16:49:25 +09:00
|
|
|
static void replaceCmd(RPanels* panels, char *title, char *cmd);
|
2018-05-11 18:41:22 +09:00
|
|
|
static void zoom(RPanels *panels);
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
static void panelPrint(RCore *core, RConsCanvas *can, RPanel *panel, int color) {
|
2018-04-14 16:48:41 +09:00
|
|
|
if (!can || !panel|| !panel->refresh) {
|
2018-03-21 19:29:46 +09:00
|
|
|
return;
|
|
|
|
}
|
2018-04-14 16:48:41 +09:00
|
|
|
panel->refresh = false;
|
2018-03-23 01:30:41 +09:00
|
|
|
char *text;
|
2015-03-05 02:07:53 +01:00
|
|
|
char title[128];
|
2018-06-16 23:51:30 +09:00
|
|
|
int delta_x, delta_y, graph_pad = 0;
|
2018-04-14 16:48:41 +09:00
|
|
|
delta_x = panel->sx;
|
|
|
|
delta_y = panel->sy;
|
2018-03-21 19:29:46 +09:00
|
|
|
// clear the canvas first
|
2018-06-10 10:27:29 +09:00
|
|
|
r_cons_canvas_fill (can, panel->x, panel->y, panel->w, panel->h, ' ');
|
2018-03-23 01:30:41 +09:00
|
|
|
// for menu
|
2018-03-28 17:00:54 +09:00
|
|
|
RCons *cons = r_cons_singleton ();
|
2018-04-14 16:48:41 +09:00
|
|
|
if (panel->type == PANEL_TYPE_MENU) {
|
|
|
|
(void) r_cons_canvas_gotoxy (can, panel->x + 2, panel->y + 2);
|
|
|
|
text = r_str_ansi_crop (panel->title,
|
|
|
|
delta_x, delta_y, panel->w + 5, panel->h - delta_y);
|
2018-03-23 01:30:41 +09:00
|
|
|
if (text) {
|
|
|
|
r_cons_canvas_write (can, text);
|
|
|
|
free (text);
|
|
|
|
} else {
|
2018-04-14 16:48:41 +09:00
|
|
|
r_cons_canvas_write (can, panel->title);
|
2018-03-23 01:30:41 +09:00
|
|
|
}
|
|
|
|
} else {
|
2018-04-07 23:51:25 +09:00
|
|
|
if (color) {
|
2018-03-05 23:32:27 +01:00
|
|
|
const char *k = cons->pal.graph_box;
|
2017-02-22 23:45:51 +01:00
|
|
|
snprintf (title, sizeof (title) - 1,
|
2018-04-14 16:48:41 +09:00
|
|
|
"%s[x] %s"Color_RESET, k, panel->title);
|
2015-03-05 02:07:53 +01:00
|
|
|
} else {
|
2017-02-22 23:45:51 +01:00
|
|
|
snprintf (title, sizeof (title) - 1,
|
2018-04-14 16:48:41 +09:00
|
|
|
" %s ", panel->title);
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
2018-04-14 16:48:41 +09:00
|
|
|
if (r_cons_canvas_gotoxy (can, panel->x + 1, panel->y + 1)) {
|
2018-02-20 10:15:17 +09:00
|
|
|
r_cons_canvas_write (can, title); // delta_x
|
2017-02-22 23:45:51 +01:00
|
|
|
}
|
2018-04-14 16:48:41 +09:00
|
|
|
(void) r_cons_canvas_gotoxy (can, panel->x + 2, panel->y + 2);
|
|
|
|
char *cmdStr;
|
2018-05-18 17:34:34 +09:00
|
|
|
bool ce = core->print->cur_enabled;
|
2018-04-24 11:32:51 +02:00
|
|
|
if (!strcmp (panel->title, PANEL_TITLE_DISASSEMBLY)) {
|
2018-05-18 17:34:34 +09:00
|
|
|
core->print->cur_enabled = false;
|
|
|
|
cmdStr = r_core_cmd_str (core, panel->cmd);
|
2018-04-24 11:32:51 +02:00
|
|
|
} else if (!strcmp (panel->title, PANEL_TITLE_STACK)) {
|
2018-05-18 17:34:34 +09:00
|
|
|
const int delta = r_config_get_i (core->config, "stack.delta");
|
2018-04-14 16:48:41 +09:00
|
|
|
const char sign = (delta < 0)? '+': '-';
|
|
|
|
const int absdelta = R_ABS (delta);
|
2018-05-18 17:34:34 +09:00
|
|
|
cmdStr = r_core_cmd_strf (core, "%s%c%d", PANEL_CMD_STACK, sign, absdelta);
|
2018-04-14 16:48:41 +09:00
|
|
|
} else {
|
2018-05-18 17:34:34 +09:00
|
|
|
cmdStr = r_core_cmd_str (core, panel->cmd);
|
2018-04-14 16:48:41 +09:00
|
|
|
}
|
2018-06-16 23:51:30 +09:00
|
|
|
if (!strcmp (core->panels->panel[core->panels->curnode].title, PANEL_TITLE_GRAPH)) {
|
|
|
|
graph_pad = 1;
|
|
|
|
}
|
2018-03-23 01:30:41 +09:00
|
|
|
if (delta_y < 0) {
|
|
|
|
delta_y = 0;
|
|
|
|
}
|
|
|
|
if (delta_x < 0) {
|
2018-06-16 23:51:30 +09:00
|
|
|
char *white = (char*)r_str_pad (' ', 128);
|
2018-03-23 01:30:41 +09:00
|
|
|
int idx = -delta_x;
|
|
|
|
if (idx >= sizeof (white)) {
|
|
|
|
idx = sizeof (white) - 1;
|
|
|
|
}
|
|
|
|
white[idx] = 0;
|
2018-04-14 16:48:41 +09:00
|
|
|
text = r_str_ansi_crop (cmdStr,
|
2018-06-16 23:51:30 +09:00
|
|
|
0, delta_y + graph_pad, panel->w + delta_x - 3, panel->h - 2 + delta_y);
|
2018-03-23 01:30:41 +09:00
|
|
|
char *newText = r_str_prefix_all (text, white);
|
|
|
|
if (newText) {
|
|
|
|
free (text);
|
|
|
|
text = newText;
|
|
|
|
}
|
|
|
|
} else {
|
2018-04-14 16:48:41 +09:00
|
|
|
text = r_str_ansi_crop (cmdStr,
|
2018-06-16 23:51:30 +09:00
|
|
|
delta_x, delta_y + graph_pad, panel->w + delta_x - 3, panel->h - 2 + delta_y);
|
2018-03-21 19:29:46 +09:00
|
|
|
}
|
2018-03-23 01:30:41 +09:00
|
|
|
if (text) {
|
|
|
|
r_cons_canvas_write (can, text);
|
2015-03-05 02:07:53 +01:00
|
|
|
free (text);
|
2018-03-23 01:30:41 +09:00
|
|
|
} else {
|
2018-04-14 16:48:41 +09:00
|
|
|
r_cons_canvas_write (can, panel->title);
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
2018-04-14 16:48:41 +09:00
|
|
|
free (cmdStr);
|
2018-05-18 17:34:34 +09:00
|
|
|
core->print->cur_enabled = ce;
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
if (color) {
|
2018-04-14 16:48:41 +09:00
|
|
|
r_cons_canvas_box (can, panel->x, panel->y, panel->w, panel->h, cons->pal.graph_box2);
|
2015-03-05 02:07:53 +01:00
|
|
|
} else {
|
2018-04-14 16:48:41 +09:00
|
|
|
r_cons_canvas_box (can, panel->x, panel->y, panel->w, panel->h, cons->pal.graph_box);
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-07 16:34:08 +09:00
|
|
|
static void layoutMenu(RPanel *panel) {
|
|
|
|
panel->w = r_str_bounds (panel->title, &panel->h);
|
|
|
|
panel->h += 4;
|
|
|
|
}
|
|
|
|
|
2018-06-13 18:12:18 +09:00
|
|
|
R_API void r_core_panels_layout(RPanels *panels) {
|
2015-03-05 02:07:53 +01:00
|
|
|
int h, w = r_cons_get_size (&h);
|
|
|
|
int i, j;
|
2018-04-07 23:51:25 +09:00
|
|
|
int colpos = w - panels->columnWidth;
|
|
|
|
RPanel *panel = panels->panel;
|
|
|
|
|
2016-05-09 11:13:37 +02:00
|
|
|
if (colpos < 0) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->columnWidth = w;
|
2015-10-08 13:24:47 +02:00
|
|
|
colpos = 0;
|
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->can->sx = 0;
|
|
|
|
panels->can->sy = 0;
|
|
|
|
for (i = j = 0; i < panels->n_panels; i++) {
|
|
|
|
switch (panel[i].type) {
|
2018-03-11 18:23:44 +09:00
|
|
|
case PANEL_TYPE_MENU:
|
2018-06-07 16:34:08 +09:00
|
|
|
layoutMenu (&panel[i]);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
|
|
|
case PANEL_TYPE_FRAME:
|
2018-04-07 23:51:25 +09:00
|
|
|
switch (panels->layout) {
|
2018-03-28 17:00:54 +09:00
|
|
|
case LAYOUT_DEFAULT:
|
2016-11-22 01:58:52 +01:00
|
|
|
if (j == 0) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].x = 0;
|
|
|
|
panel[i].y = 1;
|
2018-04-14 16:48:41 +09:00
|
|
|
if (panel[j + 1].title) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].w = colpos + 1;
|
2016-11-22 01:58:52 +01:00
|
|
|
} else {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].w = w;
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].h = h - 1;
|
2015-03-05 02:07:53 +01:00
|
|
|
} else {
|
2018-04-07 23:51:25 +09:00
|
|
|
int ph = ((h - 1) / (panels->n_panels - 2));
|
|
|
|
panel[i].x = colpos;
|
|
|
|
panel[i].y = 1 + (ph * (j - 1));
|
|
|
|
panel[i].w = w - colpos;
|
|
|
|
if (panel[i].w < 0) {
|
|
|
|
panel[i].w = 0;
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].h = ph;
|
2018-04-14 16:48:41 +09:00
|
|
|
if (!panel[i + 1].title) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].h = h - panel[i].y;
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
|
|
|
if (j != 1) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].y--;
|
|
|
|
panel[i].h++;
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
2015-03-05 23:07:39 +01:00
|
|
|
}
|
2016-11-22 01:58:52 +01:00
|
|
|
break;
|
2018-03-28 17:00:54 +09:00
|
|
|
case LAYOUT_BALANCE:
|
2016-11-22 01:58:52 +01:00
|
|
|
if (j == 0) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].x = 0;
|
|
|
|
panel[i].y = 1;
|
2018-04-14 16:48:41 +09:00
|
|
|
if (panel[j + 1].title) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].w = colpos + 1;
|
2016-11-22 01:58:52 +01:00
|
|
|
} else {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].w = w;
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].h = (h / 2) + 1;
|
2016-11-22 01:58:52 +01:00
|
|
|
} else if (j == 1) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].x = 0;
|
|
|
|
panel[i].y = (h / 2) + 1;
|
2018-04-14 16:48:41 +09:00
|
|
|
if (panel[j + 1].title) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].w = colpos + 1;
|
2016-11-22 01:58:52 +01:00
|
|
|
} else {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].w = w;
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].h = (h - 1) / 2;
|
2016-11-22 01:58:52 +01:00
|
|
|
} else {
|
2018-04-07 23:51:25 +09:00
|
|
|
int ph = ((h - 1) / (panels->n_panels - 3));
|
|
|
|
panel[i].x = colpos;
|
|
|
|
panel[i].y = 1 + (ph * (j - 2));
|
|
|
|
panel[i].w = w - colpos;
|
|
|
|
if (panel[i].w < 0) {
|
|
|
|
panel[i].w = 0;
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].h = ph;
|
2018-04-14 16:48:41 +09:00
|
|
|
if (!panel[i + 1].title) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].h = h - panel[i].y;
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
|
|
|
if (j != 2) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[i].y--;
|
|
|
|
panel[i].h++;
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
2015-09-29 04:26:00 +02:00
|
|
|
}
|
2016-11-22 01:58:52 +01:00
|
|
|
break;
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-13 18:12:18 +09:00
|
|
|
R_API void r_core_panels_layout_refresh(RCore *core) {
|
|
|
|
r_core_panels_check_stackbase (core);
|
|
|
|
r_core_panels_layout (core->panels);
|
|
|
|
r_core_panels_refresh (core);
|
|
|
|
}
|
|
|
|
|
2018-05-11 18:41:22 +09:00
|
|
|
static void setCursor(RCore *core, bool cur) {
|
2018-04-24 14:16:42 +09:00
|
|
|
core->print->cur_enabled = cur;
|
2018-05-07 17:01:25 +09:00
|
|
|
if (cur) {
|
|
|
|
core->print->cur = core->panels->panel[core->panels->curnode].curpos;
|
|
|
|
} else {
|
|
|
|
core->panels->panel[core->panels->curnode].curpos = core->print->cur;
|
2018-04-24 14:16:42 +09:00
|
|
|
}
|
|
|
|
core->print->col = core->print->cur_enabled ? 1: 0;
|
|
|
|
}
|
|
|
|
|
2018-05-11 18:41:22 +09:00
|
|
|
static void cursorRight(RCore *core) {
|
2018-05-07 17:01:25 +09:00
|
|
|
if (!strcmp (core->panels->panel[core->panels->curnode].title, PANEL_TITLE_STACK) && core->print->cur >= 15) {
|
|
|
|
return;
|
2018-04-24 14:16:42 +09:00
|
|
|
}
|
2018-05-07 17:01:25 +09:00
|
|
|
core->print->cur++;
|
|
|
|
core->panels->panel[core->panels->curnode].addr++;
|
2018-04-24 14:16:42 +09:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-11 18:41:22 +09:00
|
|
|
static void cursorLeft(RCore *core) {
|
2018-04-24 14:16:42 +09:00
|
|
|
if (core->print->cur > 0) {
|
|
|
|
core->print->cur--;
|
2018-05-02 22:52:28 +09:00
|
|
|
core->panels->panel[core->panels->curnode].addr--;
|
2018-04-24 14:16:42 +09:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
static void handleUpKey(RCore *core) {
|
|
|
|
RPanels *panels = core->panels;
|
2018-05-13 00:13:40 +09:00
|
|
|
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (false);
|
2018-05-13 00:13:40 +09:00
|
|
|
panels->panel[panels->curnode].refresh = true;
|
|
|
|
if (panels->panel[panels->curnode].type == PANEL_TYPE_MENU) {
|
|
|
|
panels->menu_y--;
|
|
|
|
if (panels->menu_y < 0) {
|
|
|
|
panels->menu_y = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_DISASSEMBLY)) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmd0 (core, "s-8");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_STACK)) {
|
2018-05-18 17:34:34 +09:00
|
|
|
int width = r_config_get_i (core->config, "hex.cols");
|
2018-05-13 00:13:40 +09:00
|
|
|
if (width < 1) {
|
|
|
|
width = 16;
|
|
|
|
}
|
2018-05-18 17:34:34 +09:00
|
|
|
r_config_set_i (core->config, "stack.delta",
|
|
|
|
r_config_get_i (core->config, "stack.delta") + width);
|
2018-05-13 00:13:40 +09:00
|
|
|
panels->panel[panels->curnode].addr -= width;
|
|
|
|
} else if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_REGISTERS)) {
|
2018-05-18 17:34:34 +09:00
|
|
|
if (core->print->cur_enabled) {
|
|
|
|
int cur = core->print->cur;
|
|
|
|
int cols = core->dbg->regcols;
|
2018-05-13 00:13:40 +09:00
|
|
|
cols = cols > 0 ? cols : 3;
|
|
|
|
cur -= cols;
|
|
|
|
if (cur >= 0) {
|
2018-05-18 17:34:34 +09:00
|
|
|
core->print->cur = cur;
|
2018-05-13 00:13:40 +09:00
|
|
|
}
|
|
|
|
}
|
2018-06-16 23:51:30 +09:00
|
|
|
} else if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_GRAPH)) {
|
|
|
|
if (panels->panel[panels->curnode].sy > 0) {
|
|
|
|
panels->panel[panels->curnode].sy -= r_config_get_i (core->config, "graph.scroll");
|
|
|
|
}
|
2018-05-13 00:13:40 +09:00
|
|
|
} else {
|
|
|
|
if (panels->panel[panels->curnode].sy > 0) {
|
|
|
|
panels->panel[panels->curnode].sy--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
static void handleDownKey(RCore *core) {
|
|
|
|
RPanels *panels = core->panels;
|
2018-05-13 00:13:40 +09:00
|
|
|
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (false);
|
2018-05-13 00:13:40 +09:00
|
|
|
panels->panel[panels->curnode].refresh = true;
|
|
|
|
if (panels->panel[panels->curnode].type == PANEL_TYPE_MENU) {
|
|
|
|
if (menus_sub[panels->menu_x][panels->menu_y]) {
|
|
|
|
panels->menu_y++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_DISASSEMBLY)) {
|
2018-05-18 17:34:34 +09:00
|
|
|
int cols = core->print->cols;
|
2018-05-13 00:13:40 +09:00
|
|
|
RAnalFunction *f = NULL;
|
|
|
|
RAsmOp op;
|
2018-05-18 17:34:34 +09:00
|
|
|
f = r_anal_get_fcn_in (core->anal, core->offset, 0);
|
2018-05-13 00:13:40 +09:00
|
|
|
op.size = 1;
|
|
|
|
if (f && f->folded) {
|
2018-05-18 17:34:34 +09:00
|
|
|
cols = core->offset - f->addr + r_anal_fcn_size (f);
|
2018-05-13 00:13:40 +09:00
|
|
|
} else {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_asm_set_pc (core->assembler, core->offset);
|
|
|
|
cols = r_asm_disassemble (core->assembler,
|
|
|
|
&op, core->block, 32);
|
2018-05-13 00:13:40 +09:00
|
|
|
}
|
|
|
|
if (cols < 1) {
|
|
|
|
cols = op.size > 1 ? op.size : 1;
|
|
|
|
}
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_seek (core, core->offset + cols, 1);
|
|
|
|
r_core_block_read (core);
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_STACK)) {
|
2018-05-18 17:34:34 +09:00
|
|
|
int width = r_config_get_i (core->config, "hex.cols");
|
2018-05-13 00:13:40 +09:00
|
|
|
if (width < 1) {
|
|
|
|
width = 16;
|
|
|
|
}
|
2018-05-18 17:34:34 +09:00
|
|
|
r_config_set_i (core->config, "stack.delta",
|
|
|
|
r_config_get_i (core->config, "stack.delta") - width);
|
2018-05-13 00:13:40 +09:00
|
|
|
panels->panel[panels->curnode].addr += width;
|
|
|
|
} else if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_REGISTERS)) {
|
2018-05-18 17:34:34 +09:00
|
|
|
if (core->print->cur_enabled) {
|
|
|
|
const int cols = core->dbg->regcols;
|
|
|
|
core->print->cur += cols > 0 ? cols : 3;
|
2018-05-13 00:13:40 +09:00
|
|
|
}
|
2018-06-16 23:51:30 +09:00
|
|
|
} else if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_GRAPH)) {
|
|
|
|
panels->panel[panels->curnode].sy += r_config_get_i (core->config, "graph.scroll");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else {
|
|
|
|
panels->panel[panels->curnode].sy++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
static void handleLeftKey(RCore *core) {
|
|
|
|
RPanels *panels = core->panels;
|
2018-05-13 00:13:40 +09:00
|
|
|
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (false);
|
2018-05-13 00:13:40 +09:00
|
|
|
panels->panel[panels->curnode].refresh = true;
|
2018-05-18 17:34:34 +09:00
|
|
|
if (core->print->cur_enabled) {
|
|
|
|
cursorLeft (core);
|
2018-05-13 00:13:40 +09:00
|
|
|
} else {
|
2018-06-19 21:25:38 +09:00
|
|
|
if (panels->curnode == panels->menu_pos) {
|
2018-05-13 00:13:40 +09:00
|
|
|
if (panels->menu_x) {
|
|
|
|
panels->menu_x--;
|
|
|
|
panels->menu_y = panels->menu_y? 1: 0;
|
|
|
|
}
|
2018-06-16 23:51:30 +09:00
|
|
|
} else if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_GRAPH)) {
|
|
|
|
if (panels->panel[panels->curnode].sx > 0) {
|
|
|
|
panels->panel[panels->curnode].sx -= r_config_get_i (core->config, "graph.scroll");
|
|
|
|
}
|
2018-05-13 00:13:40 +09:00
|
|
|
} else {
|
|
|
|
if (panels->panel[panels->curnode].sx > 0) {
|
|
|
|
panels->panel[panels->curnode].sx--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
static void handleRightKey(RCore *core) {
|
|
|
|
RPanels *panels = core->panels;
|
2018-05-13 00:13:40 +09:00
|
|
|
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (false);
|
2018-05-13 00:13:40 +09:00
|
|
|
panels->panel[panels->curnode].refresh = true;
|
2018-05-18 17:34:34 +09:00
|
|
|
if (core->print->cur_enabled) {
|
|
|
|
cursorRight (core);
|
2018-05-13 00:13:40 +09:00
|
|
|
} else {
|
2018-06-19 21:25:38 +09:00
|
|
|
if (panels->curnode == panels->menu_pos) {
|
2018-05-13 00:13:40 +09:00
|
|
|
if (menus[panels->menu_x + 1]) {
|
|
|
|
panels->menu_x++;
|
|
|
|
panels->menu_y = panels->menu_y ? 1: 0;
|
|
|
|
}
|
2018-06-16 23:51:30 +09:00
|
|
|
} else if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_GRAPH)) {
|
|
|
|
panels->panel[panels->curnode].sx += r_config_get_i (core->config, "graph.scroll");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else {
|
|
|
|
panels->panel[panels->curnode].sx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-11 18:41:22 +09:00
|
|
|
static bool handleCursorMode(RCore *core, const int key) {
|
|
|
|
const char *creg;
|
|
|
|
const RPanels *panels = core->panels;
|
|
|
|
char buf[128];
|
|
|
|
if (core->print->cur_enabled) {
|
|
|
|
switch (key) {
|
2018-06-19 10:05:40 +02:00
|
|
|
case 9: // TAB
|
|
|
|
case 'Z': // SHIFT-TAB
|
|
|
|
return true;
|
|
|
|
case 'Q':
|
|
|
|
case 'q':
|
|
|
|
setCursor (core, !core->print->cur_enabled);
|
|
|
|
panels->panel[panels->curnode].refresh = true;
|
|
|
|
return true;
|
|
|
|
case 'i':
|
|
|
|
if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_STACK)) {
|
|
|
|
// insert mode
|
|
|
|
const char *prompt = "insert hex: ";
|
|
|
|
panelPrompt (prompt, buf, sizeof (buf));
|
|
|
|
r_core_cmdf (core, "wx %s @ 0x%08" PFMT64x, buf, panels->panel[panels->curnode].addr);
|
2018-05-11 18:41:22 +09:00
|
|
|
panels->panel[panels->curnode].refresh = true;
|
2018-06-19 10:05:40 +02:00
|
|
|
} else if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_REGISTERS)) {
|
|
|
|
creg = core->dbg->creg;
|
|
|
|
if (creg) {
|
|
|
|
const char *prompt = "new-reg-value> ";
|
2018-05-21 08:53:39 +09:00
|
|
|
panelPrompt (prompt, buf, sizeof (buf));
|
2018-06-19 10:05:40 +02:00
|
|
|
r_core_cmdf (core, "dr %s = %s", creg, buf);
|
2018-05-11 18:41:22 +09:00
|
|
|
panels->panel[panels->curnode].refresh = true;
|
|
|
|
}
|
2018-06-19 10:05:40 +02:00
|
|
|
}
|
|
|
|
return true;
|
2018-05-11 18:41:22 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void delCurPanel(RPanels *panels) {
|
2016-05-09 11:13:37 +02:00
|
|
|
int i;
|
2018-04-07 23:51:25 +09:00
|
|
|
if (panels->curnode > 0 && panels->n_panels > 3) {
|
|
|
|
for (i = panels->curnode; i < (panels->n_panels - 1); i++) {
|
|
|
|
panels->panel[i] = panels->panel[i + 1];
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
2018-04-14 16:48:41 +09:00
|
|
|
panels->panel[i].title = 0;
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->n_panels--;
|
|
|
|
if (panels->curnode >= panels->n_panels) {
|
|
|
|
panels->curnode = panels->n_panels - 1;
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-03-05 02:07:53 +01:00
|
|
|
|
2018-06-15 16:49:25 +09:00
|
|
|
static void replaceCmd(RPanels* panels, char *title, char *cmd) {
|
|
|
|
free (panels->panel[panels->curnode].title);
|
|
|
|
free (panels->panel[panels->curnode].cmd);
|
|
|
|
panels->panel[panels->curnode].title = strdup (title);
|
|
|
|
panels->panel[panels->curnode].cmd = r_str_newf (cmd);
|
|
|
|
setRefreshAll (panels);
|
|
|
|
}
|
|
|
|
|
2018-04-07 23:51:25 +09:00
|
|
|
static void zoom(RPanels *panels) {
|
|
|
|
if (panels->n_panels > 2) {
|
|
|
|
if (panels->curnode < 2) {
|
|
|
|
panels->curnode = 2;
|
2015-08-31 05:43:38 +02:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
RPanel ocurnode = panels->panel[panels->curnode];
|
|
|
|
panels->panel[panels->curnode] = panels->panel[1];
|
|
|
|
panels->panel[1] = ocurnode;
|
|
|
|
panels->curnode = 1;
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-13 18:12:18 +09:00
|
|
|
static bool checkFunc(RCore *core) {
|
|
|
|
RAnalFunction *fun = r_anal_get_fcn_in (core->anal, core->offset, R_ANAL_FCN_TYPE_NULL);
|
|
|
|
if (!fun) {
|
|
|
|
r_cons_message ("Not in a function. Type 'df' to define it here");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (r_list_empty (fun->bbs)) {
|
|
|
|
r_cons_message ("No basic blocks in this function. You may want to use 'afb+'.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-05-11 18:41:22 +09:00
|
|
|
static void setRefreshAll(RPanels *panels) {
|
2018-03-23 01:30:41 +09:00
|
|
|
int i;
|
2018-04-07 23:51:25 +09:00
|
|
|
for (i = 0; i < panels->n_panels; i++) {
|
|
|
|
panels->panel[i].refresh = true;
|
2018-03-23 01:30:41 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
static void addPanelFrame(RCore *core, RPanels* panels, const char *title, const char *cmd) {
|
2018-04-07 23:51:25 +09:00
|
|
|
RPanel* panel = panels->panel;
|
|
|
|
int n_panels = panels->n_panels;
|
2018-03-23 11:17:42 +01:00
|
|
|
if (title) {
|
2018-04-14 16:48:41 +09:00
|
|
|
panel[n_panels].title = strdup (title);
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[n_panels].cmd = r_str_newf (cmd);
|
2018-03-23 11:17:42 +01:00
|
|
|
} else {
|
2018-05-18 17:34:34 +09:00
|
|
|
panel[n_panels].title = r_core_cmd_str (core, cmd);
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[n_panels].cmd = NULL;
|
2018-03-23 11:17:42 +01:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[panels->n_panels].type = PANEL_TYPE_FRAME;
|
|
|
|
panel[panels->n_panels].refresh = true;
|
2018-05-07 17:01:25 +09:00
|
|
|
panel[panels->n_panels].curpos = 0;
|
2018-05-02 22:52:28 +09:00
|
|
|
if (!strcmp (panel[panels->n_panels].title, PANEL_TITLE_STACK)) {
|
2018-05-18 17:34:34 +09:00
|
|
|
const char *sp = r_reg_get_name (core->anal->reg, R_REG_NAME_SP);
|
|
|
|
const ut64 stackbase = r_reg_getv (core->anal->reg, sp);
|
2018-05-08 16:12:45 +09:00
|
|
|
panel[panels->n_panels].baseAddr = stackbase;
|
2018-05-18 17:34:34 +09:00
|
|
|
panel[panels->n_panels].addr = stackbase - r_config_get_i (core->config, "stack.delta");
|
2018-05-02 22:52:28 +09:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->n_panels++;
|
|
|
|
panels->curnode = panels->n_panels - 1;
|
|
|
|
zoom (panels);
|
|
|
|
panels->menu_y = 0;
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
static bool initPanels(RCore *core, RPanels *panels) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->panel = NULL;
|
|
|
|
panels->panel = calloc (sizeof (RPanel), LIMIT);
|
|
|
|
if (!panels->panel) return false;
|
|
|
|
panels->n_panels = 0;
|
2018-04-14 16:48:41 +09:00
|
|
|
panels->panel[panels->n_panels].title = strdup ("");
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->panel[panels->n_panels].type = PANEL_TYPE_MENU;
|
|
|
|
panels->panel[panels->n_panels].refresh = true;
|
|
|
|
panels->n_panels++;
|
2018-03-11 18:23:44 +09:00
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_SYMBOLS, PANEL_CMD_SYMBOLS);
|
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_STACK, PANEL_CMD_STACK);
|
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_REGISTERS, PANEL_CMD_REGISTERS);
|
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_REGISTERREFS, PANEL_CMD_REGISTERREFS);
|
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_DISASSEMBLY, PANEL_CMD_DISASSEMBLY);
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->curnode = 1;
|
2018-03-11 18:23:44 +09:00
|
|
|
return true;
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// damn singletons.. there should be only one screen and therefor
|
|
|
|
// only one visual instance of the graph view. refactoring this
|
|
|
|
// into a struct makes the code to reference pointers unnecesarily
|
|
|
|
// we can look for a non-global solution here in the future if
|
|
|
|
// necessary
|
2018-06-13 18:12:18 +09:00
|
|
|
R_API void r_core_panels_refresh(RCore *core) {
|
2018-05-22 15:44:09 +09:00
|
|
|
RPanels *panels = core->panels;
|
2018-04-07 23:51:25 +09:00
|
|
|
RPanel *panel = panels->panel;
|
|
|
|
RConsCanvas *can = panels->can;
|
|
|
|
int menu_pos = panels->menu_pos;
|
|
|
|
int menu_x = panels->menu_x;
|
|
|
|
int menu_y = panels->menu_y;
|
2015-08-31 11:53:03 +02:00
|
|
|
char title[1024];
|
|
|
|
char str[1024];
|
2015-03-05 02:07:53 +01:00
|
|
|
int i, j, h, w = r_cons_get_size (&h);
|
2018-05-18 17:34:34 +09:00
|
|
|
const char *color = panels->curnode ? core->cons->pal.graph_box : core->cons->pal.graph_box2;
|
2018-03-21 19:29:46 +09:00
|
|
|
r_cons_gotoxy (0, 0);
|
2015-03-05 02:07:53 +01:00
|
|
|
if (!can) {
|
|
|
|
return;
|
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
if (panels->isResizing) {
|
|
|
|
panels->isResizing = false;
|
2018-06-16 15:25:00 +02:00
|
|
|
if (!r_cons_canvas_resize (can, w, h)) {
|
|
|
|
return;
|
|
|
|
}
|
2018-05-11 18:41:22 +09:00
|
|
|
setRefreshAll (panels);
|
2018-03-22 15:43:59 +09:00
|
|
|
}
|
2016-11-22 01:58:52 +01:00
|
|
|
#if 0
|
|
|
|
/* avoid flickering */
|
2015-03-05 02:07:53 +01:00
|
|
|
r_cons_canvas_clear (can);
|
2015-09-29 04:26:00 +02:00
|
|
|
r_cons_flush ();
|
2016-11-22 01:58:52 +01:00
|
|
|
#endif
|
2018-04-07 23:51:25 +09:00
|
|
|
if (panel) {
|
2018-06-19 21:25:38 +09:00
|
|
|
if (panel[panels->curnode].type == PANEL_TYPE_MENU) {
|
|
|
|
setRefreshAll (panels);
|
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panel[menu_pos].x = (menu_y > 0) ? menu_x * 6 : w;
|
|
|
|
panel[menu_pos].y = 1;
|
2018-04-14 16:48:41 +09:00
|
|
|
free (panel[menu_pos].title);
|
|
|
|
panel[menu_pos].title = calloc (1, 1024); // r_str_newf ("%d", menu_y);
|
2015-03-05 02:07:53 +01:00
|
|
|
int maxsub = 0;
|
2017-02-22 23:45:51 +01:00
|
|
|
for (i = 0; menus_sub[i]; i++) {
|
|
|
|
maxsub = i;
|
|
|
|
}
|
2018-03-28 17:00:54 +09:00
|
|
|
if (menu_x < 0) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->menu_x = 0;
|
2018-03-28 17:00:54 +09:00
|
|
|
}
|
|
|
|
if (menu_x > maxsub) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->menu_x = maxsub;
|
2018-03-28 17:00:54 +09:00
|
|
|
}
|
2015-08-31 05:06:01 +02:00
|
|
|
if (menu_x >= 0 && menu_x <= maxsub && menus_sub[menu_x]) {
|
2015-03-05 02:07:53 +01:00
|
|
|
for (j = 0; menus_sub[menu_x][j]; j++) {
|
2017-02-22 23:45:51 +01:00
|
|
|
if (menu_y - 1 == j) {
|
2018-04-14 16:48:41 +09:00
|
|
|
strcat (panel[menu_pos].title, "> ");
|
2015-03-05 02:07:53 +01:00
|
|
|
} else {
|
2018-04-14 16:48:41 +09:00
|
|
|
strcat (panel[menu_pos].title, " ");
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
2018-04-14 16:48:41 +09:00
|
|
|
strcat (panel[menu_pos].title, menus_sub[menu_x][j]);
|
|
|
|
strcat (panel[menu_pos].title, " \n");
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
2018-06-07 16:34:08 +09:00
|
|
|
layoutMenu (&panel[menu_pos]);
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
for (i = 0; i < panels->n_panels; i++) {
|
|
|
|
if (i != panels->curnode) {
|
2018-05-18 17:34:34 +09:00
|
|
|
panelPrint (core, can, &panel[i], 0);
|
2015-08-31 11:53:03 +02:00
|
|
|
}
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
2018-06-19 21:25:38 +09:00
|
|
|
panelPrint (core, can, &panel[panels->curnode], 1);
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
|
|
|
|
2018-02-20 10:15:17 +09:00
|
|
|
(void) r_cons_canvas_gotoxy (can, -can->sx, -can->sy);
|
2015-03-05 02:07:53 +01:00
|
|
|
title[0] = 0;
|
2018-04-07 23:51:25 +09:00
|
|
|
if (panels->curnode == 0) {
|
2015-08-31 05:06:01 +02:00
|
|
|
strcpy (title, "> ");
|
2016-10-26 23:16:31 +02:00
|
|
|
}
|
|
|
|
for (i = 0; menus[i]; i++) {
|
2015-03-05 02:07:53 +01:00
|
|
|
if (menu_x == i) {
|
2017-02-22 23:45:51 +01:00
|
|
|
snprintf (str, sizeof (title) - 1, "%s[%s]"Color_RESET, color, menus[i]);
|
2015-03-05 02:07:53 +01:00
|
|
|
} else {
|
2017-02-22 23:45:51 +01:00
|
|
|
snprintf (str, sizeof (title) - 1, "%s %s "Color_RESET, color, menus[i]);
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
|
|
|
strcat (title, str);
|
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
if (panels->curnode == 0) {
|
2018-02-20 10:15:17 +09:00
|
|
|
r_cons_canvas_write (can, Color_BLUE);
|
|
|
|
r_cons_canvas_write (can, title);
|
|
|
|
r_cons_canvas_write (can, Color_RESET);
|
2015-08-31 05:06:01 +02:00
|
|
|
} else {
|
2018-02-20 10:15:17 +09:00
|
|
|
r_cons_canvas_write (can, Color_RESET);
|
|
|
|
r_cons_canvas_write (can, title);
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
2015-03-05 02:07:53 +01:00
|
|
|
|
2017-02-22 23:45:51 +01:00
|
|
|
snprintf (title, sizeof (title) - 1,
|
2018-05-18 17:34:34 +09:00
|
|
|
"[0x%08"PFMT64x "]", core->offset);
|
2018-02-20 10:15:17 +09:00
|
|
|
(void) r_cons_canvas_gotoxy (can, -can->sx + w - strlen (title), -can->sy);
|
|
|
|
r_cons_canvas_write (can, title);
|
2015-03-05 02:07:53 +01:00
|
|
|
r_cons_canvas_print (can);
|
2015-07-13 23:04:34 +02:00
|
|
|
r_cons_flush ();
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
|
|
|
|
2018-05-22 15:44:09 +09:00
|
|
|
static void doPanelsRefresh(RCore *core) {
|
|
|
|
core->panels->isResizing = true;
|
2018-06-13 18:12:18 +09:00
|
|
|
r_core_panels_layout (core->panels);
|
|
|
|
r_core_panels_refresh (core);
|
2018-03-23 10:35:30 +01:00
|
|
|
}
|
|
|
|
|
2018-04-07 23:51:25 +09:00
|
|
|
static int havePanel(RPanels *panels, const char *s) {
|
2015-08-31 11:53:03 +02:00
|
|
|
int i;
|
2018-04-14 16:48:41 +09:00
|
|
|
if (!panels->panel || !panels->panel[0].title) {
|
2015-08-31 11:53:03 +02:00
|
|
|
return 0;
|
2016-10-26 23:16:31 +02:00
|
|
|
}
|
2015-08-31 11:53:03 +02:00
|
|
|
// add new panel for testing
|
2018-04-14 16:48:41 +09:00
|
|
|
for (i = 1; panels->panel[i].title; i++) {
|
|
|
|
if (!strcmp (panels->panel[i].title, s)) {
|
2015-08-31 11:53:03 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-05-11 18:41:22 +09:00
|
|
|
static void panelSingleStepIn(RCore *core) {
|
2017-02-22 23:45:51 +01:00
|
|
|
if (r_config_get_i (core->config, "cfg.debug")) {
|
|
|
|
if (core->print->cur_enabled) {
|
|
|
|
// dcu 0xaddr
|
|
|
|
r_core_cmdf (core, "dcu 0x%08"PFMT64x, core->offset + core->print->cur);
|
|
|
|
core->print->cur_enabled = 0;
|
|
|
|
} else {
|
|
|
|
r_core_cmd (core, "ds", 0);
|
|
|
|
r_core_cmd (core, ".dr*", 0);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
r_core_cmd (core, "aes", 0);
|
|
|
|
r_core_cmd (core, ".ar*", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-11 18:41:22 +09:00
|
|
|
static void panelSingleStepOver(RCore *core) {
|
2018-05-27 22:53:04 +09:00
|
|
|
bool io_cache = r_config_get_i (core->config, "io.cache");
|
|
|
|
r_config_set_i (core->config, "io.cache", false);
|
2017-02-22 23:45:51 +01:00
|
|
|
if (r_config_get_i (core->config, "cfg.debug")) {
|
2018-05-27 22:53:04 +09:00
|
|
|
r_core_cmd (core, "dso", 0);
|
|
|
|
r_core_cmd (core, ".dr*", 0);
|
2017-02-22 23:45:51 +01:00
|
|
|
} else {
|
|
|
|
r_core_cmd (core, "aeso", 0);
|
|
|
|
r_core_cmd (core, ".ar*", 0);
|
|
|
|
}
|
2018-05-27 22:53:04 +09:00
|
|
|
r_config_set_i (core->config, "io.cache", io_cache);
|
2017-02-22 23:45:51 +01:00
|
|
|
}
|
|
|
|
|
2018-05-11 18:41:22 +09:00
|
|
|
static void panelBreakpoint(RCore *core) {
|
2017-02-22 23:45:51 +01:00
|
|
|
r_core_cmd (core, "dbs $$", 0);
|
|
|
|
}
|
|
|
|
|
2018-05-11 18:41:22 +09:00
|
|
|
static void panelContinue(RCore *core) {
|
2017-02-22 23:45:51 +01:00
|
|
|
r_core_cmd (core, "dc", 0);
|
|
|
|
}
|
|
|
|
|
2018-06-13 18:12:18 +09:00
|
|
|
R_API void r_core_panels_check_stackbase(RCore *core) {
|
2018-05-18 17:34:34 +09:00
|
|
|
if (!core || !core->panels) {
|
|
|
|
return;
|
|
|
|
}
|
2018-05-08 16:12:45 +09:00
|
|
|
int i;
|
2018-05-18 17:34:34 +09:00
|
|
|
const char *sp = r_reg_get_name (core->anal->reg, R_REG_NAME_SP);
|
|
|
|
const ut64 stackbase = r_reg_getv (core->anal->reg, sp);
|
2018-05-08 16:12:45 +09:00
|
|
|
RPanels *panels = core->panels;
|
|
|
|
for (i = 1; i < panels->n_panels; i++) {
|
|
|
|
const RPanel panel = panels->panel[i];
|
|
|
|
if (!strcmp (panel.title, PANEL_TITLE_STACK) && panel.baseAddr != stackbase) {
|
|
|
|
panels->panel[panels->curnode].baseAddr = stackbase;
|
2018-05-18 17:34:34 +09:00
|
|
|
panels->panel[panels->curnode].addr = stackbase - r_config_get_i (core->config, "stack.delta") + core->print->cur;
|
2018-05-08 16:12:45 +09:00
|
|
|
panels->panel[panels->curnode].refresh = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-21 08:53:39 +09:00
|
|
|
static void panelPrompt(const char *prompt, char *buf, int len) {
|
2018-05-11 03:42:32 +09:00
|
|
|
r_line_set_prompt (prompt);
|
|
|
|
*buf = 0;
|
2018-05-21 08:53:39 +09:00
|
|
|
r_cons_fgets (buf, len, 0, NULL);
|
2018-05-11 03:42:32 +09:00
|
|
|
}
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
static bool init (RCore *core, RPanels *panels, int w, int h) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->panel = NULL;
|
|
|
|
panels->n_panels = 0;
|
|
|
|
panels->columnWidth = 80;
|
|
|
|
panels->layout = 0;
|
|
|
|
panels->menu_pos = 0;
|
|
|
|
panels->menu_x = 0;
|
|
|
|
panels->menu_y = 0;
|
|
|
|
panels->callgraph = 0;
|
|
|
|
panels->isResizing = false;
|
|
|
|
panels->can = r_cons_canvas_new (w, h);
|
2018-06-10 10:27:29 +09:00
|
|
|
r_cons_canvas_fill (panels->can, 0, 0, w, h, ' ');
|
2018-04-07 23:51:25 +09:00
|
|
|
if (!panels->can) {
|
2018-02-21 20:31:01 +09:00
|
|
|
eprintf ("Cannot create RCons.canvas context\n");
|
2017-02-22 23:45:51 +01:00
|
|
|
return false;
|
|
|
|
}
|
2018-05-18 17:34:34 +09:00
|
|
|
panels->can->linemode = r_config_get_i (core->config, "graph.linemode");
|
|
|
|
panels->can->color = r_config_get_i (core->config, "scr.color");
|
2016-05-09 11:13:37 +02:00
|
|
|
if (w < 140) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->columnWidth = w / 3;
|
2018-03-11 18:23:44 +09:00
|
|
|
}
|
2018-02-21 19:49:54 +08:00
|
|
|
return true;
|
2018-02-21 20:31:01 +09:00
|
|
|
}
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
static bool handleEnterKey(RCore *core) {
|
|
|
|
RPanels *panels = core->panels;
|
2018-05-13 00:13:40 +09:00
|
|
|
if (panels->curnode == 0 && panels->menu_y) {
|
|
|
|
const char *action = menus_sub[panels->menu_x][panels->menu_y - 1];
|
|
|
|
if (strstr (action, "New")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_NEWFILES, "o");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Open")) {
|
|
|
|
/* XXX doesnt autocompletes filenames */
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("open file: ");
|
|
|
|
if (res) {
|
|
|
|
if (*res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "o %s", res);
|
2018-05-13 00:13:40 +09:00
|
|
|
}
|
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "RegisterRefs")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, "drr", "drr");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Registers")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, "dr=", "dr=");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Info")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_INFO, "i");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Database")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_DATABASE, "k ***");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Registers")) {
|
|
|
|
if (!havePanel (panels, "Registers")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_REGISTERS, "dr=");
|
2018-05-13 00:13:40 +09:00
|
|
|
}
|
|
|
|
} else if (strstr (action, "About")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
char *s = r_core_cmd_str (core, "?V");
|
2018-05-13 00:13:40 +09:00
|
|
|
r_cons_message (s);
|
|
|
|
free (s);
|
|
|
|
} else if (strstr (action, "Hexdump")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_HEXDUMP, "px 512");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Disassembly")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_DISASSEMBLY, "pd 128");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Functions")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_FUNCTIONS, "afl");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Comments")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_COMMENTS, "CC");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Entropy")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_ENTROPY, "p=e");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Function")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "af");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "DRX")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_DRX, "drx");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Program")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "aaa");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Calls")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "aac");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "ROP")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("rop grep: ");
|
|
|
|
if (res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "\"/R %s\"", res);
|
2018-05-13 00:13:40 +09:00
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "String")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("search string: ");
|
|
|
|
if (res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "\"/ %s\"", res);
|
2018-05-13 00:13:40 +09:00
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "Hexpairs")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("search hexpairs: ");
|
|
|
|
if (res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "\"/x %s\"", res);
|
2018-05-13 00:13:40 +09:00
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "Code")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("search code: ");
|
|
|
|
if (res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "\"/c %s\"", res);
|
2018-05-13 00:13:40 +09:00
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "Copy")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("How many bytes? ");
|
|
|
|
if (res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "\"y %s\"", res);
|
2018-05-13 00:13:40 +09:00
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "Write String")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("insert string: ");
|
|
|
|
if (res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "\"w %s\"", res);
|
2018-05-13 00:13:40 +09:00
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "Write Value")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("insert number: ");
|
|
|
|
if (res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "\"wv %s\"", res);
|
2018-05-13 00:13:40 +09:00
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "Write Hex")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("insert hexpairs: ");
|
|
|
|
if (res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "\"wx %s\"", res);
|
2018-05-13 00:13:40 +09:00
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "Calculator")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
for (;;) {
|
|
|
|
char *s = r_cons_input ("> ");
|
|
|
|
if (!s || !*s) {
|
|
|
|
free (s);
|
|
|
|
break;
|
|
|
|
}
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "? %s", s);
|
2018-05-13 00:13:40 +09:00
|
|
|
r_cons_flush ();
|
|
|
|
free (s);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "Assemble")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_visual_asm (core, core->offset);
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Sections")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_SECTIONS, "iSq");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Close")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmd0 (core, "o-*");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Strings")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_STRINGS, "izq");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Maps")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_MAPS, "dm");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Modules")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_MODULES, "dmm");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Backtrace")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_BACKTRACE, "dbt");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Step")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmd (core, "ds", 0);
|
2018-05-13 00:13:40 +09:00
|
|
|
r_cons_flush ();
|
|
|
|
} else if (strstr (action, "Step Over")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmd (core, "dso", 0);
|
2018-05-13 00:13:40 +09:00
|
|
|
r_cons_flush ();
|
|
|
|
} else if (strstr (action, "Continue")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmd (core, "dc", 0);
|
2018-05-13 00:13:40 +09:00
|
|
|
r_cons_flush ();
|
|
|
|
} else if (strstr (action, "Breakpoints")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_BREAKPOINTS, "db");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Symbols")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_SYMBOLS, "isq");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Imports")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_IMPORTS, "iiq");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Paste")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmd0 (core, "yy");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Clipboard")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_CLIPBOARD, "yx");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "io.cache")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmd0 (core, "e!io.cache");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Fill")) {
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *s = r_cons_input ("Fill with: ");
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "wow %s", s);
|
2018-05-13 00:13:40 +09:00
|
|
|
free (s);
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
} else if (strstr (action, "References")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmdf (core, "aar");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "FcnInfo")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, PANEL_TITLE_FCNINFO, "afi");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Graph")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_visual_graph (core, NULL, NULL, true);
|
2018-05-13 00:13:40 +09:00
|
|
|
// addPanelFrame ("Graph", "agf");
|
|
|
|
} else if (strstr (action, "System Shell")) {
|
|
|
|
r_cons_set_raw (0);
|
|
|
|
r_cons_flush ();
|
|
|
|
r_sys_cmd ("$SHELL");
|
|
|
|
} else if (strstr (action, "R2 Shell")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
core->vmode = false;
|
|
|
|
r_core_visual_prompt_input (core);
|
|
|
|
core->vmode = true;
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (!strcmp (action, "2048")) {
|
|
|
|
r_cons_2048 (panels->can->color);
|
|
|
|
} else if (strstr (action, "License")) {
|
|
|
|
r_cons_message ("Copyright 2006-2016 - pancake - LGPL");
|
|
|
|
} else if (strstr (action, "Fortune")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
char *s = r_core_cmd_str (core, "fo");
|
2018-05-13 00:13:40 +09:00
|
|
|
r_cons_message (s);
|
|
|
|
free (s);
|
|
|
|
} else if (strstr (action, "Commands")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmd0 (core, "?;?@?;?$?;???");
|
2018-05-13 00:13:40 +09:00
|
|
|
r_cons_any_key (NULL);
|
|
|
|
} else if (strstr (action, "Colors")) {
|
2018-05-18 17:34:34 +09:00
|
|
|
r_core_cmd0 (core, "e!scr.color");
|
2018-05-13 00:13:40 +09:00
|
|
|
} else if (strstr (action, "Quit")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (panels->curnode > 0) {
|
|
|
|
zoom (panels);
|
|
|
|
} else {
|
2018-06-19 21:25:38 +09:00
|
|
|
panels->curnode = panels->menu_pos;
|
2018-05-13 00:13:40 +09:00
|
|
|
panels->menu_y = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-06-13 18:12:18 +09:00
|
|
|
R_API RPanels *r_core_panels_new(RCore *core) {
|
2018-04-07 23:51:25 +09:00
|
|
|
int w, h;
|
|
|
|
RPanels *panels = R_NEW0 (RPanels);
|
|
|
|
|
|
|
|
if (!panels) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
w = r_cons_get_size (&h);
|
2018-05-18 17:34:34 +09:00
|
|
|
if (!init (core, panels, w, h)) {
|
2018-04-11 10:25:22 +02:00
|
|
|
free (panels);
|
2018-04-07 23:51:25 +09:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return panels;
|
|
|
|
}
|
|
|
|
|
2018-06-13 18:12:18 +09:00
|
|
|
R_API void r_core_panels_free(RPanels *panels) {
|
2018-05-20 02:45:17 +09:00
|
|
|
int i;
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (true);
|
2018-04-07 23:51:25 +09:00
|
|
|
if (panels) {
|
2018-05-20 02:45:17 +09:00
|
|
|
for (i = 0; i < panels->n_panels; i++) {
|
|
|
|
free (panels->panel[i].title);
|
|
|
|
free (panels->panel[i].cmd);
|
|
|
|
}
|
|
|
|
free (panels->panel);
|
|
|
|
if (panels->can) {
|
2018-06-12 13:05:47 +02:00
|
|
|
r_cons_canvas_free (panels->can);
|
2018-05-20 02:45:17 +09:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
free (panels);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_core_visual_panels(RCore *core, RPanels *panels) {
|
2018-06-19 10:05:40 +02:00
|
|
|
int i, okey, key, wheel;
|
2018-04-09 11:56:15 +09:00
|
|
|
|
2018-04-07 23:51:25 +09:00
|
|
|
if (!panels) {
|
2018-06-13 18:12:18 +09:00
|
|
|
panels = r_core_panels_new (core);
|
2018-04-07 23:51:25 +09:00
|
|
|
if (!panels) {
|
2018-06-13 18:12:18 +09:00
|
|
|
r_core_panels_free (panels);
|
2018-04-07 23:51:25 +09:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-18 17:34:34 +09:00
|
|
|
if (!initPanels (core, panels)) {
|
2018-06-13 18:12:18 +09:00
|
|
|
r_core_panels_free (panels);
|
2018-02-21 19:49:54 +08:00
|
|
|
return false;
|
|
|
|
}
|
2015-03-05 02:07:53 +01:00
|
|
|
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (false);
|
2018-06-15 16:49:25 +09:00
|
|
|
int originCursor = core->print->cur;
|
2018-04-24 14:16:42 +09:00
|
|
|
core->print->cur = 0;
|
|
|
|
core->print->cur_enabled = false;
|
|
|
|
core->print->col = 0;
|
2018-04-07 23:51:25 +09:00
|
|
|
|
2015-03-05 02:07:53 +01:00
|
|
|
repeat:
|
2018-05-18 17:34:34 +09:00
|
|
|
core->panels = panels;
|
2018-05-22 15:44:09 +09:00
|
|
|
core->cons->event_data = core;
|
2018-05-11 18:41:22 +09:00
|
|
|
core->cons->event_resize = (RConsEvent) doPanelsRefresh;
|
2018-06-13 18:12:18 +09:00
|
|
|
r_core_panels_layout_refresh (core);
|
2015-03-05 02:07:53 +01:00
|
|
|
wheel = r_config_get_i (core->config, "scr.wheel");
|
2016-11-22 01:58:52 +01:00
|
|
|
if (wheel) {
|
2015-09-14 12:35:38 +02:00
|
|
|
r_cons_enable_mouse (true);
|
2016-11-22 01:58:52 +01:00
|
|
|
}
|
2015-03-05 02:07:53 +01:00
|
|
|
okey = r_cons_readchar ();
|
|
|
|
key = r_cons_arrow_to_hjkl (okey);
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (true);
|
2018-05-11 18:41:22 +09:00
|
|
|
|
|
|
|
if (handleCursorMode (core, key)) {
|
|
|
|
goto repeat;
|
2018-05-02 22:52:28 +09:00
|
|
|
}
|
2018-05-11 18:41:22 +09:00
|
|
|
|
|
|
|
const char *cmd;
|
2018-06-13 18:12:18 +09:00
|
|
|
RConsCanvas *can = panels->can;
|
2015-03-05 02:07:53 +01:00
|
|
|
switch (key) {
|
2015-08-31 05:06:01 +02:00
|
|
|
case 'u':
|
|
|
|
r_core_cmd0 (core, "s-");
|
|
|
|
break;
|
|
|
|
case 'U':
|
|
|
|
r_core_cmd0 (core, "s+");
|
|
|
|
break;
|
|
|
|
case 'n':
|
2018-03-23 11:17:42 +01:00
|
|
|
{
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("New panel with command: ");
|
|
|
|
if (res) {
|
|
|
|
if (*res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, res, res);
|
2018-03-23 11:17:42 +01:00
|
|
|
// do not refresh stuff
|
|
|
|
}
|
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'N':
|
|
|
|
{
|
|
|
|
r_cons_enable_mouse (false);
|
|
|
|
char *res = r_cons_input ("New panel with command: ");
|
|
|
|
if (res) {
|
|
|
|
if (*res) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, NULL, res);
|
2018-03-23 11:17:42 +01:00
|
|
|
}
|
|
|
|
free (res);
|
|
|
|
}
|
|
|
|
r_cons_enable_mouse (true);
|
|
|
|
}
|
2015-08-31 05:06:01 +02:00
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
r_core_cmd0 (core, "sp");
|
|
|
|
break;
|
2018-03-23 11:17:42 +01:00
|
|
|
case 'P':
|
|
|
|
r_core_cmd0 (core, "sn");
|
|
|
|
break;
|
2015-08-31 05:06:01 +02:00
|
|
|
case '.':
|
|
|
|
if (r_config_get_i (core->config, "cfg.debug")) {
|
2015-10-31 01:57:52 +01:00
|
|
|
r_core_cmd0 (core, "sr PC");
|
2017-03-24 10:46:13 +01:00
|
|
|
// r_core_seek (core, r_num_math (core->num, "entry0"), 1);
|
2015-08-31 05:06:01 +02:00
|
|
|
} else {
|
|
|
|
r_core_cmd0 (core, "s entry0; px");
|
|
|
|
}
|
2018-05-22 15:44:09 +09:00
|
|
|
doPanelsRefresh (core);
|
2015-08-31 05:06:01 +02:00
|
|
|
break;
|
2015-03-05 02:07:53 +01:00
|
|
|
case ' ':
|
2015-08-31 05:06:01 +02:00
|
|
|
case '\r':
|
2015-03-05 02:07:53 +01:00
|
|
|
case '\n':
|
2018-05-18 17:34:34 +09:00
|
|
|
if (!handleEnterKey (core)) {
|
2018-05-13 00:13:40 +09:00
|
|
|
goto exit;
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
2018-05-22 15:44:09 +09:00
|
|
|
doPanelsRefresh (core);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
r_cons_clear00 ();
|
2015-03-05 23:33:28 +01:00
|
|
|
r_cons_printf ("Visual Ascii Art Panels:\n"
|
2017-02-22 23:45:51 +01:00
|
|
|
" ! - run r2048 game\n"
|
|
|
|
" . - seek to PC or entrypoint\n"
|
2018-03-23 11:17:42 +01:00
|
|
|
" : - run r2 command in prompt\n"
|
2017-02-22 23:45:51 +01:00
|
|
|
" _ - start the hud input mode\n"
|
2018-03-23 11:17:42 +01:00
|
|
|
" ? - show this help\n"
|
2017-02-22 23:45:51 +01:00
|
|
|
" x - close current panel\n"
|
|
|
|
" m - open menubar\n"
|
|
|
|
" V - view graph\n"
|
2018-05-15 13:38:50 +09:00
|
|
|
" b - browse symbols, flags, configurations, classes, ...\n"
|
|
|
|
" c - toggle cursor\n"
|
2017-02-22 23:45:51 +01:00
|
|
|
" C - toggle color\n"
|
2018-06-18 23:02:36 +02:00
|
|
|
" d - define in current address. Same as Vd\n"
|
|
|
|
" D - show disassembly in current frame\n"
|
2018-05-15 13:38:50 +09:00
|
|
|
" i - insert hex\n"
|
2017-02-22 23:45:51 +01:00
|
|
|
" M - open new custom frame\n"
|
|
|
|
" hl - toggle scr.color\n"
|
|
|
|
" HL - move vertical column split\n"
|
|
|
|
" jk - scroll/select menu\n"
|
|
|
|
" JK - select prev/next panels (same as TAB)\n"
|
|
|
|
" sS - step in / step over\n"
|
|
|
|
" uU - undo / redo seek\n"
|
2018-03-23 11:17:42 +01:00
|
|
|
" pP - seek to next or previous scr.nkey\n"
|
|
|
|
" nN - create new panel with given command\n"
|
2017-02-22 23:45:51 +01:00
|
|
|
" q - quit, back to visual mode\n"
|
|
|
|
);
|
2015-03-05 02:07:53 +01:00
|
|
|
r_cons_flush ();
|
2015-03-05 23:33:28 +01:00
|
|
|
r_cons_any_key (NULL);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
2018-05-15 13:38:50 +09:00
|
|
|
case 'b':
|
|
|
|
r_core_visual_browse (core);
|
|
|
|
break;
|
2015-08-31 05:06:01 +02:00
|
|
|
case 's':
|
|
|
|
if (r_config_get_i (core->config, "cfg.debug")) {
|
2017-03-24 10:46:13 +01:00
|
|
|
r_core_cmd0 (core, "ds;.dr*"); // ;sr PC");
|
2015-08-31 05:06:01 +02:00
|
|
|
} else {
|
2018-05-11 18:41:22 +09:00
|
|
|
panelSingleStepIn (core);
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
2018-05-11 18:41:22 +09:00
|
|
|
setRefreshAll (panels);
|
2015-08-31 05:06:01 +02:00
|
|
|
break;
|
|
|
|
case 'S':
|
2018-05-27 22:53:04 +09:00
|
|
|
panelSingleStepOver (core);
|
2018-05-11 18:41:22 +09:00
|
|
|
setRefreshAll (panels);
|
2015-08-31 05:06:01 +02:00
|
|
|
break;
|
2015-03-05 02:07:53 +01:00
|
|
|
case ':':
|
2015-09-14 12:35:38 +02:00
|
|
|
core->vmode = false;
|
2015-03-05 02:07:53 +01:00
|
|
|
r_core_visual_prompt_input (core);
|
2015-09-14 12:35:38 +02:00
|
|
|
core->vmode = true;
|
2017-12-16 09:48:26 -06:00
|
|
|
|
|
|
|
// FIX: Issue with visual mode instruction highlighter
|
|
|
|
// not updating after 'ds' or 'dcu' commands.
|
|
|
|
r_core_cmd0 (core, ".dr*");
|
2018-05-22 15:44:09 +09:00
|
|
|
doPanelsRefresh (core);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
2018-04-24 14:16:42 +09:00
|
|
|
case 'c':
|
2018-05-07 17:01:25 +09:00
|
|
|
if (!strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_STACK) || !strcmp (panels->panel[panels->curnode].title, PANEL_TITLE_REGISTERS)) {
|
2018-05-11 18:41:22 +09:00
|
|
|
setCursor (core, !core->print->cur_enabled);
|
2018-04-24 14:16:42 +09:00
|
|
|
panels->panel[panels->curnode].refresh = true;
|
|
|
|
}
|
|
|
|
break;
|
2015-03-05 02:07:53 +01:00
|
|
|
case 'C':
|
2018-06-13 18:12:18 +09:00
|
|
|
can->color = !can->color;
|
2017-03-24 10:46:13 +01:00
|
|
|
// r_config_toggle (core->config, "scr.color");
|
2015-03-05 02:07:53 +01:00
|
|
|
// refresh graph
|
2018-05-22 15:44:09 +09:00
|
|
|
doPanelsRefresh (core);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
2015-09-29 04:26:00 +02:00
|
|
|
case 'R':
|
2016-11-22 01:58:52 +01:00
|
|
|
if (r_config_get_i (core->config, "scr.randpal")) {
|
|
|
|
r_core_cmd0 (core, "ecr");
|
|
|
|
} else {
|
|
|
|
r_core_cmd0 (core, "ecn");
|
|
|
|
}
|
2018-05-22 15:44:09 +09:00
|
|
|
doPanelsRefresh (core);
|
2015-03-05 23:33:28 +01:00
|
|
|
break;
|
2018-05-10 10:51:35 +02:00
|
|
|
case 'A':
|
|
|
|
r_core_visual_asm (core, core->offset);
|
|
|
|
break;
|
2018-06-18 23:02:36 +02:00
|
|
|
case 'd':
|
2018-05-10 10:51:35 +02:00
|
|
|
r_core_visual_define (core, "");
|
|
|
|
break;
|
2018-06-18 23:02:36 +02:00
|
|
|
case 'D':
|
2018-06-20 01:54:07 +09:00
|
|
|
replaceCmd (panels, PANEL_TITLE_DISASSEMBLY, PANEL_CMD_DISASSEMBLY);
|
2018-06-18 23:02:36 +02:00
|
|
|
break;
|
2018-06-19 10:05:40 +02:00
|
|
|
case 'J':
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
handleDownKey (core);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'K':
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
handleUpKey (core);
|
|
|
|
}
|
|
|
|
break;
|
2015-03-05 02:07:53 +01:00
|
|
|
case 'j':
|
2018-05-18 17:34:34 +09:00
|
|
|
handleDownKey (core);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
|
|
|
case 'k':
|
2018-05-18 17:34:34 +09:00
|
|
|
handleUpKey (core);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
2015-08-31 13:57:39 +02:00
|
|
|
case '_':
|
|
|
|
r_core_visual_hud (core);
|
|
|
|
break;
|
2015-08-31 05:06:01 +02:00
|
|
|
case 'x':
|
2018-05-11 18:41:22 +09:00
|
|
|
delCurPanel (panels);
|
|
|
|
setRefreshAll (panels);
|
2015-08-31 05:06:01 +02:00
|
|
|
break;
|
|
|
|
case 9: // TAB
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (false);
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->menu_y = 0;
|
|
|
|
panels->menu_x = -1;
|
|
|
|
panels->panel[panels->curnode].refresh = true;
|
|
|
|
panels->curnode++;
|
|
|
|
panels->panel[panels->curnode].refresh = true;
|
2018-04-14 16:48:41 +09:00
|
|
|
if (!panels->panel[panels->curnode].title) {
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->curnode = 0;
|
|
|
|
panels->menu_x = 0;
|
2015-03-05 23:07:39 +01:00
|
|
|
}
|
|
|
|
break;
|
2017-08-27 19:31:17 +02:00
|
|
|
case 'Z': // SHIFT-TAB
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (false);
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->menu_y = 0;
|
|
|
|
panels->menu_x = -1;
|
|
|
|
panels->panel[panels->curnode].refresh = true;
|
2018-06-18 23:02:36 +02:00
|
|
|
if (panels->curnode > 0) {
|
|
|
|
panels->curnode--;
|
|
|
|
} else {
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->curnode = panels->n_panels - 1;
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
2018-06-18 23:02:36 +02:00
|
|
|
panels->panel[panels->curnode].refresh = true;
|
2018-04-07 23:51:25 +09:00
|
|
|
if (!panels->curnode) {
|
|
|
|
panels->menu_x = 0;
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
|
|
|
break;
|
2015-08-31 23:36:35 +02:00
|
|
|
case 'M':
|
2017-02-22 23:45:51 +01:00
|
|
|
{
|
2017-02-23 19:46:01 +01:00
|
|
|
r_cons_enable_mouse (false);
|
2017-02-22 23:45:51 +01:00
|
|
|
char *name = r_cons_input ("Name: ");
|
|
|
|
char *cmd = r_cons_input ("Command: ");
|
|
|
|
if (name && *name && cmd && *cmd) {
|
2018-05-18 17:34:34 +09:00
|
|
|
addPanelFrame (core, panels, name, cmd);
|
2015-08-31 23:36:35 +02:00
|
|
|
}
|
2017-02-22 23:45:51 +01:00
|
|
|
free (name);
|
|
|
|
free (cmd);
|
2017-02-23 19:46:01 +01:00
|
|
|
r_cons_enable_mouse (true);
|
2017-02-22 23:45:51 +01:00
|
|
|
}
|
|
|
|
break;
|
2015-08-31 05:06:01 +02:00
|
|
|
case 'm':
|
2018-04-07 23:51:25 +09:00
|
|
|
if (panels->menu_x < 0) {
|
|
|
|
panels->menu_x = 0;
|
2018-06-13 18:12:18 +09:00
|
|
|
r_core_panels_refresh (core);
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
2018-06-19 21:25:38 +09:00
|
|
|
panels->curnode = panels->menu_pos;
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->menu_y = 1;
|
2015-03-05 23:07:39 +01:00
|
|
|
break;
|
|
|
|
case 'H':
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (false);
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->columnWidth += 4;
|
|
|
|
panels->isResizing = true;
|
2018-06-20 10:13:58 +02:00
|
|
|
if (panels->columnWidth > 80) {
|
|
|
|
panels->columnWidth = 80;
|
|
|
|
}
|
2015-03-05 23:07:39 +01:00
|
|
|
break;
|
|
|
|
case 'L':
|
2018-05-15 13:38:50 +09:00
|
|
|
r_cons_switchbuf (false);
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->columnWidth -= 4;
|
|
|
|
panels->isResizing = true;
|
2018-06-20 10:13:58 +02:00
|
|
|
if (panels->columnWidth < 10) {
|
|
|
|
panels->columnWidth = 10;
|
2017-02-22 23:45:51 +01:00
|
|
|
}
|
2015-03-05 23:07:39 +01:00
|
|
|
break;
|
2018-06-15 16:49:25 +09:00
|
|
|
case 'g':
|
|
|
|
if (checkFunc (core)) {
|
|
|
|
replaceCmd (panels, PANEL_TITLE_GRAPH, PANEL_CMD_GRAPH);
|
|
|
|
}
|
|
|
|
break;
|
2015-03-05 02:07:53 +01:00
|
|
|
case 'h':
|
2018-05-18 17:34:34 +09:00
|
|
|
handleLeftKey (core);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
|
|
|
case 'l':
|
2018-05-18 17:34:34 +09:00
|
|
|
handleRightKey (core);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
2015-09-29 04:26:00 +02:00
|
|
|
case 'V':
|
2016-09-02 17:14:52 +02:00
|
|
|
if (r_config_get_i (core->config, "graph.web")) {
|
|
|
|
r_core_cmd0 (core, "agv $$");
|
|
|
|
} else {
|
2018-06-13 18:12:18 +09:00
|
|
|
if (checkFunc (core)) {
|
|
|
|
int ocolor;
|
|
|
|
ocolor = r_config_get_i (core->config, "scr.color");
|
|
|
|
r_core_visual_graph (core, NULL, NULL, true);
|
|
|
|
r_config_set_i (core->config, "scr.color", ocolor);
|
|
|
|
setRefreshAll (panels);
|
2015-09-29 04:26:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2016-11-22 01:58:52 +01:00
|
|
|
case ']':
|
|
|
|
r_config_set_i (core->config, "hex.cols", r_config_get_i (core->config, "hex.cols") + 1);
|
|
|
|
break;
|
|
|
|
case '[':
|
|
|
|
r_config_set_i (core->config, "hex.cols", r_config_get_i (core->config, "hex.cols") - 1);
|
|
|
|
break;
|
|
|
|
case 'w':
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->layout++;
|
|
|
|
if (panels->layout >= layoutMaxCount) {
|
|
|
|
panels->layout = 0;
|
2018-03-28 17:00:54 +09:00
|
|
|
}
|
2018-05-11 18:41:22 +09:00
|
|
|
setRefreshAll (panels);
|
2016-11-22 01:58:52 +01:00
|
|
|
break;
|
2017-02-22 23:45:51 +01:00
|
|
|
case R_CONS_KEY_F1:
|
|
|
|
cmd = r_config_get (core->config, "key.f1");
|
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F2:
|
|
|
|
cmd = r_config_get (core->config, "key.f2");
|
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
} else {
|
2018-05-11 18:41:22 +09:00
|
|
|
panelBreakpoint (core);
|
2017-02-22 23:45:51 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F3:
|
|
|
|
cmd = r_config_get (core->config, "key.f3");
|
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F4:
|
|
|
|
cmd = r_config_get (core->config, "key.f4");
|
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
}
|
|
|
|
break;
|
2017-02-18 13:26:54 +01:00
|
|
|
case R_CONS_KEY_F5:
|
|
|
|
cmd = r_config_get (core->config, "key.f5");
|
2017-02-22 23:45:51 +01:00
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
}
|
2017-02-18 13:26:54 +01:00
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F6:
|
|
|
|
cmd = r_config_get (core->config, "key.f6");
|
2017-02-22 23:45:51 +01:00
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
}
|
2017-02-18 13:26:54 +01:00
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F7:
|
|
|
|
cmd = r_config_get (core->config, "key.f7");
|
2017-02-22 23:45:51 +01:00
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
} else {
|
2018-05-11 18:41:22 +09:00
|
|
|
panelSingleStepIn (core);
|
2017-02-22 23:45:51 +01:00
|
|
|
}
|
2017-02-18 13:26:54 +01:00
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F8:
|
|
|
|
cmd = r_config_get (core->config, "key.f8");
|
2017-02-22 23:45:51 +01:00
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
} else {
|
2018-05-11 18:41:22 +09:00
|
|
|
panelSingleStepOver (core);
|
2017-02-22 23:45:51 +01:00
|
|
|
}
|
2017-02-18 13:26:54 +01:00
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F9:
|
|
|
|
cmd = r_config_get (core->config, "key.f9");
|
2017-02-22 23:45:51 +01:00
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
} else {
|
2018-05-11 18:41:22 +09:00
|
|
|
panelContinue (core);
|
2017-02-22 23:45:51 +01:00
|
|
|
}
|
2017-02-18 13:26:54 +01:00
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F10:
|
|
|
|
cmd = r_config_get (core->config, "key.f10");
|
2017-02-22 23:45:51 +01:00
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
}
|
2017-02-18 13:26:54 +01:00
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F11:
|
|
|
|
cmd = r_config_get (core->config, "key.f11");
|
2017-02-22 23:45:51 +01:00
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
}
|
2017-02-18 13:26:54 +01:00
|
|
|
break;
|
|
|
|
case R_CONS_KEY_F12:
|
|
|
|
cmd = r_config_get (core->config, "key.f12");
|
2017-02-22 23:45:51 +01:00
|
|
|
if (cmd && *cmd) {
|
|
|
|
key = r_core_cmd0 (core, cmd);
|
|
|
|
}
|
2017-02-18 13:26:54 +01:00
|
|
|
break;
|
2015-09-29 04:26:00 +02:00
|
|
|
case '!':
|
2015-03-05 02:07:53 +01:00
|
|
|
case 'q':
|
2015-03-23 14:45:31 +01:00
|
|
|
case -1: // EOF
|
2018-04-07 23:51:25 +09:00
|
|
|
if (panels->menu_y < 1) {
|
2018-05-13 00:13:40 +09:00
|
|
|
goto exit;
|
2015-08-31 05:06:01 +02:00
|
|
|
}
|
2018-04-07 23:51:25 +09:00
|
|
|
panels->menu_y = 0;
|
2015-08-31 05:06:01 +02:00
|
|
|
break;
|
2015-08-31 05:43:38 +02:00
|
|
|
#if 0
|
2015-03-05 02:07:53 +01:00
|
|
|
case 27: // ESC
|
|
|
|
if (r_cons_readchar () == 91) {
|
2017-02-22 23:45:51 +01:00
|
|
|
if (r_cons_readchar () == 90) {}
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|
|
|
|
break;
|
2015-08-31 05:43:38 +02:00
|
|
|
#endif
|
2015-03-05 02:07:53 +01:00
|
|
|
default:
|
2017-03-24 10:46:13 +01:00
|
|
|
// eprintf ("Key %d\n", key);
|
|
|
|
// sleep (1);
|
2015-03-05 02:07:53 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
goto repeat;
|
2018-05-13 00:13:40 +09:00
|
|
|
exit:
|
2018-06-15 16:49:25 +09:00
|
|
|
core->print->cur = originCursor;
|
2018-04-24 14:16:42 +09:00
|
|
|
core->print->cur_enabled = false;
|
|
|
|
core->print->col = 0;
|
2018-05-22 15:44:09 +09:00
|
|
|
|
2018-06-13 18:12:18 +09:00
|
|
|
r_core_panels_free (panels);
|
2018-05-22 15:44:09 +09:00
|
|
|
core->panels = NULL;
|
2015-09-14 12:35:38 +02:00
|
|
|
return true;
|
2015-03-05 02:07:53 +01:00
|
|
|
}
|