diff options
Diffstat (limited to 'lib/debugger/src/dbg_ui_mon_win.erl')
-rw-r--r-- | lib/debugger/src/dbg_ui_mon_win.erl | 573 |
1 files changed, 0 insertions, 573 deletions
diff --git a/lib/debugger/src/dbg_ui_mon_win.erl b/lib/debugger/src/dbg_ui_mon_win.erl deleted file mode 100644 index 8655c7697a..0000000000 --- a/lib/debugger/src/dbg_ui_mon_win.erl +++ /dev/null @@ -1,573 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% --module(dbg_ui_mon_win). --compile([{nowarn_deprecated_function,{gs,checkbutton,2}}, - {nowarn_deprecated_function,{gs,config,2}}, - {nowarn_deprecated_function,{gs,destroy,1}}, - {nowarn_deprecated_function,{gs,frame,2}}, - {nowarn_deprecated_function,{gs,grid,2}}, - {nowarn_deprecated_function,{gs,gridline,2}}, - {nowarn_deprecated_function,{gs,label,2}}, - {nowarn_deprecated_function,{gs,listbox,2}}, - {nowarn_deprecated_function,{gs,menu,2}}, - {nowarn_deprecated_function,{gs,menubar,2}}, - {nowarn_deprecated_function,{gs,menuitem,2}}, - {nowarn_deprecated_function,{gs,read,2}}, - {nowarn_deprecated_function,{gs,window,2}}]). - -%% External exports --export([init/0]). --export([create_win/3, get_window/1, - show_option/3, - enable/2, is_enabled/1, select/2, - add_module/3, delete_module/2, - add_process/6, update_process/4, clear_processes/1, - add_break/3, update_break/2, delete_break/2, - clear_breaks/1, clear_breaks/2, - handle_event/2 - ]). - --define(default_rows,50). - --record(moduleInfo, {module, menubtn}). --record(procInfo, {pid, row}). --record(breakInfo, {point, status, break}). --record(winInfo, {window, % gsobj() - grid, % gsobj() - row, % int() Last row in grid - - focus, % int() Selected row in grid - - modules=[], % [#moduleInfo{}] Known modules - processes=[], % [#procInfo{}] Known processes - breaks=[], % [#breakInfo{}] Known breakpoints - - listbox, % gsobj() Listinng known modules - - %% Auto attach buttons - fbutton, % gsobj() - bbutton, % gsobj() - ebutton, % gsobj() - selected=[], % ['First Call'|'On Break'|'On Exit'] - - slabel, % showing Stack Trace option - blabel % showing Back Trace Size - }). - -%%==================================================================== -%% External exports -%%==================================================================== - -init() -> - dbg_ui_win:init(). - -%%-------------------------------------------------------------------- -%% create_win(GS, Title, Menus) -> #winInfo{} -%% GS = gsobj() -%% Title = string() -%% Menus = [menu()] See dbg_ui_win.erl -%%-------------------------------------------------------------------- - --define(PAD, 5). --define(Wf, 150). --define(Wg, 770). --define(W, 800). --define(H, 390). - -create_win(GS, Title, Menus) -> - Win = gs:window(GS, [{title, Title}, - {width, ?W}, {height, ?H}, - {configure,true}, {destroy,true}, - {keypress,true}, {motion,true}]), - - MenuBar = gs:menubar(Win, []), - dbg_ui_win:create_menus(MenuBar, Menus), - dbg_ui_winman:windows_menu(MenuBar), - - Font = dbg_ui_win:font(normal), - - Frame = gs:frame(Win, [{x, ?PAD}, {y, 30}, - {width, ?Wf}, {height, ?H}]), - Hlb = 200, - Listbox = gs:listbox(Frame, [{x, 0}, {y, 0}, - {width, ?Wf}, {height, Hlb}, - {data, listbox}, - {doubleclick, true}, - {items, []}]), - gs:label(Frame, [{x, 0}, {y, Hlb}, {width, ?Wf}, {height, 20}, - {align, w}, - {label, {text, "Auto Attach:"}}, {font, Font}]), - Fbtn = gs:checkbutton(Frame, [{x, 0}, {y, Hlb+20}, - {width, ?Wf}, {height, 20}, - {label, {text, 'First Call'}}, - {align, w}, {font, Font}, - {data, autoattach}]), - Bbtn = gs:checkbutton(Frame, [{x, 0}, {y, Hlb+40}, - {width, ?Wf}, {height, 20}, - {label, {text, 'On Break'}}, - {align, w}, {font, Font}, - {data, autoattach}]), - Ebtn = gs:checkbutton(Frame, [{x, 0}, {y, Hlb+60}, - {width, ?Wf}, {height, 20}, - {label, {text, 'On Exit'}}, - {align, w}, {font, Font}, - {data, autoattach}]), - SLabel = gs:label(Frame, [{x, 0}, {y, Hlb+80}, - {width, ?Wf}, {height, 40}, - {font, Font}, {align, w}]), - BLabel = gs:label(Frame, [{x, 0}, {y, Hlb+120}, - {width, ?Wf}, {height, 40}, - {font, Font}, {align, w}]), - - Grid = gs:grid(Win, [{x, 2*?PAD+?Wf}, {y, 30}, - {width, ?W-(2*?PAD+?Wf)}, {height, ?H-30}, - {bg, grey}, {fg, black}, - {vscroll, right}, {hscroll, bottom}, - calc_columnwidths(?Wg), - {rows, {1,?default_rows}}]), - gs:gridline(Grid, [{row, 1}, {bw, 5}, {fg, blue}, - {font, Font}, - {text, {1,"Pid"}}, {text, {2,"Initial Call"}}, - {text, {3,"Name"}}, {text, {4,"Status"}}, - {text, {5,"Information"}}]), - - gs:config(Win, {map, true}), - #winInfo{window=Win, grid=Grid, row=1, focus=0, - listbox=Listbox, - fbutton=Fbtn, bbutton=Bbtn, ebutton=Ebtn, - slabel=SLabel, blabel=BLabel}. - -%%-------------------------------------------------------------------- -%% get_window(WinInfo) -> Window -%% WinInfo = #winInfo{} -%% Window = gsobj() -%%-------------------------------------------------------------------- -get_window(WinInfo) -> - WinInfo#winInfo.window. - -%%-------------------------------------------------------------------- -%% show_option(WinInfo, Option, Value) -> void() -%% WinInfo = #winInfo{} -%% Option = auto_attach | stack_trace | back_trace -%% Value = [Flag] % Option==auto_attach -%% Flag = init | break | exit -%% | true | all | no_tail | false % Option==stack_trace -%% | int() % Option==back_trace -%%-------------------------------------------------------------------- -show_option(WinInfo, Option, Value) -> - case Option of - - auto_attach -> - lists:foreach(fun (Button) -> - gs:config(Button, {select, false}) - end, - option_buttons(WinInfo, [init, break, exit])), - lists:foreach(fun (Button) -> - gs:config(Button, {select, true}) - end, - option_buttons(WinInfo, Value)); - - stack_trace -> - Text = case Value of - all -> "Stack Trace:\n On (with tail)"; - true -> "Stack Trace:\n On (with tail)"; - no_tail -> "Stack Trace:\n On (no tail)"; - false -> "Stack Trace:\n Off" - end, - gs:config(WinInfo#winInfo.slabel, {label, {text, Text}}); - - back_trace -> - Text = "Back Trace Size:\n " ++ integer_to_list(Value), - gs:config(WinInfo#winInfo.blabel, {label, {text, Text}}) - end. - -option_buttons(WinInfo, [init|Flags]) -> - [WinInfo#winInfo.fbutton|option_buttons(WinInfo, Flags)]; -option_buttons(WinInfo, [break|Flags]) -> - [WinInfo#winInfo.bbutton|option_buttons(WinInfo, Flags)]; -option_buttons(WinInfo, [exit|Flags]) -> - [WinInfo#winInfo.ebutton|option_buttons(WinInfo, Flags)]; -option_buttons(_WinInfo, []) -> - []. - -%%-------------------------------------------------------------------- -%% enable([MenuItem], Bool) -%% is_enabled(MenuItem) -> Bool -%% MenuItem = atom() -%% Bool = boolean() -%%-------------------------------------------------------------------- -enable(MenuItems, Bool) -> - lists:foreach(fun(MenuItem) -> - gs:config(MenuItem, {enable, Bool}) - end, - MenuItems). - -is_enabled(MenuItem) -> - gs:read(MenuItem, enable). - -%%-------------------------------------------------------------------- -%% select(MenuItem, Bool) -%% MenuItem = atom() -%% Bool = boolean() -%%-------------------------------------------------------------------- -select(MenuItem, Bool) -> - dbg_ui_win:select(MenuItem, Bool). - -%%-------------------------------------------------------------------- -%% add_module(WinInfo, Name, Mod) -> WinInfo -%% WinInfo = #winInfo{} -%% Name = atom() -%% Mod = atom() -%%-------------------------------------------------------------------- -add_module(WinInfo, Menu, Mod) -> - Modules = WinInfo#winInfo.modules, - case lists:keymember(Mod, #moduleInfo.module, Modules) of - false -> - %% Create a menu for the module - Font = dbg_ui_win:font(normal), - MenuBtn = gs:menuitem(Menu, [{label, {text,Mod}}, - {font, Font}, - {itemtype, cascade}]), - SubMenu = gs:menu(MenuBtn, []), - gs:menuitem(SubMenu, [{label, {text,"View"}}, - {font, Font}, - {data, {module,Mod,view}}]), - gs:menuitem(SubMenu, [{label, {text,"Delete"}}, - {font, Font}, - {data, {module,Mod,delete}}]), - - %% Add the module to the listbox - gs:config(WinInfo#winInfo.listbox, {add, Mod}), - - ModInfo = #moduleInfo{module=Mod, menubtn=MenuBtn}, - WinInfo#winInfo{modules=[ModInfo | Modules]}; - true -> WinInfo - end. - -%%-------------------------------------------------------------------- -%% delete_module(WinInfo, Mod) -> WinInfo -%% WinInfo = #winInfo{} -%% Mod = atom() -%%-------------------------------------------------------------------- -delete_module(WinInfo, Mod) -> - {value, ModInfo} = lists:keysearch(Mod, #moduleInfo.module, - WinInfo#winInfo.modules), - gs:destroy(ModInfo#moduleInfo.menubtn), - delete_module(WinInfo#winInfo.listbox, atom_to_list(Mod), 0), - WinInfo#winInfo{modules=lists:keydelete(Mod, #moduleInfo.module, - WinInfo#winInfo.modules)}. - -delete_module(Listbox, ModS, Index) -> - case gs:read(Listbox, {get, Index}) of - ModS -> - gs:config(Listbox, {del, Index}); - _OtherModS -> - delete_module(Listbox, ModS, Index+1) - end. - -%%-------------------------------------------------------------------- -%% add_process(WinInfo, Pid, Name, Function, Status, Info) -> WinInfo -%% WinInfo = #winInfo{} -%% Pid = pid() -%% Name = undefined | atom() -%% Function = {Mod, Func, Args} -%% Status = idle | running | break | exit -%% Info = {} | term() -%%-------------------------------------------------------------------- -add_process(WinInfo, Pid, Name, {Mod,Func,Args}, Status, Info) -> - Grid = WinInfo#winInfo.grid, - Row = (WinInfo#winInfo.row)+1, - GridLine = case gs:read(Grid, {obj_at_row, Row}) of - undefined -> - if Row>?default_rows -> - gs:config(Grid,[{rows,{1,Row}}]); - true -> ok - end, - gs:gridline(Grid,[{row,Row}, {bw,5}, {fg,black}, - {font,dbg_ui_win:font(normal)}, - {click, true}, - {doubleclick, true}]); - GSObj -> - GSObj - end, - Name2 = case Name of undefined -> ""; _ -> Name end, - FuncS = io_lib:format("~w:~w/~w", [Mod, Func, length(Args)]), - Info2 = case Info of {} -> ""; _ -> Info end, - Options = [{text, {1,Pid}}, {text, {2,FuncS}}, {text, {3,Name2}}, - {text, {4,Status}}, {text, {5,Info2}}, - {data, {gridline, Pid}}], - gs:config(GridLine, Options), - - ProcInfo = #procInfo{pid=Pid, row=Row}, - WinInfo#winInfo{processes=[ProcInfo|WinInfo#winInfo.processes], - row=Row}. - -%%-------------------------------------------------------------------- -%% update_process(WinInfo, Pid, Status, Info) -%% WinInfo = #winInfo{} -%% Pid = pid() -%% Status = idle | running | break | exit -%% Info = {} | term() -%%-------------------------------------------------------------------- -update_process(WinInfo, Pid, Status, Info) -> - {value, ProcInfo} = lists:keysearch(Pid, #procInfo.pid, - WinInfo#winInfo.processes), - - Grid = WinInfo#winInfo.grid, - GridLine = gs:read(Grid, {obj_at_row, ProcInfo#procInfo.row}), - - Info2 = case Info of {} -> ""; _ -> Info end, - gs:config(GridLine, [{text, {4,Status}}, {text, {5,Info2}}]). - -%%-------------------------------------------------------------------- -%% clear_processes(WinInfo) -> WinInfo -%% WinInfo = #winInfo{} -%%-------------------------------------------------------------------- -clear_processes(WinInfo) -> - Grid = WinInfo#winInfo.grid, - Max = WinInfo#winInfo.row, - clear_processes(Grid, 2, Max), - gs:config(Grid,[{rows,{1,?default_rows}}]), - WinInfo#winInfo{row=1, focus=0, processes=[]}. - -clear_processes(Grid, Row, Max) when Row=<Max -> - GridLine = gs:read(Grid, {obj_at_row, Row}), - case gs:read(GridLine,{text,4}) of - "exit" -> - Pid = list_to_pid(gs:read(GridLine,{text,1})), - dbg_ui_winman:clear_process(dbg_ui_trace:title(Pid)); - _ -> - ok - end, - - Options = [{fg, black}, - {{text,1}, ""}, {{text,2},""}, {{text,3},""}, - {{text,4}, ""}, {{text,5},""}, - {data, []}], - gs:config(GridLine, Options), - clear_processes(Grid, Row+1, Max); -clear_processes(_Grid, Row, Max) when Row>Max -> - done. - -%%-------------------------------------------------------------------- -%% add_break(WinInfo, Name, {Point, Options}) -> WinInfo -%% WinInfo = #winInfo{} -%% Name = atom() -%% Point = {Mod, Line} -%% Options = [Status, Action, Mods, Cond] -%% Status = active | inactive -%% Action = enable | disable | delete -%% Mods = null (not used) -%% Cond = null | {Mod, Func} -%%-------------------------------------------------------------------- -add_break(WinInfo, Menu, {Point, Options}) -> - Break = dbg_ui_win:add_break(Menu, Point), - dbg_ui_win:update_break(Break, Options), - BreakInfo = #breakInfo{point=Point, break=Break}, - WinInfo#winInfo{breaks=[BreakInfo|WinInfo#winInfo.breaks]}. - -%%-------------------------------------------------------------------- -%% update_break(WinInfo, {Point, Options}) -%% WinInfo = #winInfo{} -%% Point = {Mod, Line} -%% Options = [Status, Action, Mods, Cond] -%% Status = active | inactive -%% Action = enable | disable | delete -%% Mods = null (not used) -%% Cond = null | {Mod, Func} -%%-------------------------------------------------------------------- -update_break(WinInfo, {Point, Options}) -> - {value, BreakInfo} = lists:keysearch(Point, #breakInfo.point, - WinInfo#winInfo.breaks), - dbg_ui_win:update_break(BreakInfo#breakInfo.break, Options). - -%%-------------------------------------------------------------------- -%% delete_break(WinInfo, Point) -> WinInfo -%% WinInfo = #winInfo{} -%% Point = {Mod, Line} -%%-------------------------------------------------------------------- -delete_break(WinInfo, Point) -> - {value, BreakInfo} = lists:keysearch(Point, #breakInfo.point, - WinInfo#winInfo.breaks), - dbg_ui_win:delete_break(BreakInfo#breakInfo.break), - WinInfo#winInfo{breaks=lists:keydelete(Point, #breakInfo.point, - WinInfo#winInfo.breaks)}. - -%%-------------------------------------------------------------------- -%% clear_breaks(WinInfo) -> WinInfo -%% clear_breaks(WinInfo, Mod) -> WinInfo -%% WinInfo = #winInfo{} -%%-------------------------------------------------------------------- -clear_breaks(WinInfo) -> - lists:foreach(fun(BreakInfo) -> - dbg_ui_win:delete_break(BreakInfo#breakInfo.break) - end, - WinInfo#winInfo.breaks), - WinInfo#winInfo{breaks=[]}. -clear_breaks(WinInfo, Mod) -> - Fun = - fun(BreakInfo) -> - case BreakInfo#breakInfo.point of - {Mod, _Line} -> - dbg_ui_win:delete_break(BreakInfo#breakInfo.break), - false; - _ -> true - end - end, - Breaks = lists:filter(Fun, WinInfo#winInfo.breaks), - WinInfo#winInfo{breaks=Breaks}. - -%%-------------------------------------------------------------------- -%% handle_event(GSEvent, WinInfo) -> Command -%% GSEvent = {gs, Id, Event, Data, Arg} -%% WinInfo = #winInfo{} -%% Command = ignore -%% | stopped -%% | {coords, {X,Y}} -%% -%% | {shortcut, Key} -%% | MenuItem | {Menu, [MenuItem]} -%% MenuItem = Menu = atom() -%% | {break, Point, What} -%% What = delete | {status, Status} | {trigger, Trigger} -%% | {module, Mod, What} -%% What = view | delete -%% -%% | {focus, Pid, WinInfo} -%% | default -%%-------------------------------------------------------------------- -%% Window events -handle_event({gs, _Id, configure, _Data, [W, H |_]}, WinInfo) -> - configure(WinInfo, {W, H}), - ignore; -handle_event({gs, _Id, destroy, _Data, _Arg}, _WinInfo) -> - stopped; -handle_event({gs, _Id, motion, _Data, [X,Y]}, WinInfo) -> - {LastX, LastY} = dbg_ui_win:motion(X, Y), - Win = WinInfo#winInfo.window, - {coords, {gs:read(Win, x)+LastX-5, gs:read(Win, y)+LastY-5}}; - -%% Menus and keyboard shortcuts -handle_event({gs, _Id, keypress, _Data, [Key,_,_,1]}, _WinInfo) when - Key/='Up', Key/='Down', Key/=p, Key/=n -> - {shortcut, Key}; -handle_event({gs, _Id, click, {dbg_ui_winman, Win}, _Arg}, _WinInfo) -> - dbg_ui_winman:raise(Win), - ignore; -handle_event({gs, _Id, click, {menuitem, Name}, _Arg}, _WinInfo) -> - Name; -handle_event({gs, _Id, click, {menu, Menu}, _Arg}, _WinInfo) -> - Names = dbg_ui_win:selected(Menu), - {Menu, Names}; -handle_event({gs, _Id, click, {break, Point, What}, _Arg}, _WinInfo) -> - {break, Point, What}; -handle_event({gs, _Id, click, {module, Mod, What}, _Arg}, _WinInfo) -> - {module, Mod, What}; - -%% Listbox -handle_event({gs, _Id, doubleclick, listbox, [_Index, ModS|_]}, _WI) -> - {module, list_to_atom(ModS), view}; - -%% Auto attach buttons -handle_event({gs, _Id, click, autoattach, _Arg}, WinInfo) -> - Names = lists:foldl(fun (Button, NamesAcc) -> - case gs:read(Button, select) of - true -> - {text, Name} = - gs:read(Button, label), - [list_to_atom(Name)|NamesAcc]; - false -> - NamesAcc - end - end, - [], - [WinInfo#winInfo.ebutton, - WinInfo#winInfo.bbutton, - WinInfo#winInfo.fbutton]), - {'Auto Attach', Names}; - -%% Process grid -handle_event({gs, _Id, keypress, _Data, [Key|_]}, WinInfo) when - Key =:= 'Up'; Key =:= 'Down' -> - Dir = if Key =:= 'Up' -> up; Key =:= 'Down' -> down end, - Row = move(WinInfo, Dir), - if Row>1 -> - WinInfo2 = highlight(WinInfo, Row), - #procInfo{pid=Pid} = - lists:keyfind(Row, #procInfo.row, WinInfo#winInfo.processes), - {focus, Pid, WinInfo2}; - true -> - ignore - end; -handle_event({gs, _Id, click, {gridline, Pid}, [_Col,Row|_]}, WinInfo) -> - WinInfo2 = highlight(WinInfo, Row), - {focus, Pid, WinInfo2}; -handle_event({gs, _Id, doubleclick, _Data, _Arg}, _WinInfo) -> - default; - -handle_event(_GSEvent, _WinInfo) -> - ignore. - -move(WinInfo, Dir) -> - Row = WinInfo#winInfo.focus, - Last = WinInfo#winInfo.row, - if - Dir =:= up, Row > 1 -> Row-1; - Dir =:= down, Row < Last -> Row+1; - true -> Row - end. - -highlight(WinInfo, Row) -> - Grid = WinInfo#winInfo.grid, - case WinInfo#winInfo.focus of - 0 -> ignore; - Focus -> - GridLine1 = gs:read(Grid, {obj_at_row, Focus}), - gs:config(GridLine1, {fg, black}) - end, - GridLine2 = gs:read(Grid, {obj_at_row, Row}), - gs:config(GridLine2, {fg, white}), - WinInfo#winInfo{focus=Row}. - -%%==================================================================== -%% Internal functions -%%==================================================================== - -configure(WinInfo, {W, H}) -> - Grid = WinInfo#winInfo.grid, - NewW = W - (2*?PAD+?Wf), - Dx = NewW - gs:read(Grid, width), - Dy = H-42 - gs:read(Grid, height), - if - (Dx+Dy) =/= 0 -> - gs:config(Grid, [{width, NewW}, {height, H-30}]), - Cols = calc_columnwidths(NewW), - gs:config(Grid, Cols); - true -> - ok - end. - -calc_columnwidths(Width) -> - W = if - Width =< ?Wg -> ?Wg; - true -> Width - end, - First = [round(X) || X <- [0.13*W, 0.27*W, 0.18*W, 0.18*W]], - Last = W - lists:sum(First) - 30, - {columnwidths, First++[Last]}. |