Rizin
unix-like reverse engineering framework and cli tools
panels.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014-2020 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2014-2020 vane11ope
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_core.h>
6 #include "../core_private.h"
7 
8 #define PANEL_NUM_LIMIT 9
9 
10 #define PANEL_TITLE_SYMBOLS "Symbols"
11 #define PANEL_TITLE_STACK "Stack"
12 #define PANEL_TITLE_XREFS_HERE "Xrefs Here"
13 #define PANEL_TITLE_XREFS "Xrefs"
14 #define PANEL_TITLE_REGISTERS "Registers"
15 #define PANEL_TITLE_DISASSEMBLY "Disassembly"
16 #define PANEL_TITLE_DISASMSUMMARY "Disassemble Summary"
17 #define PANEL_TITLE_GRAPH "Graph"
18 #define PANEL_TITLE_TINY_GRAPH "Tiny Graph"
19 #define PANEL_TITLE_FUNCTIONS "Functions"
20 #define PANEL_TITLE_FUNCTIONCALLS "Function Calls"
21 #define PANEL_TITLE_BREAKPOINTS "Breakpoints"
22 #define PANEL_TITLE_STRINGS_DATA "Strings in data sections"
23 #define PANEL_TITLE_STRINGS_BIN "Strings in the whole bin"
24 #define PANEL_TITLE_SECTIONS "Sections"
25 #define PANEL_TITLE_SEGMENTS "Segments"
26 #define PANEL_TITLE_COMMENTS "Comments"
27 
28 #define PANEL_CMD_SYMBOLS "isq"
29 #define PANEL_CMD_XREFS "axl"
30 #define PANEL_CMD_STACK "px"
31 #define PANEL_CMD_REGISTERS "?== true `e cfg.debug`; ?! dr; ?? ar" // select dr or ar depending on cfg.debug
32 #define PANEL_CMD_DISASSEMBLY "pd"
33 #define PANEL_CMD_DISASMSUMMARY "pdsf"
34 #define PANEL_CMD_FUNCTION "afl"
35 #define PANEL_CMD_GRAPH "agf"
36 #define PANEL_CMD_TINYGRAPH "agft"
37 #define PANEL_CMD_HEXDUMP "xc"
38 #define PANEL_CMD_CONSOLE "$console"
39 
40 #define PANEL_CONFIG_MENU_MAX 64
41 #define PANEL_CONFIG_PAGE 10
42 #define PANEL_CONFIG_SIDEPANEL_W 60
43 #define PANEL_CONFIG_RESIZE_W 4
44 #define PANEL_CONFIG_RESIZE_H 4
45 
46 #define COUNT(x) (sizeof((x)) / sizeof((*x)) - 1)
47 
48 static bool firstRun = true;
49 
50 typedef enum {
53  UP,
54  DOWN
56 
57 static const char *panels_dynamic[] = {
58  "Disassembly", "Stack", "Registers",
59  NULL
60 };
61 
62 static const char *panels_static[] = {
63  "Disassembly", "Functions", "Symbols",
64  NULL
65 };
66 
67 static const char *menus[] = {
68  "File", "Settings", "Edit", "View", "Tools", "Search", "Emulate", "Debug", "Analyze", "Help",
69  // "Fun", "About", "Help",
70  NULL
71 };
72 
73 static const char *menus_File[] = {
74  "New", "Open", "ReOpen", "Close", "Save Layout", "Load Layout", "Clear Saved Layouts", "Quit",
75  NULL
76 };
77 
78 static const char *menus_Settings[] = {
79  "Colors", "Disassembly", "Screen",
80  NULL
81 };
82 
83 static const char *menus_ReOpen[] = {
84  "In RW", "In Debugger",
85  NULL
86 };
87 
88 static const char *menus_loadLayout[] = {
89  "Saved", "Default",
90  NULL
91 };
92 
93 static const char *menus_Edit[] = {
94  "Copy", "Paste", "Clipboard", "Write String", "Write Hex", "Write Value", "Assemble", "Fill", "io.cache",
95  NULL
96 };
97 
98 static const char *menus_iocache[] = {
99  "On", "Off",
100  NULL
101 };
102 
103 static char *menus_View[] = {
104  "Console", "Hexdump", "Disassembly", "Disassemble Summary", "Graph", "Tiny Graph",
105  "Functions", "Function Calls", "Sections", "Segments", PANEL_TITLE_STRINGS_DATA, PANEL_TITLE_STRINGS_BIN, "Symbols", "Imports",
106  "Info", "Database", "Breakpoints", "Comments", "Classes", "Entropy", "Entropy Fire", "Stack", "Xrefs Here", "Methods",
107  "Var READ address", "Var WRITE address", "Summary", "Relocs", "Headers", "File Hashes",
108  NULL
109 };
110 
111 static const char *menus_Tools[] = {
112  "Calculator", "Rizin Shell", "System Shell",
113  NULL
114 };
115 
116 static const char *menus_Search[] = {
117  "String (Whole Bin)", "String (Data Sections)", "ROP", "Code", "Hexpairs",
118  NULL
119 };
120 
121 static const char *menus_Emulate[] = {
122  "Step From", "Step To", "Step Range",
123  NULL
124 };
125 
126 static char *menus_Debug[] = {
127  "Registers", "RegisterRefs", "DRX", "Breakpoints", "Watchpoints",
128  "Maps", "Modules", "Backtrace", "Locals", "Continue",
129  "Step", "Step Over", "Reload",
130  NULL
131 };
132 
133 static const char *menus_Analyze[] = {
134  "Function", "Symbols", "Program", "Calls", "References",
135  NULL
136 };
137 
138 static char *menus_Colors[128];
139 
140 static char *menus_settings_disassembly[] = {
141  "asm", "hex.section", "io.cache", "hex.pairs", "emu.str",
142  NULL
143 };
144 
146  "asm.bytes", "asm.section", "asm.cmt.right", "asm.emu", "asm.var.summary",
147  "asm.pseudo", "asm.flags.inbytes", "asm.arch", "asm.bits", "asm.cpu",
148  NULL
149 };
150 
151 static const char *menus_settings_screen[] = {
152  "scr.bgfill", "scr.color", "scr.utf8", "scr.utf8.curvy", "scr.wheel",
153  NULL
154 };
155 
156 static const char *menus_Help[] = {
157  "Toggle Help",
158  "License", "Version",
159  "Fortune",
160  NULL
161 };
162 
163 static const char *entropy_rotate[] = {
164  "", "2", "b", "c", "d", "e", "F", "i", "j", "m", "p", "s", "z", "0",
165  NULL
166 };
167 
168 static char *hexdump_rotate[] = {
169  "xc", "pxa", "pxr", "prx", "pxb", "pxh", "pxw", "pxq", "pxd", "pxr",
170  NULL
171 };
172 
173 static const char *register_rotate[] = {
174  "", "=", "r", "??", "C", "i", "o",
175  NULL
176 };
177 
178 static const char *function_rotate[] = {
179  "l", "i", "x",
180  NULL
181 };
182 
183 static const char *cache_white_list_cmds[] = {
184  "pddo", "agf", "Help",
185  NULL
186 };
187 
188 static const char *help_msg_panels[] = {
189  "|", "split the current panel vertically",
190  "-", "split the current panel horizontally",
191  ":", "run rizin command in prompt",
192  ";", "add/remove comment",
193  "_", "start the hud input mode",
194  "\\", "show the user-friendly hud",
195  "?", "show this help",
196  ".", "seek to PC or entrypoint",
197  "\"", "create a panel from the list and replace the current one",
198  "/", "highlight the keyword",
199  "(", "toggle snow",
200  "&", "toggle cache",
201  "[1-9]", "follow jmp/call identified by shortcut (like ;[1])",
202  "' '", "(space) toggle graph / panels",
203  "tab", "go to the next panel",
204  "Enter", "start Zoom mode",
205  "b", "browse symbols, flags, configurations, classes, ...",
206  "c", "toggle cursor",
207  "C", "toggle color",
208  "d", "define in the current address. Same as Vd",
209  "D", "show disassembly in the current panel",
210  "e", "change title and command of current panel",
211  "f", "set/add filter keywords",
212  "F", "remove all the filters",
213  "g", "go/seek to given offset",
214  "G", "go/seek to highlight",
215  "i", "insert hex",
216  "hjkl", "move around (left-down-up-right)",
217  "HJKL", "move around (left-down-up-right) by page",
218  "m", "select the menu panel",
219  "M", "open new custom frame",
220  "n/N", "seek next/prev function/flag/hit (scr.nkey)",
221  "p/P", "rotate panel layout",
222  "q", "quit, or close a tab",
223  "Q", "close all the tabs and quit",
224  "r", "toggle callhints/jmphints/leahints",
225  "R", "randomize color palette (ecr)",
226  "s/S", "step in / step over",
227  "t/T", "tab prompt / close a tab",
228  "u/U", "undo / redo seek",
229  "w", "start Window mode",
230  "V", "go to the graph mode",
231  "xX", "show xrefs/refs of current function from/to data/code",
232  "z", "swap current panel with the first one",
233  NULL
234 };
235 
236 static const char *help_msg_panels_window[] = {
237  ":", "run rizin command in prompt",
238  ";", "add/remove comment",
239  "\"", "create a panel from the list and replace the current one",
240  "?", "show this help",
241  "|", "split the current panel vertically",
242  "-", "split the current panel horizontally",
243  "tab", "go to the next panel",
244  "Enter", "start Zoom mode",
245  "d", "define in the current address. Same as Vd",
246  "b", "browse symbols, flags, configurations, classes, ...",
247  "hjkl", "move around (left-down-up-right)",
248  "HJKL", "resize panels vertically/horizontally",
249  "Q/q/w", "quit Window mode",
250  "p/P", "rotate panel layout",
251  "t/T", "rotate related commands in a panel",
252  "X", "close current panel",
253  NULL
254 };
255 
256 static const char *help_msg_panels_zoom[] = {
257  "?", "show this help",
258  ":", "run rizin command in prompt",
259  ";", "add/remove comment",
260  "\"", "create a panel from the list and replace the current one",
261  "' '", "(space) toggle graph / panels",
262  "tab", "go to the next panel",
263  "b", "browse symbols, flags, configurations, classes, ...",
264  "d", "define in the current address. Same as Vd",
265  "c", "toggle cursor",
266  "C", "toggle color",
267  "hjkl", "move around (left-down-up-right)",
268  "p/P", "seek to next or previous scr.nkey",
269  "s/S", "step in / step over",
270  "t/T", "rotate related commands in a panel",
271  "xX", "show xrefs/refs of current function from/to data/code",
272  "q/Q/Enter", "quit Zoom mode",
273  NULL
274 };
275 
276 /* init */
277 static bool __init(RzCore *core, RzPanels *panels, int w, int h);
278 static void __init_sdb(RzCore *core);
279 static void __init_rotate_db(RzCore *core);
280 static void __init_almighty_db(RzCore *core);
281 static bool __init_panels_menu(RzCore *core);
282 static bool __init_panels(RzCore *core, RzPanels *panels);
283 static void __init_all_dbs(RzCore *core);
284 static void __init_panel_param(RzCore *core, RzPanel *p, const char *title, const char *cmd);
285 static RzPanels *__panels_new(RzCore *core);
286 static void __init_new_panels_root(RzCore *core);
287 static void __init_menu_saved_layout(void *core, const char *parent);
288 static void __init_menu_color_settings_layout(void *core, const char *parent);
289 static void __init_menu_disasm_settings_layout(void *_core, const char *parent);
290 static void __init_menu_disasm_asm_settings_layout(void *_core, const char *parent);
291 static void __init_menu_screen_settings_layout(void *_core, const char *parent);
292 
293 /* create */
294 static void __create_default_panels(RzCore *core);
295 static RzConsCanvas *__create_new_canvas(RzCore *core, int w, int h);
296 
297 /* free */
298 static void __free_panel_model(RzPanel *panel);
299 static void __free_menu_item(RzPanelsMenuItem *item);
300 
301 /* get */
302 static RzPanel *__get_panel(RzPanels *panels, int i);
303 static RzPanel *__get_cur_panel(RzPanels *panels);
304 static int __get_panel_idx_in_pos(RzCore *core, int x, int y);
305 static char *get_word_from_canvas(RzCore *core, RzPanels *panels, int x, int y);
306 static char *get_word_from_canvas_for_menu(RzCore *core, RzPanels *panels, int x, int y);
307 
308 /* set */
309 static void __seek_all(RzCore *core, ut64 addr);
310 static void __set_curnode(RzCore *core, int idx);
311 static void __set_refresh_all(RzCore *core, bool clearCache, bool force_refresh);
312 static void __set_addr_by_type(RzCore *core, const char *cmd, ut64 addr);
313 static void __set_refresh_by_type(RzCore *core, const char *cmd, bool clearCache);
314 static void __set_cursor(RzCore *core, bool cur);
315 static void __set_dcb(RzCore *core, RzPanel *p);
316 static void __set_rcb(RzPanels *ps, RzPanel *p);
317 static void __set_pcb(RzPanel *p);
318 static void __set_read_only(RzCore *core, RzPanel *p, char *s);
319 static void __set_pos(RzPanelPos *pos, int x, int y);
320 static void __set_size(RzPanelPos *pos, int w, int h);
321 static void __set_geometry(RzPanelPos *pos, int x, int y, int w, int h);
322 static void __set_panel_addr(RzCore *core, RzPanel *panel, ut64 addr);
323 static void __set_root_state(RzCore *core, RzPanelsRootState state);
324 
325 /* reset */
326 static void __reset_scroll_pos(RzPanel *p);
327 
328 /* update */
329 static void __update_disassembly_or_open(RzCore *core);
330 static void __update_help(RzCore *core, RzPanels *ps);
331 static void __update_menu_contents(RzCore *core, RzPanelsMenu *menu, RzPanelsMenuItem *parent);
332 static void __update_edge_x(RzCore *core, int x);
333 static void __update_edge_y(RzCore *core, int y);
334 
335 /* check */
336 static bool __check_panel_type(RzPanel *panel, const char *type);
337 static void __panels_check_stackbase(RzCore *core);
338 static bool __check_panel_num(RzCore *core);
339 static bool __check_func(RzCore *core);
340 static bool __check_func_diff(RzCore *core, RzPanel *p);
342 static bool __check_if_cur_panel(RzCore *core, RzPanel *panel);
343 static bool __check_if_mouse_x_illegal(RzCore *core, int x);
344 static bool __check_if_mouse_y_illegal(RzCore *core, int y);
345 static bool __check_if_mouse_x_on_edge(RzCore *core, int x, int y);
346 static bool __check_if_mouse_y_on_edge(RzCore *core, int x, int y);
347 static void __check_edge(RzCore *core);
348 
349 /* add */
350 static void __add_help_panel(RzCore *core);
351 static void __add_visual_mark(RzCore *core);
352 static void __add_menu(RzCore *core, const char *parent, const char *base_name, RzPanelsMenuCallback cb);
353 static void __update_menu(RzCore *core, const char *parent, RZ_NULLABLE RzPanelMenuUpdateCallback cb);
354 
355 /* user input */
356 static int __show_status(RzCore *core, const char *msg);
357 static bool __show_status_yesno(RzCore *core, int def, const char *msg);
358 static char *__show_status_input(RzCore *core, const char *msg);
359 static void __panel_prompt(const char *prompt, char *buf, int len);
360 
361 /* panel layout */
362 static void __panels_layout_refresh(RzCore *core);
363 static void __panels_layout(RzPanels *panels);
364 static void __layout_default(RzPanels *panels);
365 RZ_API void rz_save_panels_layout(RzCore *core, const char *_name);
366 RZ_API bool rz_load_panels_layout(RzCore *core, const char *_name);
367 static void __split_panel_vertical(RzCore *core, RzPanel *p, const char *name, const char *cmd);
368 static void __split_panel_horizontal(RzCore *core, RzPanel *p, const char *name, const char *cmd);
369 static void __panel_print(RzCore *core, RzConsCanvas *can, RzPanel *panel, int color);
370 static void __menu_panel_print(RzConsCanvas *can, RzPanel *panel, int x, int y, int w, int h);
371 static void __update_help_contents(RzCore *core, RzPanel *panel);
372 static void __update_help_title(RzCore *core, RzPanel *panel);
373 static void __update_panel_contents(RzCore *core, RzPanel *panel, const char *cmdstr);
374 static void __update_panel_title(RzCore *core, RzPanel *panel);
375 static void __default_panel_print(RzCore *core, RzPanel *panel);
376 static void __resize_panel_left(RzPanels *panels);
377 static void __resize_panel_right(RzPanels *panels);
378 static void __resize_panel_up(RzPanels *panels);
379 static void __resize_panel_down(RzPanels *panels);
380 static void __adjust_side_panels(RzCore *core);
381 static void __insert_panel(RzCore *core, int n, const char *name, const char *cmd);
382 static void __dismantle_del_panel(RzCore *core, RzPanel *p, int pi);
383 static void __dismantle_panel(RzPanels *ps, RzPanel *p);
384 static void __panels_refresh(RzCore *core);
385 static void __do_panels_resize(RzCore *core);
386 static void __do_panels_refresh(RzCore *core);
387 static void __do_panels_refreshOneShot(RzCore *core);
388 static void __panel_all_clear(RzPanels *panels);
389 static void __del_panel(RzCore *core, int pi);
390 static void __del_invalid_panels(RzCore *core);
391 static void __swap_panels(RzPanels *panels, int p0, int p1);
392 static void __move_panel_to_dir(RzCore *core, RzPanel *panel, int src);
393 static void __move_panel_to_left(RzCore *core, RzPanel *panel, int src);
394 static void __move_panel_to_right(RzCore *core, RzPanel *panel, int src);
395 static void __move_panel_to_up(RzCore *core, RzPanel *panel, int src);
396 static void __move_panel_to_down(RzCore *core, RzPanel *panel, int src);
397 static void __shrink_panels_forward(RzCore *core, int target);
398 static void __shrink_panels_backward(RzCore *core, int target);
399 static void __fix_layout(RzCore *core);
400 static void __fix_layout_w(RzCore *core);
401 static void __fix_layout_h(RzCore *core);
402 static bool __drag_and_resize(RzCore *core);
403 
404 /* cursor */
405 static bool __is_abnormal_cursor_type(RzCore *core, RzPanel *panel);
406 static bool __is_normal_cursor_type(RzPanel *panel);
407 static void __activate_cursor(RzCore *core);
408 static ut64 __parse_string_on_cursor(RzCore *core, RzPanel *panel, int idx);
409 static void __cursor_left(RzCore *core);
410 static void __cursor_right(RzCore *core);
411 static void __cursor_down(RzCore *core);
412 static void __cursor_up(RzCore *core);
413 static void __fix_cursor_up(RzCore *core);
414 static void __fix_cursor_down(RzCore *core);
415 static void __jmp_to_cursor_addr(RzCore *core, RzPanel *panel);
416 static void __cursor_del_breakpoints(RzCore *core, RzPanel *panel);
417 static void __insert_value(RzCore *core);
418 static void __set_breakpoints_on_cursor(RzCore *core, RzPanel *panel);
419 
420 /* filter */
421 static void __set_filter(RzCore *core, RzPanel *panel);
422 static void __reset_filter(RzCore *core, RzPanel *panel);
423 static void __renew_filter(RzPanel *panel, int n);
424 static char *__apply_filter_cmd(RzCore *core, RzPanel *panel);
425 
426 /* cmd */
427 static int __add_cmd_panel(void *user);
428 static int __add_cmdf_panel(RzCore *core, char *input, char *str);
429 static void __set_cmd_str_cache(RzCore *core, RzPanel *p, char *s);
430 static char *__handle_cmd_str_cache(RzCore *core, RzPanel *panel, bool force_cache);
431 static char *__find_cmd_str_cache(RzCore *core, RzPanel *panel);
432 static char *__load_cmdf(RzCore *core, RzPanel *p, char *input, char *str);
433 static void __replace_cmd(RzCore *core, const char *title, const char *cmd);
434 
435 /* rotate */
436 static void __rotate_panels(RzCore *core, bool rev);
437 static void __rotate_panel_cmds(RzCore *core, const char **cmds, const int cmdslen, const char *prefix, bool rev);
438 static void __rotate_asmemu(RzCore *core, RzPanel *p);
439 
440 /* mode */
441 static void __set_mode(RzCore *core, RzPanelsMode mode);
442 static bool __handle_zoom_mode(RzCore *core, const int key);
443 static bool __handle_window_mode(RzCore *core, const int key);
444 static bool __handle_cursor_mode(RzCore *core, const int key);
445 static void __toggle_zoom_mode(RzCore *core);
446 static void __toggle_window_mode(RzCore *core);
447 
448 /* mouse */
449 static bool __handle_mouse(RzCore *core, RzPanel *panel, int *key);
450 static bool __handle_mouse_on_top(RzCore *core, int x, int y);
451 static void __handle_mouse_on_menu(RzCore *core, int x, int y);
452 static bool __handle_mouse_on_X(RzCore *core, int x, int y);
453 static bool __handle_mouse_on_panel(RzCore *core, RzPanel *panel, int x, int y, int *key);
454 
455 /* modal */
456 static void __exec_almighty(RzCore *core, RzPanel *panel, RModal *modal, Sdb *menu_db, RzPanelLayout dir);
457 static void __delete_almighty(RzCore *core, RModal *modal, Sdb *menu_db);
458 static void __create_almighty(RzCore *core, RzPanel *panel, Sdb *menu_db);
459 static void __update_modal(RzCore *core, Sdb *menu_db, RModal *modal);
460 static bool __draw_modal(RzCore *core, RModal *modal, int range_end, int start, const char *name);
461 static RModal *__init_modal(void);
462 static void __free_modal(RModal **modal);
463 
464 /* menu callback */
465 static int __open_menu_cb(void *user);
466 static int __open_file_cb(void *user);
467 static int __rw_cb(void *user);
468 static int __debugger_cb(void *user);
469 static int __load_layout_saved_cb(void *user);
470 static int __load_layout_default_cb(void *user);
471 static int __close_file_cb(void *user);
472 static int __save_layout_cb(void *user);
473 static int __clear_layout_cb(void *user);
474 static int __copy_cb(void *user);
475 static int __paste_cb(void *user);
476 static int __write_str_cb(void *user);
477 static int __write_hex_cb(void *user);
478 static int __assemble_cb(void *user);
479 static int __fill_cb(void *user);
480 static int __config_toggle_cb(void *user);
481 static int __config_value_cb(void *user);
482 static int __calculator_cb(void *user);
483 static int __rz_shell_cb(void *user);
484 static int __system_shell_cb(void *user);
485 static int __string_whole_bin_cb(void *user);
486 static int __string_data_sec_cb(void *user);
487 static int __rop_cb(void *user);
488 static int __code_cb(void *user);
489 static int __hexpairs_cb(void *user);
490 static int __continue_cb(void *user);
491 static int __esil_init_cb(void *user);
492 static int __esil_step_to_cb(void *user);
493 static int __esil_step_range_cb(void *user);
494 static int __step_cb(void *user);
495 static int __step_over_cb(void *user);
496 static int __reload_cb(void *user);
497 static int __function_cb(void *user);
498 static int __symbols_cb(void *user);
499 static int __program_cb(void *user);
500 static int __calls_cb(void *user);
501 static int __break_points_cb(void *user);
502 static int __watch_points_cb(void *user);
503 static int __references_cb(void *user);
504 static int __help_cb(void *user);
505 static int __fortune_cb(void *user);
506 static int __license_cb(void *user);
507 static int __version_cb(void *user);
508 static int __quit_cb(void *user);
509 static int __io_cache_on_cb(void *user);
510 static int __io_cache_off_cb(void *user);
511 static int __settings_colors_cb(void *user);
512 
513 /* direction callback */
514 static void __direction_default_cb(void *user, int direction);
515 static void __direction_disassembly_cb(void *user, int direction);
516 static void __direction_graph_cb(void *user, int direction);
517 static void __direction_register_cb(void *user, int direction);
518 static void __direction_stack_cb(void *user, int direction);
519 static void __direction_hexdump_cb(void *user, int direction);
520 static void __direction_panels_cursor_cb(void *user, int direction);
521 
522 /* rotate callback */
523 static void __rotate_disasm_cb(void *user, bool rev);
524 static void __rotate_entropy_v_cb(void *user, bool rev);
525 static void __rotate_entropy_h_cb(void *user, bool rev);
526 static void __rotate_hexdump_cb(void *user, bool rev);
527 static void __rotate_register_cb(void *user, bool rev);
528 static void __rotate_function_cb(void *user, bool rev);
529 
530 /* print callback */
531 static void __print_default_cb(void *user, void *p);
532 static void __print_disassembly_cb(void *user, void *p);
533 static void __print_disasmsummary_cb(void *user, void *p);
534 static void __print_graph_cb(void *user, void *p);
535 static void __print_stack_cb(void *user, void *p);
536 static void __print_hexdump_cb(void *user, void *p);
537 
538 /* almighty callback */
539 static void __create_panel(RzCore *core, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title, const char *cmd);
540 static void __create_panel_db(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title);
541 static void __create_panel_input(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title);
542 static void __replace_current_panel_input(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title);
543 static void __search_strings_data_create(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title);
544 static void __search_strings_bin_create(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title);
545 RZ_OWN static char *__search_strings(RzCore *core, bool whole);
546 static void __put_breakpoints_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title);
547 static void __continue_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title);
548 static void __step_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title);
549 static void __step_over_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title);
550 
551 /* menu */
552 static void __del_menu(RzCore *core);
553 static void __clear_panels_menu(RzCore *core);
554 static void __clear_panels_menuRec(RzPanelsMenuItem *pmi);
555 static RzStrBuf *__draw_menu(RzCore *core, RzPanelsMenuItem *item);
556 static void __handle_menu(RzCore *core, const int key);
557 static int cmpstr(const void *_a, const void *_b);
558 static RzList *__sorted_list(RzCore *core, char *menu[], int count);
559 
560 /* config */
561 static char *__get_panels_config_dir_path(void);
562 static char *__create_panels_config_path(const char *file);
563 static void __load_config_menu(RzCore *core);
564 
565 /* history */
566 static int __file_history_up(RzLine *line);
567 static int __file_history_down(RzLine *line);
568 
569 /* hud */
570 static void __hudstuff(RzCore *core);
571 
572 /* esil */
573 static void __esil_init(RzCore *core);
574 static void __esil_step_to(RzCore *core, ut64 end);
575 
576 /* debug */
577 static void __panel_breakpoint(RzCore *core);
578 static void __panel_single_step_in(RzCore *core);
579 static void __panel_single_step_over(RzCore *core);
580 
581 /* zoom mode */
582 static void __save_panel_pos(RzPanel *panel);
583 static void __restore_panel_pos(RzPanel *panel);
584 static void __maximize_panel_size(RzPanels *panels);
585 
586 /* tab */
587 static void __handle_tab(RzCore *core);
588 static void __handle_tab_nth(RzCore *core, int ch);
589 static void __handle_tab_next(RzCore *core);
590 static void __handle_print_rotate(RzCore *core);
591 static void __handle_tab_prev(RzCore *core);
592 static void __handle_tab_name(RzCore *core);
593 static void __handle_tab_new(RzCore *core);
594 static void __handle_tab_new_with_cur_panel(RzCore *core);
595 static void __del_panels(RzCore *core);
596 
597 /* other */
598 static void __panels_process(RzCore *core, RzPanels *panels);
599 static bool __handle_console(RzCore *core, RzPanel *panel, const int key);
600 static void __toggle_cache(RzCore *core, RzPanel *p);
601 static bool __move_to_direction(RzCore *core, Direction direction);
602 static void __toggle_help(RzCore *core);
603 static void __call_visual_graph(RzCore *core);
604 static void __refresh_core_offset(RzCore *core);
605 static char *__search_db(RzCore *core, const char *title);
606 static void __handle_visual_mark(RzCore *core);
607 static void __handle_tab_key(RzCore *core, bool shift);
608 static void __handle_refs(RzCore *core, RzPanel *panel, ut64 tmp);
609 static void __undo_seek(RzCore *core);
610 static void __redo_seek(RzCore *core);
611 static void __cache_white_list(RzCore *core, RzPanel *panel);
612 static bool search_db_check_panel_type(RzCore *core, RzPanel *panel, const char *ch);
613 
614 void __update_edge_x(RzCore *core, int x) {
615  RzPanels *panels = core->panels;
616  int i, j;
617  int tmp_x = 0;
618  for (i = 0; i < panels->n_panels; i++) {
619  RzPanel *p0 = __get_panel(panels, i);
620  if (p0->view->pos.x - 2 <= panels->mouse_orig_x &&
621  panels->mouse_orig_x <= p0->view->pos.x + 2) {
622  tmp_x = p0->view->pos.x;
623  p0->view->pos.x += x;
624  p0->view->pos.w -= x;
625  for (j = 0; j < panels->n_panels; j++) {
626  RzPanel *p1 = __get_panel(panels, j);
627  if (p1->view->pos.x + p1->view->pos.w - 1 == tmp_x) {
628  p1->view->pos.w += x;
629  }
630  }
631  }
632  }
633 }
634 
635 void __update_edge_y(RzCore *core, int y) {
636  RzPanels *panels = core->panels;
637  int i, j;
638  int tmp_y = 0;
639  for (i = 0; i < panels->n_panels; i++) {
640  RzPanel *p0 = __get_panel(panels, i);
641  if (p0->view->pos.y - 2 <= panels->mouse_orig_y &&
642  panels->mouse_orig_y <= p0->view->pos.y + 2) {
643  tmp_y = p0->view->pos.y;
644  p0->view->pos.y += y;
645  p0->view->pos.h -= y;
646  for (j = 0; j < panels->n_panels; j++) {
647  RzPanel *p1 = __get_panel(panels, j);
648  if (p1->view->pos.y + p1->view->pos.h - 1 == tmp_y) {
649  p1->view->pos.h += y;
650  }
651  }
652  }
653  }
654 }
655 
657  RzPanels *panels = core->panels;
658  RzConsCanvas *can = panels->can;
659  const int edge_x = 1;
660  if (x <= edge_x || can->w - edge_x <= x) {
661  return true;
662  }
663  return false;
664 }
665 
666 bool __check_if_mouse_y_illegal(RzCore *core, int y) {
667  RzPanels *panels = core->panels;
668  RzConsCanvas *can = panels->can;
669  const int edge_y = 0;
670  if (y <= edge_y || can->h - edge_y <= y) {
671  return true;
672  }
673  return false;
674 }
675 
676 bool __check_if_mouse_x_on_edge(RzCore *core, int x, int y) {
677  RzPanels *panels = core->panels;
678  const int edge_x = rz_config_get_i(core->config, "scr.panelborder") ? 3 : 1;
679  int i = 0;
680  for (; i < panels->n_panels; i++) {
681  RzPanel *panel = __get_panel(panels, i);
682  if (x > panel->view->pos.x - (edge_x - 1) && x <= panel->view->pos.x + edge_x) {
683  panels->mouse_on_edge_x = true;
684  panels->mouse_orig_x = x;
685  return true;
686  }
687  }
688  return false;
689 }
690 
691 bool __check_if_mouse_y_on_edge(RzCore *core, int x, int y) {
692  RzPanels *panels = core->panels;
693  const int edge_y = rz_config_get_i(core->config, "scr.panelborder") ? 3 : 1;
694  int i = 0;
695  for (; i < panels->n_panels; i++) {
696  RzPanel *panel = __get_panel(panels, i);
697  if (x > panel->view->pos.x && x <= panel->view->pos.x + panel->view->pos.w + edge_y) {
698  if (y > 2 && y >= panel->view->pos.y && y <= panel->view->pos.y + edge_y) {
699  panels->mouse_on_edge_y = true;
700  panels->mouse_orig_y = y;
701  return true;
702  }
703  }
704  }
705  return false;
706 }
707 
708 bool __check_if_cur_panel(RzCore *core, RzPanel *panel) {
709  return __get_cur_panel(core->panels) == panel;
710 }
711 
712 void __check_edge(RzCore *core) {
713  RzPanels *panels = core->panels;
714  int i;
715  for (i = 0; i < panels->n_panels; i++) {
716  RzPanel *panel = __get_panel(panels, i);
717  if (panel->view->pos.x + panel->view->pos.w == core->panels->can->w) {
718  panel->view->edge |= (1 << PANEL_EDGE_RIGHT);
719  } else {
720  panel->view->edge &= (1 << PANEL_EDGE_BOTTOM);
721  }
722  if (panel->view->pos.y + panel->view->pos.h == core->panels->can->h) {
723  panel->view->edge |= (1 << PANEL_EDGE_BOTTOM);
724  } else {
725  panel->view->edge &= (1 << PANEL_EDGE_RIGHT);
726  }
727  }
728 }
729 
730 void __shrink_panels_forward(RzCore *core, int target) {
731  RzPanels *panels = core->panels;
732  int i = target;
733  for (; i < panels->n_panels - 1; i++) {
734  panels->panel[i] = panels->panel[i + 1];
735  }
736 }
737 
738 void __shrink_panels_backward(RzCore *core, int target) {
739  RzPanels *panels = core->panels;
740  int i = target;
741  for (; i > 0; i--) {
742  panels->panel[i] = panels->panel[i - 1];
743  }
744 }
745 
746 void __cache_white_list(RzCore *core, RzPanel *panel) {
747  int i = 0;
748  for (; i < COUNT(cache_white_list_cmds); i++) {
749  if (!strcmp(panel->model->cmd, cache_white_list_cmds[i])) {
750  panel->model->cache = true;
751  return;
752  }
753  }
754  panel->model->cache = false;
755 }
756 
757 char *__search_db(RzCore *core, const char *title) {
758  RzPanels *panels = core->panels;
759  if (!panels->db) {
760  return NULL;
761  }
762  char *out = sdb_get(panels->db, title, 0);
763  if (out) {
764  return out;
765  }
766  return NULL;
767 }
768 
769 int __show_status(RzCore *core, const char *msg) {
770  rz_cons_gotoxy(0, 0);
772  rz_cons_flush();
773  return rz_cons_readchar();
774 }
775 
776 bool __show_status_yesno(RzCore *core, int def, const char *msg) {
777  rz_cons_gotoxy(0, 0);
778  rz_cons_flush();
779  return rz_cons_yesno(def, RZ_CONS_CLEAR_LINE "%s[Status] %s" Color_RESET, core->cons->context->pal.graph_box2, msg);
780 }
781 
782 char *__show_status_input(RzCore *core, const char *msg) {
783  char *n_msg = rz_str_newf(RZ_CONS_CLEAR_LINE "%s[Status] %s" Color_RESET, core->cons->context->pal.graph_box2, msg);
784  rz_cons_gotoxy(0, 0);
785  rz_cons_flush();
786  char *out = rz_cons_input(n_msg);
787  free(n_msg);
788  return out;
789 }
790 
791 bool __check_panel_type(RzPanel *panel, const char *type) {
792  if (!panel->model->cmd || !type) {
793  return false;
794  }
795  char *tmp = rz_str_new(panel->model->cmd);
796  int n = rz_str_split(tmp, ' ');
797  if (!n) {
798  free(tmp);
799  return false;
800  }
801  const char *base = rz_str_word_get0(tmp, 0);
802  if (RZ_STR_ISEMPTY(base)) {
803  free(tmp);
804  return false;
805  }
806  int len = strlen(type);
807  if (!strcmp(type, PANEL_CMD_DISASSEMBLY)) {
808  if (!strncmp(tmp, type, len) && strcmp(panel->model->cmd, PANEL_CMD_DISASMSUMMARY)) {
809  free(tmp);
810  return true;
811  }
812  free(tmp);
813  return false;
814  }
815  if (!strcmp(type, PANEL_CMD_STACK)) {
816  if (!strcmp(tmp, PANEL_CMD_STACK)) {
817  free(tmp);
818  return true;
819  }
820  free(tmp);
821  return false;
822  }
823  if (!strcmp(type, PANEL_CMD_HEXDUMP)) {
824  int i = 0;
825  for (; i < COUNT(hexdump_rotate); i++) {
826  if (!strcmp(tmp, hexdump_rotate[i])) {
827  free(tmp);
828  return true;
829  }
830  }
831  free(tmp);
832  return false;
833  }
834  free(tmp);
835  return !strncmp(panel->model->cmd, type, len);
836 }
837 
839  return core->panels_root->root_state == state;
840 }
841 
842 bool search_db_check_panel_type(RzCore *core, RzPanel *panel, const char *ch) {
843  char *str = __search_db(core, ch);
844  bool ret = str && __check_panel_type(panel, str);
845  free(str);
846  return ret;
847 }
848 
849 // TODO: Refactroing
852  return true;
853  }
855  return true;
856  }
858  return true;
859  }
861  return true;
862  }
864  return true;
865  }
867  return true;
868  }
870  return true;
871  }
873  return true;
874  }
875  return false;
876 }
877 
879  return (__check_panel_type(panel, PANEL_CMD_STACK) ||
883 }
884 
885 void __set_cmd_str_cache(RzCore *core, RzPanel *p, char *s) {
886  free(p->model->cmdStrCache);
887  p->model->cmdStrCache = s;
888  __set_dcb(core, p);
889  __set_pcb(p);
890 }
891 
892 void __set_read_only(RzCore *core, RzPanel *p, char *s) {
893  free(p->model->readOnly);
894  p->model->readOnly = rz_str_new(s);
895  __set_dcb(core, p);
896  __set_pcb(p);
897 }
898 
899 void __set_pos(RzPanelPos *pos, int x, int y) {
900  pos->x = x;
901  pos->y = y;
902 }
903 
904 void __set_size(RzPanelPos *pos, int w, int h) {
905  pos->w = w;
906  pos->h = h;
907 }
908 
909 void __set_geometry(RzPanelPos *pos, int x, int y, int w, int h) {
910  __set_pos(pos, x, y);
911  __set_size(pos, w, h);
912 }
913 
914 void __set_panel_addr(RzCore *core, RzPanel *panel, ut64 addr) {
915  panel->model->addr = addr;
916 }
917 
918 RzPanel *__get_panel(RzPanels *panels, int i) {
919  if (!panels || (i >= PANEL_NUM_LIMIT)) {
920  return NULL;
921  }
922  return panels->panel[i];
923 }
924 
926  return __get_panel(panels, panels->curnode);
927 }
928 
929 int __get_panel_idx_in_pos(RzCore *core, int x, int y) {
930  RzPanels *panels = core->panels;
931  int i = -1;
932  for (i = 0; i < panels->n_panels; i++) {
933  RzPanel *p = __get_panel(panels, i);
934  if (x >= p->view->pos.x && x < p->view->pos.x + p->view->pos.w) {
935  if (y >= p->view->pos.y && y < p->view->pos.y + p->view->pos.h) {
936  break;
937  }
938  }
939  }
940  return i;
941 }
942 
943 void __handlePrompt(RzCore *core, RzPanels *panels) {
945  int i;
946  for (i = 0; i < panels->n_panels; i++) {
947  RzPanel *p = __get_panel(panels, i);
949  __set_panel_addr(core, p, core->offset);
950  break;
951  }
952  }
953 }
954 
955 void __panel_print(RzCore *core, RzConsCanvas *can, RzPanel *panel, int color) {
956  if (!can || !panel || !panel->view->refresh) {
957  return;
958  }
959  if (can->w <= panel->view->pos.x || can->h <= panel->view->pos.y) {
960  return;
961  }
962  panel->view->refresh = panel->model->type == PANEL_TYPE_MENU;
963  rz_cons_canvas_fill(can, panel->view->pos.x, panel->view->pos.y, panel->view->pos.w, panel->view->pos.h, ' ');
964  if (panel->model->type == PANEL_TYPE_MENU) {
965  __menu_panel_print(can, panel, panel->view->sx, panel->view->sy, panel->view->pos.w, panel->view->pos.h);
966  } else {
967  __default_panel_print(core, panel);
968  }
969  int w, h;
970  w = RZ_MIN(panel->view->pos.w, can->w - panel->view->pos.x);
971  h = RZ_MIN(panel->view->pos.h, can->h - panel->view->pos.y);
972  if (color) {
973  rz_cons_canvas_box(can, panel->view->pos.x, panel->view->pos.y, w, h, core->cons->context->pal.graph_box2);
974  } else {
975  rz_cons_canvas_box(can, panel->view->pos.x, panel->view->pos.y, w, h, core->cons->context->pal.graph_box);
976  }
977 }
978 
979 void __menu_panel_print(RzConsCanvas *can, RzPanel *panel, int x, int y, int w, int h) {
980  (void)rz_cons_canvas_gotoxy(can, panel->view->pos.x + 2, panel->view->pos.y + 2);
981  char *text = rz_str_ansi_crop(panel->model->title, x, y, w, h);
982  if (text) {
984  free(text);
985  } else {
986  rz_cons_canvas_write(can, panel->model->title);
987  }
988 }
989 
990 void __update_help_contents(RzCore *core, RzPanel *panel) {
991  char *read_only = panel->model->readOnly;
992  char *text = NULL;
993  int sx = panel->view->sx;
994  int sy = RZ_MAX(panel->view->sy, 0);
995  int x = panel->view->pos.x;
996  int y = panel->view->pos.y;
997  int w = panel->view->pos.w;
998  int h = panel->view->pos.h;
999  RzPanels *panels = core->panels;
1000  RzConsCanvas *can = panels->can;
1001  (void)rz_cons_canvas_gotoxy(can, x + 2, y + 2);
1002  if (sx < 0) {
1003  char *white = (char *)rz_str_pad(' ', 128);
1004  int idx = RZ_MIN(-sx, strlen(white) - 1);
1005  white[idx] = 0;
1006  text = rz_str_ansi_crop(read_only,
1007  0, sy, w + sx - 3, h - 2 + sy);
1008  char *newText = rz_str_prefix_all(text, white);
1009  if (newText) {
1010  free(text);
1011  text = newText;
1012  }
1013  } else {
1014  text = rz_str_ansi_crop(read_only,
1015  sx, sy, w + sx - 3, h - 2 + sy);
1016  }
1017  if (text) {
1018  rz_cons_canvas_write(can, text);
1019  free(text);
1020  }
1021 }
1022 
1023 void __update_help_title(RzCore *core, RzPanel *panel) {
1024  RzConsCanvas *can = core->panels->can;
1025  RzStrBuf *title = rz_strbuf_new(NULL);
1026  RzStrBuf *cache_title = rz_strbuf_new(NULL);
1027  if (__check_if_cur_panel(core, panel)) {
1028  rz_strbuf_setf(title, "%s[X] %s" Color_RESET,
1029  core->cons->context->pal.graph_box2, panel->model->title);
1030  rz_strbuf_setf(cache_title, "%s[Cache] N/A" Color_RESET,
1031  core->cons->context->pal.graph_box2);
1032  } else {
1033  rz_strbuf_setf(title, "[X] %s ", panel->model->title);
1034  rz_strbuf_setf(cache_title, "[Cache] N/A");
1035  }
1036  if (rz_cons_canvas_gotoxy(can, panel->view->pos.x + 1, panel->view->pos.y + 1)) {
1037  rz_cons_canvas_write(can, rz_strbuf_get(title));
1038  }
1039  if (rz_cons_canvas_gotoxy(can, panel->view->pos.x + panel->view->pos.w - rz_str_ansi_len(rz_strbuf_get(cache_title)) - 2, panel->view->pos.y + 1)) {
1040  rz_cons_canvas_write(can, rz_strbuf_get(cache_title));
1041  }
1042  rz_strbuf_free(cache_title);
1043  rz_strbuf_free(title);
1044 }
1045 
1046 void __update_panel_contents(RzCore *core, RzPanel *panel, const char *cmdstr) {
1047  bool b = __is_abnormal_cursor_type(core, panel) && core->print->cur_enabled;
1048  int sx = b ? -2 : panel->view->sx;
1049  int sy = RZ_MAX(panel->view->sy, 0);
1050  int x = panel->view->pos.x;
1051  int y = panel->view->pos.y;
1052  if (x >= core->panels->can->w) {
1053  return;
1054  }
1055  if (y >= core->panels->can->h) {
1056  return;
1057  }
1058  int w = panel->view->pos.w;
1059  int h = panel->view->pos.h;
1060  int graph_pad = __check_panel_type(panel, PANEL_CMD_GRAPH) ? 1 : 0;
1061  char *text = NULL;
1062  RzPanels *panels = core->panels;
1063  RzConsCanvas *can = panels->can;
1064  (void)rz_cons_canvas_gotoxy(can, x + 2, y + 2);
1065  if (sx < 0) {
1066  char *white = (char *)rz_str_pad(' ', 128);
1067  int idx = RZ_MIN(-sx, strlen(white) - 1);
1068  white[idx] = 0;
1070  0, sy + graph_pad, w + sx - 3, h - 2 + sy);
1071  char *newText = rz_str_prefix_all(text, white);
1072  if (newText) {
1073  free(text);
1074  text = newText;
1075  }
1076  } else {
1077  text = rz_str_ansi_crop(cmdstr, sx, sy + graph_pad, w + sx - 3, h - 2 + sy);
1078  }
1079  if (text) {
1080  rz_cons_canvas_write(can, text);
1081  free(text);
1082  }
1083  if (b) {
1084  int sub = panel->view->curpos - panel->view->sy;
1085  (void)rz_cons_canvas_gotoxy(can, panel->view->pos.x + 2, panel->view->pos.y + 2 + sub);
1086  rz_cons_canvas_write(can, "*");
1087  }
1088 }
1089 
1090 void __update_panel_title(RzCore *core, RzPanel *panel) {
1091  RzConsCanvas *can = core->panels->can;
1092  RzStrBuf *title = rz_strbuf_new(NULL);
1093  RzStrBuf *cache_title = rz_strbuf_new(NULL);
1094  char *cmd_title = __apply_filter_cmd(core, panel);
1095  if (__check_if_cur_panel(core, panel)) {
1096  if (!strcmp(panel->model->title, cmd_title)) {
1097  rz_strbuf_setf(title, "%s[X] %s" Color_RESET, core->cons->context->pal.graph_box2, panel->model->title);
1098  } else {
1099  rz_strbuf_setf(title, "%s[X] %s (%s)" Color_RESET, core->cons->context->pal.graph_box2, panel->model->title, cmd_title);
1100  }
1101  rz_strbuf_setf(cache_title, "%s[Cache] %s" Color_RESET, core->cons->context->pal.graph_box2, panel->model->cache ? "On" : "Off");
1102  } else {
1103  if (!strcmp(panel->model->title, cmd_title)) {
1104  rz_strbuf_setf(title, "[X] %s ", panel->model->title);
1105  } else {
1106  rz_strbuf_setf(title, "[X] %s (%s) ", panel->model->title, cmd_title);
1107  }
1108  rz_strbuf_setf(cache_title, "[Cache] %s", panel->model->cache ? "On" : "Off");
1109  }
1110  rz_strbuf_slice(title, 0, panel->view->pos.w);
1111  rz_strbuf_slice(cache_title, 0, panel->view->pos.w);
1112  if (rz_cons_canvas_gotoxy(can, panel->view->pos.x + 1, panel->view->pos.y + 1)) {
1113  rz_cons_canvas_write(can, rz_strbuf_get(title));
1114  }
1115  if (rz_cons_canvas_gotoxy(can, panel->view->pos.x + panel->view->pos.w - rz_str_ansi_len(rz_strbuf_get(cache_title)) - 2, panel->view->pos.y + 1)) {
1116  rz_cons_canvas_write(can, rz_strbuf_get(cache_title));
1117  }
1118  rz_strbuf_free(title);
1119  rz_strbuf_free(cache_title);
1120  free(cmd_title);
1121 }
1122 
1123 void __default_panel_print(RzCore *core, RzPanel *panel) {
1124  bool o_cur = core->print->cur_enabled;
1125  core->print->cur_enabled = o_cur & (__get_cur_panel(core->panels) == panel);
1126  if (panel->model->readOnly) {
1127  __update_help_contents(core, panel);
1128  __update_help_title(core, panel);
1129  } else if (panel->model->cmd) {
1130  panel->model->print_cb(core, panel);
1131  __update_panel_title(core, panel);
1132  }
1133  core->print->cur_enabled = o_cur;
1134 }
1135 
1137  p->view->sx = 0;
1138  p->view->sy = 0;
1139 }
1140 
1141 char *__find_cmd_str_cache(RzCore *core, RzPanel *panel) {
1142  if (panel->model->cache && panel->model->cmdStrCache) {
1143  return panel->model->cmdStrCache;
1144  }
1145  return NULL;
1146 }
1147 
1148 char *__apply_filter_cmd(RzCore *core, RzPanel *panel) {
1149  char *out = malloc(strlen(panel->model->cmd) + 1024);
1150  if (!out) {
1151  RZ_LOG_ERROR("Fail to allocate the memory\n");
1152  return out;
1153  }
1154  strcpy(out, panel->model->cmd);
1155  int i;
1156  for (i = 0; i < panel->model->n_filter; i++) {
1157  char *filter = panel->model->filter[i];
1158  if (strlen(filter) > 1024) {
1159  (void)__show_status(core, "filter is too big.");
1160  return out;
1161  }
1162  strcat(out, "~");
1163  strcat(out, filter);
1164  }
1165  return out;
1166 }
1167 
1168 char *__handle_cmd_str_cache(RzCore *core, RzPanel *panel, bool force_cache) {
1169  char *cmd = __apply_filter_cmd(core, panel);
1170  bool b = core->print->cur_enabled && __get_cur_panel(core->panels) != panel;
1171  if (b) {
1172  core->print->cur_enabled = false;
1173  }
1174  char *out = rz_core_cmd_str(core, cmd);
1175  rz_cons_echo(NULL);
1176  if (force_cache) {
1177  panel->model->cache = true;
1178  }
1179  if (RZ_STR_ISNOTEMPTY(out)) {
1180  __set_cmd_str_cache(core, panel, out);
1181  } else {
1182  RZ_FREE(out);
1183  }
1184  free(cmd);
1185  if (b) {
1186  core->print->cur_enabled = true;
1187  }
1188  return out;
1189 }
1190 
1192  if (!panels) {
1193  return;
1194  }
1195  int i;
1196  RzPanel *panel = NULL;
1197  for (i = 0; i < panels->n_panels; i++) {
1198  panel = __get_panel(panels, i);
1199  rz_cons_canvas_fill(panels->can, panel->view->pos.x, panel->view->pos.y, panel->view->pos.w, panel->view->pos.h, ' ');
1200  }
1201  rz_cons_canvas_print(panels->can);
1202  rz_cons_flush();
1203 }
1204 
1205 void __panels_layout(RzPanels *panels) {
1206  panels->can->sx = 0;
1207  panels->can->sy = 0;
1208  __layout_default(panels);
1209 }
1210 
1212  RzPanel *p0 = __get_panel(panels, 0);
1213  int h, w = rz_cons_get_size(&h);
1214  if (panels->n_panels <= 1) {
1215  __set_geometry(&p0->view->pos, 0, 1, w, h - 1);
1216  return;
1217  }
1218 
1219  int ph = (h - 1) / (panels->n_panels - 1);
1220  int colpos = w - panels->columnWidth;
1221  __set_geometry(&p0->view->pos, 0, 1, colpos + 1, h - 1);
1222 
1223  int pos_x = p0->view->pos.x + p0->view->pos.w - 1;
1224  int i, total_h = 0;
1225  for (i = 1; i < panels->n_panels; i++) {
1226  RzPanel *p = __get_panel(panels, i);
1227  int tmp_w = RZ_MAX(w - colpos, 0);
1228  int tmp_h = 0;
1229  if (i + 1 == panels->n_panels) {
1230  tmp_h = h - total_h;
1231  } else {
1232  tmp_h = ph;
1233  }
1234  __set_geometry(&p->view->pos, pos_x, 2 + (ph * (i - 1)) - 1, tmp_w, tmp_h + 1);
1235  total_h += 2 + (ph * (i - 1)) - 1 + tmp_h + 1;
1236  }
1237 }
1238 
1240  int i, h;
1241  (void)rz_cons_get_size(&h);
1242  RzPanels *panels = core->panels;
1243  for (i = 0; i < panels->n_panels; i++) {
1244  RzPanel *p = __get_panel(panels, i);
1245  if (p->view->pos.x == 0) {
1246  if (p->view->pos.w >= PANEL_CONFIG_SIDEPANEL_W) {
1247  p->view->pos.x += PANEL_CONFIG_SIDEPANEL_W - 1;
1248  p->view->pos.w -= PANEL_CONFIG_SIDEPANEL_W - 1;
1249  }
1250  }
1251  }
1252 }
1253 
1254 int __add_cmd_panel(void *user) {
1255  RzCore *core = (RzCore *)user;
1256  RzPanels *panels = core->panels;
1257  if (!__check_panel_num(core)) {
1258  return 0;
1259  }
1260  RzPanelsMenu *menu = core->panels->panels_menu;
1261  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
1262  RzPanelsMenuItem *child = parent->sub[parent->selectedIndex];
1263  char *cmd = __search_db(core, child->name);
1264  if (!cmd) {
1265  return 0;
1266  }
1267  int h;
1268  (void)rz_cons_get_size(&h);
1269  __adjust_side_panels(core);
1270  __insert_panel(core, 0, child->name, cmd);
1271  RzPanel *p0 = __get_panel(panels, 0);
1272  __set_geometry(&p0->view->pos, 0, 1, PANEL_CONFIG_SIDEPANEL_W, h - 1);
1273  __set_curnode(core, 0);
1275  free(cmd);
1276  return 0;
1277 }
1278 
1280  // TODO: all these things done below are very hacky and refactoring needed
1281  RzPanels *ps = core->panels;
1282  int h;
1283  const char *help = "Help";
1284  (void)rz_cons_get_size(&h);
1285  __adjust_side_panels(core);
1286  __insert_panel(core, 0, help, help);
1287  RzPanel *p0 = __get_panel(ps, 0);
1288  __set_geometry(&p0->view->pos, 0, 1, PANEL_CONFIG_SIDEPANEL_W, h - 1);
1289  __set_curnode(core, 0);
1290 }
1291 
1292 char *__load_cmdf(RzCore *core, RzPanel *p, char *input, char *str) {
1293  char *ret = NULL;
1294  char *res = __show_status_input(core, input);
1295  if (res) {
1296  p->model->cmd = rz_str_newf(str, res);
1297  ret = rz_core_cmd_str(core, p->model->cmd);
1298  free(res);
1299  }
1300  return ret;
1301 }
1302 
1303 int __add_cmdf_panel(RzCore *core, char *input, char *str) {
1304  RzPanels *panels = core->panels;
1305  if (!__check_panel_num(core)) {
1306  return 0;
1307  }
1308  int h;
1309  (void)rz_cons_get_size(&h);
1310  RzPanelsMenu *menu = core->panels->panels_menu;
1311  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
1312  RzPanelsMenuItem *child = parent->sub[parent->selectedIndex];
1313  __adjust_side_panels(core);
1314  __insert_panel(core, 0, child->name, "");
1315  RzPanel *p0 = __get_panel(panels, 0);
1316  __set_geometry(&p0->view->pos, 0, 1, PANEL_CONFIG_SIDEPANEL_W, h - 1);
1317  __set_cmd_str_cache(core, p0, __load_cmdf(core, p0, input, str));
1318  __set_curnode(core, 0);
1320  return 0;
1321 }
1322 
1323 void __split_panel_vertical(RzCore *core, RzPanel *p, const char *name, const char *cmd) {
1324  RzPanels *panels = core->panels;
1325  if (!__check_panel_num(core)) {
1326  return;
1327  }
1328  __insert_panel(core, panels->curnode + 1, name, cmd);
1329  RzPanel *next = __get_panel(panels, panels->curnode + 1);
1330  int owidth = p->view->pos.w;
1331  p->view->pos.w = owidth / 2 + 1;
1332  __set_geometry(&next->view->pos, p->view->pos.x + p->view->pos.w - 1,
1333  p->view->pos.y, owidth - p->view->pos.w + 1, p->view->pos.h);
1334  __fix_layout(core);
1335  __set_refresh_all(core, false, true);
1336 }
1337 
1338 void __split_panel_horizontal(RzCore *core, RzPanel *p, const char *name, const char *cmd) {
1339  RzPanels *panels = core->panels;
1340  if (!__check_panel_num(core)) {
1341  return;
1342  }
1343  __insert_panel(core, panels->curnode + 1, name, cmd);
1344  RzPanel *next = __get_panel(panels, panels->curnode + 1);
1345  int oheight = p->view->pos.h;
1346  p->view->curpos = 0;
1347  p->view->pos.h = oheight / 2 + 1;
1348  __set_geometry(&next->view->pos, p->view->pos.x, p->view->pos.y + p->view->pos.h - 1,
1349  p->view->pos.w, oheight - p->view->pos.h + 1);
1350  __fix_layout(core);
1351  __set_refresh_all(core, false, true);
1352 }
1353 
1355  __del_invalid_panels(core);
1356  __check_edge(core);
1358  __panels_refresh(core);
1359 }
1360 
1361 void __insert_panel(RzCore *core, int n, const char *name, const char *cmd) {
1362  RzPanels *panels = core->panels;
1363  if (panels->n_panels + 1 > PANEL_NUM_LIMIT) {
1364  return;
1365  }
1366  RzPanel **panel = panels->panel;
1367  int i;
1368  RzPanel *last = panel[panels->n_panels];
1369  for (i = panels->n_panels - 1; i >= n; i--) {
1370  panel[i + 1] = panel[i];
1371  }
1372  panel[n] = last;
1373  __init_panel_param(core, panel[n], name, cmd);
1374 }
1375 
1376 void __set_cursor(RzCore *core, bool cur) {
1377  RzPanel *p = __get_cur_panel(core->panels);
1378  RzPrint *print = core->print;
1379  print->cur_enabled = cur;
1380  if (__is_abnormal_cursor_type(core, p)) {
1381  return;
1382  }
1383  if (cur) {
1384  print->cur = p->view->curpos;
1385  } else {
1386  p->view->curpos = print->cur;
1387  }
1388  print->col = print->cur_enabled ? 1 : 0;
1389 }
1390 
1392  RzPanels *panels = core->panels;
1393  RzPanel *cur = __get_cur_panel(panels);
1394  bool normal = __is_normal_cursor_type(cur);
1395  bool abnormal = __is_abnormal_cursor_type(core, cur);
1396  if (normal || abnormal) {
1397  if (normal && cur->model->cache) {
1398  if (__show_status_yesno(core, 1, "You need to turn off cache to use cursor. Turn off now?(Y/n)")) {
1399  cur->model->cache = false;
1400  __set_cmd_str_cache(core, cur, NULL);
1401  (void)__show_status(core, "Cache is off and cursor is on");
1402  __set_cursor(core, !core->print->cur_enabled);
1403  cur->view->refresh = true;
1404  __reset_scroll_pos(cur);
1405  } else {
1406  (void)__show_status(core, "You can always toggle cache by \'&\' key");
1407  }
1408  return;
1409  }
1410  __set_cursor(core, !core->print->cur_enabled);
1411  cur->view->refresh = true;
1412  } else {
1413  (void)__show_status(core, "Cursor is not available for the current panel.");
1414  }
1415 }
1416 
1418  if (!panel->model->cmdStrCache) {
1419  return UT64_MAX;
1420  }
1422  char *s = panel->model->cmdStrCache;
1423  int l = 0;
1424  while (RZ_STR_ISNOTEMPTY(s) && l != idx) {
1425  if (*s == '\n') {
1426  l++;
1427  }
1428  s++;
1429  }
1430  while (RZ_STR_ISNOTEMPTY(s) && RZ_STR_ISNOTEMPTY(s + 1)) {
1431  if (*s == '0' && *(s + 1) == 'x') {
1432  rz_strbuf_append_n(buf, s, 2);
1433  while (*s != ' ') {
1434  rz_strbuf_append_n(buf, s, 1);
1435  s++;
1436  }
1437  ut64 ret = rz_num_math(core->num, rz_strbuf_get(buf));
1439  return ret;
1440  }
1441  s++;
1442  }
1444  return UT64_MAX;
1445 }
1446 
1447 void __cursor_left(RzCore *core) {
1448  RzPanel *cur = __get_cur_panel(core->panels);
1449  RzPrint *print = core->print;
1451  if (print->cur > 0) {
1452  print->cur--;
1453  cur->model->addr--;
1454  }
1455  } else if (__check_panel_type(cur, PANEL_CMD_DISASSEMBLY)) {
1456  print->cur--;
1457  __fix_cursor_up(core);
1458  } else {
1459  print->cur--;
1460  }
1461 }
1462 
1463 void __cursor_right(RzCore *core) {
1464  RzPanel *cur = __get_cur_panel(core->panels);
1465  RzPrint *print = core->print;
1466  if (__check_panel_type(cur, PANEL_CMD_STACK) && print->cur >= 15) {
1467  return;
1468  }
1470  print->cur++;
1471  cur->model->addr++;
1472  } else if (__check_panel_type(cur, PANEL_CMD_DISASSEMBLY)) {
1473  print->cur++;
1474  __fix_cursor_down(core);
1475  } else {
1476  print->cur++;
1477  }
1478 }
1479 
1480 void __cursor_up(RzCore *core) {
1481  RzPrint *print = core->print;
1482  ut64 addr, oaddr = core->offset + print->cur;
1483  if (rz_core_prevop_addr(core, oaddr, 1, &addr)) {
1484  const int delta = oaddr - addr;
1485  print->cur -= delta;
1486  } else {
1487  print->cur -= 4;
1488  }
1489  __fix_cursor_up(core);
1490 }
1491 
1492 void __cursor_down(RzCore *core) {
1493  RzPrint *print = core->print;
1495  if (aop) {
1496  print->cur += aop->size;
1497  rz_analysis_op_free(aop);
1498  } else {
1499  print->cur += 4;
1500  }
1501  __fix_cursor_down(core);
1502 }
1503 
1505  RzPrint *print = core->print;
1506  if (print->cur >= 0) {
1507  return;
1508  }
1509  int sz = rz_core_visual_prevopsz(core, core->offset + print->cur);
1510  if (sz < 1) {
1511  sz = 1;
1512  }
1513  rz_core_seek_delta(core, -sz, false);
1514  print->cur += sz;
1515  if (print->ocur != -1) {
1516  print->ocur += sz;
1517  }
1518 }
1519 
1521  RzPrint *print = core->print;
1522  bool cur_is_visible = core->offset + print->cur + 32 < print->screen_bounds;
1523  if (!cur_is_visible) {
1524  int i = 0;
1525  // XXX: ugly hack
1526  for (i = 0; i < 2; i++) {
1527  RzAsmOp op;
1528  int sz = rz_asm_disassemble(core->rasm,
1529  &op, core->block, 32);
1530  if (sz < 1) {
1531  sz = 1;
1532  }
1533  rz_core_seek_delta(core, sz, false);
1534  print->cur = RZ_MAX(print->cur - sz, 0);
1535  if (print->ocur != -1) {
1536  print->ocur = RZ_MAX(print->ocur - sz, 0);
1537  }
1538  }
1539  }
1540 }
1541 
1542 bool __handle_zoom_mode(RzCore *core, const int key) {
1543  RzPanels *panels = core->panels;
1544  rz_cons_switchbuf(false);
1545  switch (key) {
1546  case 'Q':
1547  case 'q':
1548  case 0x0d:
1549  __toggle_zoom_mode(core);
1550  break;
1551  case 'c':
1552  case 'C':
1553  case ';':
1554  case ' ':
1555  case '_':
1556  case '/':
1557  case '"':
1558  case 'A':
1559  case 'r':
1560  case '0':
1561  case '1':
1562  case '2':
1563  case '3':
1564  case '4':
1565  case '5':
1566  case '6':
1567  case '7':
1568  case '8':
1569  case '9':
1570  case 'u':
1571  case 'U':
1572  case 'b':
1573  case 'd':
1574  case 'n':
1575  case 'N':
1576  case 'g':
1577  case 'h':
1578  case 'j':
1579  case 'k':
1580  case 'J':
1581  case 'K':
1582  case 'l':
1583  case '.':
1584  case 'R':
1585  case 'p':
1586  case 'P':
1587  case 's':
1588  case 'S':
1589  case 't':
1590  case 'T':
1591  case 'x':
1592  case 'X':
1593  case ':':
1594  case '[':
1595  case ']':
1596  return false;
1597  case 9:
1598  __restore_panel_pos(panels->panel[panels->curnode]);
1599  __handle_tab_key(core, false);
1600  __save_panel_pos(panels->panel[panels->curnode]);
1601  __maximize_panel_size(panels);
1602  break;
1603  case 'Z':
1604  __restore_panel_pos(panels->panel[panels->curnode]);
1605  __handle_tab_key(core, true);
1606  __save_panel_pos(panels->panel[panels->curnode]);
1607  __maximize_panel_size(panels);
1608  break;
1609  case '?':
1610  __toggle_zoom_mode(core);
1611  __toggle_help(core);
1612  __toggle_zoom_mode(core);
1613  break;
1614  }
1615  return true;
1616 }
1617 
1619  RzPanel *p = __get_cur_panel(core->panels);
1621  return;
1622  }
1623  char buf[4095];
1624  int i;
1625  rz_line_set_prompt("[Comment]> ");
1626  strcpy(buf, "\"CC ");
1627  i = strlen(buf);
1628  if (rz_cons_fgets(buf + i, sizeof(buf) - i, 0, NULL) > 0) {
1629  ut64 addr, orig;
1630  addr = orig = core->offset;
1631  if (core->print->cur_enabled) {
1632  addr += core->print->cur;
1633  rz_core_seek_and_save(core, addr, false);
1634  }
1635  if (!strcmp(buf + i, "-")) {
1636  strcpy(buf, "CC-");
1637  } else {
1638  switch (buf[i]) {
1639  case '-':
1640  memcpy(buf, "\"CC-", 5);
1641  break;
1642  case '!':
1643  memcpy(buf, "\"CC!", 5);
1644  break;
1645  default:
1646  memcpy(buf, "\"CC ", 4);
1647  break;
1648  }
1649  strcat(buf, "\"");
1650  }
1651  if (buf[3] == ' ') {
1652  int j, len = strlen(buf);
1653  char *duped = strdup(buf);
1654  for (i = 4, j = 4; i < len; i++, j++) {
1655  char c = duped[i];
1656  if (c == '"' && i != (len - 1)) {
1657  buf[j++] = '\\';
1658  buf[j] = '"';
1659  } else {
1660  buf[j] = c;
1661  }
1662  }
1663  free(duped);
1664  }
1665  rz_core_cmd(core, buf, 1);
1666  if (core->print->cur_enabled) {
1667  rz_core_seek(core, orig, true);
1668  }
1669  }
1670  __set_refresh_by_type(core, p->model->cmd, true);
1671 }
1672 
1673 bool __handle_window_mode(RzCore *core, const int key) {
1674  RzPanels *panels = core->panels;
1675  RzPanel *cur = __get_cur_panel(panels);
1676  rz_cons_switchbuf(false);
1677  switch (key) {
1678  case 'Q':
1679  case 'q':
1680  case 'w':
1681  __toggle_window_mode(core);
1682  break;
1683  case 0x0d:
1684  __toggle_zoom_mode(core);
1685  break;
1686  case 9: // tab
1687  __handle_tab_key(core, false);
1688  break;
1689  case 'Z': // shift-tab
1690  __handle_tab_key(core, true);
1691  break;
1692  case 'e': {
1693  char *cmd = __show_status_input(core, "New command: ");
1694  if (RZ_STR_ISNOTEMPTY(cmd)) {
1695  __replace_cmd(core, cmd, cmd);
1696  }
1697  free(cmd);
1698  } break;
1699  case 'h':
1700  (void)__move_to_direction(core, LEFT);
1701  break;
1702  case 'j':
1703  (void)__move_to_direction(core, DOWN);
1704  break;
1705  case 'k':
1706  (void)__move_to_direction(core, UP);
1707  break;
1708  case 'l':
1709  (void)__move_to_direction(core, RIGHT);
1710  break;
1711  case 'H':
1712  rz_cons_switchbuf(false);
1713  __resize_panel_left(panels);
1714  break;
1715  case 'L':
1716  rz_cons_switchbuf(false);
1717  __resize_panel_right(panels);
1718  break;
1719  case 'J':
1720  rz_cons_switchbuf(false);
1721  __resize_panel_down(panels);
1722  break;
1723  case 'K':
1724  rz_cons_switchbuf(false);
1725  __resize_panel_up(panels);
1726  break;
1727  case 'n':
1728  __create_panel_input(core, cur, VERTICAL, NULL);
1729  break;
1730  case 'N':
1731  __create_panel_input(core, cur, HORIZONTAL, NULL);
1732  break;
1733  case 'X':
1734  __dismantle_del_panel(core, cur, panels->curnode);
1735  break;
1736  case '"':
1737  case ':':
1738  case ';':
1739  case '/':
1740  case 'd':
1741  case 'b':
1742  case 'p':
1743  case 'P':
1744  case 't':
1745  case 'T':
1746  case '?':
1747  case '|':
1748  case '-':
1749  return false;
1750  }
1751  return true;
1752 }
1753 
1754 bool __handle_cursor_mode(RzCore *core, const int key) {
1755  RzPanel *cur = __get_cur_panel(core->panels);
1756  RzPrint *print = core->print;
1757  char *db_val;
1758  switch (key) {
1759  case ':':
1760  case ';':
1761  case 'd':
1762  case 'h':
1763  case 'j':
1764  case 'k':
1765  case 'J':
1766  case 'K':
1767  case 'l':
1768  case 'm':
1769  case 'Z':
1770  case '"':
1771  case 9:
1772  return false;
1773  case 'g':
1774  cur->view->curpos = 0;
1775  __reset_scroll_pos(cur);
1776  cur->view->refresh = true;
1777  break;
1778  case ']':
1780  rz_config_set_i(core->config, "hex.cols", rz_config_get_i(core->config, "hex.cols") + 1);
1781  } else {
1782  int cmtcol = rz_config_get_i(core->config, "asm.cmt.col");
1783  rz_config_set_i(core->config, "asm.cmt.col", cmtcol + 2);
1784  }
1785  cur->view->refresh = true;
1786  break;
1787  case '[':
1789  rz_config_set_i(core->config, "hex.cols", rz_config_get_i(core->config, "hex.cols") - 1);
1790  } else {
1791  int cmtcol = rz_config_get_i(core->config, "asm.cmt.col");
1792  if (cmtcol > 2) {
1793  rz_config_set_i(core->config, "asm.cmt.col", cmtcol - 2);
1794  }
1795  }
1796  cur->view->refresh = true;
1797  break;
1798  case 'Q':
1799  case 'q':
1800  case 'c':
1801  __set_cursor(core, !print->cur_enabled);
1802  cur->view->refresh = true;
1803  break;
1804  case 'w':
1805  __toggle_window_mode(core);
1806  __set_cursor(core, false);
1807  cur->view->refresh = true;
1808  break;
1809  case 'i':
1810  __insert_value(core);
1811  break;
1812  case '*':
1814  rz_core_reg_set_by_role_or_name(core, "PC", core->offset + print->cur);
1815  __set_panel_addr(core, cur, core->offset + print->cur);
1816  }
1817  break;
1818  case '-':
1819  db_val = __search_db(core, "Breakpoints");
1820  if (__check_panel_type(cur, db_val)) {
1821  __cursor_del_breakpoints(core, cur);
1822  free(db_val);
1823  break;
1824  }
1825  free(db_val);
1826  return false;
1827  case 'x':
1828  __handle_refs(core, cur, __parse_string_on_cursor(core, cur, cur->view->curpos));
1829  break;
1830  case 0x0d:
1831  __jmp_to_cursor_addr(core, cur);
1832  break;
1833  case 'b':
1834  __set_breakpoints_on_cursor(core, cur);
1835  break;
1836  case 'H':
1837  cur->view->curpos = cur->view->sy;
1838  cur->view->refresh = true;
1839  break;
1840  }
1841  return true;
1842 }
1843 
1844 bool __handle_mouse(RzCore *core, RzPanel *panel, int *key) {
1845  const int MENU_Y = 1;
1846  RzPanels *panels = core->panels;
1847  if (__drag_and_resize(core)) {
1848  return true;
1849  }
1850  if (!*key) {
1851  int x, y;
1852  if (rz_cons_get_click(&x, &y)) {
1853  if (y == MENU_Y && __handle_mouse_on_top(core, x, y)) {
1854  return true;
1855  }
1856  if (panels->mode == PANEL_MODE_MENU) {
1857  __handle_mouse_on_menu(core, x, y);
1858  return true;
1859  }
1860  if (__handle_mouse_on_X(core, x, y)) {
1861  return true;
1862  }
1863  if (__check_if_mouse_x_illegal(core, x) || __check_if_mouse_y_illegal(core, y)) {
1864  panels->mouse_on_edge_x = false;
1865  panels->mouse_on_edge_y = false;
1866  return true;
1867  }
1868  panels->mouse_on_edge_x = __check_if_mouse_x_on_edge(core, x, y);
1869  panels->mouse_on_edge_y = __check_if_mouse_y_on_edge(core, x, y);
1870  if (panels->mouse_on_edge_x || panels->mouse_on_edge_y) {
1871  return true;
1872  }
1873  if (__handle_mouse_on_panel(core, panel, x, y, key)) {
1874  return true;
1875  }
1876  int h, w = rz_cons_get_size(&h);
1877  if (y == h) {
1878  RzPanel *p = __get_cur_panel(panels);
1879  __split_panel_horizontal(core, p, p->model->title, p->model->cmd);
1880  } else if (x == w) {
1881  RzPanel *p = __get_cur_panel(panels);
1882  __split_panel_vertical(core, p, p->model->title, p->model->cmd);
1883  }
1884  } else {
1885  return false;
1886  }
1887  }
1888  if (*key == INT8_MAX) {
1889  *key = '"';
1890  return false;
1891  }
1892  return false;
1893 }
1894 
1895 bool __handle_mouse_on_top(RzCore *core, int x, int y) {
1896  RzPanels *panels = core->panels;
1897  char *word = get_word_from_canvas(core, panels, x, y);
1898  int i;
1899  for (i = 0; i < COUNT(menus); i++) {
1900  if (!strcmp(word, menus[i])) {
1901  __set_mode(core, PANEL_MODE_MENU);
1902  __clear_panels_menu(core);
1903  RzPanelsMenu *menu = panels->panels_menu;
1904  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
1905  parent->selectedIndex = i;
1906  RzPanelsMenuItem *child = parent->sub[parent->selectedIndex];
1907  (void)(child->cb(core));
1908  free(word);
1909  return true;
1910  }
1911  }
1912  if (!strcmp(word, "Tab")) {
1913  __handle_tab_new(core);
1914  free(word);
1915  return true;
1916  }
1917  if (word[0] == '[' && word[1] && word[2] == ']') {
1918  return true;
1919  }
1920  if (atoi(word)) {
1921  __handle_tab_nth(core, word[0]);
1922  return true;
1923  }
1924  return false;
1925 }
1926 
1927 static bool __handle_mouse_on_X(RzCore *core, int x, int y) {
1928  RzPanels *panels = core->panels;
1929  const int idx = __get_panel_idx_in_pos(core, x, y);
1930  char *word = get_word_from_canvas(core, panels, x, y);
1931  if (idx == -1) {
1932  return false;
1933  }
1934  RzPanel *ppos = __get_panel(panels, idx);
1935  const int TITLE_Y = ppos->view->pos.y + 2;
1936  if (y == TITLE_Y && strcmp(word, " X ")) {
1937  int fx = ppos->view->pos.x;
1938  int fX = fx + ppos->view->pos.w;
1939  __set_curnode(core, idx);
1940  __set_refresh_all(core, true, true);
1941  if (x > (fX - 13) && x < fX) {
1942  __toggle_cache(core, __get_cur_panel(panels));
1943  } else if (x > fx && x < (fx + 5)) {
1944  __dismantle_del_panel(core, ppos, idx);
1945  } else {
1946  __create_almighty(core, __get_panel(panels, 0), panels->almighty_db);
1948  }
1949  free(word);
1950  return true;
1951  }
1952  free(word);
1953  return false;
1954 }
1955 
1956 static bool __handle_mouse_on_panel(RzCore *core, RzPanel *panel, int x, int y, int *key) {
1957  RzPanels *panels = core->panels;
1958  int h;
1959  (void)rz_cons_get_size(&h);
1960  const int idx = __get_panel_idx_in_pos(core, x, y);
1961  char *word = get_word_from_canvas(core, panels, x, y);
1962  if (idx == -1) {
1963  return false;
1964  }
1965  __set_curnode(core, idx);
1966  __set_refresh_all(core, true, true);
1967  RzPanel *ppos = __get_panel(panels, idx);
1968  if (word) {
1969  const ut64 addr = rz_num_math(core->num, word);
1970  if (__check_panel_type(panel, PANEL_CMD_FUNCTION) &&
1971  addr > 0) {
1972  rz_core_seek_and_save(core, addr, true);
1974  }
1975  rz_flag_set(core->flags, "panel.addr", addr, 1);
1976  rz_config_set(core->config, "scr.highlight", word);
1977 #if 1
1978  // TODO implement sync
1979  {
1980  ut64 addr = rz_num_math(core->num, word);
1981  if (addr > 0) {
1982  // __set_panel_addr (core, cur, addr);
1983  __seek_all(core, addr);
1984  }
1985  }
1986 #endif
1987  free(word);
1988  }
1989  if (x >= ppos->view->pos.x && x < ppos->view->pos.x + 4) {
1990  *key = 'c';
1991  return false;
1992  }
1993  return true;
1994 }
1995 
1996 void __handle_mouse_on_menu(RzCore *core, int x, int y) {
1997  RzPanels *panels = core->panels;
1998  char *word = get_word_from_canvas_for_menu(core, panels, x, y);
1999  RzPanelsMenu *menu = panels->panels_menu;
2000  int i, d = menu->depth - 1;
2001  while (d) {
2002  RzPanelsMenuItem *parent = menu->history[d--];
2003  for (i = 0; i < parent->n_sub; i++) {
2004  if (!strcmp(word, parent->sub[i]->name)) {
2005  parent->selectedIndex = i;
2006  (void)(parent->sub[parent->selectedIndex]->cb(core));
2007  __update_menu_contents(core, menu, parent);
2008  free(word);
2009  return;
2010  }
2011  }
2012  __del_menu(core);
2013  }
2014  __clear_panels_menu(core);
2016  __get_cur_panel(panels)->view->refresh = true;
2017  free(word);
2018 }
2019 
2021  RzPanels *panels = core->panels;
2022  if (panels->mouse_on_edge_x || panels->mouse_on_edge_y) {
2023  int x, y;
2024  if (rz_cons_get_click(&x, &y)) {
2025  if (panels->mouse_on_edge_x) {
2026  __update_edge_x(core, x - panels->mouse_orig_x);
2027  }
2028  if (panels->mouse_on_edge_y) {
2029  __update_edge_y(core, y - panels->mouse_orig_y);
2030  }
2031  }
2032  panels->mouse_on_edge_x = false;
2033  panels->mouse_on_edge_y = false;
2034  return true;
2035  }
2036  return false;
2037 }
2038 
2039 void __jmp_to_cursor_addr(RzCore *core, RzPanel *panel) {
2040  ut64 addr = __parse_string_on_cursor(core, panel, panel->view->curpos);
2041  if (addr == UT64_MAX) {
2042  return;
2043  }
2044  core->offset = addr;
2046 }
2047 
2049  RzListIter *iter;
2051  int i = 0;
2052  rz_list_foreach (core->dbg->bp->bps, iter, b) {
2053  if (panel->view->curpos == i++) {
2054  rz_bp_del(core->dbg->bp, b->addr);
2055  }
2056  }
2057 }
2058 
2060  RzPanel *cur = __get_cur_panel(core->panels);
2062  return;
2063  }
2064  int act = __show_status(core, "Visual Mark s:set -:remove \':use: ");
2065  switch (act) {
2066  case 's':
2067  __add_visual_mark(core);
2068  break;
2069  case '-':
2070  rz_cons_gotoxy(0, 0);
2071  if (rz_core_visual_mark_dump(core)) {
2072  rz_cons_printf(RZ_CONS_CLEAR_LINE "Remove a shortcut key from the list\n");
2073  rz_cons_flush();
2074  int ch = rz_cons_readchar();
2075  rz_core_visual_mark_del(core, ch);
2076  }
2077  break;
2078  case '\'':
2079  rz_cons_gotoxy(0, 0);
2080  if (rz_core_visual_mark_dump(core)) {
2081  rz_cons_flush();
2082  int ch = rz_cons_readchar();
2083  rz_core_visual_mark_seek(core, ch);
2084  __set_panel_addr(core, cur, core->offset);
2085  }
2086  }
2087  return;
2088 }
2089 
2090 void __handle_refs(RzCore *core, RzPanel *panel, ut64 tmp) {
2091  if (tmp != UT64_MAX) {
2092  core->offset = tmp;
2093  }
2094  int key = __show_status(core, "xrefs:x refs:X ");
2095  switch (key) {
2096  case 'x':
2097  (void)rz_core_visual_xrefs(core, true, false);
2098  break;
2099  case 'X':
2100  (void)rz_core_visual_xrefs(core, false, false);
2101  break;
2102  default:
2103  break;
2104  }
2106  __set_panel_addr(core, panel, core->offset);
2107  return;
2108  }
2110 }
2111 
2113  char *msg = rz_str_newf(RZ_CONS_CLEAR_LINE "Set shortcut key for 0x%" PFMT64x ": ", core->offset);
2114  int ch = __show_status(core, msg);
2115  free(msg);
2116  rz_core_visual_mark(core, ch);
2117 }
2118 
2120  RzPanel *cur = __get_cur_panel(panels);
2121  int i, cx0, cx1, cy0, cy1, tx0, tx1, ty0, ty1, cur1 = 0, cur2 = 0, cur3 = 0, cur4 = 0;
2122  cx0 = cur->view->pos.x;
2123  cx1 = cur->view->pos.x + cur->view->pos.w - 1;
2124  cy0 = cur->view->pos.y;
2125  cy1 = cur->view->pos.y + cur->view->pos.h - 1;
2126  RzPanel **targets1 = malloc(sizeof(RzPanel *) * panels->n_panels);
2127  RzPanel **targets2 = malloc(sizeof(RzPanel *) * panels->n_panels);
2128  RzPanel **targets3 = malloc(sizeof(RzPanel *) * panels->n_panels);
2129  RzPanel **targets4 = malloc(sizeof(RzPanel *) * panels->n_panels);
2130  if (!targets1 || !targets2 || !targets3 || !targets4) {
2131  goto beach;
2132  }
2133  for (i = 0; i < panels->n_panels; i++) {
2134  if (i == panels->curnode) {
2135  continue;
2136  }
2137  RzPanel *p = __get_panel(panels, i);
2138  tx0 = p->view->pos.x;
2139  tx1 = p->view->pos.x + p->view->pos.w - 1;
2140  ty0 = p->view->pos.y;
2141  ty1 = p->view->pos.y + p->view->pos.h - 1;
2142  if (ty0 == cy0 && ty1 == cy1 && tx1 == cx0 && tx1 - PANEL_CONFIG_RESIZE_W > tx0) {
2143  p->view->pos.w -= PANEL_CONFIG_RESIZE_W;
2144  cur->view->pos.x -= PANEL_CONFIG_RESIZE_W;
2145  cur->view->pos.w += PANEL_CONFIG_RESIZE_W;
2146  p->view->refresh = true;
2147  cur->view->refresh = true;
2148  goto beach;
2149  }
2150  bool y_included = (ty1 >= cy0 && cy1 >= ty1) || (ty0 >= cy0 && cy1 >= ty0);
2151  if (tx1 == cx0 && y_included) {
2152  if (tx1 - PANEL_CONFIG_RESIZE_W > tx0) {
2153  targets1[cur1++] = p;
2154  }
2155  }
2156  if (tx0 == cx1 && y_included) {
2157  if (tx0 - PANEL_CONFIG_RESIZE_W > cx0) {
2158  targets3[cur3++] = p;
2159  }
2160  }
2161  if (tx0 == cx0) {
2162  if (tx0 - PANEL_CONFIG_RESIZE_W > 0) {
2163  targets2[cur2++] = p;
2164  }
2165  }
2166  if (tx1 == cx1) {
2167  if (tx1 + PANEL_CONFIG_RESIZE_W < panels->can->w) {
2168  targets4[cur4++] = p;
2169  }
2170  }
2171  }
2172  if (cur1 > 0) {
2173  for (i = 0; i < cur1; i++) {
2174  targets1[i]->view->pos.w -= PANEL_CONFIG_RESIZE_W;
2175  targets1[i]->view->refresh = true;
2176  }
2177  for (i = 0; i < cur2; i++) {
2178  targets2[i]->view->pos.x -= PANEL_CONFIG_RESIZE_W;
2179  targets2[i]->view->pos.w += PANEL_CONFIG_RESIZE_W;
2180  targets2[i]->view->refresh = true;
2181  }
2182  cur->view->pos.x -= PANEL_CONFIG_RESIZE_W;
2183  cur->view->pos.w += PANEL_CONFIG_RESIZE_W;
2184  cur->view->refresh = true;
2185  } else if (cur3 > 0) {
2186  for (i = 0; i < cur3; i++) {
2187  targets3[i]->view->pos.w += PANEL_CONFIG_RESIZE_W;
2188  targets3[i]->view->pos.x -= PANEL_CONFIG_RESIZE_W;
2189  targets3[i]->view->refresh = true;
2190  }
2191  for (i = 0; i < cur4; i++) {
2192  targets4[i]->view->pos.w -= PANEL_CONFIG_RESIZE_W;
2193  targets4[i]->view->refresh = true;
2194  }
2195  cur->view->pos.w -= PANEL_CONFIG_RESIZE_W;
2196  cur->view->refresh = true;
2197  }
2198 beach:
2199  free(targets1);
2200  free(targets2);
2201  free(targets3);
2202  free(targets4);
2203 }
2204 
2206  RzPanel *cur = __get_cur_panel(panels);
2207  int i, tx0, tx1, ty0, ty1, cur1 = 0, cur2 = 0, cur3 = 0, cur4 = 0;
2208  int cx0 = cur->view->pos.x;
2209  int cx1 = cur->view->pos.x + cur->view->pos.w - 1;
2210  int cy0 = cur->view->pos.y;
2211  int cy1 = cur->view->pos.y + cur->view->pos.h - 1;
2212  RzPanel **targets1 = malloc(sizeof(RzPanel *) * panels->n_panels);
2213  RzPanel **targets2 = malloc(sizeof(RzPanel *) * panels->n_panels);
2214  RzPanel **targets3 = malloc(sizeof(RzPanel *) * panels->n_panels);
2215  RzPanel **targets4 = malloc(sizeof(RzPanel *) * panels->n_panels);
2216  if (!targets1 || !targets2 || !targets3 || !targets4) {
2217  goto beach;
2218  }
2219  for (i = 0; i < panels->n_panels; i++) {
2220  if (i == panels->curnode) {
2221  continue;
2222  }
2223  RzPanel *p = __get_panel(panels, i);
2224  tx0 = p->view->pos.x;
2225  tx1 = p->view->pos.x + p->view->pos.w - 1;
2226  ty0 = p->view->pos.y;
2227  ty1 = p->view->pos.y + p->view->pos.h - 1;
2228  if (ty0 == cy0 && ty1 == cy1 && tx0 == cx1 && tx0 + PANEL_CONFIG_RESIZE_W < tx1) {
2229  p->view->pos.x += PANEL_CONFIG_RESIZE_W;
2230  p->view->pos.w -= PANEL_CONFIG_RESIZE_W;
2231  cur->view->pos.w += PANEL_CONFIG_RESIZE_W;
2232  p->view->refresh = true;
2233  cur->view->refresh = true;
2234  goto beach;
2235  }
2236  bool y_included = (ty1 >= cy0 && cy1 >= ty1) || (ty0 >= cy0 && cy1 >= ty0);
2237  if (tx1 == cx0 && y_included) {
2238  if (tx1 + PANEL_CONFIG_RESIZE_W < cx1) {
2239  targets1[cur1++] = p;
2240  }
2241  }
2242  if (tx0 == cx1 && y_included) {
2243  if (tx0 + PANEL_CONFIG_RESIZE_W < tx1) {
2244  targets3[cur3++] = p;
2245  }
2246  }
2247  if (tx0 == cx0) {
2248  if (tx0 + PANEL_CONFIG_RESIZE_W < tx1) {
2249  targets2[cur2++] = p;
2250  }
2251  }
2252  if (tx1 == cx1) {
2253  if (tx1 + PANEL_CONFIG_RESIZE_W < panels->can->w) {
2254  targets4[cur4++] = p;
2255  }
2256  }
2257  }
2258  if (cur3 > 0) {
2259  for (i = 0; i < cur3; i++) {
2260  targets3[i]->view->pos.x += PANEL_CONFIG_RESIZE_W;
2261  targets3[i]->view->pos.w -= PANEL_CONFIG_RESIZE_W;
2262  targets3[i]->view->refresh = true;
2263  }
2264  for (i = 0; i < cur4; i++) {
2265  targets4[i]->view->pos.w += PANEL_CONFIG_RESIZE_W;
2266  targets4[i]->view->refresh = true;
2267  }
2268  cur->view->pos.w += PANEL_CONFIG_RESIZE_W;
2269  cur->view->refresh = true;
2270  } else if (cur1 > 0) {
2271  for (i = 0; i < cur1; i++) {
2272  targets1[i]->view->pos.w += PANEL_CONFIG_RESIZE_W;
2273  targets1[i]->view->refresh = true;
2274  }
2275  for (i = 0; i < cur2; i++) {
2276  targets2[i]->view->pos.x += PANEL_CONFIG_RESIZE_W;
2277  targets2[i]->view->pos.w -= PANEL_CONFIG_RESIZE_W;
2278  targets2[i]->view->refresh = true;
2279  }
2280  cur->view->pos.x += PANEL_CONFIG_RESIZE_W;
2281  cur->view->pos.w -= PANEL_CONFIG_RESIZE_W;
2282  cur->view->refresh = true;
2283  }
2284 beach:
2285  free(targets1);
2286  free(targets2);
2287  free(targets3);
2288  free(targets4);
2289 }
2290 
2292  RzPanel *cur = __get_cur_panel(panels);
2293  int i, tx0, tx1, ty0, ty1, cur1 = 0, cur2 = 0, cur3 = 0, cur4 = 0;
2294  int cx0 = cur->view->pos.x;
2295  int cx1 = cur->view->pos.x + cur->view->pos.w - 1;
2296  int cy0 = cur->view->pos.y;
2297  int cy1 = cur->view->pos.y + cur->view->pos.h - 1;
2298  RzPanel **targets1 = malloc(sizeof(RzPanel *) * panels->n_panels);
2299  RzPanel **targets2 = malloc(sizeof(RzPanel *) * panels->n_panels);
2300  RzPanel **targets3 = malloc(sizeof(RzPanel *) * panels->n_panels);
2301  RzPanel **targets4 = malloc(sizeof(RzPanel *) * panels->n_panels);
2302  if (!targets1 || !targets2 || !targets3 || !targets4) {
2303  goto beach;
2304  }
2305  for (i = 0; i < panels->n_panels; i++) {
2306  if (i == panels->curnode) {
2307  continue;
2308  }
2309  RzPanel *p = __get_panel(panels, i);
2310  tx0 = p->view->pos.x;
2311  tx1 = p->view->pos.x + p->view->pos.w - 1;
2312  ty0 = p->view->pos.y;
2313  ty1 = p->view->pos.y + p->view->pos.h - 1;
2314  if (tx0 == cx0 && tx1 == cx1 && ty1 == cy0 && ty1 - PANEL_CONFIG_RESIZE_H > ty0) {
2315  p->view->pos.h -= PANEL_CONFIG_RESIZE_H;
2316  cur->view->pos.y -= PANEL_CONFIG_RESIZE_H;
2317  cur->view->pos.h += PANEL_CONFIG_RESIZE_H;
2318  p->view->refresh = true;
2319  cur->view->refresh = true;
2320  goto beach;
2321  }
2322  bool x_included = (tx1 >= cx0 && cx1 >= tx1) || (tx0 >= cx0 && cx1 >= tx0);
2323  if (ty1 == cy0 && x_included) {
2324  if (ty1 - PANEL_CONFIG_RESIZE_H > ty0) {
2325  targets1[cur1++] = p;
2326  }
2327  }
2328  if (ty0 == cy1 && x_included) {
2329  if (ty0 - PANEL_CONFIG_RESIZE_H > cy0) {
2330  targets3[cur3++] = p;
2331  }
2332  }
2333  if (ty0 == cy0) {
2334  if (ty0 - PANEL_CONFIG_RESIZE_H > 0) {
2335  targets2[cur2++] = p;
2336  }
2337  }
2338  if (ty1 == cy1) {
2339  if (ty1 - PANEL_CONFIG_RESIZE_H > ty0) {
2340  targets4[cur4++] = p;
2341  }
2342  }
2343  }
2344  if (cur1 > 0) {
2345  for (i = 0; i < cur1; i++) {
2346  targets1[i]->view->pos.h -= PANEL_CONFIG_RESIZE_H;
2347  targets1[i]->view->refresh = true;
2348  }
2349  for (i = 0; i < cur2; i++) {
2350  targets2[i]->view->pos.y -= PANEL_CONFIG_RESIZE_H;
2351  targets2[i]->view->pos.h += PANEL_CONFIG_RESIZE_H;
2352  targets2[i]->view->refresh = true;
2353  }
2354  cur->view->pos.y -= PANEL_CONFIG_RESIZE_H;
2355  cur->view->pos.h += PANEL_CONFIG_RESIZE_H;
2356  cur->view->refresh = true;
2357  } else if (cur3 > 0) {
2358  for (i = 0; i < cur3; i++) {
2359  targets3[i]->view->pos.h += PANEL_CONFIG_RESIZE_H;
2360  targets3[i]->view->pos.y -= PANEL_CONFIG_RESIZE_H;
2361  targets3[i]->view->refresh = true;
2362  }
2363  for (i = 0; i < cur4; i++) {
2364  targets4[i]->view->pos.h -= PANEL_CONFIG_RESIZE_H;
2365  targets4[i]->view->refresh = true;
2366  }
2367  cur->view->pos.h -= PANEL_CONFIG_RESIZE_H;
2368  cur->view->refresh = true;
2369  }
2370 beach:
2371  free(targets1);
2372  free(targets2);
2373  free(targets3);
2374  free(targets4);
2375 }
2376 
2377 void __move_panel_to_dir(RzCore *core, RzPanel *panel, int src) {
2378  RzPanels *panels = core->panels;
2379  __dismantle_panel(panels, panel);
2380  int key = __show_status(core, "Move the current panel to direction (h/j/k/l): ");
2382  __set_refresh_all(core, false, true);
2383  switch (key) {
2384  case 'h':
2385  __move_panel_to_left(core, panel, src);
2386  break;
2387  case 'l':
2388  __move_panel_to_right(core, panel, src);
2389  break;
2390  case 'k':
2391  __move_panel_to_up(core, panel, src);
2392  break;
2393  case 'j':
2394  __move_panel_to_down(core, panel, src);
2395  break;
2396  default:
2397  break;
2398  }
2399 }
2400 
2401 void __move_panel_to_left(RzCore *core, RzPanel *panel, int src) {
2402  RzPanels *panels = core->panels;
2404  panels->panel[0] = panel;
2405  int h, w = rz_cons_get_size(&h);
2406  int p_w = w - panels->columnWidth;
2407  p_w /= 2;
2408  int new_w = w - p_w;
2409  __set_geometry(&panel->view->pos, 0, 1, p_w + 1, h - 1);
2410  int i = 1;
2411  for (; i < panels->n_panels; i++) {
2412  RzPanel *tmp = __get_panel(panels, i);
2413  int t_x = (int)(((double)tmp->view->pos.x / (double)w) * (double)new_w + p_w);
2414  int t_w = (int)(((double)tmp->view->pos.w / (double)w) * (double)new_w + 1);
2415  __set_geometry(&tmp->view->pos, t_x, tmp->view->pos.y, t_w, tmp->view->pos.h);
2416  }
2417  __fix_layout(core);
2418  __set_curnode(core, 0);
2419 }
2420 
2421 void __move_panel_to_right(RzCore *core, RzPanel *panel, int src) {
2422  RzPanels *panels = core->panels;
2424  panels->panel[panels->n_panels - 1] = panel;
2425  int h, w = rz_cons_get_size(&h);
2426  int p_w = w - panels->columnWidth;
2427  p_w /= 2;
2428  int p_x = w - p_w;
2429  __set_geometry(&panel->view->pos, p_x - 1, 1, p_w + 1, h - 1);
2430  int new_w = w - p_w;
2431  int i = 0;
2432  for (; i < panels->n_panels - 1; i++) {
2433  RzPanel *tmp = __get_panel(panels, i);
2434  int t_x = ((double)tmp->view->pos.x / (double)w) * (double)new_w;
2435  int t_w = ((double)tmp->view->pos.w / (double)w) * (double)new_w + 1;
2436  __set_geometry(&tmp->view->pos, t_x, tmp->view->pos.y, t_w, tmp->view->pos.h);
2437  }
2438  __fix_layout(core);
2439  __set_curnode(core, panels->n_panels - 1);
2440 }
2441 
2442 void __move_panel_to_up(RzCore *core, RzPanel *panel, int src) {
2443  RzPanels *panels = core->panels;
2445  panels->panel[0] = panel;
2446  int h, w = rz_cons_get_size(&h);
2447  int p_h = h / 2;
2448  int new_h = h - p_h;
2449  __set_geometry(&panel->view->pos, 0, 1, w, p_h - 1);
2450  int i = 1;
2451  for (; i < panels->n_panels; i++) {
2452  RzPanel *tmp = __get_panel(panels, i);
2453  int t_y = ((double)tmp->view->pos.y / (double)h) * (double)new_h + p_h;
2454  int t_h = ((double)tmp->view->pos.h / (double)h) * (double)new_h + 1;
2455  __set_geometry(&tmp->view->pos, tmp->view->pos.x, t_y, tmp->view->pos.w, t_h);
2456  }
2457  __fix_layout(core);
2458  __set_curnode(core, 0);
2459 }
2460 
2461 void __move_panel_to_down(RzCore *core, RzPanel *panel, int src) {
2462  RzPanels *panels = core->panels;
2464  panels->panel[panels->n_panels - 1] = panel;
2465  int h, w = rz_cons_get_size(&h);
2466  int p_h = h / 2;
2467  int new_h = h - p_h;
2468  __set_geometry(&panel->view->pos, 0, new_h, w, p_h);
2469  size_t i = 0;
2470  for (; i < panels->n_panels - 1; i++) {
2471  RzPanel *tmp = __get_panel(panels, i);
2472  const size_t t_y = (tmp->view->pos.y * new_h / h) + 1;
2473  const size_t t_h = (tmp->view->edge & (1 << PANEL_EDGE_BOTTOM)) ? new_h - t_y : (tmp->view->pos.h * new_h / h);
2474  __set_geometry(&tmp->view->pos, tmp->view->pos.x, t_y, tmp->view->pos.w, t_h);
2475  }
2476  __fix_layout(core);
2477  __set_curnode(core, panels->n_panels - 1);
2478 }
2479 
2480 void __fix_layout(RzCore *core) {
2481  __fix_layout_w(core);
2482  __fix_layout_h(core);
2483 }
2484 
2485 void __fix_layout_w(RzCore *core) {
2486  RzPanels *panels = core->panels;
2487  RzList *list = rz_list_new();
2488  int i = 0;
2489  for (; i < panels->n_panels - 1; i++) {
2490  RzPanel *p = __get_panel(panels, i);
2491  int64_t t = p->view->pos.x + p->view->pos.w;
2492  rz_list_append(list, (void *)(size_t)t);
2493  }
2494  RzListIter *iter;
2495  for (i = 0; i < panels->n_panels; i++) {
2496  RzPanel *p = __get_panel(panels, i);
2497  int tx = p->view->pos.x;
2498  if (!tx) {
2499  continue;
2500  }
2501  int min = INT8_MAX;
2502  int target_num = INT8_MAX;
2503  bool found = false;
2504  void *num = NULL;
2505  rz_list_foreach (list, iter, num) {
2506  int64_t numi = (int64_t)(size_t)num;
2507  if (numi - 1 == tx) {
2508  found = true;
2509  break;
2510  }
2511  int sub = numi - tx;
2512  if (min > RZ_ABS(sub)) {
2513  min = RZ_ABS(sub);
2514  target_num = numi;
2515  }
2516  }
2517  if (!found) {
2518  int t = p->view->pos.x - target_num + 1;
2519  p->view->pos.x = target_num - 1;
2520  p->view->pos.w += t;
2521  }
2522  }
2523 }
2524 
2525 void __fix_layout_h(RzCore *core) {
2526  RzPanels *panels = core->panels;
2527  RzList *list = rz_list_new();
2528  int h;
2529  (void)rz_cons_get_size(&h);
2530  int i = 0;
2531  for (; i < panels->n_panels - 1; i++) {
2532  RzPanel *p = __get_panel(panels, i);
2533  int64_t t = p->view->pos.y + p->view->pos.h;
2534  rz_list_append(list, (void *)(size_t)t);
2535  }
2536  RzListIter *iter;
2537  for (i = 0; i < panels->n_panels; i++) {
2538  RzPanel *p = __get_panel(panels, i);
2539  int ty = p->view->pos.y;
2540  int th = p->view->pos.h;
2541  if (ty == 1 || th == (h - 1)) {
2542  continue;
2543  }
2544  int min = INT8_MAX;
2545  int target_num = INT8_MAX;
2546  bool found = false;
2547  void *num = NULL;
2548  rz_list_foreach (list, iter, num) {
2549  int64_t numi = (int64_t)(size_t)num;
2550  if (numi - 1 == ty) {
2551  found = true;
2552  break;
2553  }
2554  int sub = numi - ty;
2555  if (min > RZ_ABS(sub)) {
2556  min = RZ_ABS(sub);
2557  target_num = numi;
2558  }
2559  }
2560  if (!found) {
2561  int t = p->view->pos.y - target_num + 1;
2562  p->view->pos.y = target_num - 1;
2563  p->view->pos.h += t;
2564  }
2565  }
2566  rz_list_free(list);
2567 }
2568 
2570  RzPanel *cur = __get_cur_panel(panels);
2571  int i, tx0, tx1, ty0, ty1, cur1 = 0, cur2 = 0, cur3 = 0, cur4 = 0;
2572  int cx0 = cur->view->pos.x;
2573  int cx1 = cur->view->pos.x + cur->view->pos.w - 1;
2574  int cy0 = cur->view->pos.y;
2575  int cy1 = cur->view->pos.y + cur->view->pos.h - 1;
2576  RzPanel **targets1 = malloc(sizeof(RzPanel *) * panels->n_panels);
2577  RzPanel **targets2 = malloc(sizeof(RzPanel *) * panels->n_panels);
2578  RzPanel **targets3 = malloc(sizeof(RzPanel *) * panels->n_panels);
2579  RzPanel **targets4 = malloc(sizeof(RzPanel *) * panels->n_panels);
2580  if (!targets1 || !targets2 || !targets3 || !targets4) {
2581  goto beach;
2582  }
2583  for (i = 0; i < panels->n_panels; i++) {
2584  if (i == panels->curnode) {
2585  continue;
2586  }
2587  RzPanel *p = __get_panel(panels, i);
2588  tx0 = p->view->pos.x;
2589  tx1 = p->view->pos.x + p->view->pos.w - 1;
2590  ty0 = p->view->pos.y;
2591  ty1 = p->view->pos.y + p->view->pos.h - 1;
2592  if (tx0 == cx0 && tx1 == cx1 && ty0 == cy1 && ty0 + PANEL_CONFIG_RESIZE_H < ty1) {
2593  p->view->pos.y += PANEL_CONFIG_RESIZE_H;
2594  p->view->pos.h -= PANEL_CONFIG_RESIZE_H;
2595  cur->view->pos.h += PANEL_CONFIG_RESIZE_H;
2596  p->view->refresh = true;
2597  cur->view->refresh = true;
2598  goto beach;
2599  }
2600  bool x_included = (tx1 >= cx0 && cx1 >= tx1) || (tx0 >= cx0 && cx1 >= tx0);
2601  if (ty1 == cy0 && x_included) {
2602  if (ty1 + PANEL_CONFIG_RESIZE_H < cy1) {
2603  targets1[cur1++] = p;
2604  }
2605  }
2606  if (ty0 == cy1 && x_included) {
2607  if (ty0 + PANEL_CONFIG_RESIZE_H < ty1) {
2608  targets3[cur3++] = p;
2609  }
2610  }
2611  if (ty0 == cy0) {
2612  if (ty0 + PANEL_CONFIG_RESIZE_H < ty1) {
2613  targets2[cur2++] = p;
2614  }
2615  }
2616  if (ty1 == cy1) {
2617  if (ty1 + PANEL_CONFIG_RESIZE_H < panels->can->h) {
2618  targets4[cur4++] = p;
2619  }
2620  }
2621  }
2622  if (cur3 > 0) {
2623  for (i = 0; i < cur3; i++) {
2624  targets3[i]->view->pos.h -= PANEL_CONFIG_RESIZE_H;
2625  targets3[i]->view->pos.y += PANEL_CONFIG_RESIZE_H;
2626  targets3[i]->view->refresh = true;
2627  }
2628  for (i = 0; i < cur4; i++) {
2629  targets4[i]->view->pos.h += PANEL_CONFIG_RESIZE_H;
2630  targets4[i]->view->refresh = true;
2631  }
2632  cur->view->pos.h += PANEL_CONFIG_RESIZE_H;
2633  cur->view->refresh = true;
2634  } else if (cur1 > 0) {
2635  for (i = 0; i < cur1; i++) {
2636  targets1[i]->view->pos.h += PANEL_CONFIG_RESIZE_H;
2637  targets1[i]->view->refresh = true;
2638  }
2639  for (i = 0; i < cur2; i++) {
2640  targets2[i]->view->pos.y += PANEL_CONFIG_RESIZE_H;
2641  targets2[i]->view->pos.h -= PANEL_CONFIG_RESIZE_H;
2642  targets2[i]->view->refresh = true;
2643  }
2644  cur->view->pos.y += PANEL_CONFIG_RESIZE_H;
2645  cur->view->pos.h -= PANEL_CONFIG_RESIZE_H;
2646  cur->view->refresh = true;
2647  }
2648 beach:
2649  free(targets1);
2650  free(targets2);
2651  free(targets3);
2652  free(targets4);
2653 }
2654 
2655 void __del_panel(RzCore *core, int pi) {
2656  int i;
2657  RzPanels *panels = core->panels;
2658  RzPanel *tmp = __get_panel(panels, pi);
2659  if (!tmp) {
2660  return;
2661  }
2662  for (i = pi; i < (panels->n_panels - 1); i++) {
2663  panels->panel[i] = panels->panel[i + 1];
2664  }
2665  panels->panel[panels->n_panels - 1] = tmp;
2666  panels->n_panels--;
2667  __set_curnode(core, panels->curnode);
2668 }
2669 
2670 void __dismantle_del_panel(RzCore *core, RzPanel *p, int pi) {
2671  RzPanels *panels = core->panels;
2672  if (panels->n_panels <= 1) {
2673  return;
2674  }
2675  __dismantle_panel(panels, p);
2676  __del_panel(core, pi);
2677 }
2678 
2680  RzPanels *panels = core->panels;
2681  int i;
2682  for (i = 1; i < panels->n_panels; i++) {
2683  RzPanel *panel = __get_panel(panels, i);
2684  if (panel->view->pos.w < 2) {
2685  __del_panel(core, i);
2686  __del_invalid_panels(core);
2687  break;
2688  }
2689  if (panel->view->pos.h < 2) {
2690  __del_panel(core, i);
2691  __del_invalid_panels(core);
2692  break;
2693  }
2694  }
2695 }
2696 
2698  RzPanel *justLeftPanel = NULL, *justRightPanel = NULL, *justUpPanel = NULL, *justDownPanel = NULL;
2699  RzPanel *tmpPanel = NULL;
2700  bool leftUpValid = false, leftDownValid = false, rightUpValid = false, rightDownValid = false,
2701  upLeftValid = false, upRightValid = false, downLeftValid = false, downRightValid = false;
2702  int left[PANEL_NUM_LIMIT], right[PANEL_NUM_LIMIT], up[PANEL_NUM_LIMIT], down[PANEL_NUM_LIMIT];
2703  memset(left, -1, sizeof(left));
2704  memset(right, -1, sizeof(right));
2705  memset(up, -1, sizeof(up));
2706  memset(down, -1, sizeof(down));
2707  int i, ox, oy, ow, oh;
2708  ox = p->view->pos.x;
2709  oy = p->view->pos.y;
2710  ow = p->view->pos.w;
2711  oh = p->view->pos.h;
2712  for (i = 0; i < ps->n_panels; i++) {
2713  tmpPanel = __get_panel(ps, i);
2714  if (tmpPanel->view->pos.x + tmpPanel->view->pos.w - 1 == ox) {
2715  left[i] = 1;
2716  if (oy == tmpPanel->view->pos.y) {
2717  leftUpValid = true;
2718  if (oh == tmpPanel->view->pos.h) {
2719  justLeftPanel = tmpPanel;
2720  break;
2721  }
2722  }
2723  if (oy + oh == tmpPanel->view->pos.y + tmpPanel->view->pos.h) {
2724  leftDownValid = true;
2725  }
2726  }
2727  if (tmpPanel->view->pos.x == ox + ow - 1) {
2728  right[i] = 1;
2729  if (oy == tmpPanel->view->pos.y) {
2730  rightUpValid = true;
2731  if (oh == tmpPanel->view->pos.h) {
2732  rightDownValid = true;
2733  justRightPanel = tmpPanel;
2734  }
2735  }
2736  if (oy + oh == tmpPanel->view->pos.y + tmpPanel->view->pos.h) {
2737  rightDownValid = true;
2738  }
2739  }
2740  if (tmpPanel->view->pos.y + tmpPanel->view->pos.h - 1 == oy) {
2741  up[i] = 1;
2742  if (ox == tmpPanel->view->pos.x) {
2743  upLeftValid = true;
2744  if (ow == tmpPanel->view->pos.w) {
2745  upRightValid = true;
2746  justUpPanel = tmpPanel;
2747  }
2748  }
2749  if (ox + ow == tmpPanel->view->pos.x + tmpPanel->view->pos.w) {
2750  upRightValid = true;
2751  }
2752  }
2753  if (tmpPanel->view->pos.y == oy + oh - 1) {
2754  down[i] = 1;
2755  if (ox == tmpPanel->view->pos.x) {
2756  downLeftValid = true;
2757  if (ow == tmpPanel->view->pos.w) {
2758  downRightValid = true;
2759  justDownPanel = tmpPanel;
2760  }
2761  }
2762  if (ox + ow == tmpPanel->view->pos.x + tmpPanel->view->pos.w) {
2763  downRightValid = true;
2764  }
2765  }
2766  }
2767  if (justLeftPanel) {
2768  justLeftPanel->view->pos.w += ox + ow - (justLeftPanel->view->pos.x + justLeftPanel->view->pos.w);
2769  } else if (justRightPanel) {
2770  justRightPanel->view->pos.w = justRightPanel->view->pos.x + justRightPanel->view->pos.w - ox;
2771  justRightPanel->view->pos.x = ox;
2772  } else if (justUpPanel) {
2773  justUpPanel->view->pos.h += oy + oh - (justUpPanel->view->pos.y + justUpPanel->view->pos.h);
2774  } else if (justDownPanel) {
2775  justDownPanel->view->pos.h = oh + justDownPanel->view->pos.y + justDownPanel->view->pos.h - (oy + oh);
2776  justDownPanel->view->pos.y = oy;
2777  } else if (leftUpValid && leftDownValid) {
2778  for (i = 0; i < ps->n_panels; i++) {
2779  if (left[i] != -1) {
2780  tmpPanel = __get_panel(ps, i);
2781  tmpPanel->view->pos.w += ox + ow - (tmpPanel->view->pos.x + tmpPanel->view->pos.w);
2782  }
2783  }
2784  } else if (rightUpValid && rightDownValid) {
2785  for (i = 0; i < ps->n_panels; i++) {
2786  if (right[i] != -1) {
2787  tmpPanel = __get_panel(ps, i);
2788  tmpPanel->view->pos.w = tmpPanel->view->pos.x + tmpPanel->view->pos.w - ox;
2789  tmpPanel->view->pos.x = ox;
2790  }
2791  }
2792  } else if (upLeftValid && upRightValid) {
2793  for (i = 0; i < ps->n_panels; i++) {
2794  if (up[i] != -1) {
2795  tmpPanel = __get_panel(ps, i);
2796  tmpPanel->view->pos.h += oy + oh - (tmpPanel->view->pos.y + tmpPanel->view->pos.h);
2797  }
2798  }
2799  } else if (downLeftValid && downRightValid) {
2800  for (i = 0; i < ps->n_panels; i++) {
2801  if (down[i] != -1) {
2802  tmpPanel = __get_panel(ps, i);
2803  tmpPanel->view->pos.h = oh + tmpPanel->view->pos.y + tmpPanel->view->pos.h - (oy + oh);
2804  tmpPanel->view->pos.y = oy;
2805  }
2806  }
2807  }
2808 }
2809 
2810 void __replace_cmd(RzCore *core, const char *title, const char *cmd) {
2811  RzPanels *panels = core->panels;
2812  RzPanel *cur = __get_cur_panel(panels);
2813  __free_panel_model(cur);
2814  cur->model = RZ_NEW0(RzPanelModel);
2815  cur->model->title = rz_str_dup(cur->model->title, title);
2816  cur->model->cmd = rz_str_dup(cur->model->cmd, cmd);
2817  __set_cmd_str_cache(core, cur, NULL);
2818  __set_panel_addr(core, cur, core->offset);
2819  cur->model->type = PANEL_TYPE_DEFAULT;
2820  __set_dcb(core, cur);
2821  __set_pcb(cur);
2822  __set_rcb(panels, cur);
2823  __cache_white_list(core, cur);
2824  __set_refresh_all(core, false, true);
2825 }
2826 
2827 void __swap_panels(RzPanels *panels, int p0, int p1) {
2828  RzPanel *panel0 = __get_panel(panels, p0);
2829  RzPanel *panel1 = __get_panel(panels, p1);
2830  RzPanelModel *tmp = panel0->model;
2831 
2832  panel0->model = panel1->model;
2833  panel1->model = tmp;
2834 }
2835 
2837  if (__check_func(core)) {
2838  RzPanels *panels = core->panels;
2839 
2840  rz_cons_canvas_free(panels->can);
2841  panels->can = NULL;
2842 
2843  int ocolor = rz_config_get_i(core->config, "scr.color");
2844 
2845  rz_core_visual_graph(core, NULL, NULL, true);
2846  rz_config_set_i(core->config, "scr.color", ocolor);
2847 
2848  int h, w = rz_cons_get_size(&h);
2849  panels->can = __create_new_canvas(core, w, h);
2850  }
2851 }
2852 
2853 bool __check_func(RzCore *core) {
2855  if (!fun) {
2856  rz_cons_message("Not in a function. Type 'df' to define it here");
2857  return false;
2858  }
2859  if (rz_list_empty(fun->bbs)) {
2860  rz_cons_message("No basic blocks in this function. You may want to use 'afb+'.");
2861  return false;
2862  }
2863  return true;
2864 }
2865 
2868  if (!func) {
2869  if (RZ_STR_ISEMPTY(p->model->funcName)) {
2870  return false;
2871  }
2872  p->model->funcName = NULL;
2873  return true;
2874  }
2875  if (!p->model->funcName || strcmp(p->model->funcName, func->name)) {
2876  p->model->funcName = rz_str_dup(p->model->funcName, func->name);
2877  return true;
2878  }
2879  return false;
2880 }
2881 
2882 void __seek_all(RzCore *core, ut64 addr) {
2883  RzPanels *panels = core->panels;
2884  int i;
2885  for (i = 0; i < panels->n_panels; i++) {
2886  RzPanel *panel = __get_panel(panels, i);
2887  panel->model->addr = addr;
2888  }
2889 }
2890 
2891 void __set_refresh_all(RzCore *core, bool clearCache, bool force_refresh) {
2892  RzPanels *panels = core->panels;
2893  int i;
2894  for (i = 0; i < panels->n_panels; i++) {
2895  RzPanel *panel = __get_panel(panels, i);
2896  if (!force_refresh && __check_panel_type(panel, PANEL_CMD_CONSOLE)) {
2897  continue;
2898  }
2899  panel->view->refresh = true;
2900  if (clearCache) {
2901  __set_cmd_str_cache(core, panel, NULL);
2902  }
2903  }
2904 }
2905 
2906 void __set_refresh_by_type(RzCore *core, const char *cmd, bool clearCache) {
2907  RzPanels *panels = core->panels;
2908  int i;
2909  for (i = 0; i < panels->n_panels; i++) {
2910  RzPanel *p = __get_panel(panels, i);
2911  if (!__check_panel_type(p, cmd)) {
2912  continue;
2913  }
2914  p->view->refresh = true;
2915  if (clearCache) {
2916  __set_cmd_str_cache(core, p, NULL);
2917  }
2918  }
2919 }
2920 
2921 void __set_addr_by_type(RzCore *core, const char *cmd, ut64 addr) {
2922  RzPanels *panels = core->panels;
2923  int i;
2924  for (i = 0; i < panels->n_panels; i++) {
2925  RzPanel *p = __get_panel(panels, i);
2926  if (!__check_panel_type(p, cmd)) {
2927  continue;
2928  }
2929  __set_panel_addr(core, p, addr);
2930  }
2931 }
2932 
2935  if (!can) {
2936  eprintf("Cannot create RzCons.canvas context\n");
2937  return false;
2938  }
2939  rz_cons_canvas_fill(can, 0, 0, w, h, ' ');
2940  can->linemode = rz_config_get_i(core->config, "graph.linemode");
2941  can->color = rz_config_get_i(core->config, "scr.color");
2942  return can;
2943 }
2944 
2946  RzPanels *panels = core->panels;
2947  if (panels->n_panels + 1 > PANEL_NUM_LIMIT) {
2948  const char *msg = "panel limit exceeded.";
2949  (void)__show_status(core, msg);
2950  return false;
2951  }
2952  return true;
2953 }
2954 
2955 void __init_panel_param(RzCore *core, RzPanel *p, const char *title, const char *cmd) {
2956  RzPanelModel *m = p->model;
2957  RzPanelView *v = p->view;
2958  m->type = PANEL_TYPE_DEFAULT;
2959  m->rotate = 0;
2960  v->curpos = 0;
2961  __set_panel_addr(core, p, core->offset);
2962  m->rotateCb = NULL;
2963  __set_cmd_str_cache(core, p, NULL);
2964  __set_read_only(core, p, NULL);
2965  m->funcName = NULL;
2966  v->refresh = true;
2967  v->edge = 0;
2968  if (title) {
2969  m->title = rz_str_dup(m->title, title);
2970  if (cmd) {
2971  m->cmd = rz_str_dup(m->cmd, cmd);
2972  } else {
2973  m->cmd = rz_str_dup(m->cmd, "");
2974  }
2975  } else if (cmd) {
2976  m->title = rz_str_dup(m->title, cmd);
2977  m->cmd = rz_str_dup(m->cmd, cmd);
2978  } else {
2979  m->title = rz_str_dup(m->title, "");
2980  m->cmd = rz_str_dup(m->cmd, "");
2981  }
2982  __set_pcb(p);
2983  if (RZ_STR_ISNOTEMPTY(m->cmd)) {
2984  __set_dcb(core, p);
2985  __set_rcb(core->panels, p);
2987  const char *sp = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SP);
2988  const ut64 stackbase = rz_reg_getv(core->analysis->reg, sp);
2989  m->baseAddr = stackbase;
2990  __set_panel_addr(core, p, stackbase - rz_config_get_i(core->config, "stack.delta"));
2991  }
2992  }
2993  core->panels->n_panels++;
2994  __cache_white_list(core, p);
2995  return;
2996 }
2997 
2998 void __set_dcb(RzCore *core, RzPanel *p) {
2999  if (__is_abnormal_cursor_type(core, p)) {
3000  p->model->cache = true;
3001  p->model->directionCb = __direction_panels_cursor_cb;
3002  return;
3003  }
3004  if ((p->model->cache && p->model->cmdStrCache) || p->model->readOnly) {
3005  p->model->directionCb = __direction_default_cb;
3006  return;
3007  }
3008  if (!p->model->cmd) {
3009  return;
3010  }
3012  p->model->directionCb = __direction_graph_cb;
3013  return;
3014  }
3016  p->model->directionCb = __direction_stack_cb;
3018  p->model->directionCb = __direction_disassembly_cb;
3019  } else if (__check_panel_type(p, PANEL_CMD_REGISTERS)) {
3020  p->model->directionCb = __direction_register_cb;
3021  } else if (__check_panel_type(p, PANEL_CMD_HEXDUMP)) {
3022  p->model->directionCb = __direction_hexdump_cb;
3023  } else {
3024  p->model->directionCb = __direction_default_cb;
3025  }
3026 }
3027 
3029  SdbKv *kv;
3030  SdbListIter *sdb_iter;
3031  SdbList *sdb_list = sdb_foreach_list(ps->rotate_db, false);
3032  ls_foreach (sdb_list, sdb_iter, kv) {
3033  char *key = sdbkv_key(kv);
3034  if (!__check_panel_type(p, key)) {
3035  continue;
3036  }
3037  p->model->rotateCb = (RzPanelRotateCallback)sdb_ptr_get(ps->rotate_db, key, 0);
3038  break;
3039  }
3040  ls_free(sdb_list);
3041 }
3042 
3044  if (!p->model->cmd) {
3045  return;
3046  }
3048  p->model->print_cb = __print_disassembly_cb;
3049  return;
3050  }
3052  p->model->print_cb = __print_stack_cb;
3053  return;
3054  }
3056  p->model->print_cb = __print_hexdump_cb;
3057  return;
3058  }
3060  p->model->print_cb = __print_graph_cb;
3061  return;
3062  }
3064  p->model->print_cb = __print_graph_cb;
3065  return;
3066  }
3068  p->model->print_cb = __print_disasmsummary_cb;
3069  return;
3070  }
3071  p->model->print_cb = __print_default_cb;
3072 }
3073 
3074 int __open_file_cb(void *user) {
3075  RzCore *core = (RzCore *)user;
3078  __add_cmdf_panel(core, "open file: ", "o %s");
3081  return 0;
3082 }
3083 
3084 int __rw_cb(void *user) {
3085  RzCore *core = (RzCore *)user;
3086  rz_core_io_file_reopen(core, core->io->desc->fd, core->io->desc->perm | RZ_PERM_RW);
3087  return 0;
3088 }
3089 
3090 int __debugger_cb(void *user) {
3091  RzCore *core = (RzCore *)user;
3092  rz_core_io_file_open(core, core->io->desc->fd);
3093  return 0;
3094 }
3095 
3096 int __load_layout_saved_cb(void *user) {
3097  RzCore *core = (RzCore *)user;
3098  RzPanelsMenu *menu = core->panels->panels_menu;
3099  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
3100  RzPanelsMenuItem *child = parent->sub[parent->selectedIndex];
3101  if (!rz_load_panels_layout(core, child->name)) {
3103  __panels_layout(core->panels);
3104  }
3105  __set_curnode(core, 0);
3106  core->panels->panels_menu->depth = 1;
3108  return 0;
3109 }
3110 
3111 int __load_layout_default_cb(void *user) {
3112  RzCore *core = (RzCore *)user;
3113  __init_panels(core, core->panels);
3115  __panels_layout(core->panels);
3116  core->panels->panels_menu->depth = 1;
3118  return 0;
3119 }
3120 
3121 int __close_file_cb(void *user) {
3122  RzCore *core = (RzCore *)user;
3123  rz_core_file_close_fd(core, -1);
3124  rz_io_close_all(core->io);
3125  rz_bin_file_delete_all(core->bin);
3126  if (core->files) {
3127  rz_list_purge(core->files);
3128  }
3129  return 0;
3130 }
3131 
3132 int __save_layout_cb(void *user) {
3133  RzCore *core = (RzCore *)user;
3134  rz_save_panels_layout(core, NULL);
3136  __clear_panels_menu(core);
3137  __get_cur_panel(core->panels)->view->refresh = true;
3138  return 0;
3139 }
3140 
3141 int __clear_layout_cb(void *user) {
3142  RzCore *core = (RzCore *)user;
3143  if (!__show_status_yesno(core, 0, "Clear all the saved layouts?(y/n): ")) {
3144  return 0;
3145  }
3146  char *dir_path = __get_panels_config_dir_path();
3147  RzList *dir = rz_sys_dir((const char *)dir_path);
3148  if (!dir) {
3149  free(dir_path);
3150  return 0;
3151  }
3152  RzListIter *it;
3153  char *entry;
3154  rz_list_foreach (dir, it, entry) {
3155  char *tmp = rz_str_newf("%s%s%s", dir_path, RZ_SYS_DIR, entry);
3156  rz_file_rm(tmp);
3157  free(tmp);
3158  }
3159  rz_file_rm(dir_path);
3160  rz_list_free(dir);
3161  free(dir_path);
3162 
3163  __update_menu(core, "File.Load Layout.Saved", __init_menu_saved_layout);
3164  return 0;
3165 }
3166 
3167 int __copy_cb(void *user) {
3168  RzCore *core = (RzCore *)user;
3169  __add_cmdf_panel(core, "How many bytes? ", "\"y %s\"");
3170  return 0;
3171 }
3172 
3173 int __paste_cb(void *user) {
3174  RzCore *core = (RzCore *)user;
3175  rz_core_yank_paste(core, core->offset, 0);
3176  return 0;
3177 }
3178 
3179 int __write_str_cb(void *user) {
3180  RzCore *core = (RzCore *)user;
3181  __add_cmdf_panel(core, "insert string: ", "\"w %s\"");
3182  return 0;
3183 }
3184 
3185 int __write_hex_cb(void *user) {
3186  RzCore *core = (RzCore *)user;
3187  __add_cmdf_panel(core, "insert hexpairs: ", "\"wx %s\"");
3188  return 0;
3189 }
3190 
3191 int __assemble_cb(void *user) {
3192  RzCore *core = (RzCore *)user;
3193  rz_core_visual_asm(core, core->offset);
3194  return 0;
3195 }
3196 
3197 int __fill_cb(void *user) {
3198  RzCore *core = (RzCore *)user;
3199  __add_cmdf_panel(core, "Fill with: ", "wow %s");
3200  return 0;
3201 }
3202 
3203 int __settings_colors_cb(void *user) {
3204  RzCore *core = (RzCore *)user;
3205  RzPanelsMenu *menu = core->panels->panels_menu;
3206  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
3207  RzPanelsMenuItem *child = parent->sub[parent->selectedIndex];
3208  rz_str_ansi_filter(child->name, NULL, NULL, -1);
3209  rz_core_theme_load(core, child->name);
3210  int i;
3211  for (i = 1; i < menu->depth; i++) {
3212  RzPanel *p = menu->history[i]->p;
3213  p->view->refresh = true;
3214  menu->refreshPanels[i - 1] = p;
3215  }
3216  __update_menu(core, "Settings.Colors", __init_menu_color_settings_layout);
3217  return 0;
3218 }
3219 
3220 int __config_toggle_cb(void *user) {
3221  RzCore *core = (RzCore *)user;
3222  RzPanelsMenu *menu = core->panels->panels_menu;
3223  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
3224  RzPanelsMenuItem *child = parent->sub[parent->selectedIndex];
3225  RzStrBuf *tmp = rz_strbuf_new(child->name);
3226  (void)rz_str_split(rz_strbuf_get(tmp), ':');
3229  free(parent->p->model->title);
3230  parent->p->model->title = rz_strbuf_drain(__draw_menu(core, parent));
3231  int i;
3232  for (i = 1; i < menu->depth; i++) {
3233  RzPanel *p = menu->history[i]->p;
3234  p->view->refresh = true;
3235  menu->refreshPanels[i - 1] = p;
3236  }
3237  if (!strcmp(parent->name, "asm")) {
3238  __update_menu(core, "Settings.Disassembly.asm", __init_menu_disasm_asm_settings_layout);
3239  }
3240  if (!strcmp(parent->name, "Screen")) {
3241  __update_menu(core, "Settings.Screen", __init_menu_screen_settings_layout);
3242  }
3243  return 0;
3244 }
3245 
3246 int __config_value_cb(void *user) {
3247  RzCore *core = (RzCore *)user;
3248  RzPanelsMenu *menu = core->panels->panels_menu;
3249  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
3250  RzPanelsMenuItem *child = parent->sub[parent->selectedIndex];
3251  RzStrBuf *tmp = rz_strbuf_new(child->name);
3252  (void)rz_str_split(rz_strbuf_get(tmp), ':');
3253  const char *v = __show_status_input(core, "New value: ");
3256  free(parent->p->model->title);
3257  parent->p->model->title = rz_strbuf_drain(__draw_menu(core, parent));
3258  int i;
3259  for (i = 1; i < menu->depth; i++) {
3260  RzPanel *p = menu->history[i]->p;
3261  p->view->refresh = true;
3262  menu->refreshPanels[i - 1] = p;
3263  }
3264  if (!strcmp(parent->name, "asm")) {
3265  __update_menu(core, "Settings.Disassembly.asm", __init_menu_disasm_asm_settings_layout);
3266  }
3267  if (!strcmp(parent->name, "Screen")) {
3268  __update_menu(core, "Settings.Screen", __init_menu_screen_settings_layout);
3269  }
3270  return 0;
3271 }
3272 
3273 int __calculator_cb(void *user) {
3274  RzCore *core = (RzCore *)user;
3275  for (;;) {
3276  char *s = __show_status_input(core, "> ");
3277  if (!s || !*s) {
3278  free(s);
3279  break;
3280  }
3281  rz_core_cmdf(core, "? %s", s);
3282  rz_cons_flush();
3283  free(s);
3284  }
3285  return 0;
3286 }
3287 
3288 int __rz_shell_cb(void *user) {
3289  RzCore *core = (RzCore *)user;
3290  core->vmode = false;
3292  core->vmode = true;
3293  return 0;
3294 }
3295 
3296 int __system_shell_cb(void *user) {
3297  rz_cons_set_raw(0);
3298  rz_cons_flush();
3299  rz_sys_xsystem("$SHELL");
3300  return 0;
3301 }
3302 
3303 int __string_whole_bin_cb(void *user) {
3304  RzCore *core = (RzCore *)user;
3305  __add_cmdf_panel(core, "search strings in the whole binary: ", "izzq~%s");
3306  return 0;
3307 }
3308 
3309 int __string_data_sec_cb(void *user) {
3310  RzCore *core = (RzCore *)user;
3311  __add_cmdf_panel(core, "search string in data sections: ", "izq~%s");
3312  return 0;
3313 }
3314 
3315 int __rop_cb(void *user) {
3316  RzCore *core = (RzCore *)user;
3317  __add_cmdf_panel(core, "rop grep: ", "\"/R %s\"");
3318  return 0;
3319 }
3320 
3321 int __code_cb(void *user) {
3322  RzCore *core = (RzCore *)user;
3323  __add_cmdf_panel(core, "search code: ", "\"/c %s\"");
3324  return 0;
3325 }
3326 
3327 int __hexpairs_cb(void *user) {
3328  RzCore *core = (RzCore *)user;
3329  __add_cmdf_panel(core, "search hexpairs: ", "\"/x %s\"");
3330  return 0;
3331 }
3332 
3333 int __continue_cb(void *user) {
3334  RzCore *core = (RzCore *)user;
3335  rz_core_debug_continue(core);
3336  rz_cons_flush();
3337  return 0;
3338 }
3339 
3340 int __esil_init_cb(void *user) {
3341  RzCore *core = (RzCore *)user;
3342  __esil_init(core);
3343  return 0;
3344 }
3345 
3346 int __esil_step_to_cb(void *user) {
3347  RzCore *core = (RzCore *)user;
3348  char *end = __show_status_input(core, "target addr: ");
3349  __esil_step_to(core, rz_num_math(core->num, end));
3350  return 0;
3351 }
3352 
3353 int __esil_step_range_cb(void *user) {
3354  RzStrBuf *rsb = rz_strbuf_new(NULL);
3355  RzCore *core = (RzCore *)user;
3356  rz_strbuf_append(rsb, "start addr: ");
3357  char *s = __show_status_input(core, rz_strbuf_get(rsb));
3358  rz_strbuf_append(rsb, s);
3359  rz_strbuf_append(rsb, " end addr: ");
3360  char *d = __show_status_input(core, rz_strbuf_get(rsb));
3361  rz_strbuf_free(rsb);
3362  ut64 s_a = rz_num_math(core->num, s);
3363  ut64 d_a = rz_num_math(core->num, d);
3364  if (s_a >= d_a) {
3365  return 0;
3366  }
3367  ut64 tmp = core->offset;
3368  core->offset = s_a;
3369  __esil_init(core);
3370  __esil_step_to(core, d_a);
3371  core->offset = tmp;
3372  return 0;
3373 }
3374 
3375 int __step_cb(void *user) {
3376  RzCore *core = (RzCore *)user;
3377  __panel_single_step_in(core);
3379  return 0;
3380 }
3381 
3382 int __step_over_cb(void *user) {
3383  RzCore *core = (RzCore *)user;
3386  return 0;
3387 }
3388 
3389 int __io_cache_on_cb(void *user) {
3390  RzCore *core = (RzCore *)user;
3391  rz_config_set_b(core->config, "io.cache", true);
3392  (void)__show_status(core, "io.cache is on");
3394  return 0;
3395 }
3396 
3397 int __io_cache_off_cb(void *user) {
3398  RzCore *core = (RzCore *)user;
3399  rz_config_set_b(core->config, "io.cache", false);
3400  (void)__show_status(core, "io.cache is off");
3402  return 0;
3403 }
3404 
3406  RzPanels *panels = core->panels;
3407  int i;
3408  bool create_new = true;
3409  for (i = 0; i < panels->n_panels; i++) {
3410  RzPanel *p = __get_panel(panels, i);
3412  __set_panel_addr(core, p, core->offset);
3413  create_new = false;
3414  }
3415  }
3416  if (create_new) {
3417  RzPanel *panel = __get_panel(panels, 0);
3418  int x0 = panel->view->pos.x;
3419  int y0 = panel->view->pos.y;
3420  int w0 = panel->view->pos.w;
3421  int h0 = panel->view->pos.h;
3422  int threshold_w = x0 + panel->view->pos.w;
3423  int x1 = x0 + w0 / 2 - 1;
3424  int w1 = threshold_w - x1;
3425 
3427  RzPanel *p0 = __get_panel(panels, 0);
3428  __set_geometry(&p0->view->pos, x0, y0, w0 / 2, h0);
3429 
3430  RzPanel *p1 = __get_panel(panels, 1);
3431  __set_geometry(&p1->view->pos, x1, y0, w1, h0);
3432 
3433  __set_cursor(core, false);
3434  __set_curnode(core, 0);
3435  }
3436 }
3437 
3438 void __set_curnode(RzCore *core, int idx) {
3439  RzPanels *panels = core->panels;
3440  if (idx >= panels->n_panels) {
3441  idx = 0;
3442  }
3443  if (idx < 0) {
3444  idx = panels->n_panels - 1;
3445  }
3446  panels->curnode = idx;
3447 
3448  RzPanel *cur = __get_cur_panel(panels);
3449  cur->view->curpos = cur->view->sy;
3450 }
3451 
3453  RzPanels *panels = core->panels;
3454  __set_cursor(core, false);
3455  panels->mode = mode;
3456  __update_help(core, panels);
3457 }
3458 
3459 void __update_help(RzCore *core, RzPanels *ps) {
3460  int i;
3461  for (i = 0; i < ps->n_panels; i++) {
3462  RzPanel *p = __get_panel(ps, i);
3463  if (rz_str_endswith(p->model->cmd, "Help")) {
3464  RzStrBuf *rsb = rz_strbuf_new(NULL);
3465  const char *title, *cmd;
3466  const char **msg;
3467  switch (ps->mode) {
3468  case PANEL_MODE_WINDOW:
3469  title = "Panels Window mode help";
3470  cmd = "Window Mode Help";
3472  break;
3473  case PANEL_MODE_ZOOM:
3474  title = "Panels Zoom mode help";
3475  cmd = "Zoom Mode Help";
3477  break;
3478  default:
3479  title = "Visual Ascii Art Panels";
3480  cmd = "Help";
3481  msg = help_msg_panels;
3482  break;
3483  }
3484  p->model->title = rz_str_dup(p->model->title, cmd);
3485  p->model->cmd = rz_str_dup(p->model->cmd, cmd);
3486  rz_core_visual_append_help(rsb, title, msg);
3487  if (!rsb) {
3488  return;
3489  }
3490  char *drained = rz_strbuf_drain(rsb);
3491  __set_read_only(core, p, drained);
3492  free(drained);
3493  p->view->refresh = true;
3494  }
3495  }
3496 }
3497 
3498 int __reload_cb(void *user) {
3499  RzCore *core = (RzCore *)user;
3500  rz_core_file_reopen_debug(core, "");
3502  return 0;
3503 }
3504 
3505 int __function_cb(void *user) {
3506  RzCore *core = (RzCore *)user;
3507  rz_core_analysis_function_add(core, NULL, core->offset, false);
3508  return 0;
3509 }
3510 
3511 int __symbols_cb(void *user) {
3512  RzCore *core = (RzCore *)user;
3513  rz_core_analysis_all(core);
3514  return 0;
3515 }
3516 
3517 int __program_cb(void *user) {
3518  RzCore *core = (RzCore *)user;
3519  char *dh_orig = core->dbg->cur
3520  ? strdup(core->dbg->cur->name)
3521  : strdup("esil");
3522  rz_core_analysis_all(core);
3523  rz_core_analysis_everything(core, false, dh_orig);
3524  return 0;
3525 }
3526 
3527 int __calls_cb(void *user) {
3528  RzCore *core = (RzCore *)user;
3529  rz_core_analysis_calls(core, false);
3530  return 0;
3531 }
3532 
3533 int __break_points_cb(void *user) {
3534  RzCore *core = (RzCore *)user;
3535  char buf[128];
3536  const char *prompt = "addr: ";
3537 
3542  __panel_prompt(prompt, buf, sizeof(buf));
3545 
3546  ut64 addr = rz_num_math(core->num, buf);
3548  return 0;
3549 }
3550 
3551 int __watch_points_cb(void *user) {
3552  RzCore *core = (RzCore *)user;
3553  char addrBuf[128], perm[128];
3554  const char *addrPrompt = "addr: ", *rwPrompt = "<r/w/rw>: ";
3555  __panel_prompt(addrPrompt, addrBuf, sizeof(addrBuf));
3556  __panel_prompt(rwPrompt, perm, sizeof(perm));
3557  ut64 addr = rz_num_math(core->num, addrBuf);
3558  bool hwbp = rz_config_get_b(core->config, "dbg.hwbp");
3559  rz_core_debug_bp_add(core, addr, perm, hwbp, true);
3560  return 0;
3561 }
3562 
3563 int __references_cb(void *user) {
3564  RzCore *core = (RzCore *)user;
3565  rz_core_analysis_refs(core, 0);
3566  return 0;
3567 }
3568 
3569 int __fortune_cb(void *user) {
3570  RzCore *core = (RzCore *)user;
3571  char *s = rz_core_fortune_get_random(core);
3572  rz_cons_message(s);
3573  free(s);
3574  return 0;
3575 }
3576 
3577 int __help_cb(void *user) {
3578  RzCore *core = (RzCore *)user;
3579  __toggle_help(core);
3580  return 0;
3581 }
3582 
3583 int __license_cb(void *user) {
3584  rz_cons_message("Copyright 2006-2020 - pancake - LGPL");
3585  return 0;
3586 }
3587 
3588 int __version_cb(void *user) {
3589  char *v = rz_str_version(NULL);
3590  rz_cons_message(v);
3591  free(v);
3592  return 0;
3593 }
3594 
3595 int __writeValueCb(void *user) {
3596  RzCore *core = (RzCore *)user;
3597  char *res = __show_status_input(core, "insert number: ");
3598  if (res) {
3599  rz_core_cmdf(core, "\"wv %s\"", res);
3600  free(res);
3601  }
3602  return 0;
3603 }
3604 
3605 int __quit_cb(void *user) {
3606  __set_root_state((RzCore *)user, QUIT);
3607  return 0;
3608 }
3609 
3610 void __direction_default_cb(void *user, int direction) {
3611  RzCore *core = (RzCore *)user;
3612  RzPanel *cur = __get_cur_panel(core->panels);
3613  cur->view->refresh = true;
3614  switch ((Direction)direction) {
3615  case LEFT:
3616  if (cur->view->sx > 0) {
3617  cur->view->sx--;
3618  }
3619  return;
3620  case RIGHT:
3621  cur->view->sx++;
3622  return;
3623  case UP:
3624  if (cur->view->sy > 0) {
3625  cur->view->sy--;
3626  }
3627  return;
3628  case DOWN:
3629  cur->view->sy++;
3630  return;
3631  }
3632 }
3633 
3634 void __direction_disassembly_cb(void *user, int direction) {
3635  RzCore *core = (RzCore *)user;
3636  RzPanels *panels = core->panels;
3637  RzPanel *cur = __get_cur_panel(panels);
3638  int cols = core->print->cols;
3639  cur->view->refresh = true;
3640  switch ((Direction)direction) {
3641  case LEFT:
3642  if (core->print->cur_enabled) {
3643  __cursor_left(core);
3644  rz_core_block_read(core);
3645  __set_panel_addr(core, cur, core->offset);
3646  } else if (panels->mode == PANEL_MODE_ZOOM) {
3647  cur->model->addr--;
3648  } else if (cur->view->sx > 0) {
3649  cur->view->sx--;
3650  }
3651  return;
3652  case RIGHT:
3653  if (core->print->cur_enabled) {
3654  __cursor_right(core);
3655  rz_core_block_read(core);
3656  __set_panel_addr(core, cur, core->offset);
3657  } else if (panels->mode == PANEL_MODE_ZOOM) {
3658  cur->model->addr++;
3659  } else {
3660  cur->view->sx++;
3661  }
3662  return;
3663  case UP:
3664  core->offset = cur->model->addr;
3665  if (core->print->cur_enabled) {
3666  __cursor_up(core);
3667  rz_core_block_read(core);
3668  __set_panel_addr(core, cur, core->offset);
3669  } else {
3670  rz_core_visual_disasm_up(core, &cols);
3671  rz_core_seek_delta(core, -cols, false);
3672  __set_panel_addr(core, cur, core->offset);
3673  }
3674  return;
3675  case DOWN:
3676  core->offset = cur->model->addr;
3677  if (core->print->cur_enabled) {
3678  __cursor_down(core);
3679  rz_core_block_read(core);
3680  __set_panel_addr(core, cur, core->offset);
3681  } else {
3682  RzAsmOp op;
3683  rz_core_visual_disasm_down(core, &op, &cols);
3684  rz_core_seek(core, core->offset + cols, true);
3685  __set_panel_addr(core, cur, core->offset);
3686  }
3687  return;
3688  }
3689 }
3690 
3691 void __direction_graph_cb(void *user, int direction) {
3692  RzCore *core = (RzCore *)user;
3693  RzPanels *panels = core->panels;
3694  RzPanel *cur = __get_cur_panel(panels);
3695  cur->view->refresh = true;
3696  const int speed = rz_config_get_i(core->config, "graph.scroll") * 2;
3697  switch ((Direction)direction) {
3698  case LEFT:
3699  if (cur->view->sx > 0) {
3700  cur->view->sx -= speed;
3701  }
3702  return;
3703  case RIGHT:
3704  cur->view->sx += speed;
3705  return;
3706  case UP:
3707  if (cur->view->sy > 0) {
3708  cur->view->sy -= speed;
3709  }
3710  return;
3711  case DOWN:
3712  cur->view->sy += speed;
3713  return;
3714  }
3715 }
3716 
3717 void __direction_register_cb(void *user, int direction) {
3718  RzCore *core = (RzCore *)user;
3719  RzPanels *panels = core->panels;
3720  RzPanel *cur = __get_cur_panel(panels);
3721  int cols = core->dbg->regcols;
3722  cols = cols > 0 ? cols : 3;
3723  cur->view->refresh = true;
3724  switch ((Direction)direction) {
3725  case LEFT:
3726  if (core->print->cur_enabled) {
3727  __cursor_left(core);
3728  } else if (cur->view->sx > 0) {
3729  cur->view->sx--;
3730  cur->view->refresh = true;
3731  }
3732  return;
3733  case RIGHT:
3734  if (core->print->cur_enabled) {
3735  __cursor_right(core);
3736  } else {
3737  cur->view->sx++;
3738  cur->view->refresh = true;
3739  }
3740  return;
3741  case UP:
3742  if (core->print->cur_enabled) {
3743  int tmp = core->print->cur;
3744  tmp -= cols;
3745  if (tmp >= 0) {
3746  core->print->cur = tmp;
3747  }
3748  }
3749  return;
3750  case DOWN:
3751  if (core->print->cur_enabled) {
3752  core->print->cur += cols;
3753  }
3754  return;
3755  }
3756 }
3757 
3758 void __direction_stack_cb(void *user, int direction) {
3759  RzCore *core = (RzCore *)user;
3760  RzPanels *panels = core->panels;
3761  RzPanel *cur = __get_cur_panel(panels);
3762  int cols = rz_config_get_i(core->config, "hex.cols");
3763  if (cols < 1) {
3764  cols = 16;
3765  }
3766  cur->view->refresh = true;
3767  switch ((Direction)direction) {
3768  case LEFT:
3769  if (core->print->cur_enabled) {
3770  __cursor_left(core);
3771  } else if (cur->view->sx > 0) {
3772  cur->view->sx--;
3773  cur->view->refresh = true;
3774  }
3775  return;
3776  case RIGHT:
3777  if (core->print->cur_enabled) {
3778  __cursor_right(core);
3779  } else {
3780  cur->view->sx++;
3781  cur->view->refresh = true;
3782  }
3783  return;
3784  case UP:
3785  rz_config_set_i(core->config, "stack.delta",
3786  rz_config_get_i(core->config, "stack.delta") + cols);
3787  cur->model->addr -= cols;
3788  return;
3789  case DOWN:
3790  rz_config_set_i(core->config, "stack.delta",
3791  rz_config_get_i(core->config, "stack.delta") - cols);
3792  cur->model->addr += cols;
3793  return;
3794  }
3795 }
3796 
3797 void __direction_hexdump_cb(void *user, int direction) {
3798  RzCore *core = (RzCore *)user;
3799  RzPanels *panels = core->panels;
3800  RzPanel *cur = __get_cur_panel(panels);
3801  int cols = rz_config_get_i(core->config, "hex.cols");
3802  if (cols < 1) {
3803  cols = 16;
3804  }
3805  cur->view->refresh = true;
3806  switch ((Direction)direction) {
3807  case LEFT:
3808  if (!core->print->cur) {
3809  cur->model->addr -= cols;
3810  core->print->cur += cols - 1;
3811  } else if (core->print->cur_enabled) {
3812  __cursor_left(core);
3813  } else {
3814  cur->model->addr--;
3815  }
3816  return;
3817  case RIGHT:
3818  if (core->print->cur / cols + 1 > cur->view->pos.h - 5 && core->print->cur % cols == cols - 1) {
3819  cur->model->addr += cols;
3820  core->print->cur -= cols - 1;
3821  } else if (core->print->cur_enabled) {
3822  __cursor_right(core);
3823  } else {
3824  cur->model->addr++;
3825  }
3826  return;
3827  case UP:
3828  if (!cur->model->cache) {
3829  if (core->print->cur_enabled) {
3830  if (!(core->print->cur / cols)) {
3831  cur->model->addr -= cols;
3832  } else {
3833  core->print->cur -= cols;
3834  }
3835  } else {
3836  if (cur->model->addr <= cols) {
3837  __set_panel_addr(core, cur, 0);
3838  } else {
3839  cur->model->addr -= cols;
3840  }
3841  }
3842  } else if (cur->view->sy > 0) {
3843  cur->view->sy--;
3844  }
3845  return;
3846  case DOWN:
3847  if (!cur->model->cache) {
3848  if (core->print->cur_enabled) {
3849  if (core->print->cur / cols + 1 > cur->view->pos.h - 5) {
3850  cur->model->addr += cols;
3851  } else {
3852  core->print->cur += cols;
3853  }
3854  } else {
3855  cur->model->addr += cols;
3856  }
3857  } else {
3858  cur->view->sy++;
3859  }
3860  return;
3861  }
3862 }
3863 
3864 void __direction_panels_cursor_cb(void *user, int direction) {
3865  RzCore *core = (RzCore *)user;
3866  RzPanels *panels = core->panels;
3867  RzPanel *cur = __get_cur_panel(panels);
3868  cur->view->refresh = true;
3869  const int THRESHOLD = cur->view->pos.h / 3;
3870  int sub;
3871  switch ((Direction)direction) {
3872  case LEFT:
3873  if (core->print->cur_enabled) {
3874  return;
3875  }
3876  if (cur->view->sx > 0) {
3877  cur->view->sx -= rz_config_get_i(core->config, "graph.scroll");
3878  }
3879  return;
3880  case RIGHT:
3881  if (core->print->cur_enabled) {
3882  return;
3883  }
3884  cur->view->sx += rz_config_get_i(core->config, "graph.scroll");
3885  return;
3886  case UP:
3887  if (core->print->cur_enabled) {
3888  if (cur->view->curpos > 0) {
3889  cur->view->curpos--;
3890  }
3891  if (cur->view->sy > 0) {
3892  sub = cur->view->curpos - cur->view->sy;
3893  if (sub < 0) {
3894  cur->view->sy--;
3895  }
3896  }
3897  } else {
3898  if (cur->view->sy > 0) {
3899  cur->view->curpos -= 1;
3900  cur->view->sy -= 1;
3901  }
3902  }
3903  return;
3904  case DOWN:
3905  core->offset = cur->model->addr;
3906  if (core->print->cur_enabled) {
3907  cur->view->curpos++;
3908  sub = cur->view->curpos - cur->view->sy;
3909  if (sub > THRESHOLD) {
3910  cur->view->sy++;
3911  }
3912  } else {
3913  cur->view->curpos += 1;
3914  cur->view->sy += 1;
3915  }
3916  return;
3917  }
3918 }
3919 
3920 void __print_default_cb(void *user, void *p) {
3921  RzCore *core = (RzCore *)user;
3922  RzPanel *panel = (RzPanel *)p;
3923  bool update = core->panels->autoUpdate && __check_func_diff(core, panel);
3924  char *cmdstr = __find_cmd_str_cache(core, panel);
3925  if (update || !cmdstr) {
3926  cmdstr = __handle_cmd_str_cache(core, panel, false);
3927  if (panel->model->cache && panel->model->cmdStrCache) {
3928  __reset_scroll_pos(panel);
3929  }
3930  }
3931  __update_panel_contents(core, panel, cmdstr);
3932 }
3933 
3934 void __print_disasmsummary_cb(void *user, void *p) {
3935  RzCore *core = (RzCore *)user;
3936  RzPanel *panel = (RzPanel *)p;
3937  bool update = core->panels->autoUpdate && __check_func_diff(core, panel);
3938  char *cmdstr = __find_cmd_str_cache(core, panel);
3939  if (update || !cmdstr) {
3940  cmdstr = __handle_cmd_str_cache(core, panel, true);
3941  if (panel->model->cache && panel->model->cmdStrCache) {
3942  __reset_scroll_pos(panel);
3943  }
3944  }
3945  __update_panel_contents(core, panel, cmdstr);
3946 }
3947 
3948 void __print_disassembly_cb(void *user, void *p) {
3949  RzCore *core = (RzCore *)user;
3950  RzPanel *panel = (RzPanel *)p;
3951  core->print->screen_bounds = 1LL;
3952  char *cmdstr = __find_cmd_str_cache(core, panel);
3953  if (cmdstr) {
3954  __update_panel_contents(core, panel, cmdstr);
3955  return;
3956  }
3957  char *ocmd = panel->model->cmd;
3958  panel->model->cmd = rz_str_newf("%s %d", panel->model->cmd, panel->view->pos.h - 3);
3959  ut64 o_offset = core->offset;
3960  core->offset = panel->model->addr;
3961  rz_core_seek(core, panel->model->addr, true);
3962  if (rz_config_get_b(core->config, "cfg.debug")) {
3964  }
3965  cmdstr = __handle_cmd_str_cache(core, panel, false);
3966  core->offset = o_offset;
3967  free(panel->model->cmd);
3968  panel->model->cmd = ocmd;
3969  __update_panel_contents(core, panel, cmdstr);
3970 }
3971 
3972 void __print_graph_cb(void *user, void *p) {
3973  RzCore *core = (RzCore *)user;
3974  RzPanel *panel = (RzPanel *)p;
3975  bool update = core->panels->autoUpdate && __check_func_diff(core, panel);
3976  char *cmdstr = __find_cmd_str_cache(core, panel);
3977  if (update || !cmdstr) {
3978  cmdstr = __handle_cmd_str_cache(core, panel, false);
3979  }
3980  core->cons->event_resize = NULL;
3981  core->cons->event_data = core;
3983  __update_panel_contents(core, panel, cmdstr);
3984 }
3985 
3986 void __print_stack_cb(void *user, void *p) {
3987  RzCore *core = (RzCore *)user;
3988  RzPanel *panel = (RzPanel *)p;
3989  const int delta = rz_config_get_i(core->config, "stack.delta");
3990  const int bits = rz_config_get_i(core->config, "asm.bits");
3991  const char sign = (delta < 0) ? '+' : '-';
3992  const int absdelta = RZ_ABS(delta);
3993  char *cmd = rz_str_newf("%s%s ", PANEL_CMD_STACK, bits == 32 ? "w" : "q");
3994  int n = rz_str_split(panel->model->cmd, ' ');
3995  int i;
3996  for (i = 0; i < n; i++) {
3997  const char *s = rz_str_word_get0(panel->model->cmd, i);
3998  if (!i) {
3999  continue;
4000  }
4001  cmd = rz_str_append(cmd, s);
4002  }
4003  panel->model->cmd = cmd;
4004  const char *cmdstr = rz_core_cmd_str(core, rz_str_newf("%s%c%d", cmd, sign, absdelta));
4005  __update_panel_contents(core, panel, cmdstr);
4006 }
4007 
4008 void __print_hexdump_cb(void *user, void *p) {
4009  RzCore *core = (RzCore *)user;
4010  RzPanel *panel = (RzPanel *)p;
4011  char *cmdstr = __find_cmd_str_cache(core, panel);
4012  if (!cmdstr) {
4013  ut64 o_offset = core->offset;
4014  if (!panel->model->cache) {
4015  core->offset = panel->model->addr;
4016  rz_core_seek(core, core->offset, true);
4017  rz_core_block_read(core);
4018  }
4019  char *base = hexdump_rotate[RZ_ABS(panel->model->rotate) % COUNT(hexdump_rotate)];
4020  char *cmd = rz_str_newf("%s ", base);
4021  int n = rz_str_split(panel->model->cmd, ' ');
4022  int i;
4023  for (i = 0; i < n; i++) {
4024  const char *s = rz_str_word_get0(panel->model->cmd, i);
4025  if (!i) {
4026  continue;
4027  }
4028  cmd = rz_str_append(cmd, s);
4029  }
4030  panel->model->cmd = cmd;
4031  cmdstr = __handle_cmd_str_cache(core, panel, false);
4032  core->offset = o_offset;
4033  }
4034  __update_panel_contents(core, panel, cmdstr);
4035 }
4036 
4037 void __hudstuff(RzCore *core) {
4038  RzPanels *panels = core->panels;
4039  RzPanel *cur = __get_cur_panel(panels);
4041 
4043  __set_panel_addr(core, cur, core->offset);
4044  } else {
4045  int i;
4046  for (i = 0; i < panels->n_panels; i++) {
4047  RzPanel *panel = __get_panel(panels, i);
4049  __set_panel_addr(core, panel, core->offset);
4050  break;
4051  }
4052  }
4053  }
4054 }
4055 
4056 void __esil_init(RzCore *core) {
4059 }
4060 
4062  rz_core_esil_step(core, end, NULL, NULL, false);
4063 }
4064 
4065 int __open_menu_cb(void *user) {
4066  RzCore *core = (RzCore *)user;
4067  RzPanelsMenu *menu = core->panels->panels_menu;
4068  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
4069  RzPanelsMenuItem *child = parent->sub[parent->selectedIndex];
4070  if (menu->depth < 2) {
4071  __set_pos(&child->p->view->pos, menu->root->selectedIndex * 6, 1);
4072  } else {
4073  RzPanelsMenuItem *p = menu->history[menu->depth - 2];
4074  RzPanelsMenuItem *parent2 = p->sub[p->selectedIndex];
4075  __set_pos(&child->p->view->pos, parent2->p->view->pos.x + parent2->p->view->pos.w - 1,
4076  menu->depth == 2 ? parent2->p->view->pos.y + parent2->selectedIndex : parent2->p->view->pos.y);
4077  }
4078  RzStrBuf *buf = __draw_menu(core, child);
4079  if (!buf) {
4080  return 0;
4081  }
4082  free(child->p->model->title);
4083  child->p->model->title = rz_strbuf_drain(buf);
4084  child->p->view->pos.w = rz_str_bounds(child->p->model->title, &child->p->view->pos.h);
4085  child->p->view->pos.h += 4;
4086  child->p->model->type = PANEL_TYPE_MENU;
4087  child->p->view->refresh = true;
4088  menu->refreshPanels[menu->n_refresh++] = child->p;
4089  menu->history[menu->depth++] = child;
4090  return 0;
4091 }
4092 
4093 void __add_menu(RzCore *core, const char *parent, const char *name, RzPanelsMenuCallback cb) {
4094  RzPanels *panels = core->panels;
4095  RzPanelsMenuItem *p_item, *item = RZ_NEW0(RzPanelsMenuItem);
4096  if (!item) {
4097  return;
4098  }
4099  if (parent) {
4100  void *addr = ht_pp_find(panels->mht, parent, NULL);
4101  p_item = (RzPanelsMenuItem *)addr;
4102  ht_pp_insert(panels->mht, sdb_fmt("%s.%s", parent, name), item);
4103  } else {
4104  p_item = panels->panels_menu->root;
4105  ht_pp_insert(panels->mht, sdb_fmt("%s", name), item);
4106  }
4107  item->n_sub = 0;
4108  item->selectedIndex = 0;
4109  item->name = name ? rz_str_new(name) : NULL;
4110  item->sub = NULL;
4111  item->cb = cb;
4112  item->p = RZ_NEW0(RzPanel);
4113  if (!item->p) {
4114  __free_menu_item(item);
4115  return;
4116  }
4117  item->p->model = RZ_NEW0(RzPanelModel);
4118  item->p->view = RZ_NEW0(RzPanelView);
4119  if (!item->p->model || !item->p->view) {
4120  __free_menu_item(item);
4121  return;
4122  }
4123  p_item->n_sub++;
4124  RzPanelsMenuItem **sub = realloc(p_item->sub, sizeof(RzPanelsMenuItem *) * p_item->n_sub);
4125  if (sub) {
4126  p_item->sub = sub;
4127  p_item->sub[p_item->n_sub - 1] = item;
4128  } else {
4129  __free_menu_item(item);
4130  }
4131 }
4132 
4134  RzPanels *panels = core->panels;
4135  void *addr = ht_pp_find(panels->mht, parent, NULL);
4136  RzPanelsMenuItem *p_item = (RzPanelsMenuItem *)addr;
4137  int i;
4138  for (i = 0; i < p_item->n_sub; i++) {
4139  RzPanelsMenuItem *sub = p_item->sub[i];
4140  ht_pp_delete(core->panels->mht, sdb_fmt("%s.%s", parent, sub->name));
4141  }
4142  p_item->sub = NULL;
4143  p_item->n_sub = 0;
4144  if (cb) {
4145  cb(core, parent);
4146  }
4147  RzPanelsMenu *menu = panels->panels_menu;
4148  __update_menu_contents(core, menu, p_item);
4149 }
4150 
4151 void __del_menu(RzCore *core) {
4152  RzPanels *panels = core->panels;
4153  RzPanelsMenu *menu = panels->panels_menu;
4154  int i;
4155  menu->depth--;
4156  for (i = 1; i < menu->depth; i++) {
4157  menu->history[i]->p->view->refresh = true;
4158  menu->refreshPanels[i - 1] = menu->history[i]->p;
4159  }
4160  menu->n_refresh = menu->depth - 1;
4161 }
4162 
4165  if (!buf) {
4166  return NULL;
4167  }
4168  int i;
4169  for (i = 0; i < item->n_sub; i++) {
4170  if (i == item->selectedIndex) {
4171  rz_strbuf_appendf(buf, "%s> %s" Color_RESET,
4172  core->cons->context->pal.graph_box2, item->sub[i]->name);
4173  } else {
4174  rz_strbuf_appendf(buf, " %s", item->sub[i]->name);
4175  }
4176  rz_strbuf_append(buf, " \n");
4177  }
4178  return buf;
4179 }
4180 
4182  RzPanel *p = parent->p;
4183  RzStrBuf *buf = __draw_menu(core, parent);
4184  if (!buf) {
4185  return;
4186  }
4187  free(p->model->title);
4188  p->model->title = rz_strbuf_drain(buf);
4189  int new_w = rz_str_bounds(p->model->title, &p->view->pos.h);
4190  p->view->pos.w = new_w;
4191  p->view->pos.h += 4;
4192  p->model->type = PANEL_TYPE_MENU;
4193  p->view->refresh = true;
4194  menu->refreshPanels[menu->n_refresh - 1] = p;
4195 }
4196 
4197 void __init_menu_saved_layout(void *_core, const char *parent) {
4198  char *dir_path = __get_panels_config_dir_path();
4199  RzList *dir = rz_sys_dir(dir_path);
4200  if (!dir) {
4201  free(dir_path);
4202  return;
4203  }
4204  RzCore *core = (RzCore *)_core;
4205  RzListIter *it;
4206  char *entry;
4207  rz_list_foreach (dir, it, entry) {
4208  if (strcmp(entry, ".") && strcmp(entry, "..")) {
4209  __add_menu(core, parent, entry, __load_layout_saved_cb);
4210  }
4211  }
4212  rz_list_free(dir);
4213  free(dir_path);
4214 }
4215 
4216 void __init_menu_color_settings_layout(void *_core, const char *parent) {
4217  RzCore *core = (RzCore *)_core;
4218  const char *color = core->cons->context->pal.graph_box2;
4219  char *now = rz_core_cmd_str(core, "eco.");
4220  rz_str_split(now, '\n');
4221  parent = "Settings.Colors";
4223  char *pos;
4224  RzListIter *iter;
4226  rz_list_foreach (list, iter, pos) {
4227  if (pos && !strcmp(now, pos)) {
4228  rz_strbuf_setf(buf, "%s%s", color, pos);
4230  continue;
4231  }
4232  __add_menu(core, parent, pos, __settings_colors_cb);
4233  }
4234  free(now);
4235  rz_list_free(list);
4237 }
4238 
4239 void __init_menu_disasm_settings_layout(void *_core, const char *parent) {
4240  RzCore *core = (RzCore *)_core;
4241  int i = 0;
4243  char *pos;
4244  RzListIter *iter;
4245  RzStrBuf *rsb = rz_strbuf_new(NULL);
4246  rz_list_foreach (list, iter, pos) {
4247  if (!strcmp(pos, "asm")) {
4248  __add_menu(core, parent, pos, __open_menu_cb);
4249  __init_menu_disasm_asm_settings_layout(core, "Settings.Disassembly.asm");
4250  } else {
4251  rz_strbuf_set(rsb, pos);
4252  rz_strbuf_append(rsb, ": ");
4253  rz_strbuf_append(rsb, rz_config_get(core->config, pos));
4254  __add_menu(core, parent, rz_strbuf_get(rsb), __config_toggle_cb);
4255  }
4256  i++;
4257  }
4258  rz_list_free(list);
4259  rz_strbuf_free(rsb);
4260 }
4261 
4262 static void __init_menu_disasm_asm_settings_layout(void *_core, const char *parent) {
4263  RzCore *core = (RzCore *)_core;
4265  char *pos;
4266  RzListIter *iter;
4267  RzStrBuf *rsb = rz_strbuf_new(NULL);
4268  rz_list_foreach (list, iter, pos) {
4269  rz_strbuf_set(rsb, pos);
4270  rz_strbuf_append(rsb, ": ");
4271  rz_strbuf_append(rsb, rz_config_get(core->config, pos));
4272  if (!strcmp(pos, "asm.var.summary") ||
4273  !strcmp(pos, "asm.arch") ||
4274  !strcmp(pos, "asm.bits") ||
4275  !strcmp(pos, "asm.cpu")) {
4276  __add_menu(core, parent, rz_strbuf_get(rsb), __config_value_cb);
4277  } else {
4278  __add_menu(core, parent, rz_strbuf_get(rsb), __config_toggle_cb);
4279  }
4280  }
4281  rz_list_free(list);
4282  rz_strbuf_free(rsb);
4283 }
4284 
4285 static void __init_menu_screen_settings_layout(void *_core, const char *parent) {
4286  RzCore *core = (RzCore *)_core;
4287  RzStrBuf *rsb = rz_strbuf_new(NULL);
4288  int i = 0;
4289  while (menus_settings_screen[i]) {
4290  const char *menu = menus_settings_screen[i];
4291  rz_strbuf_set(rsb, menu);
4292  rz_strbuf_append(rsb, ": ");
4293  rz_strbuf_append(rsb, rz_config_get(core->config, menu));
4294  if (!strcmp(menus_settings_screen[i], "scr.color")) {
4295  __add_menu(core, parent, rz_strbuf_get(rsb), __config_value_cb);
4296  } else {
4297  __add_menu(core, parent, rz_strbuf_get(rsb), __config_toggle_cb);
4298  }
4299  i++;
4300  }
4301  rz_strbuf_free(rsb);
4302 }
4303 
4305  RzPanels *panels = core->panels;
4306  RzPanelsMenu *panels_menu = RZ_NEW0(RzPanelsMenu);
4307  if (!panels_menu) {
4308  return false;
4309  }
4311  if (!root) {
4312  RZ_FREE(panels_menu);
4313  return false;
4314  }
4315  panels->panels_menu = panels_menu;
4316  panels_menu->root = root;
4317  root->n_sub = 0;
4318  root->name = NULL;
4319  root->sub = NULL;
4320 
4321  __load_config_menu(core);
4322 
4323  int i = 0;
4324  while (menus[i]) {
4325  __add_menu(core, NULL, menus[i], __open_menu_cb);
4326  i++;
4327  }
4328  char *parent = "File";
4329  i = 0;
4330  while (menus_File[i]) {
4331  if (!strcmp(menus_File[i], "Open")) {
4332  __add_menu(core, parent, menus_File[i], __open_file_cb);
4333  } else if (!strcmp(menus_File[i], "ReOpen")) {
4334  __add_menu(core, parent, menus_File[i], __open_menu_cb);
4335  } else if (!strcmp(menus_File[i], "Close")) {
4336  __add_menu(core, parent, menus_File[i], __close_file_cb);
4337  } else if (!strcmp(menus_File[i], "Save Layout")) {
4338  __add_menu(core, parent, menus_File[i], __save_layout_cb);
4339  } else if (!strcmp(menus_File[i], "Load Layout")) {
4340  __add_menu(core, parent, menus_File[i], __open_menu_cb);
4341  } else if (!strcmp(menus_File[i], "Clear Saved Layouts")) {
4342  __add_menu(core, parent, menus_File[i], __clear_layout_cb);
4343  } else if (!strcmp(menus_File[i], "Quit")) {
4344  __add_menu(core, parent, menus_File[i], __quit_cb);
4345  } else {
4346  __add_menu(core, parent, menus_File[i], __add_cmd_panel);
4347  }
4348  i++;
4349  }
4350 
4351  parent = "Settings";
4352  i = 0;
4353  while (menus_Settings[i]) {
4354  __add_menu(core, parent, menus_Settings[i++], __open_menu_cb);
4355  }
4356 
4357  parent = "Edit";
4358  i = 0;
4359  while (menus_Edit[i]) {
4360  if (!strcmp(menus_Edit[i], "Copy")) {
4361  __add_menu(core, parent, menus_Edit[i], __copy_cb);
4362  } else if (!strcmp(menus_Edit[i], "Paste")) {
4363  __add_menu(core, parent, menus_Edit[i], __paste_cb);
4364  } else if (!strcmp(menus_Edit[i], "Write String")) {
4365  __add_menu(core, parent, menus_Edit[i], __write_str_cb);
4366  } else if (!strcmp(menus_Edit[i], "Write Hex")) {
4367  __add_menu(core, parent, menus_Edit[i], __write_hex_cb);
4368  } else if (!strcmp(menus_Edit[i], "Write Value")) {
4369  __add_menu(core, parent, menus_Edit[i], __writeValueCb);
4370  } else if (!strcmp(menus_Edit[i], "Assemble")) {
4371  __add_menu(core, parent, menus_Edit[i], __assemble_cb);
4372  } else if (!strcmp(menus_Edit[i], "Fill")) {
4373  __add_menu(core, parent, menus_Edit[i], __fill_cb);
4374  } else if (!strcmp(menus_Edit[i], "io.cache")) {
4375  __add_menu(core, parent, menus_Edit[i], __open_menu_cb);
4376  } else {
4377  __add_menu(core, parent, menus_Edit[i], __add_cmd_panel);
4378  }
4379  i++;
4380  }
4381 
4382  {
4383  parent = "View";
4385  char *pos;
4386  RzListIter *iter;
4387  rz_list_foreach (list, iter, pos) {
4388  __add_menu(core, parent, pos, __add_cmd_panel);
4389  }
4390  }
4391 
4392  parent = "Tools";
4393  i = 0;
4394  while (menus_Tools[i]) {
4395  if (!strcmp(menus_Tools[i], "Calculator")) {
4396  __add_menu(core, parent, menus_Tools[i], __calculator_cb);
4397  } else if (!strcmp(menus_Tools[i], "R2 Shell")) {
4398  __add_menu(core, parent, menus_Tools[i], __rz_shell_cb);
4399  } else if (!strcmp(menus_Tools[i], "System Shell")) {
4400  __add_menu(core, parent, menus_Tools[i], __system_shell_cb);
4401  }
4402  i++;
4403  }
4404 
4405  parent = "Search";
4406  i = 0;
4407  while (menus_Search[i]) {
4408  if (!strcmp(menus_Search[i], "String (Whole Bin)")) {
4410  } else if (!strcmp(menus_Search[i], "String (Data Sections)")) {
4411  __add_menu(core, parent, menus_Search[i], __string_data_sec_cb);
4412  } else if (!strcmp(menus_Search[i], "ROP")) {
4413  __add_menu(core, parent, menus_Search[i], __rop_cb);
4414  } else if (!strcmp(menus_Search[i], "Code")) {
4415  __add_menu(core, parent, menus_Search[i], __code_cb);
4416  } else if (!strcmp(menus_Search[i], "Hexpairs")) {
4417  __add_menu(core, parent, menus_Search[i], __hexpairs_cb);
4418  }
4419  i++;
4420  }
4421 
4422  parent = "Emulate";
4423  i = 0;
4424  while (menus_Emulate[i]) {
4425  if (!strcmp(menus_Emulate[i], "Step From")) {
4426  __add_menu(core, parent, menus_Emulate[i], __esil_init_cb);
4427  } else if (!strcmp(menus_Emulate[i], "Step To")) {
4428  __add_menu(core, parent, menus_Emulate[i], __esil_step_to_cb);
4429  } else if (!strcmp(menus_Emulate[i], "Step Range")) {
4431  }
4432  i++;
4433  }
4434 
4435  {
4436  parent = "Debug";
4438  char *pos;
4439  RzListIter *iter;
4440  rz_list_foreach (list, iter, pos) {
4441  if (!strcmp(pos, "Breakpoints")) {
4442  __add_menu(core, parent, pos, __break_points_cb);
4443  } else if (!strcmp(pos, "Watchpoints")) {
4444  __add_menu(core, parent, pos, __watch_points_cb);
4445  } else if (!strcmp(pos, "Continue")) {
4446  __add_menu(core, parent, pos, __continue_cb);
4447  } else if (!strcmp(pos, "Step")) {
4448  __add_menu(core, parent, pos, __step_cb);
4449  } else if (!strcmp(pos, "Step Over")) {
4450  __add_menu(core, parent, pos, __step_over_cb);
4451  } else if (!strcmp(pos, "Reload")) {
4452  __add_menu(core, parent, pos, __reload_cb);
4453  } else {
4454  __add_menu(core, parent, pos, __add_cmd_panel);
4455  }
4456  }
4457  }
4458 
4459  parent = "Analyze";
4460  i = 0;
4461  while (menus_Analyze[i]) {
4462  if (!strcmp(menus_Analyze[i], "Function")) {
4463  __add_menu(core, parent, menus_Analyze[i], __function_cb);
4464  } else if (!strcmp(menus_Analyze[i], "Symbols")) {
4465  __add_menu(core, parent, menus_Analyze[i], __symbols_cb);
4466  } else if (!strcmp(menus_Analyze[i], "Program")) {
4467  __add_menu(core, parent, menus_Analyze[i], __program_cb);
4468  } else if (!strcmp(menus_Analyze[i], "Calls")) {
4469  __add_menu(core, parent, menus_Analyze[i], __calls_cb);
4470  } else if (!strcmp(menus_Analyze[i], "References")) {
4471  __add_menu(core, parent, menus_Analyze[i], __references_cb);
4472  }
4473  i++;
4474  }
4475  parent = "Help";
4476  i = 0;
4477  while (menus_Help[i]) {
4478  if (!strcmp(menus_Help[i], "License")) {
4479  __add_menu(core, parent, menus_Help[i], __license_cb);
4480  } else if (!strcmp(menus_Help[i], "Version")) {
4481  __add_menu(core, parent, menus_Help[i], __version_cb);
4482  } else if (!strcmp(menus_Help[i], "Fortune")) {
4483  __add_menu(core, parent, menus_Help[i], __fortune_cb);
4484  } else {
4485  __add_menu(core, parent, menus_Help[i], __help_cb);
4486  }
4487  i++;
4488  }
4489 
4490  parent = "File.ReOpen";
4491  i = 0;
4492  while (menus_ReOpen[i]) {
4493  if (!strcmp(menus_ReOpen[i], "In RW")) {
4494  __add_menu(core, parent, menus_ReOpen[i], __rw_cb);
4495  } else if (!strcmp(menus_ReOpen[i], "In Debugger")) {
4496  __add_menu(core, parent, menus_ReOpen[i], __debugger_cb);
4497  }
4498  i++;
4499  }
4500 
4501  parent = "File.Load Layout";
4502  i = 0;
4503  while (menus_loadLayout[i]) {
4504  if (!strcmp(menus_loadLayout[i], "Saved")) {
4505  __add_menu(core, parent, menus_loadLayout[i], __open_menu_cb);
4506  } else if (!strcmp(menus_loadLayout[i], "Default")) {
4508  }
4509  i++;
4510  }
4511 
4512  __init_menu_saved_layout(core, "File.Load Layout.Saved");
4513 
4514  __init_menu_color_settings_layout(core, "Settings.Colors");
4515  __init_menu_disasm_settings_layout(core, "Settings.Disassembly");
4516  __init_menu_screen_settings_layout(core, "Settings.Screen");
4517 
4518  parent = "Edit.io.cache";
4519  i = 0;
4520  while (menus_iocache[i]) {
4521  if (!strcmp(menus_iocache[i], "On")) {
4522  __add_menu(core, parent, menus_iocache[i], __io_cache_on_cb);
4523  } else if (!strcmp(menus_iocache[i], "Off")) {
4524  __add_menu(core, parent, menus_iocache[i], __io_cache_off_cb);
4525  }
4526  i++;
4527  }
4528 
4529  panels_menu->history = calloc(8, sizeof(RzPanelsMenuItem *));
4530  __clear_panels_menu(core);
4531  panels_menu->refreshPanels = calloc(8, sizeof(RzPanel *));
4532  return true;
4533 }
4534 
4535 int cmpstr(const void *_a, const void *_b) {
4536  char *a = (char *)_a, *b = (char *)_b;
4537  return strcmp(a, b);
4538 }
4539 
4540 RzList *__sorted_list(RzCore *core, char *menu[], int count) {
4541  RzList *list = rz_list_new();
4542  int i;
4543  for (i = 0; i < count; i++) {
4544  if (menu[i]) {
4545  (void)rz_list_append(list, menu[i]);
4546  }
4547  }
4549  return list;
4550 }
4551 
4553  int i = 0;
4554  for (i = 0; i < pmi->n_sub; i++) {
4555  RzPanelsMenuItem *sub = pmi->sub[i];
4556  if (sub) {
4557  sub->selectedIndex = 0;
4559  }
4560  }
4561 }
4562 
4564  RzPanels *p = core->panels;
4565  RzPanelsMenu *pm = p->panels_menu;
4567  pm->root->selectedIndex = 0;
4568  pm->history[0] = pm->root;
4569  pm->depth = 1;
4570  pm->n_refresh = 0;
4571 }
4572 
4573 bool __init_panels(RzCore *core, RzPanels *panels) {
4574  panels->panel = calloc(sizeof(RzPanel *), PANEL_NUM_LIMIT);
4575  if (!panels->panel) {
4576  return false;
4577  }
4578  int i;
4579  for (i = 0; i < PANEL_NUM_LIMIT; i++) {
4580  panels->panel[i] = RZ_NEW0(RzPanel);
4581  panels->panel[i]->model = RZ_NEW0(RzPanelModel);
4583  panels->panel[i]->view = RZ_NEW0(RzPanelView);
4584  if (!panels->panel[i]->model || !panels->panel[i]->view) {
4585  return false;
4586  }
4587  }
4588  return true;
4589 }
4590 
4592  RModal *modal = RZ_NEW0(RModal);
4593  if (!modal) {
4594  return NULL;
4595  }
4596  __set_pos(&modal->pos, 0, 0);
4597  modal->idx = 0;
4598  modal->offset = 0;
4599  return modal;
4600 }
4601 
4603  free(panel->model->title);
4604  free(panel->model->cmd);
4605  free(panel->model->cmdStrCache);
4606  free(panel->model->readOnly);
4607  free(panel->model);
4608 }
4609 
4610 void __free_modal(RModal **modal) {
4611  free(*modal);
4612  *modal = NULL;
4613 }
4614 
4616  if (!item) {
4617  return;
4618  }
4619  int i;
4620  free(item->name);
4621  free(item->p->model);
4622  free(item->p->view);
4623  free(item->p);
4624  for (i = 0; i < item->n_sub; i++) {
4625  __free_menu_item(item->sub[i]);
4626  }
4627  free(item->sub);
4628  free(item);
4629 }
4630 
4632  RzPanels *panels = core->panels;
4633  RzPanel *cur = __get_cur_panel(panels);
4635  core->offset = cur->model->addr;
4636  }
4637 }
4638 
4640  RzPanels *panels = core->panels;
4641  if (!panels) {
4642  return;
4643  }
4644  RzConsCanvas *can = panels->can;
4645  if (!can) {
4646  return;
4647  }
4648  rz_cons_gotoxy(0, 0);
4649  int i, h, w = rz_cons_get_size(&h);
4650  if (!rz_cons_canvas_resize(can, w, h)) {
4651  return;
4652  }
4653  RzStrBuf *title = rz_strbuf_new(" ");
4654  bool utf8 = rz_config_get_b(core->config, "scr.utf8");
4655  if (firstRun) {
4656  rz_config_set_b(core->config, "scr.utf8", false);
4657  }
4658 
4659  __refresh_core_offset(core);
4660  __set_refresh_all(core, false, false);
4661 
4662  // TODO use getPanel
4663  for (i = 0; i < panels->n_panels; i++) {
4664  if (i != panels->curnode) {
4665  __panel_print(core, can, __get_panel(panels, i), 0);
4666  }
4667  }
4668  if (panels->mode == PANEL_MODE_MENU) {
4669  __panel_print(core, can, __get_cur_panel(panels), 0);
4670  } else {
4671  __panel_print(core, can, __get_cur_panel(panels), 1);
4672  }
4673  for (i = 0; i < panels->panels_menu->n_refresh; i++) {
4674  __panel_print(core, can, panels->panels_menu->refreshPanels[i], 1);
4675  }
4676  (void)rz_cons_canvas_gotoxy(can, -can->sx, -can->sy);
4677  rz_cons_canvas_fill(can, -can->sx, -can->sy, w, 1, ' ');
4678  const char *color = core->cons->context->pal.graph_box2;
4679  if (panels->mode == PANEL_MODE_ZOOM) {
4680  rz_strbuf_appendf(title, "%s Zoom Mode | Press Enter or q to quit" Color_RESET, color);
4681  } else if (panels->mode == PANEL_MODE_WINDOW) {
4682  rz_strbuf_appendf(title, "%s Window Mode | hjkl: move around the panels | q: quit the mode | Enter: Zoom mode" Color_RESET, color);
4683  } else {
4684  RzPanelsMenuItem *parent = panels->panels_menu->root;
4685  for (i = 0; i < parent->n_sub; i++) {
4686  RzPanelsMenuItem *item = parent->sub[i];
4687  if (panels->mode == PANEL_MODE_MENU && i == parent->selectedIndex) {
4688  rz_strbuf_appendf(title, "%s[%s]" Color_RESET, color, item->name);
4689  } else {
4690  rz_strbuf_appendf(title, " %s ", item->name);
4691  }
4692  }
4693  }
4694  if (panels->mode == PANEL_MODE_MENU) {
4696  rz_cons_canvas_write(can, rz_strbuf_get(title));
4698  } else {
4700  rz_cons_canvas_write(can, rz_strbuf_get(title));
4701  }
4702  rz_strbuf_setf(title, "[0x%08" PFMT64x "]", core->offset);
4703  i = -can->sx + w - rz_strbuf_length(title);
4704  (void)rz_cons_canvas_gotoxy(can, i, -can->sy);
4705  rz_cons_canvas_write(can, rz_strbuf_get(title));
4706 
4707  int tab_pos = i;
4708  for (i = core->panels_root->n_panels; i > 0; i--) {
4709  RzPanels *panels = core->panels_root->panels[i - 1];
4710  char *name = NULL;
4711  if (panels) {
4712  name = panels->name;
4713  }
4714  if (i - 1 == core->panels_root->cur_panels) {
4715  if (!name) {
4716  rz_strbuf_setf(title, "%s[%d] " Color_RESET, color, i);
4717  } else {
4718  rz_strbuf_setf(title, "%s[%s] " Color_RESET, color, name);
4719  }
4720  tab_pos -= rz_str_ansi_len(rz_strbuf_get(title));
4721  } else {
4722  if (!name) {
4723  rz_strbuf_setf(title, "%d ", i);
4724  } else {
4725  rz_strbuf_setf(title, "%s ", name);
4726  }
4727  tab_pos -= rz_strbuf_length(title);
4728  }
4729  (void)rz_cons_canvas_gotoxy(can, tab_pos, -can->sy);
4730  rz_cons_canvas_write(can, rz_strbuf_get(title));
4731  }
4732  rz_strbuf_set(title, "Tab ");
4733  tab_pos -= rz_strbuf_length(title);
4734  (void)rz_cons_canvas_gotoxy(can, tab_pos, -can->sy);
4735  rz_cons_canvas_write(can, rz_strbuf_get(title));
4736  rz_strbuf_free(title);
4737 
4738  if (firstRun) {
4739  firstRun = false;
4740  rz_config_set_b(core->config, "scr.utf8", utf8);
4741  RzPanel *cur = __get_cur_panel(core->panels);
4742  cur->view->refresh = true;
4743  __panels_refresh(core);
4744  return;
4745  }
4746  rz_cons_canvas_print(can);
4747  if (core->scr_gadgets) {
4748  rz_core_gadget_print(core);
4749  }
4750  rz_cons_flush();
4751 }
4752 
4754  RzPanels *panels = core->panels;
4755  int i;
4756  int h, w = rz_cons_get_size(&h);
4757  for (i = 0; i < panels->n_panels; i++) {
4758  RzPanel *panel = __get_panel(panels, i);
4759  if ((panel->view->edge & (1 << PANEL_EDGE_BOTTOM)) && (panel->view->pos.y + panel->view->pos.h < h)) {
4760  panel->view->pos.h = h - panel->view->pos.y;
4761  }
4762  if ((panel->view->edge & (1 << PANEL_EDGE_RIGHT)) && (panel->view->pos.x + panel->view->pos.w < w)) {
4763  panel->view->pos.w = w - panel->view->pos.x;
4764  }
4765  }
4766  __do_panels_refresh(core);
4767 }
4768 
4770  if (!core->panels) {
4771  return;
4772  }
4773  __panel_all_clear(core->panels);
4775 }
4776 
4778  rz_core_task_enqueue_oneshot(&core->tasks, (RzCoreTaskOneShot)__do_panels_resize, core);
4779 }
4780 
4783 }
4784 
4787 }
4788 
4790  RzPanel *cur = __get_cur_panel(core->panels);
4793  cur->view->refresh = true;
4794  }
4795 }
4796 
4798  if (!core || !core->panels) {
4799  return;
4800  }
4801  int i;
4802  const char *sp = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SP);
4803  if (!sp) {
4804  return;
4805  }
4806  const ut64 stackbase = rz_reg_getv(core->analysis->reg, sp);
4807  RzPanels *panels = core->panels;
4808  for (i = 1; i < panels->n_panels; i++) {
4809  RzPanel *panel = __get_panel(panels, i);
4810  if (panel->model->cmd && __check_panel_type(panel, PANEL_CMD_STACK) && panel->model->baseAddr != stackbase) {
4811  panel->model->baseAddr = stackbase;
4812  __set_panel_addr(core, panel, stackbase - rz_config_get_i(core->config, "stack.delta") + core->print->cur);
4813  }
4814  }
4815 }
4816 
4818  Sdb *db = core->panels->rotate_db;
4819  sdb_ptr_set(db, "pd", &__rotate_disasm_cb, 0);
4820  sdb_ptr_set(db, "p==", &__rotate_entropy_h_cb, 0);
4821  sdb_ptr_set(db, "p=", &__rotate_entropy_v_cb, 0);
4822  sdb_ptr_set(db, "px", &__rotate_hexdump_cb, 0);
4824  sdb_ptr_set(db, "af", &__rotate_function_cb, 0);
4826 }
4827 
4828 void __init_sdb(RzCore *core) {
4829  Sdb *db = core->panels->db;
4830  sdb_set(db, "Symbols", "isq", 0);
4831  sdb_set(db, "Stack", "px 256@r:SP", 0);
4832  sdb_set(db, "Locals", "afvd", 0);
4833  sdb_set(db, "Registers", PANEL_CMD_REGISTERS, 0);
4834  sdb_set(db, "RegisterRefs", "drr", 0);
4835  sdb_set(db, "Disassembly", "pd", 0);
4836  sdb_set(db, "Disassemble Summary", "pdsf", 0);
4837  sdb_set(db, "Graph", "agf", 0);
4838  sdb_set(db, "Tiny Graph", "agft", 0);
4839  sdb_set(db, "Info", "i", 0);
4840  sdb_set(db, "Database", "k ***", 0);
4841  sdb_set(db, "Console", "$console", 0);
4842  sdb_set(db, "Hexdump", "xc $r*16", 0);
4843  sdb_set(db, "Xrefs", "axl", 0);
4844  sdb_set(db, "Functions", "afl", 0);
4845  sdb_set(db, "Function Calls", "aflm", 0);
4846  sdb_set(db, "Comments", "CC", 0);
4847  sdb_set(db, "Entropy", "p=e 100", 0);
4848  sdb_set(db, "Entropy Fire", "p==e 100", 0);
4849  sdb_set(db, "DRX", "drx", 0);
4850  sdb_set(db, "Sections", "iSq", 0);
4851  sdb_set(db, "Segments", "iSSq", 0);
4852  sdb_set(db, PANEL_TITLE_STRINGS_DATA, "izq", 0);
4853  sdb_set(db, PANEL_TITLE_STRINGS_BIN, "izzq", 0);
4854  sdb_set(db, "Maps", "dm", 0);
4855  sdb_set(db, "Modules", "dmm", 0);
4856  sdb_set(db, "Backtrace", "dbt", 0);
4857  sdb_set(db, "Breakpoints", "db", 0);
4858  sdb_set(db, "Imports", "iiq", 0);
4859  sdb_set(db, "Clipboard", "yx", 0);
4860  sdb_set(db, "New", "o", 0);
4861  sdb_set(db, "Var READ address", "afvR", 0);
4862  sdb_set(db, "Var WRITE address", "afvW", 0);
4863  sdb_set(db, "Summary", "pdsf", 0);
4864  sdb_set(db, "Classes", "icq", 0);
4865  sdb_set(db, "Methods", "ic", 0);
4866  sdb_set(db, "Relocs", "ir", 0);
4867  sdb_set(db, "Headers", "iH", 0);
4868  sdb_set(db, "File Hashes", "it", 0);
4869 }
4870 
4872  Sdb *db = core->panels->almighty_db;
4873  SdbKv *kv;
4874  SdbListIter *sdb_iter;
4875  SdbList *sdb_list = sdb_foreach_list(core->panels->db, true);
4876  ls_foreach (sdb_list, sdb_iter, kv) {
4877  const char *key = sdbkv_key(kv);
4879  }
4880  sdb_ptr_set(db, "Search strings in data sections", &__search_strings_data_create, 0);
4881  sdb_ptr_set(db, "Search strings in the whole bin", &__search_strings_bin_create, 0);
4882  sdb_ptr_set(db, "Create New", &__create_panel_input, 0);
4883  sdb_ptr_set(db, "Change Command of Current Panel", &__replace_current_panel_input, 0);
4884  if (rz_config_get_b(core->config, "cfg.debug")) {
4885  sdb_ptr_set(db, "Put Breakpoints", &__put_breakpoints_cb, 0);
4886  sdb_ptr_set(db, "Continue", &__continue_almighty_cb, 0);
4887  sdb_ptr_set(db, "Step", &__step_almighty_cb, 0);
4888  sdb_ptr_set(db, "Step Over", &__step_over_almighty_cb, 0);
4889  }
4890 }
4891 
4892 void __init_all_dbs(RzCore *core) {
4893  __init_sdb(core);
4894  __init_almighty_db(core);
4895  __init_rotate_db(core);
4896 }
4897 
4898 void __create_panel_db(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title) {
4899  RzCore *core = (RzCore *)user;
4900  char *cmd = sdb_get(core->panels->db, title, 0);
4901  if (!cmd) {
4902  return;
4903  }
4904  __create_panel(core, panel, dir, title, cmd);
4905 }
4906 
4907 void __replace_current_panel_input(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title) {
4908  RzCore *core = (RzCore *)user;
4909  char *cmd = __show_status_input(core, "New command: ");
4910  if (RZ_STR_ISNOTEMPTY(cmd)) {
4911  __replace_cmd(core, cmd, cmd);
4912  }
4913  free(cmd);
4914 }
4915 
4916 void __create_panel_input(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title) {
4917  RzCore *core = (RzCore *)user;
4918  char *cmd = __show_status_input(core, "Command: ");
4919  if (!cmd) {
4920  return;
4921  }
4922  __create_panel(core, panel, dir, cmd, cmd);
4923 }
4924 
4925 void __create_panel(RzCore *core, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title, const char *cmd) {
4926  if (!__check_panel_num(core)) {
4927  return;
4928  }
4929  switch (dir) {
4930  case VERTICAL:
4931  __split_panel_vertical(core, panel, title, cmd);
4932  break;
4933  case HORIZONTAL:
4934  __split_panel_horizontal(core, panel, title, cmd);
4935  break;
4936  case NONE:
4937  __replace_cmd(core, title, cmd);
4938  break;
4939  }
4940 }
4941 
4942 void __search_strings_data_create(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title) {
4943  RzCore *core = (RzCore *)user;
4944  char *strings = __search_strings(core, false);
4945  __create_panel(core, panel, dir, title, strings);
4946  free(strings);
4947 }
4948 
4949 void __search_strings_bin_create(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title) {
4950  RzCore *core = (RzCore *)user;
4951  char *strings = __search_strings(core, true);
4952  __create_panel(core, panel, dir, title, strings);
4953  free(strings);
4954 }
4955 
4956 RZ_OWN char *__search_strings(RzCore *core, bool whole) {
4957  const char *title = whole ? PANEL_TITLE_STRINGS_BIN : PANEL_TITLE_STRINGS_DATA;
4958  const char *str = __show_status_input(core, "Search Strings: ");
4959  char *db_val = __search_db(core, title);
4960  char *ret = rz_str_newf("%s~%s", db_val, str);
4961  free(db_val);
4962  return ret;
4963 }
4964 
4965 void __put_breakpoints_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title) {
4966  __break_points_cb(user);
4967 }
4968 
4969 void __continue_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title) {
4970  __continue_cb(user);
4972 }
4973 
4974 void __step_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title) {
4975  __step_cb(user);
4976 }
4977 
4978 void __step_over_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title) {
4979  __step_over_cb(user);
4980 }
4981 
4982 void __mht_free_kv(HtPPKv *kv) {
4983  free(kv->key);
4984  __free_menu_item((RzPanelsMenuItem *)kv->value);
4985 }
4986 
4987 bool __init(RzCore *core, RzPanels *panels, int w, int h) {
4988  panels->panel = NULL;
4989  panels->n_panels = 0;
4990  panels->columnWidth = 80;
4991  if (rz_config_get_b(core->config, "cfg.debug")) {
4993  } else {
4995  }
4996  panels->autoUpdate = false;
4997  panels->mouse_on_edge_x = false;
4998  panels->mouse_on_edge_y = false;
4999  panels->mouse_orig_x = 0;
5000  panels->mouse_orig_y = 0;
5001  panels->can = __create_new_canvas(core, w, h);
5002  panels->db = sdb_new0();
5003  panels->rotate_db = sdb_new0();
5004  panels->almighty_db = sdb_new0();
5005  panels->mht = ht_pp_new(NULL, (HtPPKvFreeFunc)__mht_free_kv, (HtPPCalcSizeV)strlen);
5006  panels->prevMode = PANEL_MODE_DEFAULT;
5007  panels->name = NULL;
5008 
5009  if (w < 140) {
5010  panels->columnWidth = w / 3;
5011  }
5012  return true;
5013 }
5014 
5016  RzCore *core = line->user;
5017  RzList *files = rz_id_storage_list(core->io->files);
5018  int num_files = rz_list_length(files);
5019  if (line->file_hist_index >= num_files || line->file_hist_index < 0) {
5020  return false;
5021  }
5022  line->file_hist_index++;
5023  RzIODesc *desc = rz_list_get_n(files, num_files - line->file_hist_index);
5024  if (desc) {
5025  strncpy(line->buffer.data, desc->name, RZ_LINE_BUFSIZE - 1);
5026  line->buffer.index = line->buffer.length = strlen(line->buffer.data);
5027  }
5029  return true;
5030 }
5031 
5033  RzCore *core = line->user;
5034  RzList *files = rz_id_storage_list(core->io->files);
5035  int num_files = rz_list_length(files);
5036  if (line->file_hist_index <= 0 || line->file_hist_index > num_files) {
5037  return false;
5038  }
5039  line->file_hist_index--;
5040  if (line->file_hist_index <= 0) {
5041  line->buffer.data[0] = '\0';
5042  line->buffer.index = line->buffer.length = 0;
5043  return false;
5044  }
5045  RzIODesc *desc = rz_list_get_n(files, num_files - line->file_hist_index);
5046  if (desc) {
5047  strncpy(line->buffer.data, desc->name, RZ_LINE_BUFSIZE - 1);
5048  line->buffer.index = line->buffer.length = strlen(line->buffer.data);
5049  }
5051  return true;
5052 }
5053 
5054 void __handle_menu(RzCore *core, const int key) {
5055  RzPanels *panels = core->panels;
5056  RzPanelsMenu *menu = panels->panels_menu;
5057  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
5058  RzPanelsMenuItem *child = parent->sub[parent->selectedIndex];
5059  rz_cons_switchbuf(false);
5060  switch (key) {
5061  case 'h':
5062  if (menu->depth <= 2) {
5063  menu->n_refresh = 0;
5064  if (menu->root->selectedIndex > 0) {
5065  menu->root->selectedIndex--;
5066  } else {
5067  menu->root->selectedIndex = menu->root->n_sub - 1;
5068  }
5069  if (menu->depth == 2) {
5070  menu->depth = 1;
5071  (void)(menu->root->sub[menu->root->selectedIndex]->cb(core));
5072  }
5073  } else {
5074  __del_menu(core);
5075  }
5076  break;
5077  case 'j': {
5078  if (menu->depth == 1) {
5079  (void)(child->cb(core));
5080  } else {
5081  parent->selectedIndex = RZ_MIN(parent->n_sub - 1, parent->selectedIndex + 1);
5082  __update_menu_contents(core, menu, parent);
5083  }
5084  } break;
5085  case 'k': {
5086  if (menu->depth < 2) {
5087  break;
5088  }
5089  RzPanelsMenuItem *parent = menu->history[menu->depth - 1];
5090  if (parent->selectedIndex > 0) {
5091  parent->selectedIndex--;
5092  __update_menu_contents(core, menu, parent);
5093  } else if (menu->depth == 2) {
5094  menu->depth--;
5095  }
5096  } break;
5097  case 'l': {
5098  if (menu->depth == 1) {
5099  menu->root->selectedIndex++;
5100  menu->root->selectedIndex %= menu->root->n_sub;
5101  break;
5102  }
5103  if (parent->sub[parent->selectedIndex]->sub) {
5104  (void)(parent->sub[parent->selectedIndex]->cb(core));
5105  } else {
5106  menu->n_refresh = 0;
5107  menu->root->selectedIndex++;
5108  menu->root->selectedIndex %= menu->root->n_sub;
5109  menu->depth = 1;
5110  (void)(menu->root->sub[menu->root->selectedIndex]->cb(core));
5111  }
5112  } break;
5113  case 'm':
5114  case 'q':
5115  case 'Q':
5116  case -1:
5117  if (panels->panels_menu->depth > 1) {
5118  __del_menu(core);
5119  } else {
5120  menu->n_refresh = 0;
5122  __get_cur_panel(panels)->view->refresh = true;
5123  }
5124  break;
5125  case '$':
5126  rz_core_reg_set_by_role_or_name(core, "PC", core->offset);
5127  break;
5128  case ' ':
5129  case '\r':
5130  case '\n':
5131  (void)(child->cb(core));
5132  break;
5133  case 9:
5134  menu->n_refresh = 0;
5135  __handle_tab_key(core, false);
5136  break;
5137  case 'Z':
5138  menu->n_refresh = 0;
5139  __handle_tab_key(core, true);
5140  break;
5141  case ':':
5142  menu->n_refresh = 0;
5143  __handlePrompt(core, panels);
5144  break;
5145  case '?':
5146  menu->n_refresh = 0;
5147  __toggle_help(core);
5148  break;
5149  case '"':
5150  menu->n_refresh = 0;
5151  __create_almighty(core, __get_panel(panels, 0), panels->almighty_db);
5153  break;
5154  }
5155 }
5156 
5157 bool __handle_console(RzCore *core, RzPanel *panel, const int key) {
5158  if (!__check_panel_type(panel, PANEL_CMD_CONSOLE)) {
5159  return false;
5160  }
5161  rz_cons_switchbuf(false);
5162  switch (key) {
5163  case 'i': {
5164  char cmd[128] = { 0 };
5165  char *prompt = rz_str_newf("[0x%08" PFMT64x "]) ", core->offset);
5166  __panel_prompt(prompt, cmd, sizeof(cmd));
5167  if (*cmd) {
5168  if (!strcmp(cmd, "clear")) {
5169  rz_core_cmd0(core, ":>$console");
5170  } else {
5171  rz_core_cmdf(core, "?e %s %s>>$console", prompt, cmd);
5172  rz_core_cmdf(core, "%s >>$console", cmd);
5173  }
5174  }
5175  panel->view->refresh = true;
5176  }
5177  return true;
5178  case 'l':
5179  rz_core_cmd0(core, ":>$console");
5180  panel->view->refresh = true;
5181  return true;
5182  default:
5183  // add more things later
5184  break;
5185  }
5186  return false;
5187 }
5188 
5189 void __handle_tab_key(RzCore *core, bool shift) {
5190  __set_cursor(core, false);
5191  RzPanels *panels = core->panels;
5192  RzPanel *cur = __get_cur_panel(panels);
5193  rz_cons_switchbuf(false);
5194  cur->view->refresh = true;
5195  if (!shift) {
5196  if (panels->mode == PANEL_MODE_MENU) {
5197  __set_curnode(core, 0);
5199  } else if (panels->mode == PANEL_MODE_ZOOM) {
5200  __set_curnode(core, ++panels->curnode);
5201  } else {
5202  __set_curnode(core, ++panels->curnode);
5203  }
5204  } else {
5205  if (panels->mode == PANEL_MODE_MENU) {
5206  __set_curnode(core, panels->n_panels - 1);
5208  } else if (panels->mode == PANEL_MODE_ZOOM) {
5209  __set_curnode(core, --panels->curnode);
5210  } else {
5211  __set_curnode(core, --panels->curnode);
5212  }
5213  }
5214  cur = __get_cur_panel(panels);
5215  cur->view->refresh = true;
5216 }
5217 
5219  __set_geometry(&panel->view->prevPos, panel->view->pos.x, panel->view->pos.y,
5220  panel->view->pos.w, panel->view->pos.h);
5221 }
5222 
5224  __set_geometry(&panel->view->pos, panel->view->prevPos.x, panel->view->prevPos.y,
5225  panel->view->prevPos.w, panel->view->prevPos.h);
5226 }
5227 
5229  char *home_datadir = rz_path_home_prefix(RZ_DATADIR);
5230  char *res = rz_file_path_join(home_datadir, ".rzpanels");
5231  free(home_datadir);
5232  return res;
5233 }
5234 
5235 char *__create_panels_config_path(const char *file) {
5236  char *dir_path = __get_panels_config_dir_path();
5237  rz_sys_mkdirp(dir_path);
5238  char *file_path = rz_str_newf(RZ_JOIN_2_PATHS("%s", "%s"), dir_path, file);
5239  RZ_FREE(dir_path);
5240  return file_path;
5241 }
5242 
5244  char *dir_path = __get_panels_config_dir_path();
5245  RzList *dir = rz_sys_dir(dir_path);
5246  if (!dir_path || !dir) {
5247  free(dir_path);
5248  return NULL;
5249  }
5250  char *tmp = NULL;
5251  RzListIter *it;
5252  char *entry;
5253  rz_list_foreach (dir, it, entry) {
5254  if (!strcmp(entry, file)) {
5255  tmp = entry;
5256  break;
5257  }
5258  }
5259  if (!tmp) {
5260  rz_list_free(dir);
5261  free(dir_path);
5262  return NULL;
5263  }
5264  char *ret = rz_str_newf(RZ_JOIN_2_PATHS("%s", "%s"), dir_path, tmp);
5265  rz_list_free(dir);
5266  free(dir_path);
5267  return ret;
5268 }
5269 
5270 RZ_API void rz_save_panels_layout(RzCore *core, const char *oname) {
5271  int i;
5272  if (!core->panels) {
5273  return;
5274  }
5275  const char *name = oname;
5276  if (RZ_STR_ISEMPTY(name)) {
5277  name = __show_status_input(core, "Name for the layout: ");
5278  if (RZ_STR_ISEMPTY(name)) {
5279  (void)__show_status(core, "Name can't be empty!");
5280  return;
5281  }
5282  }
5284  RzPanels *panels = core->panels;
5285  PJ *pj = pj_new();
5286  pj_a(pj);
5287  for (i = 0; i < panels->n_panels; i++) {
5288  RzPanel *panel = __get_panel(panels, i);
5289  pj_o(pj);
5290  pj_ks(pj, "title", panel->model->title);
5291  pj_ks(pj, "cmd", panel->model->cmd);
5292  pj_kn(pj, "x", panel->view->pos.x);
5293  pj_kn(pj, "y", panel->view->pos.y);
5294  pj_kn(pj, "w", panel->view->pos.w);
5295  pj_kn(pj, "h", panel->view->pos.h);
5296  pj_end(pj);
5297  }
5298  pj_end(pj);
5299  FILE *fd = rz_sys_fopen(config_path, "w");
5300  if (fd) {
5301  char *pjs = pj_drain(pj);
5302  fprintf(fd, "%s\n", pjs);
5303  free(pjs);
5304  fclose(fd);
5305  __update_menu(core, "File.Load Layout.Saved", __init_menu_saved_layout);
5306  (void)__show_status(core, "Panels layout saved!");
5307  }
5308  free(config_path);
5309 }
5310 
5312  RzList *themes_list = rz_core_theme_list(core);
5313  RzListIter *th_iter;
5314  char *th;
5315  int i = 0;
5316  rz_list_foreach (themes_list, th_iter, th) {
5317  menus_Colors[i++] = th;
5318  }
5319 }
5320 
5321 RZ_API bool rz_load_panels_layout(RzCore *core, const char *_name) {
5322  if (!core->panels) {
5323  return false;
5324  }
5326  if (!config_path) {
5327  char *tmp = rz_str_newf("No saved layout found for the name: %s", _name);
5328  (void)__show_status(core, tmp);
5329  free(tmp);
5330  return false;
5331  }
5332  char *panels_config = rz_file_slurp(config_path, NULL);
5333  free(config_path);
5334  if (!panels_config) {
5335  char *tmp = rz_str_newf("Layout is empty: %s", _name);
5336  (void)__show_status(core, tmp);
5337  free(tmp);
5338  return false;
5339  }
5340  RzPanels *panels = core->panels;
5341  __panel_all_clear(panels);
5342  panels->n_panels = 0;
5343  __set_curnode(core, 0);
5344 
5345  RzJson *json = rz_json_parse(panels_config);
5346  if (!json || json->type != RZ_JSON_ARRAY) {
5347  free(panels_config);
5348  return false;
5349  }
5350  RzJson *child, *baby;
5351  const char *title = NULL, *cmd = NULL;
5352  int x = 0, y = 0, w = 0, h = 0;
5353  // Configuration stored as an array of JSON objects
5354  for (child = json->children.first; child; child = child->next) {
5355  if (child->type != RZ_JSON_OBJECT) {
5356  break;
5357  }
5358  size_t params_read = 0;
5359  for (baby = child->children.first; baby; baby = baby->next) {
5360  if (params_read == 6) {
5361  break;
5362  }
5363  if (baby->type != RZ_JSON_INTEGER && baby->type != RZ_JSON_STRING) {
5364  continue;
5365  }
5366  // Get window title and executed command
5367  if (strcmp(baby->key, "title") == 0) {
5368  title = baby->str_value;
5369  params_read++;
5370  } else if (strcmp(baby->key, "cmd") == 0) {
5371  cmd = baby->str_value;
5372  params_read++;
5373  // Parse window geometry
5374  } else if (strcmp(baby->key, "x") == 0) {
5375  x = baby->num.u_value;
5376  params_read++;
5377  } else if (strcmp(baby->key, "y") == 0) {
5378  y = baby->num.u_value;
5379  params_read++;
5380  } else if (strcmp(baby->key, "w") == 0) {
5381  w = baby->num.u_value;
5382  params_read++;
5383  } else if (strcmp(baby->key, "h") == 0) {
5384  h = baby->num.u_value;
5385  params_read++;
5386  }
5387  }
5388  if (!title || !cmd) {
5389  eprintf("Malformed Visual Panels config: %s\n", _name);
5390  rz_json_free(json);
5391  free(panels_config);
5392  return false;
5393  }
5394  RzPanel *p = __get_panel(panels, panels->n_panels);
5395  __set_geometry(&p->view->pos, x, y, w, h);
5396  __init_panel_param(core, p, title, cmd);
5397  if (rz_str_endswith(cmd, "Help")) {
5398  p->model->title = rz_str_dup(p->model->title, "Help");
5399  p->model->cmd = rz_str_dup(p->model->cmd, "Help");
5400  RzStrBuf *rsb = rz_strbuf_new(NULL);
5401  rz_core_visual_append_help(rsb, "Visual Ascii Art Panels", help_msg_panels);
5402  if (!rsb) {
5403  rz_json_free(json);
5404  free(panels_config);
5405  return false;
5406  }
5407  char *helptxt = rz_strbuf_drain(rsb);
5408  __set_read_only(core, p, helptxt);
5409  free(helptxt);
5410  }
5411  }
5412  rz_json_free(json);
5413  free(panels_config);
5414  if (!panels->n_panels) {
5415  return false;
5416  }
5417  __set_refresh_all(core, true, false);
5418  return true;
5419 }
5420 
5422  RzPanel *cur = __get_cur_panel(panels);
5423  __set_geometry(&cur->view->pos, 0, 1, panels->can->w, panels->can->h - 1);
5424  cur->view->refresh = true;
5425 }
5426 
5428  RzPanels *panels = core->panels;
5429  RzPanel *cur = __get_cur_panel(panels);
5430  if (panels->mode != PANEL_MODE_ZOOM) {
5431  panels->prevMode = panels->mode;
5432  __set_mode(core, PANEL_MODE_ZOOM);
5433  __save_panel_pos(cur);
5434  __maximize_panel_size(panels);
5435  } else {
5436  __set_mode(core, panels->prevMode);
5437  panels->prevMode = PANEL_MODE_DEFAULT;
5438  __restore_panel_pos(cur);
5439  }
5440 }
5441 
5443  RzPanels *panels = core->panels;
5444  if (panels->mode != PANEL_MODE_WINDOW) {
5445  panels->prevMode = panels->mode;
5447  } else {
5448  __set_mode(core, panels->prevMode);
5449  panels->prevMode = PANEL_MODE_DEFAULT;
5450  }
5451 }
5452 
5454  p->model->cache = !p->model->cache;
5455  __set_cmd_str_cache(core, p, NULL);
5456  p->view->refresh = true;
5457 }
5458 
5459 void __toggle_help(RzCore *core) {
5460  RzPanels *ps = core->panels;
5461  int i;
5462  for (i = 0; i < ps->n_panels; i++) {
5463  RzPanel *p = __get_panel(ps, i);
5464  if (rz_str_endswith(p->model->cmd, "Help")) {
5465  __dismantle_del_panel(core, p, i);
5466  if (ps->mode == PANEL_MODE_MENU) {
5468  }
5469  return;
5470  }
5471  }
5472  __add_help_panel(core);
5473  if (ps->mode == PANEL_MODE_MENU) {
5475  }
5476  __update_help(core, ps);
5477 }
5478 
5480  if (!rz_config_get_b(core->config, "cfg.debug")) {
5481  return;
5482  }
5484  rz_core_debug_breakpoint_toggle(core, core->offset + core->print->cur);
5485  panel->view->refresh = true;
5486  }
5487 }
5488 
5489 void __insert_value(RzCore *core) {
5490  if (!rz_config_get_b(core->config, "io.cache")) {
5491  if (__show_status_yesno(core, 1, "Insert is not available because io.cache is off. Turn on now?(Y/n)")) {
5492  rz_config_set_b(core->config, "io.cache", true);
5493  (void)__show_status(core, "io.cache is on and insert is available now.");
5494  } else {
5495  (void)__show_status(core, "You can always turn on io.cache in Menu->Edit->io.cache");
5496  return;
5497  }
5498  }
5499  RzPanels *panels = core->panels;
5500  RzPanel *cur = __get_cur_panel(panels);
5501  char buf[128];
5502  if (__check_panel_type(cur, PANEL_CMD_STACK)) {
5503  const char *prompt = "insert hex: ";
5504  __panel_prompt(prompt, buf, sizeof(buf));
5505  rz_core_write_hexpair(core, cur->model->addr, buf);
5506  cur->view->refresh = true;
5507  } else if (__check_panel_type(cur, PANEL_CMD_DISASSEMBLY)) {
5508  const char *prompt = "insert hex: ";
5509  __panel_prompt(prompt, buf, sizeof(buf));
5510  rz_core_write_hexpair(core, core->offset + core->print->cur, buf);
5511  cur->view->refresh = true;
5512  } else if (__check_panel_type(cur, PANEL_CMD_HEXDUMP)) {
5513  const char *prompt = "insert hex: ";
5514  __panel_prompt(prompt, buf, sizeof(buf));
5515  rz_core_write_hexpair(core, cur->model->addr + core->print->cur, buf);
5516  cur->view->refresh = true;
5517  }
5518 }
5519 
5521  RzPanels *panels = RZ_NEW0(RzPanels);
5522  if (!panels) {
5523  return NULL;
5524  }
5525  int h, w = rz_cons_get_size(&h);
5526  firstRun = true;
5527  if (!__init(core, panels, w, h)) {
5528  free(panels);
5529  return NULL;
5530  }
5531  return panels;
5532 }
5533 
5534 void __renew_filter(RzPanel *panel, int n) {
5535  panel->model->n_filter = 0;
5536  char **filter = calloc(sizeof(char *), n);
5537  if (!filter) {
5538  panel->model->filter = NULL;
5539  return;
5540  }
5541  panel->model->filter = filter;
5542 }
5543 
5544 bool __move_to_direction(RzCore *core, Direction direction) {
5545  RzPanels *panels = core->panels;
5546  RzPanel *cur = __get_cur_panel(panels);
5547  int cur_x0 = cur->view->pos.x, cur_x1 = cur->view->pos.x + cur->view->pos.w - 1, cur_y0 = cur->view->pos.y, cur_y1 = cur->view->pos.y + cur->view->pos.h - 1;
5548  int temp_x0, temp_x1, temp_y0, temp_y1;
5549  int i;
5550  for (i = 0; i < panels->n_panels; i++) {
5551  RzPanel *p = __get_panel(panels, i);
5552  temp_x0 = p->view->pos.x;
5553  temp_x1 = p->view->pos.x + p->view->pos.w - 1;
5554  temp_y0 = p->view->pos.y;
5555  temp_y1 = p->view->pos.y + p->view->pos.h - 1;
5556  switch (direction) {
5557  case LEFT:
5558  if (temp_x1 == cur_x0) {
5559  if (temp_y1 <= cur_y0 || cur_y1 <= temp_y0) {
5560  continue;
5561  }
5562  __set_curnode(core, i);
5563  return true;
5564  }
5565  break;
5566  case RIGHT:
5567  if (temp_x0 == cur_x1) {
5568  if (temp_y1 <= cur_y0 || cur_y1 <= temp_y0) {
5569  continue;
5570  }
5571  __set_curnode(core, i);
5572  return true;
5573  }
5574  break;
5575  case UP:
5576  if (temp_y1 == cur_y0) {
5577  if (temp_x1 <= cur_x0 || cur_x1 <= temp_x0) {
5578  continue;
5579  }
5580  __set_curnode(core, i);
5581  return true;
5582  }
5583  break;
5584  case DOWN:
5585  if (temp_y0 == cur_y1) {
5586  if (temp_x1 <= cur_x0 || cur_x1 <= temp_x0) {
5587  continue;
5588  }
5589  __set_curnode(core, i);
5590  return true;
5591  }
5592  break;
5593  default:
5594  break;
5595  }
5596  }
5597  return false;
5598 }
5599 
5600 void __update_modal(RzCore *core, Sdb *menu_db, RModal *modal) {
5601  RzPanels *panels = core->panels;
5602  RzConsCanvas *can = panels->can;
5603  modal->data = rz_strbuf_new(NULL);
5604  int count = sdb_count(menu_db);
5605  if (modal->idx >= count) {
5606  modal->idx = 0;
5607  modal->offset = 0;
5608  } else if (modal->idx >= modal->offset + modal->pos.h) {
5609  if (modal->offset + modal->pos.h >= count) {
5610  modal->offset = 0;
5611  modal->idx = 0;
5612  } else {
5613  modal->offset += 1;
5614  }
5615  } else if (modal->idx < 0) {
5616  modal->offset = RZ_MAX(count - modal->pos.h, 0);
5617  modal->idx = count - 1;
5618  } else if (modal->idx < modal->offset) {
5619  modal->offset -= 1;
5620  }
5621  SdbList *l = sdb_foreach_list(menu_db, true);
5622  SdbKv *kv;
5623  SdbListIter *iter;
5624  int i = 0;
5625  int max_h = RZ_MIN(modal->offset + modal->pos.h, count);
5626  ls_foreach (l, iter, kv) {
5627  if (__draw_modal(core, modal, max_h, i, sdbkv_key(kv))) {
5628  i++;
5629  }
5630  }
5631  rz_cons_gotoxy(0, 0);
5632  rz_cons_canvas_fill(can, modal->pos.x, modal->pos.y, modal->pos.w + 2, modal->pos.h + 2, ' ');
5633  (void)rz_cons_canvas_gotoxy(can, modal->pos.x + 2, modal->pos.y + 1);
5634  rz_cons_canvas_write(can, rz_strbuf_get(modal->data));
5635  rz_strbuf_free(modal->data);
5636 
5637  rz_cons_canvas_box(can, modal->pos.x, modal->pos.y, modal->pos.w + 2, modal->pos.h + 2, core->cons->context->pal.graph_box2);
5638 
5639  rz_cons_canvas_print(can);
5640  rz_cons_flush();
5641 }
5642 
5643 bool __draw_modal(RzCore *core, RModal *modal, int range_end, int start, const char *name) {
5644  if (start < modal->offset) {
5645  return true;
5646  }
5647  if (start >= range_end) {
5648  return false;
5649  }
5650  if (start == modal->idx) {
5651  rz_strbuf_appendf(modal->data, "> %s%s" Color_RESET, core->cons->context->pal.graph_box2, name);
5652  } else {
5653  rz_strbuf_appendf(modal->data, " %s", name);
5654  }
5655  rz_strbuf_append(modal->data, " \n");
5656  return true;
5657 }
5658 
5659 // TODO: rename to modal
5660 void __create_almighty(RzCore *core, RzPanel *panel, Sdb *menu_db) {
5661  __set_cursor(core, false);
5662  const int w = 40;
5663  const int h = 20;
5664  const int x = (core->panels->can->w - w) / 2;
5665  const int y = (core->panels->can->h - h) / 2;
5666  RModal *modal = __init_modal();
5667  __set_geometry(&modal->pos, x, y, w, h);
5668  int okey, key, cx, cy;
5669  char *word = NULL;
5670  __update_modal(core, menu_db, modal);
5671  while (modal) {
5672  okey = rz_cons_readchar();
5673  key = rz_cons_arrow_to_hjkl(okey);
5674  word = NULL;
5675  if (key == INT8_MAX - 1) {
5676  if (rz_cons_get_click(&cx, &cy)) {
5677  if ((cx < x || x + w < cx) ||
5678  ((cy < y || y + h < cy))) {
5679  key = 'q';
5680  } else {
5681  word = get_word_from_canvas_for_menu(core, core->panels, cx, cy);
5682  if (word) {
5683  void *cb = sdb_ptr_get(menu_db, word, 0);
5684  if (cb) {
5685  ((RzPanelAlmightyCallback)cb)(core, panel, NONE, word);
5686  __free_modal(&modal);
5687  free(word);
5688  break;
5689  }
5690  free(word);
5691  }
5692  }
5693  }
5694  }
5695  switch (key) {
5696  case 'e': {
5697  __free_modal(&modal);
5698  char *cmd = __show_status_input(core, "New command: ");
5699  if (RZ_STR_ISNOTEMPTY(cmd)) {
5700  __replace_cmd(core, cmd, cmd);
5701  }
5702  free(cmd);
5703  } break;
5704  case 'j':
5705  modal->idx++;
5706  __update_modal(core, menu_db, modal);
5707  break;
5708  case 'k':
5709  modal->idx--;
5710  __update_modal(core, menu_db, modal);
5711  break;
5712  case 'v':
5713  __exec_almighty(core, panel, modal, menu_db, VERTICAL);
5714  __free_modal(&modal);
5715  break;
5716  case 'h':
5717  __exec_almighty(core, panel, modal, menu_db, HORIZONTAL);
5718  __free_modal(&modal);
5719  break;
5720  case 0x0d:
5721  __exec_almighty(core, panel, modal, menu_db, NONE);
5722  __free_modal(&modal);
5723  break;
5724  case '-':
5725  __delete_almighty(core, modal, menu_db);
5726  __update_modal(core, menu_db, modal);
5727  break;
5728  case 'q':
5729  case '"':
5730  __free_modal(&modal);
5731  break;
5732  }
5733  }
5734 }
5735 
5736 void __exec_almighty(RzCore *core, RzPanel *panel, RModal *modal, Sdb *menu_db, RzPanelLayout dir) {
5737  SdbList *l = sdb_foreach_list(menu_db, true);
5738  SdbKv *kv;
5739  SdbListIter *iter;
5740  int i = 0;
5741  ls_foreach (l, iter, kv) {
5742  if (i++ == modal->idx) {
5743  RzPanelAlmightyCallback cb = sdb_ptr_get(menu_db, sdbkv_key(kv), 0);
5744  cb(core, panel, dir, sdbkv_key(kv));
5745  break;
5746  }
5747  }
5748 }
5749 
5750 void __delete_almighty(RzCore *core, RModal *modal, Sdb *menu_db) {
5751  SdbList *l = sdb_foreach_list(menu_db, true);
5752  SdbKv *kv;
5753  SdbListIter *iter;
5754  int i = 0;
5755  ls_foreach (l, iter, kv) {
5756  if (i++ == modal->idx) {
5757  sdb_remove(menu_db, sdbkv_key(kv), 0);
5758  }
5759  }
5760 }
5761 
5763  RzPanels *panels = core->panels;
5764  panels->n_panels = 0;
5765  __set_curnode(core, 0);
5766  const char **panels_list = panels_static;
5767  if (panels->layout == PANEL_LAYOUT_DEFAULT_DYNAMIC) {
5768  panels_list = panels_dynamic;
5769  }
5770 
5771  int i = 0;
5772  while (panels_list[i]) {
5773  RzPanel *p = __get_panel(panels, panels->n_panels);
5774  if (!p) {
5775  return;
5776  }
5777  const char *s = panels_list[i++];
5778  char *db_val = __search_db(core, s);
5779  __init_panel_param(core, p, s, db_val);
5780  free(db_val);
5781  }
5782 }
5783 
5784 void __rotate_panels(RzCore *core, bool rev) {
5785  RzPanels *panels = core->panels;
5786  RzPanel *first = __get_panel(panels, 0);
5787  RzPanel *last = __get_panel(panels, panels->n_panels - 1);
5788  int i;
5789  RzPanelModel *tmp_model;
5790  if (!rev) {
5791  tmp_model = first->model;
5792  for (i = 0; i < panels->n_panels - 1; i++) {
5793  RzPanel *p0 = __get_panel(panels, i);
5794  RzPanel *p1 = __get_panel(panels, i + 1);
5795  p0->model = p1->model;
5796  }
5797  last->model = tmp_model;
5798  } else {
5799  tmp_model = last->model;
5800  for (i = panels->n_panels - 1; i > 0; i--) {
5801  RzPanel *p0 = __get_panel(panels, i);
5802  RzPanel *p1 = __get_panel(panels, i - 1);
5803  p0->model = p1->model;
5804  }
5805  first->model = tmp_model;
5806  }
5807  __set_refresh_all(core, false, true);
5808 }
5809 
5810 void __rotate_disasm_cb(void *user, bool rev) {
5811  RzCore *core = (RzCore *)user;
5812  RzPanel *p = __get_cur_panel(core->panels);
5813 
5814  if (rev) {
5815  if (!p->model->rotate) {
5816  p->model->rotate = 4;
5817  } else {
5818  p->model->rotate--;
5819  }
5820  } else {
5821  p->model->rotate++;
5822  }
5823  rz_core_visual_applyDisMode(core, p->model->rotate);
5824  __rotate_asmemu(core, p);
5825 }
5826 
5827 void __rotate_panel_cmds(RzCore *core, const char **cmds, const int cmdslen, const char *prefix, bool rev) {
5828  if (!cmdslen) {
5829  return;
5830  }
5831  RzPanel *p = __get_cur_panel(core->panels);
5832  __reset_filter(core, p);
5833  if (rev) {
5834  if (!p->model->rotate) {
5835  p->model->rotate = cmdslen - 1;
5836  } else {
5837  p->model->rotate--;
5838  }
5839  } else {
5840  p->model->rotate++;
5841  }
5842  char tmp[64], *between;
5843  int i = p->model->rotate % cmdslen;
5844  snprintf(tmp, sizeof(tmp), "%s%s", prefix, cmds[i]);
5845  between = rz_str_between(p->model->cmd, prefix, " ");
5846  if (between) {
5847  char replace[64];
5848  snprintf(replace, sizeof(replace), "%s%s", prefix, between);
5849  p->model->cmd = rz_str_replace(p->model->cmd, replace, tmp, 1);
5850  } else {
5851  p->model->cmd = rz_str_dup(p->model->cmd, tmp);
5852  }
5853  __set_cmd_str_cache(core, p, NULL);
5854  p->view->refresh = true;
5855 }
5856 
5857 void __rotate_entropy_v_cb(void *user, bool rev) {
5858  RzCore *core = (RzCore *)user;
5860 }
5861 
5862 void __rotate_entropy_h_cb(void *user, bool rev) {
5863  RzCore *core = (RzCore *)user;
5865 }
5866 
5867 void __rotate_hexdump_cb(void *user, bool rev) {
5868  RzCore *core = (RzCore *)user;
5869  RzPanel *p = __get_cur_panel(core->panels);
5870 
5871  if (rev) {
5872  p->model->rotate--;
5873  } else {
5874  p->model->rotate++;
5875  }
5876  rz_core_visual_applyHexMode(core, p->model->rotate);
5877  __rotate_asmemu(core, p);
5878 }
5879 
5880 void __rotate_register_cb(void *user, bool rev) {
5881  RzCore *core = (RzCore *)user;
5883 }
5884 
5885 void __rotate_function_cb(void *user, bool rev) {
5886  RzCore *core = (RzCore *)user;
5888 }
5889 
5890 void __undo_seek(RzCore *core) {
5891  RzPanel *cur = __get_cur_panel(core->panels);
5893  return;
5894  }
5896  __set_panel_addr(core, cur, core->offset);
5897 }
5898 
5899 void __set_filter(RzCore *core, RzPanel *panel) {
5900  if (!panel->model->filter) {
5901  return;
5902  }
5903  char *input = __show_status_input(core, "filter word: ");
5904  if (input) {
5905  panel->model->filter[panel->model->n_filter++] = input;
5906  __set_cmd_str_cache(core, panel, NULL);
5907  panel->view->refresh = true;
5908  }
5909  __reset_scroll_pos(panel);
5910 }
5911 
5912 void __reset_filter(RzCore *core, RzPanel *panel) {
5913  free(panel->model->filter);
5914  panel->model->filter = NULL;
5916  __set_cmd_str_cache(core, panel, NULL);
5917  panel->view->refresh = true;
5918  __reset_scroll_pos(panel);
5919 }
5920 
5921 void __redo_seek(RzCore *core) {
5922  RzPanel *cur = __get_cur_panel(core->panels);
5924  return;
5925  }
5927  __set_panel_addr(core, cur, core->offset);
5928 }
5929 
5931  const bool isEmuStr = rz_config_get_b(core->config, "emu.str");
5932  const bool isEmu = rz_config_get_b(core->config, "asm.emu");
5933  if (isEmu) {
5934  if (isEmuStr) {
5935  rz_config_set(core->config, "emu.str", "false");
5936  } else {
5937  rz_config_set(core->config, "asm.emu", "false");
5938  }
5939  } else {
5940  rz_config_set(core->config, "emu.str", "true");
5941  }
5942  p->view->refresh = true;
5943 }
5944 
5945 static bool fromVisual = false;
5946 
5948  fromVisual = core->vmode;
5949  if (!panels_root) {
5950  panels_root = RZ_NEW0(RzPanelsRoot);
5951  if (!panels_root) {
5952  return false;
5953  }
5954  core->panels_root = panels_root;
5955  panels_root->panels = calloc(sizeof(RzPanels *), PANEL_NUM_LIMIT);
5956  panels_root->n_panels = 0;
5957  panels_root->cur_panels = 0;
5958  __set_root_state(core, DEFAULT);
5959  __init_new_panels_root(core);
5960  } else {
5961  if (!panels_root->n_panels) {
5962  panels_root->n_panels = 0;
5963  panels_root->cur_panels = 0;
5964  __init_new_panels_root(core);
5965  }
5966  }
5967  {
5968  const char *l = rz_config_get(core->config, "scr.layout");
5969  if (l && *l) {
5970  rz_load_panels_layout(core, l);
5971  }
5972  }
5973  RzPanels *panels = panels_root->panels[panels_root->cur_panels];
5974  if (panels) {
5975  int i = 0;
5976  for (; i < panels->n_panels; i++) {
5977  RzPanel *cur = __get_panel(panels, i);
5978  if (cur) {
5979  cur->model->addr = core->offset;
5980  }
5981  }
5982  }
5983  while (panels_root->n_panels) {
5984  __set_root_state(core, DEFAULT);
5985  __panels_process(core, panels_root->panels[panels_root->cur_panels]);
5986  if (__check_root_state(core, DEL)) {
5987  __del_panels(core);
5988  }
5989  if (__check_root_state(core, QUIT)) {
5990  break;
5991  }
5992  }
5993  rz_cons_enable_mouse(false);
5994  if (fromVisual) {
5995  rz_core_visual(core, "");
5996  }
5997  return true;
5998 }
5999 
6001  RzPanelsRoot *panels_root = core->panels_root;
6002  RzPanels *panels = __panels_new(core);
6003  if (!panels) {
6004  return;
6005  }
6006  RzPanels *prev = core->panels;
6007  core->panels = panels;
6008  panels_root->panels[panels_root->n_panels++] = panels;
6009  if (!__init_panels_menu(core)) {
6010  core->panels = prev;
6011  return;
6012  }
6013  if (!__init_panels(core, panels)) {
6014  core->panels = prev;
6015  return;
6016  }
6017  __init_all_dbs(core);
6020  __panels_layout(panels);
6021  core->panels = prev;
6022 }
6023 
6025  core->panels_root->root_state = state;
6026 }
6027 
6028 void __del_panels(RzCore *core) {
6029  RzPanelsRoot *panels_root = core->panels_root;
6030  if (panels_root->n_panels <= 1) {
6031  core->panels_root->root_state = QUIT;
6032  return;
6033  }
6034  int i;
6035  for (i = panels_root->cur_panels; i < panels_root->n_panels - 1; i++) {
6036  panels_root->panels[i] = panels_root->panels[i + 1];
6037  }
6038  panels_root->n_panels--;
6039  if (panels_root->cur_panels >= panels_root->n_panels) {
6040  panels_root->cur_panels = panels_root->n_panels - 1;
6041  }
6042 }
6043 
6044 void __handle_tab(RzCore *core) {
6045  rz_cons_gotoxy(0, 0);
6046  if (core->panels_root->n_panels <= 1) {
6047  rz_cons_printf(RZ_CONS_CLEAR_LINE "%s[Tab] t:new T:new with current panel -:del =:name" Color_RESET, core->cons->context->pal.graph_box2);
6048  } else {
6049  int min = 1;
6050  int max = core->panels_root->n_panels;
6051  rz_cons_printf(RZ_CONS_CLEAR_LINE "%s[Tab] [%d..%d]:select; p:prev; n:next; t:new T:new with current panel -:del =:name" Color_RESET, core->cons->context->pal.graph_box2, min, max);
6052  }
6053  rz_cons_flush();
6054  int ch = rz_cons_readchar();
6055 
6056  if (isdigit(ch)) {
6057  __handle_tab_nth(core, ch);
6058  return;
6059  }
6060 
6061  switch (ch) {
6062  case 'n':
6063  __handle_tab_next(core);
6064  return;
6065  case 'p':
6066  __handle_tab_prev(core);
6067  return;
6068  case '-':
6069  __set_root_state(core, DEL);
6070  return;
6071  case '=':
6072  __handle_tab_name(core);
6073  return;
6074  case 't':
6075  __handle_tab_new(core);
6076  return;
6077  case 'T':
6079  return;
6080  }
6081 }
6082 
6083 void __handle_tab_nth(RzCore *core, int ch) {
6084  ch -= '0' + 1;
6085  if (ch < 0) {
6086  return;
6087  }
6088  if (ch != core->panels_root->cur_panels && ch < core->panels_root->n_panels) {
6089  core->panels_root->cur_panels = ch;
6090  __set_root_state(core, ROTATE);
6091  }
6092 }
6093 
6095  if (core->panels_root->n_panels > 1) {
6096  core->panels_root->cur_panels++;
6097  core->panels_root->cur_panels %= core->panels_root->n_panels;
6098  __set_root_state(core, ROTATE);
6099  }
6100 }
6101 
6103  if (rz_config_get_b(core->config, "asm.pseudo")) {
6104  rz_config_toggle(core->config, "asm.pseudo");
6105  rz_config_toggle(core->config, "asm.esil");
6106  } else if (rz_config_get_b(core->config, "asm.esil")) {
6107  rz_config_toggle(core->config, "asm.esil");
6108  } else {
6109  rz_config_toggle(core->config, "asm.pseudo");
6110  }
6111 }
6112 
6114  if (core->panels_root->n_panels > 1) {
6115  core->panels_root->cur_panels--;
6116  if (core->panels_root->cur_panels < 0) {
6117  core->panels_root->cur_panels = core->panels_root->n_panels - 1;
6118  }
6119  __set_root_state(core, ROTATE);
6120  }
6121 }
6122 
6124  core->panels->name = __show_status_input(core, "tab name: ");
6125 }
6126 
6128  if (core->panels_root->n_panels >= PANEL_NUM_LIMIT) {
6129  return;
6130  }
6131  __init_new_panels_root(core);
6132 }
6133 
6135  RzPanels *panels = core->panels;
6136  if (panels->n_panels <= 1) {
6137  return;
6138  }
6139 
6140  RzPanelsRoot *root = core->panels_root;
6141  if (root->n_panels + 1 >= PANEL_NUM_LIMIT) {
6142  return;
6143  }
6144 
6145  RzPanel *cur = __get_cur_panel(panels);
6146 
6147  RzPanels *new_panels = __panels_new(core);
6148  if (!new_panels) {
6149  return;
6150  }
6151  root->panels[root->n_panels] = new_panels;
6152 
6153  RzPanels *prev = core->panels;
6154  core->panels = new_panels;
6155 
6156  if (!__init_panels_menu(core) || !__init_panels(core, new_panels)) {
6157  core->panels = prev;
6158  return;
6159  }
6161  __init_all_dbs(core);
6162 
6163  RzPanel *new_panel = __get_panel(new_panels, 0);
6164  __init_panel_param(core, new_panel, cur->model->title, cur->model->cmd);
6165  new_panel->model->cache = cur->model->cache;
6166  new_panel->model->funcName = rz_str_new(cur->model->funcName);
6167  __set_cmd_str_cache(core, new_panel, rz_str_new(cur->model->cmdStrCache));
6168  __maximize_panel_size(new_panels);
6169 
6170  core->panels = prev;
6171  __dismantle_del_panel(core, cur, panels->curnode);
6172 
6173  root->cur_panels = root->n_panels;
6174  root->n_panels++;
6175 
6176  __set_root_state(core, ROTATE);
6177 }
6178 
6179 void __panel_prompt(const char *prompt, char *buf, int len) {
6181  *buf = 0;
6182  rz_cons_fgets(buf, len, 0, NULL);
6183 }
6184 
6185 char *get_word_from_canvas(RzCore *core, RzPanels *panels, int x, int y) {
6186  RzStrBuf rsb;
6187  rz_strbuf_init(&rsb);
6188  char *cs = rz_cons_canvas_to_string(panels->can);
6189  rz_strbuf_setf(&rsb, " %s", cs);
6190  char *R = rz_str_ansi_crop(rz_strbuf_get(&rsb), 0, y - 1, x + 1024, y);
6191  rz_str_ansi_filter(R, NULL, NULL, -1);
6192  char *r = rz_str_ansi_crop(rz_strbuf_get(&rsb), x - 1, y - 1, x + 1024, y);
6193  rz_str_ansi_filter(r, NULL, NULL, -1);
6194  char *pos = strstr(R, r);
6195  if (!pos) {
6196  pos = R;
6197  }
6198 #define TOkENs ":=*+-/()[,] "
6199  const char *sp = rz_str_rsep(R, pos, TOkENs);
6200  if (sp) {
6201  sp++;
6202  } else {
6203  sp = pos;
6204  }
6205  char *sp2 = (char *)rz_str_sep(sp, TOkENs);
6206  if (sp2) {
6207  *sp2 = 0;
6208  }
6209  char *res = strdup(sp);
6210  free(r);
6211  free(R);
6212  free(cs);
6213  rz_strbuf_fini(&rsb);
6214  return res;
6215 }
6216 
6217 char *get_word_from_canvas_for_menu(RzCore *core, RzPanels *panels, int x, int y) {
6218  char *cs = rz_cons_canvas_to_string(panels->can);
6219  char *R = rz_str_ansi_crop(cs, 0, y - 1, x + 1024, y);
6220  rz_str_ansi_filter(R, NULL, NULL, -1);
6221  char *r = rz_str_ansi_crop(cs, x - 1, y - 1, x + 1024, y);
6222  rz_str_ansi_filter(r, NULL, NULL, -1);
6223  char *pos = strstr(R, r);
6224  char *tmp = pos;
6225  const char *padding = " ";
6226  if (!pos) {
6227  pos = R;
6228  }
6229  int i = 0;
6230  while (pos > R && strncmp(padding, pos, strlen(padding))) {
6231  pos--;
6232  i++;
6233  }
6234  while (RZ_STR_ISNOTEMPTY(tmp) && strncmp(padding, tmp, strlen(padding))) {
6235  tmp++;
6236  i++;
6237  }
6238  char *ret = rz_str_newlen(pos += strlen(padding), i - strlen(padding));
6239  if (!ret) {
6240  ret = strdup(pos);
6241  }
6242  free(r);
6243  free(R);
6244  free(cs);
6245  return ret;
6246 }
6247 
6248 // copypasted from visual.c
6249 static void nextOpcode(RzCore *core) {
6251  RzPrint *p = core->print;
6252  if (aop) {
6253  p->cur += aop->size;
6254  rz_analysis_op_free(aop);
6255  } else {
6256  p->cur += 4;
6257  }
6258 }
6259 
6260 static void prevOpcode(RzCore *core) {
6261  RzPrint *p = core->print;
6262  ut64 addr, oaddr = core->offset + core->print->cur;
6263  if (rz_core_prevop_addr(core, oaddr, 1, &addr)) {
6264  const int delta = oaddr - addr;
6265  p->cur -= delta;
6266  } else {
6267  p->cur -= 4;
6268  }
6269 }
6270 
6271 void __panels_process(RzCore *core, RzPanels *panels) {
6272  if (!panels) {
6273  return;
6274  }
6275  int i, okey, key;
6276  RzPanelsRoot *panels_root = core->panels_root;
6277  RzPanels *prev;
6278  prev = core->panels;
6279  core->panels = panels;
6280  panels->autoUpdate = true;
6281  int h, w = rz_cons_get_size(&h);
6282  panels->can = __create_new_canvas(core, w, h);
6283  __set_refresh_all(core, false, true);
6284 
6285  rz_cons_switchbuf(false);
6286 
6287  int originCursor = core->print->cur;
6288  core->print->cur = 0;
6289  core->print->cur_enabled = false;
6290  core->print->col = 0;
6291 
6292  bool originVmode = core->vmode;
6293  core->vmode = true;
6294  {
6295  const char *layout = rz_config_get(core->config, "scr.layout");
6296  if (RZ_STR_ISNOTEMPTY(layout)) {
6297  rz_load_panels_layout(core, layout);
6298  }
6299  }
6300 
6301  bool o_interactive = rz_cons_is_interactive();
6303  rz_core_visual_showcursor(core, false);
6304 
6305  rz_cons_enable_mouse(false);
6306 repeat:
6307  rz_cons_enable_mouse(rz_config_get_b(core->config, "scr.wheel"));
6308  core->panels = panels;
6309  core->cons->event_resize = NULL; // avoid running old event with new data
6310  core->cons->event_data = core;
6313  RzPanel *cur = __get_cur_panel(panels);
6314  okey = rz_cons_readchar();
6315  key = rz_cons_arrow_to_hjkl(okey);
6316  if (__handle_mouse(core, cur, &key)) {
6317  if (panels_root->root_state != DEFAULT) {
6318  goto exit;
6319  }
6320  goto repeat;
6321  }
6322 
6323  rz_cons_switchbuf(true);
6324 
6325  if (panels->mode == PANEL_MODE_MENU) {
6326  __handle_menu(core, key);
6327  if (__check_root_state(core, QUIT) ||
6328  __check_root_state(core, ROTATE)) {
6329  goto exit;
6330  }
6331  goto repeat;
6332  }
6333 
6334  if (core->print->cur_enabled) {
6335  if (__handle_cursor_mode(core, key)) {
6336  goto repeat;
6337  }
6338  }
6339 
6340  if (panels->mode == PANEL_MODE_ZOOM) {
6341  if (__handle_zoom_mode(core, key)) {
6342  goto repeat;
6343  }
6344  }
6345 
6346  if (panels->mode == PANEL_MODE_WINDOW) {
6347  if (__handle_window_mode(core, key)) {
6348  goto repeat;
6349  }
6350  }
6351 
6352  if (__check_panel_type(cur, PANEL_CMD_DISASSEMBLY) && '0' < key && key <= '9') {
6353  ut8 ch = key;
6354  rz_core_visual_jump(core, ch);
6355  __set_panel_addr(core, cur, core->offset);
6356  goto repeat;
6357  }
6358 
6359  const char *cmd;
6360  RzConsCanvas *can = panels->can;
6361  if (__handle_console(core, cur, key)) {
6362  goto repeat;
6363  }
6364  switch (key) {
6365  case 'u':
6366  __undo_seek(core);
6367  break;
6368  case 'U':
6369  __redo_seek(core);
6370  break;
6371  case 'p':
6372  __rotate_panels(core, false);
6373  break;
6374  case 'P':
6375  __rotate_panels(core, true);
6376  break;
6377  case '.':
6379  ut64 addr = rz_debug_reg_get(core->dbg, "PC");
6380  if (addr && addr != UT64_MAX) {
6381  rz_core_seek(core, addr, true);
6382  } else {
6383  addr = rz_num_get(core->num, "entry0");
6384  if (addr && addr != UT64_MAX) {
6385  rz_core_seek(core, addr, true);
6386  }
6387  }
6388  __set_panel_addr(core, cur, core->offset);
6389  }
6390  break;
6391  case '?':
6392  __toggle_help(core);
6393  break;
6394  case 'b':
6395  rz_core_visual_browse(core, NULL);
6396  break;
6397  case ';':
6398  __handleComment(core);
6399  break;
6400  case '$':
6401  if (core->print->cur_enabled) {
6402  rz_core_reg_set_by_role_or_name(core, "PC", core->offset + core->print->cur);
6403  } else {
6404  rz_core_reg_set_by_role_or_name(core, "PC", core->offset);
6405  }
6406  break;
6407  case 's':
6408  __panel_single_step_in(core);
6410  __set_panel_addr(core, cur, core->offset);
6411  }
6412  break;
6413  case 'S':
6416  __set_panel_addr(core, cur, core->offset);
6417  }
6418  break;
6419  case ' ':
6420  __call_visual_graph(core);
6421  break;
6422  case ':':
6424  __set_panel_addr(core, cur, core->offset);
6425  break;
6426  case 'c':
6427  __activate_cursor(core);
6428  break;
6429  case 'C': {
6430  int color = rz_config_get_i(core->config, "scr.color");
6431  if (++color > 2) {
6432  color = 0;
6433  }
6434  rz_config_set_i(core->config, "scr.color", color);
6435  can->color = color;
6436  __set_refresh_all(core, true, false);
6437  } break;
6438  case 'r':
6439  // TODO: toggle shortcut hotkeys
6441  break;
6442  case 'R':
6443  if (rz_config_get_b(core->config, "scr.randpal")) {
6445  } else {
6446  rz_core_theme_nextpal(core, 'n');
6447  }
6448  __do_panels_refresh(core);
6449  break;
6450  case 'a':
6451  panels->autoUpdate = __show_status_yesno(core, 1, "Auto update On? (Y/n)");
6452  break;
6453  case 'A': {
6454  const int ocur = core->print->cur_enabled;
6455  rz_core_visual_asm(core, core->offset);
6456  core->print->cur_enabled = ocur;
6457  } break;
6458  case 'd':
6459  rz_core_visual_define(core, "", 0);
6460  break;
6461  case 'D':
6463  break;
6464  case 'j':
6465  if (core->print->cur_enabled) {
6466  nextOpcode(core);
6467  } else {
6468  rz_cons_switchbuf(false);
6469  if (cur->model->directionCb) {
6470  cur->model->directionCb(core, (int)DOWN);
6471  }
6472  }
6473  break;
6474  case 'k':
6475  if (core->print->cur_enabled) {
6476  prevOpcode(core);
6477  } else {
6478  rz_cons_switchbuf(false);
6479  if (cur->model->directionCb) {
6480  cur->model->directionCb(core, (int)UP);
6481  }
6482  }
6483  break;
6484  case 'K':
6485  if (core->print->cur_enabled) {
6486  size_t i;
6487  for (i = 0; i < 4; i++) {
6488  prevOpcode(core);
6489  }
6490  } else {
6491  rz_cons_switchbuf(false);
6492  if (cur->model->directionCb) {
6493  for (i = 0; i < __get_cur_panel(panels)->view->pos.h / 2 - 6; i++) {
6494  cur->model->directionCb(core, (int)UP);
6495  }
6496  }
6497  }
6498  break;
6499  case 'J':
6500  if (core->print->cur_enabled) {
6501  size_t i;
6502  for (i = 0; i < 4; i++) {
6503  nextOpcode(core);
6504  }
6505  } else {
6506  rz_cons_switchbuf(false);
6507  if (cur->model->directionCb) {
6508  for (i = 0; i < __get_cur_panel(panels)->view->pos.h / 2 - 6; i++) {
6509  cur->model->directionCb(core, (int)DOWN);
6510  }
6511  }
6512  }
6513  break;
6514  case 'H':
6515  if (core->print->cur_enabled) {
6516  core->print->cur -= 5;
6517  } else {
6518  rz_cons_switchbuf(false);
6519  if (cur->model->directionCb) {
6520  for (i = 0; i < __get_cur_panel(panels)->view->pos.w / 3; i++) {
6521  cur->model->directionCb(core, (int)LEFT);
6522  }
6523  }
6524  }
6525  break;
6526  case 'L':
6527  if (core->print->cur_enabled) {
6528  core->print->cur += 5;
6529  } else {
6530  rz_cons_switchbuf(false);
6531  if (cur->model->directionCb) {
6532  for (i = 0; i < __get_cur_panel(panels)->view->pos.w / 3; i++) {
6533  cur->model->directionCb(core, (int)RIGHT);
6534  }
6535  }
6536  }
6537  break;
6538  case 'f':
6539  __set_filter(core, cur);
6540  break;
6541  case 'F':
6542  __reset_filter(core, cur);
6543  break;
6544  case '_':
6545  __hudstuff(core);
6546  break;
6547  case '\\':
6548  rz_core_visual_hud(core);
6549  break;
6550  case '"':
6551  rz_cons_switchbuf(false);
6552  __create_almighty(core, cur, panels->almighty_db);
6553  if (__check_root_state(core, ROTATE)) {
6554  goto exit;
6555  }
6556  cur->model->cache = false;
6557  break;
6558  case 'O':
6559  __handle_print_rotate(core);
6560  break;
6561  case 'n':
6563  rz_core_seek_next(core, rz_config_get(core->config, "scr.nkey"), true);
6564  __set_panel_addr(core, cur, core->offset);
6565  }
6566  break;
6567  case 'N':
6569  rz_core_seek_prev(core, rz_config_get(core->config, "scr.nkey"), true);
6570  __set_panel_addr(core, cur, core->offset);
6571  }
6572  break;
6573  case 'x':
6574  __handle_refs(core, cur, UT64_MAX);
6575  break;
6576  case 'X':
6577 #if 0
6578 // already accessible via xX
6579  rz_core_visual_xrefs (core, false, true);
6580  cur->model->addr = core->offset;
6581  set_refresh_all (panels, false);
6582 #endif
6583  __dismantle_del_panel(core, cur, panels->curnode);
6584  break;
6585  case 9: // TAB
6586  __handle_tab_key(core, false);
6587  break;
6588  case 'Z': // SHIFT-TAB
6589  __handle_tab_key(core, true);
6590  break;
6591  case 'M':
6592  __handle_visual_mark(core);
6593  break;
6594  case 'e': {
6595  char *cmd = __show_status_input(core, "New command: ");
6596  if (RZ_STR_ISNOTEMPTY(cmd)) {
6597  __replace_cmd(core, cmd, cmd);
6598  }
6599  free(cmd);
6600  } break;
6601  case 'm':
6602  __set_mode(core, PANEL_MODE_MENU);
6603  __clear_panels_menu(core);
6604  __get_cur_panel(panels)->view->refresh = true;
6605  break;
6606  case 'g':
6607  rz_core_visual_showcursor(core, true);
6608  rz_core_visual_offset(core);
6609  rz_core_visual_showcursor(core, false);
6610  __set_panel_addr(core, cur, core->offset);
6611  break;
6612  case 'G': {
6613  const char *hl = rz_config_get(core->config, "scr.highlight");
6614  if (hl) {
6615  ut64 addr = rz_num_math(core->num, hl);
6616  __set_panel_addr(core, cur, addr);
6617  }
6618  } break;
6619  case 'h':
6620  if (core->print->cur_enabled) {
6621  core->print->cur--;
6622  } else {
6623  rz_cons_switchbuf(false);
6624  if (cur->model->directionCb) {
6625  cur->model->directionCb(core, (int)LEFT);
6626  }
6627  }
6628  break;
6629  case 'l':
6630  if (core->print->cur_enabled) {
6631  core->print->cur++;
6632  } else {
6633  rz_cons_switchbuf(false);
6634  if (cur->model->directionCb) {
6635  cur->model->directionCb(core, (int)RIGHT);
6636  }
6637  }
6638  break;
6639  case 'V':
6640  __call_visual_graph(core);
6641  break;
6642  case ']':
6644  rz_config_set_i(core->config, "hex.cols", rz_config_get_i(core->config, "hex.cols") + 1);
6645  } else {
6646  int cmtcol = rz_config_get_i(core->config, "asm.cmt.col");
6647  rz_config_set_i(core->config, "asm.cmt.col", cmtcol + 2);
6648  }
6649  cur->view->refresh = true;
6650  break;
6651  case '[':
6653  rz_config_set_i(core->config, "hex.cols", rz_config_get_i(core->config, "hex.cols") - 1);
6654  } else {
6655  int cmtcol = rz_config_get_i(core->config, "asm.cmt.col");
6656  if (cmtcol > 2) {
6657  rz_config_set_i(core->config, "asm.cmt.col", cmtcol - 2);
6658  }
6659  }
6660  cur->view->refresh = true;
6661  break;
6662  case '/':
6663  rz_core_cmd0(core, "?i highlight;e scr.highlight=`yp`");
6664  break;
6665  case 'z':
6666  if (panels->curnode > 0) {
6667  __swap_panels(panels, 0, panels->curnode);
6668  __set_curnode(core, 0);
6669  }
6670  break;
6671  case 'i':
6672  if (cur->model->rotateCb) {
6673  cur->model->rotateCb(core, false);
6674  cur->view->refresh = true;
6675  }
6676  break;
6677  case 'I':
6678  if (cur->model->rotateCb) {
6679  cur->model->rotateCb(core, true);
6680  cur->view->refresh = true;
6681  }
6682  break;
6683  case 't':
6684  __handle_tab(core);
6685  if (panels_root->root_state != DEFAULT) {
6686  goto exit;
6687  }
6688  break;
6689  case 'T':
6690  if (panels_root->n_panels > 1) {
6691  __set_root_state(core, DEL);
6692  goto exit;
6693  }
6694  break;
6695  case 'w':
6696  __toggle_window_mode(core);
6697  break;
6698  case 'W':
6699  __move_panel_to_dir(core, cur, panels->curnode);
6700  break;
6701  case 0x0d: // "\\n"
6702  __toggle_zoom_mode(core);
6703  break;
6704  case '|': {
6705  RzPanel *p = __get_cur_panel(panels);
6706  __split_panel_vertical(core, p, p->model->title, p->model->cmd);
6707  break;
6708  }
6709  case '-': {
6710  RzPanel *p = __get_cur_panel(panels);
6711  __split_panel_horizontal(core, p, p->model->title, p->model->cmd);
6712  break;
6713  }
6714  case '*':
6715  if (__check_func(core)) {
6716  rz_cons_canvas_free(can);
6717  panels->can = NULL;
6718  int h, w = rz_cons_get_size(&h);
6719  panels->can = __create_new_canvas(core, w, h);
6720  }
6721  break;
6722  case ')':
6723  __rotate_asmemu(core, __get_cur_panel(panels));
6724  break;
6725  case '&':
6726  __toggle_cache(core, __get_cur_panel(panels));
6727  break;
6728  case RZ_CONS_KEY_F1:
6729  cmd = rz_config_get(core->config, "key.f1");
6730  if (cmd && *cmd) {
6731  (void)rz_core_cmd0(core, cmd);
6732  }
6733  break;
6734  case RZ_CONS_KEY_F2:
6735  cmd = rz_config_get(core->config, "key.f2");
6736  if (cmd && *cmd) {
6737  (void)rz_core_cmd0(core, cmd);
6738  } else {
6739  __panel_breakpoint(core);
6740  }
6741  break;
6742  case RZ_CONS_KEY_F3:
6743  cmd = rz_config_get(core->config, "key.f3");
6744  if (cmd && *cmd) {
6745  (void)rz_core_cmd0(core, cmd);
6746  }
6747  break;
6748  case RZ_CONS_KEY_F4:
6749  cmd = rz_config_get(core->config, "key.f4");
6750  if (cmd && *cmd) {
6751  (void)rz_core_cmd0(core, cmd);
6752  }
6753  break;
6754  case RZ_CONS_KEY_F5:
6755  cmd = rz_config_get(core->config, "key.f5");
6756  if (cmd && *cmd) {
6757  (void)rz_core_cmd0(core, cmd);
6758  }
6759  break;
6760  case RZ_CONS_KEY_F6:
6761  cmd = rz_config_get(core->config, "key.f6");
6762  if (cmd && *cmd) {
6763  (void)rz_core_cmd0(core, cmd);
6764  }
6765  break;
6766  case RZ_CONS_KEY_F7:
6767  cmd = rz_config_get(core->config, "key.f7");
6768  if (cmd && *cmd) {
6769  (void)rz_core_cmd0(core, cmd);
6770  } else {
6771  __panel_single_step_in(core);
6773  __set_panel_addr(core, cur, core->offset);
6774  }
6775  }
6776  break;
6777  case RZ_CONS_KEY_F8:
6778  cmd = rz_config_get(core->config, "key.f8");
6779  if (cmd && *cmd) {
6780  (void)rz_core_cmd0(core, cmd);
6781  } else {
6784  __set_panel_addr(core, cur, core->offset);
6785  }
6786  }
6787  break;
6788  case RZ_CONS_KEY_F9:
6789  cmd = rz_config_get(core->config, "key.f9");
6790  if (cmd && *cmd) {
6791  (void)rz_core_cmd0(core, cmd);
6792  } else {
6794  rz_core_debug_continue(core);
6795  __set_panel_addr(core, cur, core->offset);
6796  }
6797  }
6798  break;
6799  case RZ_CONS_KEY_F10:
6800  cmd = rz_config_get(core->config, "key.f10");
6801  if (cmd && *cmd) {
6802  (void)rz_core_cmd0(core, cmd);
6803  }
6804  break;
6805  case RZ_CONS_KEY_F11:
6806  cmd = rz_config_get(core->config, "key.f11");
6807  if (cmd && *cmd) {
6808  (void)rz_core_cmd0(core, cmd);
6809  }
6810  break;
6811  case RZ_CONS_KEY_F12:
6812  cmd = rz_config_get(core->config, "key.f12");
6813  if (cmd && *cmd) {
6814  (void)rz_core_cmd0(core, cmd);
6815  }
6816  break;
6817  case 'Q':
6818  __set_root_state(core, QUIT);
6819  goto exit;
6820  case '!':
6821  fromVisual = true;
6822  // fallthrough
6823  case 'q':
6824  // fallthrough
6825  case -1: // EOF
6826  __set_root_state(core, DEL);
6827  goto exit;
6828 #if 0
6829  case 27: // ESC
6830  if (rz_cons_readchar () == 91) {
6831  if (rz_cons_readchar () == 90) {}
6832  }
6833  break;
6834 #endif
6835  default:
6836  // eprintf ("Key %d\n", key);
6837  // sleep (1);
6838  break;
6839  }
6840  goto repeat;
6841 exit:
6842  if (!originVmode) {
6843  rz_core_visual_showcursor(core, true);
6844  }
6845  core->cons->event_resize = NULL;
6846  core->cons->event_data = NULL;
6847  core->print->cur = originCursor;
6848  core->print->cur_enabled = false;
6849  core->print->col = 0;
6850  core->vmode = originVmode;
6851  core->panels = prev;
6852  rz_cons_set_interactive(o_interactive);
6853 }
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
RZ_API int rz_core_visual_graph(RzCore *core, RzAGraph *g, RzAnalysisFunction *_fcn, int is_interactive)
Definition: agraph.c:4114
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
#define R(x, b, m)
Definition: arc.h:168
static RzILOpEffect * rev(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:1590
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
Definition: arm_il32.c:190
RZ_API int rz_asm_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm.c:543
RZ_API ut64 rz_bin_file_delete_all(RzBin *bin)
Definition: bfile.c:199
const char * desc
Definition: bin_vsf.c:19
int bits(struct state *s, int need)
Definition: blast.c:72
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
RZ_API bool rz_bp_del(RzBreakpoint *bp, ut64 addr)
Definition: bp.c:315
RZ_API int rz_core_analysis_all(RzCore *core)
Definition: canalysis.c:3552
RZ_API bool rz_core_analysis_function_add(RzCore *core, const char *name, ut64 addr, bool analyze_recursively)
Definition: canalysis.c:5298
RZ_API RzAnalysisOp * rz_core_analysis_op(RzCore *core, ut64 addr, int mask)
Definition: canalysis.c:1033
RZ_API bool rz_core_analysis_everything(RzCore *core, bool experimental, char *dh_orig)
Definition: canalysis.c:5784
RZ_API bool rz_core_analysis_refs(RZ_NONNULL RzCore *core, size_t nbytes)
Analyze xrefs and prints the result.
Definition: canalysis.c:3272
RZ_API void rz_cons_canvas_print(RzConsCanvas *c)
Definition: canvas.c:423
RZ_API RZ_OWN char * rz_cons_canvas_to_string(RzConsCanvas *c)
Definition: canvas.c:351
RZ_API void rz_cons_canvas_write(RzConsCanvas *c, const char *s)
Definition: canvas.c:283
RZ_API bool rz_cons_canvas_gotoxy(RzConsCanvas *c, int x, int y)
Definition: canvas.c:184
RZ_API void rz_cons_canvas_fill(RzConsCanvas *c, int x, int y, int w, int h, char ch)
Definition: canvas.c:551
RZ_API int rz_cons_canvas_resize(RzConsCanvas *c, int w, int h)
Definition: canvas.c:432
RZ_API RzConsCanvas * rz_cons_canvas_new(int w, int h)
Definition: canvas.c:223
RZ_API void rz_cons_canvas_box(RzConsCanvas *c, int x, int y, int w, int h, const char *color)
Definition: canvas.c:486
RZ_API void rz_cons_canvas_free(RzConsCanvas *c)
Definition: canvas.c:150
RZ_API void rz_core_debug_breakpoint_toggle(RZ_NONNULL RzCore *core, ut64 addr)
Toggle breakpoint.
Definition: cdebug.c:235
RZ_IPI void rz_core_debug_continue(RzCore *core)
Definition: cdebug.c:81
RZ_IPI void rz_core_debug_single_step_in(RzCore *core)
Definition: cdebug.c:193
RZ_IPI void rz_core_debug_single_step_over(RzCore *core)
Definition: cdebug.c:207
RZ_API void rz_core_file_reopen_debug(RzCore *core, const char *args)
Definition: cfile.c:269
RZ_API void rz_core_io_file_open(RZ_NONNULL RzCore *core, int fd)
Open file use read-only Permission.
Definition: cfile.c:1601
RZ_API void rz_core_io_file_reopen(RZ_NONNULL RzCore *core, int fd, int perms)
Reopen file.
Definition: cfile.c:1650
RZ_API bool rz_core_file_close_fd(RzCore *core, int fd)
Definition: cfile.c:1510
RZ_API void rz_core_analysis_esil_init_mem(RZ_NONNULL RzCore *core, RZ_NULLABLE const char *name, ut64 addr, ut32 size)
Definition: cil.c:149
RZ_API void rz_core_analysis_esil_init_regs(RZ_NONNULL RzCore *core)
Definition: cil.c:264
RZ_API int rz_core_write_hexpair(RzCore *core, ut64 addr, const char *pairs)
Definition: cio.c:268
RZ_API int rz_core_block_read(RzCore *core)
Definition: cio.c:243
#define cmdstr(x)
RZ_API int rz_core_cmd0(RzCore *core, const char *cmd)
Definition: cmd.c:5428
RZ_API int rz_core_cmd(RzCore *core, const char *cstr, int log)
Definition: cmd.c:5328
RZ_API int rz_core_cmdf(RzCore *core, const char *fmt,...)
Definition: cmd.c:5413
RZ_API char * rz_core_cmd_str(RzCore *core, const char *cmd)
Executes a rizin command and returns the stdout as a string.
Definition: cmd.c:5513
RZ_API void rz_core_analysis_calls(RZ_NONNULL RzCore *core, bool imports_only)
RZ_API int rz_core_esil_step(RzCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver)
Definition: cmd_analysis.c:860
static RzCore * _core
Definition: cmd_debug.c:1622
RZ_IPI void rz_core_debug_bp_add(RzCore *core, ut64 addr, const char *arg_perm, bool hwbp, bool watch)
Definition: cmd_debug.c:1574
RZ_API void rz_core_theme_nextpal(RzCore *core, RzConsPalSeekMode mode)
Definition: cmd_eval.c:148
RZ_API RZ_OWN RzList * rz_core_theme_list(RZ_NONNULL RzCore *core)
Returns the list of the rizin themes.
Definition: cmd_eval.c:119
RZ_API bool rz_core_theme_load(RzCore *core, const char *name)
Definition: cmd_eval.c:56
RZ_API void rz_core_gadget_print(RzCore *core)
Prints or displays the print gadgets while in visual mode.
Definition: cmd_print.c:1185
static char * config_path(RzCore *core)
Definition: cmd_system.c:16
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:142
RZ_API RzConfigNode * rz_config_set(RzConfig *cfg, RZ_NONNULL const char *name, const char *value)
Definition: config.c:267
RZ_API RzConfigNode * rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, const ut64 i)
Definition: config.c:419
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:75
RZ_API RzConfigNode * rz_config_set_b(RzConfig *cfg, RZ_NONNULL const char *name, bool value)
Definition: config.c:201
RZ_API bool rz_config_toggle(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:97
RZ_API void rz_cons_set_raw(bool is_raw)
Definition: cons.c:1617
RZ_API int rz_cons_get_size(int *rows)
Definition: cons.c:1446
RZ_API bool rz_cons_enable_mouse(const bool enable)
Definition: cons.c:500
RZ_API void rz_cons_set_interactive(bool x)
Definition: cons.c:1724
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API void rz_cons_echo(const char *msg)
Definition: cons.c:939
RZ_API bool rz_cons_is_interactive(void)
Definition: cons.c:365
RZ_API bool rz_cons_get_click(int *x, int *y)
Definition: cons.c:484
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API void rz_cons_gotoxy(int x, int y)
Definition: cons.c:724
#define RZ_API
RZ_API void rz_core_reg_update_flags(RzCore *core)
Update or create flags for all registers where it makes sense.
Definition: creg.c:106
RZ_API bool rz_core_reg_set_by_role_or_name(RzCore *core, const char *name, ut64 num)
set on rz_core_reg_default()
Definition: creg.c:39
#define NULL
Definition: cris-opc.c:27
static bool update(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto_aes.c:92
#define r
Definition: crypto_rc6.c:12
#define w
Definition: crypto_rc6.c:13
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
RZ_API int rz_line_hist_cmd_down(RzLine *line)
Definition: dietline.c:346
RZ_API int rz_line_hist_cmd_up(RzLine *line)
Definition: dietline.c:316
RZ_API int rz_line_set_hist_callback(RzLine *line, RzLineHistoryUpCb up, RzLineHistoryDownCb down)
Definition: dietline.c:292
RZ_API ut64 rz_debug_reg_get(RzDebug *dbg, const char *name)
Definition: dreg.c:99
const char * v
Definition: dsignal.c:12
int root
Definition: enough.c:226
int max
Definition: enough.c:225
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1687
checking print the parsed form of the magic use in n conjunction with m to debug a new magic file n before installing it n output MIME type strings(--mime-type and\n" " --mime-encoding)\n") OPT('s'
checking print the parsed form of the magic use in n conjunction with m to debug a new magic file n before installing it n output MIME type special files
Definition: file_opts.h:46
RZ_API RzFlagItem * rz_flag_set(RzFlag *f, const char *name, ut64 off, ut32 size)
Definition: flag.c:521
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
#define THRESHOLD
Definition: format.c:29
RZ_API RZ_OWN char * rz_core_fortune_get_random(RzCore *core)
Definition: fortune.c:49
unsigned short prefix[65536]
Definition: gun.c:163
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
RZ_API void rz_cons_message(RZ_NONNULL const char *msg)
Definition: hud.c:321
RZ_API void rz_cons_switchbuf(bool active)
Definition: input.c:601
RZ_API char * rz_cons_input(const char *msg)
Definition: input.c:696
RZ_API int rz_cons_arrow_to_hjkl(int ch)
Definition: input.c:78
RZ_API int rz_cons_fgets(char *buf, int len, int argc, const char **argv)
Definition: input.c:339
RZ_API bool rz_cons_yesno(int def, const char *fmt,...)
Definition: input.c:666
RZ_API int rz_cons_readchar(void)
Definition: input.c:619
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
Definition: list.c:743
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
RZ_API void rz_line_set_prompt(const char *prompt)
Definition: line.c:56
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
RZ_API void ls_free(SdbList *list)
Definition: ls.c:191
#define ls_foreach(list, it, pos)
Definition: ls.h:31
@ RZ_ABS
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
string FILE
Definition: benchmark.py:21
line
Definition: setup.py:34
int idx
Definition: setup.py:197
RZ_API void * sdb_ptr_get(Sdb *db, const char *key, ut32 *cas)
Definition: num.c:87
RZ_API int sdb_ptr_set(Sdb *db, const char *key, void *p, ut32 cas)
Definition: num.c:83
RZ_API void rz_analysis_op_free(void *op)
Definition: op.c:61
RZ_API void rz_cons_pal_random(void)
Definition: pal.c:270
static int __function_cb(void *user)
Definition: panels.c:3505
static const char * menus_Emulate[]
Definition: panels.c:121
static void __create_panel(RzCore *core, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title, const char *cmd)
Definition: panels.c:4925
static int __calls_cb(void *user)
Definition: panels.c:3527
static void __panels_layout(RzPanels *panels)
Definition: panels.c:1205
static void __toggle_help(RzCore *core)
Definition: panels.c:5459
static void __rotate_entropy_h_cb(void *user, bool rev)
Definition: panels.c:5862
static void __split_panel_vertical(RzCore *core, RzPanel *p, const char *name, const char *cmd)
Definition: panels.c:1323
static void __dismantle_del_panel(RzCore *core, RzPanel *p, int pi)
Definition: panels.c:2670
#define PANEL_CMD_TINYGRAPH
Definition: panels.c:36
static void __free_modal(RModal **modal)
Definition: panels.c:4610
static int __reload_cb(void *user)
Definition: panels.c:3498
static void __reset_filter(RzCore *core, RzPanel *panel)
Definition: panels.c:5912
static void __do_panels_refresh(RzCore *core)
Definition: panels.c:4769
static bool __check_panel_num(RzCore *core)
Definition: panels.c:2945
static void __hudstuff(RzCore *core)
Definition: panels.c:4037
static int __continue_cb(void *user)
Definition: panels.c:3333
static void __toggle_cache(RzCore *core, RzPanel *p)
Definition: panels.c:5453
static void __move_panel_to_left(RzCore *core, RzPanel *panel, int src)
Definition: panels.c:2401
static void __init_panel_param(RzCore *core, RzPanel *p, const char *title, const char *cmd)
Definition: panels.c:2955
static int __get_panel_idx_in_pos(RzCore *core, int x, int y)
Definition: panels.c:929
static void __fix_layout_h(RzCore *core)
Definition: panels.c:2525
static void __init_almighty_db(RzCore *core)
Definition: panels.c:4871
static void __rotate_asmemu(RzCore *core, RzPanel *p)
Definition: panels.c:5930
static void __toggle_window_mode(RzCore *core)
Definition: panels.c:5442
static void __load_config_menu(RzCore *core)
Definition: panels.c:5311
static bool __handle_console(RzCore *core, RzPanel *panel, const int key)
Definition: panels.c:5157
static void __handle_tab_key(RzCore *core, bool shift)
Definition: panels.c:5189
static int __watch_points_cb(void *user)
Definition: panels.c:3551
static const char * menus_loadLayout[]
Definition: panels.c:88
static void __set_addr_by_type(RzCore *core, const char *cmd, ut64 addr)
Definition: panels.c:2921
static const char * menus_Analyze[]
Definition: panels.c:133
static int __symbols_cb(void *user)
Definition: panels.c:3511
#define PANEL_CMD_FUNCTION
Definition: panels.c:34
static int __version_cb(void *user)
Definition: panels.c:3588
static void __set_refresh_all(RzCore *core, bool clearCache, bool force_refresh)
Definition: panels.c:2891
#define PANEL_TITLE_STRINGS_DATA
Definition: panels.c:22
#define PANEL_CONFIG_RESIZE_W
Definition: panels.c:43
static void __set_size(RzPanelPos *pos, int w, int h)
Definition: panels.c:904
Direction
Definition: panels.c:50
@ DOWN
Definition: panels.c:54
@ UP
Definition: panels.c:53
@ LEFT
Definition: panels.c:51
@ RIGHT
Definition: panels.c:52
static const char * menus_ReOpen[]
Definition: panels.c:83
RZ_API bool rz_core_visual_panels_root(RzCore *core, RzPanelsRoot *panels_root)
Definition: panels.c:5947
static void __print_hexdump_cb(void *user, void *p)
Definition: panels.c:4008
static bool __init_panels_menu(RzCore *core)
Definition: panels.c:4304
static void __rotate_register_cb(void *user, bool rev)
Definition: panels.c:5880
static void __set_read_only(RzCore *core, RzPanel *p, char *s)
Definition: panels.c:892
static void __handle_visual_mark(RzCore *core)
Definition: panels.c:2059
static int __config_value_cb(void *user)
Definition: panels.c:3246
static void __resize_panel_up(RzPanels *panels)
Definition: panels.c:2291
static void __init_menu_color_settings_layout(void *core, const char *parent)
Definition: panels.c:4216
#define PANEL_CMD_STACK
Definition: panels.c:30
static int __save_layout_cb(void *user)
Definition: panels.c:3132
static void __resize_panel_left(RzPanels *panels)
Definition: panels.c:2119
RZ_API void rz_save_panels_layout(RzCore *core, const char *_name)
Definition: panels.c:5270
static void __continue_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title)
Definition: panels.c:4969
static const char * menus_settings_screen[]
Definition: panels.c:151
static char * __handle_cmd_str_cache(RzCore *core, RzPanel *panel, bool force_cache)
Definition: panels.c:1168
static bool __check_if_mouse_y_on_edge(RzCore *core, int x, int y)
Definition: panels.c:691
static void __set_pcb(RzPanel *p)
Definition: panels.c:3043
static void __update_edge_y(RzCore *core, int y)
Definition: panels.c:635
static void __fix_layout(RzCore *core)
Definition: panels.c:2480
static void __cursor_right(RzCore *core)
Definition: panels.c:1463
static int __assemble_cb(void *user)
Definition: panels.c:3191
static char * get_word_from_canvas_for_menu(RzCore *core, RzPanels *panels, int x, int y)
Definition: panels.c:6217
static void __activate_cursor(RzCore *core)
Definition: panels.c:1391
static char * __apply_filter_cmd(RzCore *core, RzPanel *panel)
Definition: panels.c:1148
static void __panel_prompt(const char *prompt, char *buf, int len)
Definition: panels.c:6179
static void __del_menu(RzCore *core)
Definition: panels.c:4151
static void __do_panels_resize(RzCore *core)
Definition: panels.c:4753
static void __handle_mouse_on_menu(RzCore *core, int x, int y)
Definition: panels.c:1996
static char * menus_Debug[]
Definition: panels.c:126
static int __load_layout_saved_cb(void *user)
Definition: panels.c:3096
static bool __handle_mouse_on_panel(RzCore *core, RzPanel *panel, int x, int y, int *key)
Definition: panels.c:1956
static void __resize_panel_right(RzPanels *panels)
Definition: panels.c:2205
static int __fortune_cb(void *user)
Definition: panels.c:3569
#define PANEL_TITLE_SEGMENTS
Definition: panels.c:25
static char * get_word_from_canvas(RzCore *core, RzPanels *panels, int x, int y)
Definition: panels.c:6185
static void __handle_refs(RzCore *core, RzPanel *panel, ut64 tmp)
Definition: panels.c:2090
static void __adjust_side_panels(RzCore *core)
Definition: panels.c:1239
static void __direction_hexdump_cb(void *user, int direction)
Definition: panels.c:3797
static const char * menus_Settings[]
Definition: panels.c:78
static void __toggle_zoom_mode(RzCore *core)
Definition: panels.c:5427
static char * hexdump_rotate[]
Definition: panels.c:168
static int __open_menu_cb(void *user)
Definition: panels.c:4065
static bool __is_abnormal_cursor_type(RzCore *core, RzPanel *panel)
Definition: panels.c:850
static bool __check_panel_type(RzPanel *panel, const char *type)
Definition: panels.c:791
static void __handle_tab(RzCore *core)
Definition: panels.c:6044
static void __set_dcb(RzCore *core, RzPanel *p)
Definition: panels.c:2998
static bool __check_if_mouse_y_illegal(RzCore *core, int y)
Definition: panels.c:666
static int __rz_shell_cb(void *user)
Definition: panels.c:3288
static bool __move_to_direction(RzCore *core, Direction direction)
Definition: panels.c:5544
static int __fill_cb(void *user)
Definition: panels.c:3197
static bool __check_if_cur_panel(RzCore *core, RzPanel *panel)
Definition: panels.c:708
static bool __draw_modal(RzCore *core, RModal *modal, int range_end, int start, const char *name)
Definition: panels.c:5643
static void __add_help_panel(RzCore *core)
Definition: panels.c:1279
static void __move_panel_to_right(RzCore *core, RzPanel *panel, int src)
Definition: panels.c:2421
static int __references_cb(void *user)
Definition: panels.c:3563
static const char * cache_white_list_cmds[]
Definition: panels.c:183
static void __init_all_dbs(RzCore *core)
Definition: panels.c:4892
static const char * register_rotate[]
Definition: panels.c:173
static void __panels_layout_refresh(RzCore *core)
Definition: panels.c:1354
static int __io_cache_off_cb(void *user)
Definition: panels.c:3397
static void __update_help_contents(RzCore *core, RzPanel *panel)
Definition: panels.c:990
static void __update_edge_x(RzCore *core, int x)
Definition: panels.c:614
static char * __create_panels_config_path(const char *file)
Definition: panels.c:5235
static void __exec_almighty(RzCore *core, RzPanel *panel, RModal *modal, Sdb *menu_db, RzPanelLayout dir)
Definition: panels.c:5736
static void __do_panels_refreshOneShot(RzCore *core)
Definition: panels.c:4777
static void __fix_cursor_up(RzCore *core)
Definition: panels.c:1504
static bool __check_root_state(RzCore *core, RzPanelsRootState state)
Definition: panels.c:838
static void __clear_panels_menuRec(RzPanelsMenuItem *pmi)
Definition: panels.c:4552
#define PANEL_TITLE_SECTIONS
Definition: panels.c:24
static int __break_points_cb(void *user)
Definition: panels.c:3533
#define TOkENs
static void __rotate_function_cb(void *user, bool rev)
Definition: panels.c:5885
static void __handle_tab_new(RzCore *core)
Definition: panels.c:6127
static void __add_visual_mark(RzCore *core)
Definition: panels.c:2112
static void __update_help(RzCore *core, RzPanels *ps)
Definition: panels.c:3459
static char * __search_db(RzCore *core, const char *title)
Definition: panels.c:757
static void __add_menu(RzCore *core, const char *parent, const char *base_name, RzPanelsMenuCallback cb)
Definition: panels.c:4093
static void __panel_single_step_in(RzCore *core)
Definition: panels.c:4781
static void __fix_layout_w(RzCore *core)
Definition: panels.c:2485
static void nextOpcode(RzCore *core)
Definition: panels.c:6249
static RZ_OWN char * __search_strings(RzCore *core, bool whole)
Definition: panels.c:4956
static void __undo_seek(RzCore *core)
Definition: panels.c:5890
static int __copy_cb(void *user)
Definition: panels.c:3167
static void __print_disassembly_cb(void *user, void *p)
Definition: panels.c:3948
static void __direction_panels_cursor_cb(void *user, int direction)
Definition: panels.c:3864
static void __direction_disassembly_cb(void *user, int direction)
Definition: panels.c:3634
static void __replace_cmd(RzCore *core, const char *title, const char *cmd)
Definition: panels.c:2810
static void __rotate_disasm_cb(void *user, bool rev)
Definition: panels.c:5810
static void __panel_print(RzCore *core, RzConsCanvas *can, RzPanel *panel, int color)
Definition: panels.c:955
static char * __show_status_input(RzCore *core, const char *msg)
Definition: panels.c:782
static char * __get_panels_config_dir_path(void)
Definition: panels.c:5228
static bool __show_status_yesno(RzCore *core, int def, const char *msg)
Definition: panels.c:776
static void __set_mode(RzCore *core, RzPanelsMode mode)
Definition: panels.c:3452
int __writeValueCb(void *user)
Definition: panels.c:3595
static void __resize_panel_down(RzPanels *panels)
Definition: panels.c:2569
static RModal * __init_modal(void)
Definition: panels.c:4591
static void __renew_filter(RzPanel *panel, int n)
Definition: panels.c:5534
static void __cursor_down(RzCore *core)
Definition: panels.c:1492
static RzList * __sorted_list(RzCore *core, char *menu[], int count)
Definition: panels.c:4540
static void __update_panel_title(RzCore *core, RzPanel *panel)
Definition: panels.c:1090
static void __rotate_panels(RzCore *core, bool rev)
Definition: panels.c:5784
#define PANEL_CMD_SYMBOLS
Definition: panels.c:28
#define PANEL_CMD_DISASSEMBLY
Definition: panels.c:32
static bool firstRun
Definition: panels.c:48
static bool __handle_mouse_on_X(RzCore *core, int x, int y)
Definition: panels.c:1927
static ut64 __parse_string_on_cursor(RzCore *core, RzPanel *panel, int idx)
Definition: panels.c:1417
static void __handle_tab_name(RzCore *core)
Definition: panels.c:6123
static const char * menus_Tools[]
Definition: panels.c:111
RZ_API bool rz_load_panels_layout(RzCore *core, const char *_name)
Definition: panels.c:5321
static void __print_graph_cb(void *user, void *p)
Definition: panels.c:3972
static int __help_cb(void *user)
Definition: panels.c:3577
static bool __check_if_mouse_x_on_edge(RzCore *core, int x, int y)
Definition: panels.c:676
static const char * menus[]
Definition: panels.c:67
#define PANEL_TITLE_STRINGS_BIN
Definition: panels.c:23
static bool search_db_check_panel_type(RzCore *core, RzPanel *panel, const char *ch)
Definition: panels.c:842
void __handlePrompt(RzCore *core, RzPanels *panels)
Definition: panels.c:943
static void __init_menu_saved_layout(void *core, const char *parent)
Definition: panels.c:4197
static void __refresh_core_offset(RzCore *core)
Definition: panels.c:4631
static const char * entropy_rotate[]
Definition: panels.c:163
static void __cursor_up(RzCore *core)
Definition: panels.c:1480
static RzPanels * __panels_new(RzCore *core)
Definition: panels.c:5520
static const char * menus_Help[]
Definition: panels.c:156
static void __handle_tab_nth(RzCore *core, int ch)
Definition: panels.c:6083
static const char * help_msg_panels_zoom[]
Definition: panels.c:256
static void __save_panel_pos(RzPanel *panel)
Definition: panels.c:5218
static void __cursor_del_breakpoints(RzCore *core, RzPanel *panel)
Definition: panels.c:2048
static bool __handle_mouse_on_top(RzCore *core, int x, int y)
Definition: panels.c:1895
static void __delete_almighty(RzCore *core, RModal *modal, Sdb *menu_db)
Definition: panels.c:5750
static void __set_rcb(RzPanels *ps, RzPanel *p)
Definition: panels.c:3028
#define PANEL_NUM_LIMIT
Definition: panels.c:8
static const char * menus_Search[]
Definition: panels.c:116
static bool __handle_window_mode(RzCore *core, const int key)
Definition: panels.c:1673
static void __set_panel_addr(RzCore *core, RzPanel *panel, ut64 addr)
Definition: panels.c:914
static int __open_file_cb(void *user)
Definition: panels.c:3074
static int __file_history_down(RzLine *line)
Definition: panels.c:5032
static void __update_disassembly_or_open(RzCore *core)
Definition: panels.c:3405
#define PANEL_CMD_DISASMSUMMARY
Definition: panels.c:33
static void __rotate_hexdump_cb(void *user, bool rev)
Definition: panels.c:5867
static bool __handle_mouse(RzCore *core, RzPanel *panel, int *key)
Definition: panels.c:1844
static char * __find_cmd_str_cache(RzCore *core, RzPanel *panel)
Definition: panels.c:1141
static RzStrBuf * __draw_menu(RzCore *core, RzPanelsMenuItem *item)
Definition: panels.c:4163
static void __move_panel_to_dir(RzCore *core, RzPanel *panel, int src)
Definition: panels.c:2377
static void __insert_panel(RzCore *core, int n, const char *name, const char *cmd)
Definition: panels.c:1361
static int __close_file_cb(void *user)
Definition: panels.c:3121
static void __set_refresh_by_type(RzCore *core, const char *cmd, bool clearCache)
Definition: panels.c:2906
static void __menu_panel_print(RzConsCanvas *can, RzPanel *panel, int x, int y, int w, int h)
Definition: panels.c:979
static void __replace_current_panel_input(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title)
Definition: panels.c:4907
static void __set_pos(RzPanelPos *pos, int x, int y)
Definition: panels.c:899
static void __put_breakpoints_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title)
Definition: panels.c:4965
static void __print_disasmsummary_cb(void *user, void *p)
Definition: panels.c:3934
static int __file_history_up(RzLine *line)
Definition: panels.c:5015
static void __handle_print_rotate(RzCore *core)
Definition: panels.c:6102
void __handleComment(RzCore *core)
Definition: panels.c:1618
static bool __is_normal_cursor_type(RzPanel *panel)
Definition: panels.c:878
static void __create_panel_input(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title)
Definition: panels.c:4916
static void __check_edge(RzCore *core)
Definition: panels.c:712
static void __handle_tab_prev(RzCore *core)
Definition: panels.c:6113
static void __cursor_left(RzCore *core)
Definition: panels.c:1447
static int __settings_colors_cb(void *user)
Definition: panels.c:3203
static void __handle_tab_next(RzCore *core)
Definition: panels.c:6094
static int __code_cb(void *user)
Definition: panels.c:3321
static bool fromVisual
Definition: panels.c:5945
static void __move_panel_to_up(RzCore *core, RzPanel *panel, int src)
Definition: panels.c:2442
char * __get_panels_config_file_from_dir(const char *file)
Definition: panels.c:5243
static void __panels_process(RzCore *core, RzPanels *panels)
Definition: panels.c:6271
#define PANEL_CMD_HEXDUMP
Definition: panels.c:37
static void __shrink_panels_forward(RzCore *core, int target)
Definition: panels.c:730
void __mht_free_kv(HtPPKv *kv)
Definition: panels.c:4982
static void __direction_graph_cb(void *user, int direction)
Definition: panels.c:3691
static int __rw_cb(void *user)
Definition: panels.c:3084
static int __string_whole_bin_cb(void *user)
Definition: panels.c:3303
static void __update_help_title(RzCore *core, RzPanel *panel)
Definition: panels.c:1023
#define PANEL_CONFIG_RESIZE_H
Definition: panels.c:44
static int __system_shell_cb(void *user)
Definition: panels.c:3296
static void __set_root_state(RzCore *core, RzPanelsRootState state)
Definition: panels.c:6024
static void __rotate_entropy_v_cb(void *user, bool rev)
Definition: panels.c:5857
static void __panels_refresh(RzCore *core)
Definition: panels.c:4639
static void __del_panels(RzCore *core)
Definition: panels.c:6028
static char * menus_settings_disassembly[]
Definition: panels.c:140
static void __set_geometry(RzPanelPos *pos, int x, int y, int w, int h)
Definition: panels.c:909
static void __shrink_panels_backward(RzCore *core, int target)
Definition: panels.c:738
static const char * panels_dynamic[]
Definition: panels.c:57
static void __set_filter(RzCore *core, RzPanel *panel)
Definition: panels.c:5899
static bool __init(RzCore *core, RzPanels *panels, int w, int h)
Definition: panels.c:4987
static void __panels_check_stackbase(RzCore *core)
Definition: panels.c:4797
static int __add_cmdf_panel(RzCore *core, char *input, char *str)
Definition: panels.c:1303
static int __load_layout_default_cb(void *user)
Definition: panels.c:3111
static int __quit_cb(void *user)
Definition: panels.c:3605
static RzConsCanvas * __create_new_canvas(RzCore *core, int w, int h)
Definition: panels.c:2933
static void __print_default_cb(void *user, void *p)
Definition: panels.c:3920
static int __write_str_cb(void *user)
Definition: panels.c:3179
static int __license_cb(void *user)
Definition: panels.c:3583
#define PANEL_CMD_CONSOLE
Definition: panels.c:38
static const char * function_rotate[]
Definition: panels.c:178
#define PANEL_CONFIG_SIDEPANEL_W
Definition: panels.c:42
static int __rop_cb(void *user)
Definition: panels.c:3315
static char * menus_settings_disassembly_asm[]
Definition: panels.c:145
static int __hexpairs_cb(void *user)
Definition: panels.c:3327
static int __step_cb(void *user)
Definition: panels.c:3375
static void __init_sdb(RzCore *core)
Definition: panels.c:4828
static const char * help_msg_panels_window[]
Definition: panels.c:236
static void __maximize_panel_size(RzPanels *panels)
Definition: panels.c:5421
static void __update_menu_contents(RzCore *core, RzPanelsMenu *menu, RzPanelsMenuItem *parent)
Definition: panels.c:4181
static int __show_status(RzCore *core, const char *msg)
Definition: panels.c:769
static void __update_panel_contents(RzCore *core, RzPanel *panel, const char *cmdstr)
Definition: panels.c:1046
static char * menus_Colors[128]
Definition: panels.c:138
static bool __check_if_mouse_x_illegal(RzCore *core, int x)
Definition: panels.c:656
static void __layout_default(RzPanels *panels)
Definition: panels.c:1211
static void __print_stack_cb(void *user, void *p)
Definition: panels.c:3986
static void __handle_tab_new_with_cur_panel(RzCore *core)
Definition: panels.c:6134
static void __del_invalid_panels(RzCore *core)
Definition: panels.c:2679
static void __init_menu_disasm_asm_settings_layout(void *_core, const char *parent)
Definition: panels.c:4262
#define PANEL_TITLE_DISASSEMBLY
Definition: panels.c:15
static void __panel_single_step_over(RzCore *core)
Definition: panels.c:4785
static void __search_strings_bin_create(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title)
Definition: panels.c:4949
static int __clear_layout_cb(void *user)
Definition: panels.c:3141
static void __seek_all(RzCore *core, ut64 addr)
Definition: panels.c:2882
static void __set_cursor(RzCore *core, bool cur)
Definition: panels.c:1376
static void __init_menu_screen_settings_layout(void *_core, const char *parent)
Definition: panels.c:4285
static int cmpstr(const void *_a, const void *_b)
Definition: panels.c:4535
static void __set_breakpoints_on_cursor(RzCore *core, RzPanel *panel)
Definition: panels.c:5479
static void __update_modal(RzCore *core, Sdb *menu_db, RModal *modal)
Definition: panels.c:5600
static int __io_cache_on_cb(void *user)
Definition: panels.c:3389
static bool __handle_zoom_mode(RzCore *core, const int key)
Definition: panels.c:1542
static bool __handle_cursor_mode(RzCore *core, const int key)
Definition: panels.c:1754
static int __string_data_sec_cb(void *user)
Definition: panels.c:3309
static void __handle_menu(RzCore *core, const int key)
Definition: panels.c:5054
static int __paste_cb(void *user)
Definition: panels.c:3173
#define PANEL_CMD_REGISTERS
Definition: panels.c:31
static void __reset_scroll_pos(RzPanel *p)
Definition: panels.c:1136
static bool __init_panels(RzCore *core, RzPanels *panels)
Definition: panels.c:4573
#define PANEL_TITLE_BREAKPOINTS
Definition: panels.c:21
#define PANEL_CMD_GRAPH
Definition: panels.c:35
static void __step_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title)
Definition: panels.c:4974
static RzPanel * __get_panel(RzPanels *panels, int i)
Definition: panels.c:918
static void __swap_panels(RzPanels *panels, int p0, int p1)
Definition: panels.c:2827
static void __panel_breakpoint(RzCore *core)
Definition: panels.c:4789
static void __redo_seek(RzCore *core)
Definition: panels.c:5921
static void __esil_init(RzCore *core)
Definition: panels.c:4056
static int __step_over_cb(void *user)
Definition: panels.c:3382
#define PANEL_TITLE_DISASMSUMMARY
Definition: panels.c:16
static void __split_panel_horizontal(RzCore *core, RzPanel *p, const char *name, const char *cmd)
Definition: panels.c:1338
static void __clear_panels_menu(RzCore *core)
Definition: panels.c:4563
static void __dismantle_panel(RzPanels *ps, RzPanel *p)
Definition: panels.c:2697
static void __free_panel_model(RzPanel *panel)
Definition: panels.c:4602
static void __jmp_to_cursor_addr(RzCore *core, RzPanel *panel)
Definition: panels.c:2039
static int __esil_step_range_cb(void *user)
Definition: panels.c:3353
static void __insert_value(RzCore *core)
Definition: panels.c:5489
static void __esil_step_to(RzCore *core, ut64 end)
Definition: panels.c:4061
static void __set_curnode(RzCore *core, int idx)
Definition: panels.c:3438
static void __default_panel_print(RzCore *core, RzPanel *panel)
Definition: panels.c:1123
static const char * menus_File[]
Definition: panels.c:73
static const char * help_msg_panels[]
Definition: panels.c:188
static int __add_cmd_panel(void *user)
Definition: panels.c:1254
static void __update_menu(RzCore *core, const char *parent, RZ_NULLABLE RzPanelMenuUpdateCallback cb)
Definition: panels.c:4133
static void __cache_white_list(RzCore *core, RzPanel *panel)
Definition: panels.c:746
static int __esil_step_to_cb(void *user)
Definition: panels.c:3346
static const char * panels_static[]
Definition: panels.c:62
static int __program_cb(void *user)
Definition: panels.c:3517
static void __del_panel(RzCore *core, int pi)
Definition: panels.c:2655
static void __panel_all_clear(RzPanels *panels)
Definition: panels.c:1191
static void __init_menu_disasm_settings_layout(void *_core, const char *parent)
Definition: panels.c:4239
static RzPanel * __get_cur_panel(RzPanels *panels)
Definition: panels.c:925
static const char * menus_iocache[]
Definition: panels.c:98
static void __free_menu_item(RzPanelsMenuItem *item)
Definition: panels.c:4615
static void __call_visual_graph(RzCore *core)
Definition: panels.c:2836
static int __write_hex_cb(void *user)
Definition: panels.c:3185
static void __direction_register_cb(void *user, int direction)
Definition: panels.c:3717
static void __search_strings_data_create(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title)
Definition: panels.c:4942
static void __set_cmd_str_cache(RzCore *core, RzPanel *p, char *s)
Definition: panels.c:885
static void __init_new_panels_root(RzCore *core)
Definition: panels.c:6000
static bool __check_func_diff(RzCore *core, RzPanel *p)
Definition: panels.c:2866
static void __init_rotate_db(RzCore *core)
Definition: panels.c:4817
static void __restore_panel_pos(RzPanel *panel)
Definition: panels.c:5223
static void __step_over_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED const RzPanelLayout dir, RZ_UNUSED RZ_NULLABLE const char *title)
Definition: panels.c:4978
static void __move_panel_to_down(RzCore *core, RzPanel *panel, int src)
Definition: panels.c:2461
#define PANEL_TITLE_COMMENTS
Definition: panels.c:26
static void __direction_default_cb(void *user, int direction)
Definition: panels.c:3610
static void __create_default_panels(RzCore *core)
Definition: panels.c:5762
#define COUNT(x)
Definition: panels.c:46
static void __create_almighty(RzCore *core, RzPanel *panel, Sdb *menu_db)
Definition: panels.c:5660
static char * __load_cmdf(RzCore *core, RzPanel *p, char *input, char *str)
Definition: panels.c:1292
static int __config_toggle_cb(void *user)
Definition: panels.c:3220
static void __create_panel_db(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title)
Definition: panels.c:4898
static void __direction_stack_cb(void *user, int direction)
Definition: panels.c:3758
static int __debugger_cb(void *user)
Definition: panels.c:3090
static int __calculator_cb(void *user)
Definition: panels.c:3273
static bool __check_func(RzCore *core)
Definition: panels.c:2853
static void prevOpcode(RzCore *core)
Definition: panels.c:6260
static const char * menus_Edit[]
Definition: panels.c:93
static char * menus_View[]
Definition: panels.c:103
static int __esil_init_cb(void *user)
Definition: panels.c:3340
static void __rotate_panel_cmds(RzCore *core, const char **cmds, const int cmdslen, const char *prefix, bool rev)
Definition: panels.c:5827
static void __fix_cursor_down(RzCore *core)
Definition: panels.c:1520
static bool __drag_and_resize(RzCore *core)
Definition: panels.c:2020
static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char *data, char *str, int len, bool big_endian)
Definition: filter.c:185
#define ph(a_type)
Definition: ph.h:27
#define min(a, b)
Definition: qsort.h:83
RZ_API ut64 rz_reg_getv(RzReg *reg, const char *name)
Definition: reg.c:332
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
Definition: reg.c:147
static void repeat(struct parse *, sopno, int, int)
Definition: regcomp.c:1155
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
@ RZ_ANALYSIS_FCN_TYPE_NULL
Definition: rz_analysis.h:192
@ RZ_ANALYSIS_OP_MASK_BASIC
Definition: rz_analysis.h:440
#define RZ_CONS_KEY_F12
Definition: rz_cons.h:589
#define RZ_CONS_KEY_F11
Definition: rz_cons.h:588
#define RZ_CONS_CLEAR_LINE
Definition: rz_cons.h:593
#define RZ_CONS_KEY_F10
Definition: rz_cons.h:587
#define Color_RESET
Definition: rz_cons.h:617
#define RZ_CONS_KEY_F6
Definition: rz_cons.h:583
#define RZ_CONS_KEY_F7
Definition: rz_cons.h:584
#define RZ_CONS_KEY_F3
Definition: rz_cons.h:580
#define RZ_CONS_KEY_F2
Definition: rz_cons.h:579
void(* RzConsEvent)(void *)
Definition: rz_cons.h:346
#define RZ_CONS_KEY_F1
Definition: rz_cons.h:578
#define RZ_CONS_KEY_F5
Definition: rz_cons.h:582
@ PANEL_LAYOUT_DEFAULT_DYNAMIC
Definition: rz_cons.h:1193
@ PANEL_LAYOUT_DEFAULT_STATIC
Definition: rz_cons.h:1192
int(* RzPanelsMenuCallback)(void *user)
Definition: rz_cons.h:1166
#define RZ_CONS_KEY_F4
Definition: rz_cons.h:581
@ RZ_LINE_PROMPT_DEFAULT
Definition: rz_cons.h:1037
@ RZ_LINE_PROMPT_OFFSET
Definition: rz_cons.h:1038
@ RZ_LINE_PROMPT_FILE
Definition: rz_cons.h:1039
#define RZ_CONS_KEY_F9
Definition: rz_cons.h:586
#define RZ_LINE_BUFSIZE
Definition: rz_cons.h:991
#define Color_BLUE
Definition: rz_cons.h:635
RzPanelsMode
Definition: rz_cons.h:1183
@ PANEL_MODE_MENU
Definition: rz_cons.h:1185
@ PANEL_MODE_DEFAULT
Definition: rz_cons.h:1184
@ PANEL_MODE_ZOOM
Definition: rz_cons.h:1186
@ PANEL_MODE_WINDOW
Definition: rz_cons.h:1187
#define RZ_CONS_KEY_F8
Definition: rz_cons.h:585
RzPanelsRootState
Definition: rz_cons.h:1225
@ DEL
Definition: rz_cons.h:1228
@ ROTATE
Definition: rz_cons.h:1227
@ QUIT
Definition: rz_cons.h:1229
@ DEFAULT
Definition: rz_cons.h:1226
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
Definition: file.c:454
RZ_API bool rz_file_rm(const char *file)
Definition: file.c:865
RZ_API RZ_OWN char * rz_file_path_join(RZ_NONNULL const char *s1, RZ_NULLABLE const char *s2)
Concatenate two paths to create a new one with s1+s2 with the correct path separator.
Definition: file.c:1312
RZ_API RzList * rz_id_storage_list(RzIDStorage *s)
Definition: idpool.c:283
RZ_API int rz_io_close_all(RzIO *io)
Definition: io.c:258
@ RZ_JSON_INTEGER
Definition: rz_json.h:33
@ RZ_JSON_ARRAY
Definition: rz_json.h:31
@ RZ_JSON_OBJECT
Definition: rz_json.h:30
@ RZ_JSON_STRING
Definition: rz_json.h:32
RZ_API RzJson * rz_json_parse(char *text)
Definition: json_parser.c:382
RZ_API void rz_json_free(RzJson *js)
Definition: json_parser.c:45
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
@ PANEL_EDGE_RIGHT
Definition: rz_panels.h:24
@ PANEL_EDGE_BOTTOM
Definition: rz_panels.h:23
@ PANEL_TYPE_MENU
Definition: rz_panels.h:18
@ PANEL_TYPE_DEFAULT
Definition: rz_panels.h:17
void(* RzPanelRotateCallback)(void *user, bool rev)
Definition: rz_panels.h:29
void(* RzPanelAlmightyCallback)(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title)
Definition: rz_panels.h:72
RzPanelLayout
Definition: rz_panels.h:10
@ VERTICAL
Definition: rz_panels.h:11
@ HORIZONTAL
Definition: rz_panels.h:12
@ NONE
Definition: rz_panels.h:13
void(* RzPanelMenuUpdateCallback)(void *user, const char *parent)
Definition: rz_panels.h:27
RZ_API RZ_OWN char * rz_path_home_prefix(RZ_NULLABLE const char *path)
Return path prefixed by the home prefix.
Definition: path.c:182
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API char * pj_drain(PJ *j)
Definition: pj.c:50
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
RZ_API char * rz_str_between(const char *str, const char *prefix, const char *suffix)
Definition: str.c:3264
RZ_API const char * rz_str_sep(const char *base, const char *sep)
Definition: str.c:788
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_append(char *ptr, const char *string)
Definition: str.c:1063
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
RZ_API char RZ_API char * rz_str_newlen(const char *str, int len)
Definition: str.c:871
RZ_API size_t rz_str_ansi_len(const char *str)
Definition: str.c:1945
RZ_API int rz_str_ansi_filter(char *str, char **out, int **cposs, int len)
Definition: str.c:2124
RZ_API char * rz_str_dup(char *ptr, const char *string)
Definition: str.c:1021
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API char * rz_str_prefix_all(const char *s, const char *pfx)
Definition: str.c:3038
RZ_API char * rz_str_ansi_crop(const char *str, unsigned int x, unsigned int y, unsigned int x2, unsigned int y2)
Definition: str.c:2174
RZ_API const char * rz_str_rsep(const char *base, const char *p, const char *sep)
Definition: str.c:801
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
RZ_API const char * rz_str_pad(const char ch, int len)
Definition: str.c:3236
RZ_API char * rz_str_version(const char *program)
Definition: str.c:4051
RZ_API const char * rz_str_word_get0(const char *str, int idx)
Definition: str.c:598
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
Definition: str.c:3329
RZ_API int rz_str_bounds(const char *str, int *h)
Definition: str.c:3124
RZ_API size_t rz_str_split(char *str, char ch)
Split string str in place by using ch as a delimiter.
Definition: str.c:406
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API bool rz_strbuf_slice(RZ_NONNULL RzStrBuf *sb, size_t from, size_t len)
Cuts the current string into a substring.
Definition: strbuf.c:122
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
RZ_API int rz_strbuf_length(RzStrBuf *sb)
Definition: strbuf.c:28
RZ_API bool rz_strbuf_append_n(RzStrBuf *sb, const char *s, size_t l)
Definition: strbuf.c:229
RZ_API bool rz_sys_mkdirp(const char *dir)
Definition: sys.c:691
#define rz_sys_xsystem(cmd)
Definition: rz_sys.h:83
RZ_API RzList * rz_sys_dir(const char *path)
Definition: sys.c:216
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
Definition: sys.c:1815
#define RZ_SYS_DIR
Definition: rz_types.h:218
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RW
Definition: rz_types.h:96
#define RZ_UNUSED
Definition: rz_types.h:73
#define RZ_JOIN_2_PATHS(p1, p2)
Definition: rz_types.h:224
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define RZ_MIN(x, y)
#define UT32_MAX
Definition: rz_types_base.h:99
#define RZ_MAX(x, y)
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_DATADIR
Definition: rz_userconf.h:73
#define isdigit(c)
Definition: safe-ctype.h:131
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611
RZ_API Sdb * sdb_new0(void)
Definition: sdb.c:43
RZ_API char * sdb_get(Sdb *s, const char *key, ut32 *cas)
Definition: sdb.c:290
RZ_API bool sdb_remove(Sdb *s, const char *key, ut32 cas)
Definition: sdb.c:299
RZ_API int sdb_count(Sdb *s)
Definition: sdb.c:163
RZ_API SdbList * sdb_foreach_list(Sdb *s, bool sorted)
Definition: sdb.c:630
static char * sdbkv_key(const SdbKv *kv)
Definition: sdbht.h:21
RZ_API bool rz_core_seek_delta(RzCore *core, st64 delta, bool save)
Seek relative to current offset and optionally save the current offset in seek history.
Definition: seek.c:152
RZ_API bool rz_core_seek_and_save(RzCore *core, ut64 addr, bool rb)
Save currently marked state in seek history and seek to addr .
Definition: seek.c:101
RZ_API bool rz_core_seek_next(RzCore *core, const char *type, bool save)
Seek to the next type of item from current offset.
Definition: seek.c:203
RZ_API bool rz_core_seek_prev(RzCore *core, const char *type, bool save)
Seek to the previous type of item from current offset.
Definition: seek.c:241
RZ_API bool rz_core_seek(RzCore *core, ut64 addr, bool rb)
Seek to addr.
Definition: seek.c:116
static int
Definition: sfsocketcall.h:114
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
long int64_t
Definition: sftypes.h:32
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41
#define h(i)
Definition: sha256.c:48
#define INT8_MAX
RzPanelPos pos
Definition: rz_cons.h:1198
int offset
Definition: rz_cons.h:1200
int idx
Definition: rz_cons.h:1199
RzStrBuf * data
Definition: rz_cons.h:1197
Definition: zipcmp.c:77
Definition: gzappend.c:170
Definition: ls.h:17
Definition: ls.h:22
Definition: z80asm.h:102
Definition: rz_pj.h:12
RzList * bps
Definition: rz_bp.h:93
RzConsPrintablePalette pal
Definition: rz_cons.h:491
struct rz_line_t * line
Definition: rz_cons.h:553
RzConsEvent event_resize
Definition: rz_cons.h:522
void * event_data
Definition: rz_cons.h:523
RzConsContext * context
Definition: rz_cons.h:502
bool vmode
Definition: rz_core.h:309
RzCons * cons
Definition: rz_core.h:312
bool scr_gadgets
Definition: rz_core.h:385
RzList * files
Definition: rz_core.h:315
RzBin * bin
Definition: rz_core.h:298
ut64 offset
Definition: rz_core.h:301
RzAsm * rasm
Definition: rz_core.h:323
RzAnalysis * analysis
Definition: rz_core.h:322
RzDebug * dbg
Definition: rz_core.h:329
RzPanels * panels
Definition: rz_core.h:335
RzIO * io
Definition: rz_core.h:313
RzNum * num
Definition: rz_core.h:316
RzCoreTaskScheduler tasks
Definition: rz_core.h:362
ut8 * block
Definition: rz_core.h:305
RzFlag * flags
Definition: rz_core.h:330
RzPanelsRoot * panels_root
Definition: rz_core.h:334
RzPrint * print
Definition: rz_core.h:327
RzConfig * config
Definition: rz_core.h:300
const char * name
Definition: rz_debug.h:359
int regcols
Definition: rz_debug.h:260
struct rz_debug_plugin_t * cur
Definition: rz_debug.h:295
RzBreakpoint * bp
Definition: rz_debug.h:288
int fd
Definition: rz_io.h:96
int perm
Definition: rz_io.h:97
RzIDStorage * files
Definition: rz_io.h:75
struct rz_io_desc_t * desc
Definition: rz_io.h:60
struct rz_json_t::@304::@307 children
const char * str_value
Definition: rz_json.h:42
const char * key
Definition: rz_json.h:40
struct rz_json_t * next
Definition: rz_json.h:56
RzJsonType type
Definition: rz_json.h:39
struct rz_json_t::@304::@306 num
RzLinePromptType prompt_type
Definition: rz_cons.h:1116
char * funcName
Definition: rz_panels.h:51
char * cmdStrCache
Definition: rz_panels.h:49
RzPanelRotateCallback rotateCb
Definition: rz_panels.h:41
RzPanelDirectionCallback directionCb
Definition: rz_panels.h:40
char ** filter
Definition: rz_panels.h:52
RzPanelType type
Definition: rz_panels.h:43
char * readOnly
Definition: rz_panels.h:50
RzPanelPrintCallback print_cb
Definition: rz_panels.h:42
RzPanelModel * model
Definition: rz_panels.h:68
RzPanelView * view
Definition: rz_panels.h:69
RzPanelPos pos
Definition: rz_panels.h:58
RzPanelPos prevPos
Definition: rz_panels.h:59
RzPanelsMenuCallback cb
Definition: rz_cons.h:1171
struct rz_panels_menu_item ** sub
Definition: rz_cons.h:1170
RzPanelsMenuItem * root
Definition: rz_cons.h:1176
RzPanelsMenuItem ** history
Definition: rz_cons.h:1177
RzPanel ** refreshPanels
Definition: rz_cons.h:1180
RzPanelsRootState root_state
Definition: rz_cons.h:1238
RzPanels ** panels
Definition: rz_cons.h:1237
bool mouse_on_edge_x
Definition: rz_cons.h:1212
Sdb * almighty_db
Definition: rz_cons.h:1217
int mouse_orig_y
Definition: rz_cons.h:1210
RzConsCanvas * can
Definition: rz_cons.h:1204
char * name
Definition: rz_cons.h:1222
RzPanelsLayout layout
Definition: rz_cons.h:1221
RzPanelsMenu * panels_menu
Definition: rz_cons.h:1214
bool mouse_on_edge_y
Definition: rz_cons.h:1213
RzPanelsMode prevMode
Definition: rz_cons.h:1220
RzPanel ** panel
Definition: rz_cons.h:1205
bool autoUpdate
Definition: rz_cons.h:1211
int curnode
Definition: rz_cons.h:1208
RzPanelsMode mode
Definition: rz_cons.h:1219
int mouse_orig_x
Definition: rz_cons.h:1209
int columnWidth
Definition: rz_cons.h:1207
int n_panels
Definition: rz_cons.h:1206
HtPP * mht
Definition: rz_cons.h:1218
Sdb * db
Definition: rz_cons.h:1215
Sdb * rotate_db
Definition: rz_cons.h:1216
ut64 screen_bounds
Definition: rz_print.h:179
int cols
Definition: rz_print.h:136
int ocur
Definition: rz_print.h:135
bool cur_enabled
Definition: rz_print.h:130
Definition: sdbht.h:14
Definition: sdb.h:63
Definition: dis.h:43
int pos
Definition: main.c:11
RZ_API void rz_core_task_enqueue_oneshot(RzCoreTaskScheduler *scheduler, RzCoreTaskOneShot func, void *user)
Definition: task.c:391
int replace(char *string, const char *token, const char *fmt,...)
Definition: tms320_dasm.c:325
Definition: dis.c:32
RZ_API void rz_core_visual_asm(RzCore *core, ut64 off)
Definition: vasm.c:73
static int color
Definition: visual.c:20
RZ_API int rz_core_visual_prevopsz(RzCore *core, ut64 addr)
Definition: visual.c:1272
RZ_API void rz_core_visual_offset(RzCore *core)
Definition: visual.c:1247
RZ_API void rz_core_visual_seek_animation_undo(RzCore *core)
Definition: visual.c:1088
RZ_API void rz_core_visual_applyDisMode(RzCore *core, int disMode)
Definition: visual.c:174
RZ_API void rz_core_visual_disasm_up(RzCore *core, int *cols)
Definition: visual.c:3802
RZ_API bool rz_core_visual_hud(RzCore *core)
Definition: visual.c:471
RZ_API void rz_core_visual_append_help(RzStrBuf *p, const char *title, const char **help)
Definition: visual.c:532
RZ_API bool rz_core_prevop_addr(RzCore *core, ut64 start_addr, int numinstrs, ut64 *prev_addr)
Definition: visual.c:1173
RZ_API void rz_core_visual_prompt_input(RzCore *core)
Definition: visual.c:733
RZ_API void rz_core_visual_browse(RzCore *core, const char *input)
Definition: visual.c:2067
RZ_API void rz_core_visual_applyHexMode(RzCore *core, int hexMode)
Definition: visual.c:84
RZ_API int rz_core_visual(RzCore *core, const char *input)
Definition: visual.c:3856
RZ_API void rz_core_visual_disasm_down(RzCore *core, RzAsmOp *op, int *cols)
Definition: visual.c:3806
RZ_API int rz_core_visual_xrefs(RzCore *core, bool xref_to, bool fcnInsteadOfAddr)
Definition: visual.c:1312
RZ_API void rz_core_visual_toggle_hints(RzCore *core)
Definition: visual.c:109
RZ_API void rz_core_visual_showcursor(RzCore *core, int x)
Definition: visual.c:420
RZ_API void rz_core_visual_jump(RzCore *core, ut8 ch)
Definition: visual.c:514
RZ_API int rz_line_hist_offset_up(RzLine *line)
Definition: visual.c:1222
RZ_API int rz_line_hist_offset_down(RzLine *line)
Definition: visual.c:1235
RZ_API void rz_core_visual_seek_animation_redo(RzCore *core)
Definition: visual.c:1082
RZ_API void rz_core_visual_mark(RzCore *core, ut8 ch)
Definition: vmarks.c:47
RZ_API bool rz_core_visual_mark_dump(RzCore *core)
Definition: vmarks.c:14
RZ_API void rz_core_visual_mark_seek(RzCore *core, ut8 ch)
Definition: vmarks.c:54
RZ_API void rz_core_visual_mark_del(RzCore *core, ut8 ch)
Definition: vmarks.c:40
static char * prompt(const char *str, const char *txt)
Definition: vmenus.c:30
RZ_API void rz_core_visual_define(RzCore *core, const char *args, int distance)
Definition: vmenus.c:3149
RZ_API bool rz_core_visual_hudstuff(RzCore *core)
Definition: vmenus.c:539
static st64 delta
Definition: vmenus.c:2425
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
RZ_API bool rz_core_yank_paste(RzCore *core, ut64 addr, ut64 len)
Definition: yank.c:174
static const z80_opcode fd[]
Definition: z80_tab.h:997
static const char * cb[]
Definition: z80_tab.h:176
static int sp
Definition: z80asm.c:91
static int addr
Definition: z80asm.c:58
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
int def(FILE *source, FILE *dest, int level)
Definition: zpipe.c:36