From: mats c. <ma...@us...> - 2005-11-07 09:49:44
|
Update of /cvsroot/jungerl/jungerl/lib/prf/examples/gperf In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15438/examples/gperf Added Files: gperfGtk.erl gperfConsumer.erl gperf.gladep gperf.glade gperf.erl gperf Makefile Log Message: initial checkin --- NEW FILE: gperfConsumer.erl --- %%%------------------------------------------------------------------- %%% File : gperfConsumer.erl %%% Author : Mats Cronqvist <locmacr@mwlx084> %%% Description : %%% %%% Created : 17 May 2005 by Mats Cronqvist <locmacr@mwlx084> %%%------------------------------------------------------------------- -module(gperfConsumer). -export([init/1, terminate/1, tick/2, collectors/0, config/2]). -record(data,{net=[],sys=[]}). -record(ld, {node,gtkPid,data=#data{}, mem_max=512*1024*1024,net_max=100,load_max=1}). collectors() -> [prfSys,prfNet]. init(Node) -> {_,Reg} = process_info(self(),registered_name), GtkPid = gperfGtk:start(list_to_atom((atom_to_list(Reg)++"_GUI")),Node), link(GtkPid), #ld{node = Node, gtkPid=GtkPid}. terminate(LD) -> gperfGtk:stop(LD#ld.gtkPid). tick(LD, Data) -> NLD = update_ld(LD, Data), NLD#ld.gtkPid ! {tick, {ltime(NLD#ld.data),info(NLD,LD)}}, NLD. config(LD,{maxs,[Mem,Net]}) -> LD#ld{net_max=Net,mem_max=Mem}; config(LD,dbg) -> dump_ld(LD), LD. info(NLD,LD) -> [load(LD#ld.load_max,NLD#ld.data,LD#ld.data), mem(LD#ld.mem_max,NLD#ld.data,LD#ld.data), net(LD#ld.net_max,NLD#ld.data,LD#ld.data)]. dump_ld(LD) -> F = fun({N,V}) -> io:fwrite("~p~n",[{N,V}]) end, lists:foreach(F,zip(record_info(fields,ld),tl(tuple_to_list(LD)))). zip([],[]) -> []; zip([A|As],[B|Bs]) -> [{A,B}|zip(As,Bs)]. update_ld(LD,[]) -> LD#ld{data=#data{}}; update_ld(LD,[[{prfNet,Net},{prfSys,Sys}]|_]) -> LD#ld{data=#data{net=Net,sys=Sys}}. ltime(#data{sys=Sys}) -> case catch calendar:now_to_local_time(w(now,Sys)) of {'EXIT',_} -> io:fwrite("bad time: ~p~n",[catch w(now,Sys)]),no_time; {_Date,Time}-> Time end. load(Max,#data{sys=N},#data{sys=O}) -> [sysload(N),beamload(Max,N,O)]. sysload(N) -> (w(user,N)+w(kernel,N))/100. beamload(Max,N,O) -> case dv(w(runtime,N)-w(runtime,O),w(wall_clock,N)-w(wall_clock,O)) of Load when 0 < Load, Load < Max -> Load; _ -> 0 end. mem(Max,#data{sys=Sys},_LD) -> [max(1,dv(w(beamsize,Sys),Max)), max(1,dv(w(total,Sys),Max)), max(1,dv(w(ets,Sys)+w(processes,Sys),Max)), max(1,dv(w(processes,Sys),Max))]. net(Max,#data{net=NetN},#data{net=NetO}) -> {InO,OutO} = net1(NetO,0,0), {InN,OutN} = net1(NetN,0,0), [max(1,dv(InN-InO,Max)), max(1,dv(OutN-OutO,Max))]. net1([],In,Out) -> {In,Out}; net1([{Nod,N}|X],I,O) -> {In,Out} = net2(N,[],[]), net1(X,I+In,O+Out). net2(_,I,O) when is_integer(I),is_integer(O) -> {I,O}; net2([{in,I}|X],_,O) -> net2(X,I,O); net2([{out,O}|X],I,_) -> net2(X,I,O); net2([_|X],I,O) -> net2(X,I,O). w(Tag,List) -> case lists:keysearch(Tag,1,List) of {value, {Tag,{Val,_}}} -> Val; {value, {Tag,Val}} -> Val; _ -> 0 end. dv(A,0) -> 0; dv(A,B) -> A/B. max(R,V) when V < R -> V; max(R,_) -> R. --- NEW FILE: gperf.gladep --- <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> <!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd"> <glade-project> <name>Gperf</name> <program_name>gperf</program_name> <gnome_support>FALSE</gnome_support> </glade-project> --- NEW FILE: gperf --- #!/bin/bash usage(){ U1="usage: $0 [-setcookie <cookie>] [-nocookie] " U2="[-nettick <tick>] [-nospawn] nodename" echo $U1 $U2 exit } while [ -n "$1" ] do ARGS="$ARGS $LAST" LAST=$1 shift done if [ -n "$LAST"]; then usage; fi Erl -vsn R9 $ARGS \ -pa $JUNGERL/lib/prf/examples/gperf \ -pa $JUNGERL/lib/prf/ebin \ -pa $JUNGERL/lib/gtkNode/ebin \ -s gperf start $LAST --- NEW FILE: gperf.erl --- -module(gperf). -export([start/1]). start([Node]) -> prfHost:start([gperf,Node,gperfConsumer]); start(Node) -> prfHost:start(gperf,Node,gperfConsumer). --- NEW FILE: Makefile --- ERLC = $(OTP_ROOT)/bin/erlc EFLAGS = +debug_info ERLS = $(wildcard *.erl) BEAMS = $(patsubst %.erl, %.beam, $(ERLS)) #.PHONY: default all default: all all: $(BEAMS) clean: rm -f *.beam %.beam : %.erl $(ERLC) $(EFLAGS) $< --- NEW FILE: gperf.glade --- <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> <glade-interface> <widget class="GtkWindow" id="window"> <property name="visible">True</property> <property name="title" translatable="yes">gperf</property> <property name="type">GTK_WINDOW_TOPLEVEL</property> <property name="window_position">GTK_WIN_POS_NONE</property> <property name="modal">False</property> <property name="default_width">200</property> <property name="default_height">100</property> <property name="resizable">True</property> <property name="destroy_with_parent">False</property> <property name="decorated">True</property> <property name="skip_taskbar_hint">False</property> <property name="skip_pager_hint">False</property> <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> <property name="focus_on_map">True</property> <signal name="delete_event" handler="gtk_true" last_modification_time="Fri, 06 May 2005 14:21:19 GMT"/> <signal name="delete_event" handler="gn_sighandler" last_modification_time="Mon, 09 May 2005 07:57:28 GMT"/> <child> <widget class="GtkVBox" id="vbox1"> <property name="visible">True</property> <property name="homogeneous">False</property> <property name="spacing">0</property> <child> <widget class="GtkMenuBar" id="menubar"> <property name="visible">True</property> <child> <widget class="GtkMenuItem" id="menuitem1"> <property name="visible">True</property> <property name="label" translatable="yes">_File</property> <property name="use_underline">True</property> <child> <widget class="GtkMenu" id="menuitem1_menu"> <child> <widget class="GtkMenuItem" id="view1"> <property name="visible">True</property> <property name="label" translatable="yes">View</property> <property name="use_underline">True</property> <child> <widget class="GtkMenu" id="view1_menu"> <child> <widget class="GtkCheckMenuItem" id="load"> <property name="visible">True</property> <property name="label" translatable="yes">Load</property> <property name="use_underline">True</property> <property name="active">True</property> <signal name="activate" handler="gn_sighandler" last_modification_time="Tue, 20 Sep 2005 13:17:54 GMT"/> </widget> </child> <child> <widget class="GtkCheckMenuItem" id="memory"> <property name="visible">True</property> <property name="label" translatable="yes">Memory</property> <property name="use_underline">True</property> <property name="active">True</property> <signal name="activate" handler="gn_sighandler" last_modification_time="Tue, 20 Sep 2005 13:17:54 GMT"/> </widget> </child> <child> <widget class="GtkCheckMenuItem" id="netload"> <property name="visible">True</property> <property name="label" translatable="yes">Netload</property> <property name="use_underline">True</property> <property name="active">True</property> <signal name="activate" handler="gn_sighandler" last_modification_time="Tue, 20 Sep 2005 13:17:54 GMT"/> </widget> </child> </widget> </child> </widget> </child> <child> <widget class="GtkImageMenuItem" id="quit"> <property name="visible">True</property> <property name="label">gtk-quit</property> <property name="use_stock">True</property> <signal name="activate" handler="gn_sighandler" last_modification_time="Wed, 04 May 2005 12:42:07 GMT"/> </widget> </child> </widget> </child> </widget> </child> <child> <widget class="GtkMenuItem" id="menuitem4"> <property name="visible">True</property> <property name="label" translatable="yes">_Help</property> <property name="use_underline">True</property> <child> <widget class="GtkMenu" id="menuitem4_menu"> <child> <widget class="GtkMenuItem" id="about"> <property name="visible">True</property> <property name="label" translatable="yes">_About</property> <property name="use_underline">True</property> <signal name="activate" handler="gn_sighandler" last_modification_time="Wed, 04 May 2005 12:42:07 GMT"/> </widget> </child> </widget> </child> </widget> </child> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> </child> <child> <widget class="GtkVBox" id="vbox2"> <property name="visible">True</property> <property name="homogeneous">False</property> <property name="spacing">0</property> <child> <widget class="GtkDrawingArea" id="drawingarea1"> <property name="visible">True</property> <signal name="expose_event" handler="gn_sighandler" last_modification_time="Wed, 04 May 2005 12:43:20 GMT"/> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> </child> <child> <widget class="GtkDrawingArea" id="drawingarea2"> <property name="visible">True</property> <signal name="expose_event" handler="gn_sighandler" last_modification_time="Wed, 04 May 2005 12:43:20 GMT"/> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> </child> <child> <widget class="GtkDrawingArea" id="drawingarea3"> <property name="visible">True</property> <signal name="expose_event" handler="gn_sighandler" last_modification_time="Wed, 04 May 2005 12:43:20 GMT"/> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> </child> </widget> <packing> <property name="padding">0</property> <property name="expand">True</property> <property name="fill">True</property> </packing> </child> <child> <widget class="GtkStatusbar" id="statusbar"> <property name="visible">True</property> <property name="has_resize_grip">True</property> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> </child> </widget> </child> </widget> <widget class="GtkDialog" id="about"> <property name="title" translatable="yes">about</property> <property name="type">GTK_WINDOW_TOPLEVEL</property> <property name="window_position">GTK_WIN_POS_NONE</property> <property name="modal">False</property> <property name="resizable">True</property> <property name="destroy_with_parent">False</property> <property name="decorated">True</property> <property name="skip_taskbar_hint">False</property> <property name="skip_pager_hint">False</property> <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> <property name="focus_on_map">True</property> <property name="has_separator">True</property> <signal name="delete_event" handler="gtk_widget_hide" last_modification_time="Wed, 18 May 2005 15:19:19 GMT"/> <child internal-child="vbox"> <widget class="GtkVBox" id="dialog-vbox1"> <property name="visible">True</property> <property name="homogeneous">False</property> <property name="spacing">0</property> <child internal-child="action_area"> <widget class="GtkHButtonBox" id="dialog-action_area1"> <property name="visible">True</property> <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property> <child> <widget class="GtkButton" id="okbutton1"> <property name="visible">True</property> <property name="can_default">True</property> <property name="can_focus">True</property> <property name="label">gtk-ok</property> <property name="use_stock">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <property name="focus_on_click">True</property> <property name="response_id">-5</property> <signal name="clicked" handler="gtk_widget_hide" object="about" last_modification_time="Fri, 06 May 2005 14:12:03 GMT"/> </widget> </child> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">GTK_PACK_END</property> </packing> </child> <child> <widget class="GtkLabel" id="label1"> <property name="visible">True</property> <property name="label" translatable="yes">The mighty gperf program Use it or suffer the consequences</property> <property name="use_underline">False</property> <property name="use_markup">False</property> <property name="justify">GTK_JUSTIFY_CENTER</property> <property name="wrap">False</property> <property name="selectable">False</property> <property name="xalign">0.5</property> <property name="yalign">0.5</property> <property name="xpad">0</property> <property name="ypad">0</property> <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> </child> </widget> </child> </widget> </glade-interface> --- NEW FILE: gperfGtk.erl --- %%%------------------------------------------------------------------- %%% File : gperfFoo.erl %%% Author : Mats Cronqvist <locmacr@mwlx084> %%% Description : %%% %%% Created : 12 Sep 2005 by Mats Cronqvist <locmacr@mwlx084> %%%------------------------------------------------------------------- -module(gperfGtk). -export([start/2,stop/1]). -export([loop/1]). %internal export -import(filename,[join/1,dirname/1]). -import(random,[uniform/1]). -define(MARG,10). -define(XSIZE,2000). -define(YSIZE,100). -define(WXSIZE,200). -define(WYSIZE,?YSIZE). -define(XHALF,(?XSIZE div 2)). -define(DAREAS, [{drawingarea1,[blue,red]}, {drawingarea2,[black,blue,red,yellow]}, {drawingarea3,[red,green]}]). -record(dArea, {win,px_fg,px_bg,gc_fg,gc_bg,gcs,layout}). -record(ld, {name,node,minute,x=?XHALF,dAreas=[],state=disc,stat_ctxt}). start(Name, Node) -> spawn_link(fun()-> init(Name,Node) end). stop(Name) -> catch (Name ! quit), quit. init(Name,Node) -> put(gui_name,Name), gtkNode:start(Name), g([],'GN_glade_init',[glade_file()]), loop(do_init(#ld{name=Name,node=atom_to_list(Node)})). glade_file() -> join([dirname(code:which(?MODULE)),gperf])++".glade". loop(LD = #ld{name=Name}) -> receive {Name,{signal,{window,'GDK_DELETE'}}} -> die(LD); {Name,{signal,{But,'GDK_BUTTON_RELEASE'}}} -> loop(do_button(LD,But)); {Name,{signal,{Darea,'GDK_EXPOSE'}}} -> loop(do_expose(LD,Darea)); {tick, Stuff} -> ?MODULE:loop(do_tick(LD,Stuff)); dbg -> dump_ld(LD), ?MODULE:loop(LD); quit -> die(LD); X -> loop(do_unknown(LD,X)) end. dump_ld(LD) -> F = fun({N,V})->io:fwrite("~p~n",[{N,V}]) end, lists:foreach(F,zip(record_info(fields,ld),tl(tuple_to_list(LD)))). zip([],[]) -> []; zip([A|As],[B|Bs]) -> [{A,B}|zip(As,Bs)]. die(LD) -> gtkNode:stop(LD#ld.name), io:fwrite("~w - terminating~n", [?MODULE]), exit(dying). do_unknown(LD,X) -> io:fwrite("~w - unknown signal - ~p~n",[?MODULE,X]), LD. do_expose(LD,Darea) -> redraw(Darea,LD). do_tick(LD, {Time, Stuff}) -> redraw(stuff(timeline(switch(LD),Time), Stuff)). do_button(LD,quit) -> die(LD); do_button(LD,about) -> g(about,'Gtk_widget_show',[]),LD; do_button(LD,load) -> maybe_show(load,drawingarea1),LD; do_button(LD,memory) -> maybe_show(memory,drawingarea2),LD; do_button(LD,netload) -> maybe_show(netload,drawingarea3),LD. maybe_show(Item, Darea) -> case g(Item,'Gtk_check_menu_item_get_active',[]) of true -> g(Darea,'Gtk_widget_show',[]); false -> g(Darea,'Gtk_widget_hide',[]),resize_toplevel(Darea) end. resize_toplevel(Widget) -> TopLevel = g(Widget,'Gtk_widget_get_toplevel',[]), g(TopLevel,'Gtk_window_resize',[1,1]). %%% redraw(LD) -> lists:foreach(fun({DA,_Colors}) -> redraw(DA,LD) end, ?DAREAS), LD. redraw(Darea,LD = #ld{x=X,dAreas=Dareas}) -> #dArea{win=Win,px_fg=Pixmap,gc_fg=GC} = lks(Darea,Dareas), Width = g(Darea,'GN_widget_get_attr',[width]), g(Win,'Gdk_draw_drawable',[GC,Pixmap,0,0,Width-?MARG-X,0,X+1,-1]), LD. stuff(LD = #ld{dAreas=Dareas,x=X},Datas) -> stuffit(X,Datas,Dareas), LD#ld{x=X+1}. stuffit(_X,[],[]) -> ok; stuffit(X,[Data|Datas],[{_DAname,Darea}|Dareas]) -> stuffer(X,Data,1,Darea), stuffit(X,Datas,Dareas). stuffer(_X,[],_N,Darea) -> ok; stuffer(X,[Val|Vals],N,Darea) -> draw_line(Darea,N,X,Val), stuffer(X,Vals,N+1,Darea). timeline(LD = #ld{state=disc}, no_time) -> LD; timeline(LD = #ld{state=disc}, {_H,M,_S}) -> stat_change(up,LD#ld{minute=M}); timeline(LD = #ld{state=conn}, no_time) -> stat_change(down,LD); %%timeline(LD = #ld{minute=undefined},{_H,M,_S}) -> LD#ld{minute=M}; timeline(LD = #ld{minute=M},{_H,M,_S}) -> LD; timeline(LD = #ld{dAreas=Dareas},{_,M,_}=HMS) -> lists:foreach(fun(Darea)->draw_timeline(Darea,LD,HMS) end,Dareas), LD#ld{minute=M}. stat_change(up,LD) -> Msg = LD#ld.node++" - connected", g(statusbar,'Gtk_statusbar_push',[LD#ld.stat_ctxt,Msg]), LD#ld{state=conn}; stat_change(down,LD) -> g(statusbar,'Gtk_statusbar_pop',[LD#ld.stat_ctxt]), LD#ld{state=disc}. draw_timeline({_,Darea},LD,{H,M,_S}) -> draw_line(Darea,fg,LD#ld.x,1), draw_time(Darea,LD,{H,M}). draw_time(#dArea{px_fg=Pxfg,px_bg=Pxbg,layout=Layout,gc_fg=GC},LD,{H,M}) -> Tm = lists:flatten(io_lib:fwrite("~2.2.0w:~2.2.0w",[H,M])), g(Layout,'GN_pango_layout_set_text',[Tm,"geneva 6"]), g(Pxfg,'Gdk_draw_layout',[GC,LD#ld.x,90,Layout]), g(Pxbg,'Gdk_draw_layout',[GC,LD#ld.x-?XHALF,90,Layout]). draw_line(DA,GCtag,X,Y) -> %% draws a line from {X,0} to {X,Y} where 0<Y<1. %% Y=0: upper margin, Y=1: lower margin Y0 = ?YSIZE-?MARG, Y1 = Y0-round(Y*(?YSIZE-2*?MARG)), GC = get_gc(DA,GCtag), g(DA#dArea.px_fg,'Gdk_draw_line',[GC,X,Y0,X,Y1]), g(DA#dArea.px_bg,'Gdk_draw_line',[GC,X-?XHALF,Y0,X-?XHALF,Y1]). get_gc(DA,N) when is_integer(N) -> lists:nth(N,DA#dArea.gcs); get_gc(DA,fg) -> DA#dArea.gc_fg; get_gc(DA,bg) -> DA#dArea.gc_bg. switch(LD) -> case LD#ld.x > ?XSIZE of false-> LD; true -> LD#ld{x=?XHALF,dAreas=switch_das(LD#ld.dAreas)} end. switch_das([]) -> []; switch_das([{D,DA = #dArea{px_fg=Px1,px_bg=Px2,gc_fg=GCfg,gc_bg=GCbg}}|DAs]) -> clear_px(GCfg,GCbg,Px1), [{D,DA#dArea{px_fg=Px2,px_bg=Px1}}|switch_das(DAs)]. do_init(LD) -> redraw(clear_all(LD#ld{dAreas=init_das(),stat_ctxt=init_stat(LD)})). init_stat(LD) -> Msg = LD#ld.node++" - disconnected", Id = g(statusbar,'Gtk_statusbar_get_context_id',["state"]), g(statusbar,'Gtk_statusbar_push',[Id,Msg]), Id. init_das() -> [init_da(DA_Colors) || DA_Colors <- ?DAREAS]. init_da({DA,Colors})-> Win = g(DA,'GN_widget_get_attr',[window]), Layout = g(DA,'Gtk_widget_create_pango_layout',[""]), g(Win,'Gdk_window_clear',[]), [GCblack,GCwhite] = gcs(Win,[black,white]), [P1,P2] = pixmaps(2,Win), g(DA, 'Gtk_widget_set_size_request',[?WXSIZE,?WYSIZE]), g(DA,'Gtk_widget_modify_bg', ['GTK_STATE_NORMAL',white]), {DA,#dArea{win=Win,layout=Layout, gc_fg=GCblack,gc_bg=GCwhite, px_fg=P1,px_bg=P2, gcs=gcs(Win,Colors)}}. pixmaps(0, _Win) -> []; pixmaps(N,Win) -> Pixmap = g(Win,'Gdk_pixmap_new',[?XSIZE,?YSIZE,-1]), [Pixmap|pixmaps(N-1,Win)]. clear_all(LD) -> lists:foreach(fun(DA)->clear_one(DA) end, LD#ld.dAreas), LD. clear_one({_,#dArea{px_fg=Px1,px_bg=Px2,gc_fg=GCfg,gc_bg=GCbg}}) -> clear_px(GCfg,GCbg,Px1), clear_px(GCfg,GCbg,Px2). clear_px(GCfg,GCbg,Pixmap) -> g(Pixmap,'Gdk_draw_rectangle', [GCbg, true, 0, 0, -1, -1]), g(Pixmap,'Gdk_draw_rectangle', [GCfg,false,?MARG,?MARG,?XSIZE-2*?MARG,?YSIZE-2*?MARG]). gcs(_Win,[]) -> []; gcs(Win,[Color|T]) -> GC = g(Win,'Gdk_gc_new',[]), ColorMap = g(GC,'Gdk_gc_get_colormap',[]), g([],'Gdk_color_parse',[atom_to_list(Color),Color]), g(ColorMap,'Gdk_colormap_alloc_color',[Color,false,true]), g(GC,'Gdk_gc_set_foreground',[Color]), [GC|gcs(Win,T)]. g([],Cmd,Args) -> snd_rec(Cmd,Args); g(Wid,Cmd,Args) -> snd_rec(Cmd,[Wid|Args]). snd_rec(Cmd, Args) -> GuiName = get(gui_name), GuiName ! {self(),[{Cmd,Args}]}, receive {GuiName,{reply,[{ok,Rep}]}} -> %%io:fwrite("~w ~p -> ~p~n",[Cmd,Args,Rep]), Rep; {GuiName,{reply,[{error,Rep}]}} -> erlang:fault({Cmd,Args,Rep}) end. lks(Tag,List) -> {value,{Tag,Val}} = lists:keysearch(Tag,1,List), Val. dv(A,0) -> 0; dv(A,B) -> A/B. %%%GUI=gperf_GUI,G = fun(Wid,Cmd,Args)->GUI! {self(),[{Cmd,[Wid|Args]}]}, receive {GUI,{reply,[{ok,Rep}]}} -> Rep;{GUI,{reply,[{error,Rep}]}} -> erlang:fault({Cmd,Args,Rep}) end end. |