hello,
Calling all those people (yes both of you), who know anything about X and pop11.
We have been trying to emulate pwm, under X, and have built up a number of
procedures which do pwm things, only using the OpenLook widget set.
The eventhandling is carried out similarly to pop using pwm_eventhandler,
two procedures which we are trying to get right are pwm_make_menu,
and pwm_display_menu (The code for these procedures is included at the end). The
question I want answering is why pwm_display_menu will work from a command line,
but fail when used in the eventhandler
i.e. -
: pwm_make_gfxwin('tst',100,100) -> win;
: procedure(ev);
pwm_display_menu('Test\tHello\tWorld\t') =>
endprocedure -> pwm_eventhandler(win,"press");
/* Okay calling it on its own works */
: pwm_display_menu('Test\tHello\tWorld\t') =>
** 1
But when you press a button in 'win' the menu is created but appears blank
and no events are processed. Pop siezes up and you need a kill -QUIT to get
rid of the menu.
When you remove the loop from pwm_display_menu, it works (but we don't get any response) is there a better way of doing it. Or is there a simple fix
Cheers Kev
____________________________________________________________________
Kevin Richards K.Richards@reading.ac.uk
University of Reading, Whiteknights,
Reading, Berkshire, Uk
Phone +44 734 875123 ext 7642
/* CODE ----------------------------------------------------------------*/
/* --- Copyright Intelligent Systems Group at University of Reading --------
--- 1991. All rights reserved. -----------------------------------------
> File: pwm_eventhandler.p
> Purpose: provide an event handler for X pwm windows
> Documentation: HELP * dummy
> Related Files: MAN * rcsintro
> RCS Information
> $Author: adw $
> $Date: 92/11/14 18:14:44 $
> $RCSfile: pwm_eventhandler.p,v $
> $Revision: 1.2 $
> $State: Exp $
> $Locker: $
CONTENTS - (Use <ENTER> gd to access required procedure)
define pwm_inputcatcher(ev);
define handle_button_event(widget,client,call_data);
define handle_resize_event(widget,client,call_data);
define handle_keyboard_event(widget,client,call_data);
define global pwm_eventhandler(widget,type)->proc;
define updaterof global pwm_eventhandler(proc,widget,type);
*/
uses pwm_windowtype;
uses popxlib;
uses xt_widget;
uses xt_callback;
uses xt_event;
uses XolConstants;
uses xlib;
uses XWindowAttributes;
uses XHouseKeeping;
uses XWindowConstants;
uses XKeyboard;
uses XEvents;
loadinclude xpt_xevent.ph;
section;
section $-library XLookupString => pwm_eventhandler handle_resize_event handle_keyboard_event handle_button_event handle_move_event handle_status_event;
section $-library$-pwmlib XLookupString => pwm_eventhandler handle_resize_event handle_keyboard_event handle_button_event handle_move_event handle_status_event;
global vars pwm_last_button = 1;
global vars pwmreport = false;
;;;defined in pwm_track_mouse
vars report_motion = false;
vars tracking_motion = false;
vars handle_tracking exit_tracking;
define global pwm_inputcatcher(ev);
lvars ev message;
switchon subscrv(1,ev) ==
case "quitrequest" then
pwm_kill_window(pwminputsource);
pwminputsource <> ' killed';
case "release"
orcase "press"
orcase "move"
orcase "mouseexit"
orcase "character" then
('message ' >< ev) >< ' received from ' >< pwminputsource;
else
false;
endswitchon -> message;
if message and pwmreport then
if vedediting then
vedputmessage(message);
else
pr(';;; ' <> message <> '\n');
endif;
endif;
enddefine;
vars win_proc_table = newproperty([],32,false,"tmparg");
define handle_move_event(widget,client,call_data);
lvars widget,button,client,ev,proc_table,proc,call_data;
if (pwm_last_button>0) and (exacc :XEvent call_data.type == MotionNotify)
then
{%
"move",
abs(pwm_last_button),
exacc :XMotionEvent call_data.x,
exacc :XMotionEvent call_data.y
%} -> ev;
;;;get the widgets evant handlers
win_proc_table(pwm_widget_windows(widget)) -> proc_table;
if tracking_motion then
handle_tracking(ev);
if report_motion then
unless proc_table and (proc_table("move")->> proc) then
pwm_inputcatcher -> proc;
endunless;
;;;set the widget as the input source
pwm_widget_windows(widget) -> pwminputsource;
chain(ev,proc);
endif;
endif;
endif;
enddefine;
define handle_button_event(widget,client,call_data);
lvars widget,button,client,ev,proc_table,proc,call_data,type,x,y;
;;;convert button to a pop int
if exacc :XButtonEvent call_data.type = 5 then
( exacc :XButtonReleasedEvent call_data.button ) * (-1)-> button;
exacc :XButtonReleasedEvent call_data.x -> x;
exacc :XButtonReleasedEvent call_data.y -> y;
else
exacc :XButtonPressedEvent call_data.button -> button;
exacc :XButtonPressedEvent call_data.x -> x;
exacc :XButtonPressedEvent call_data.y -> y;
endif;
button -> pwm_last_button;
if button < 0 then
if x =< 0 or x >= XptValue(widget,XtN width, "short")
or y =< 0 or y >= XptValue(widget,XtN height, "short")
then
"mouseexit" -> type;
0 ->> x -> y;
else
"release" -> type;
endif;
else
"press" -> type;
endif;
{% type, abs(button), x, y %} -> ev;
if tracking_motion then
exit_tracking(ev);
endif;
;;;get the widgets evant handlers
win_proc_table(pwm_widget_windows(widget)) -> proc_table;
unless proc_table and (proc_table(type)->> proc) then
pwm_inputcatcher -> proc;
endunless;
;;;set the widget as the input source
pwm_widget_windows(widget) -> pwminputsource;
proc(ev);
enddefine;
define handle_status_event(widget,client,call_data);
lvars widget,button,client,ev,proc_table,proc,call_data;
;;; Windows opening and closing and destroying
;;; pr('Status');
switchon exacc :XEvent call_data.type ==
case FocusIn then
{% "focusin",
0,0,0
%} -> ev;
pwm_widget_windows(widget) -> pwminputsource;
;;;get the widgets evant handlers
win_proc_table(pwm_widget_windows(widget)) -> proc_table;
unless proc_table and (proc_table("focusin")->> proc) then
pwm_inputcatcher -> proc;
endunless;
;;;set the widget as the input source
pwm_widget_windows(widget) -> pwminputsource;
chain(ev,proc);
case FocusOut then
{% "focusout",
0,0,0
%} -> ev;
;;;get the widgets evant handlers
pwm_widget_windows(widget) -> pwminputsource;
win_proc_table(pwm_widget_windows(widget)) -> proc_table;
unless proc_table and (proc_table("focusout")->> proc) then
pwm_inputcatcher -> proc;
endunless;
chain(ev,proc);
case DestroyNotify then
{%
"quitrequest",
0,0,0
%} -> ev;
pr('Destroy\n');
;;;get the widgets evant handlers
win_proc_table(pwm_widget_windows(widget)) -> proc_table;
unless proc_table and (proc_table("quitrequest")->> proc) then
pwm_inputcatcher -> proc;
endunless;
chain(ev,proc);
else
;;; ignore
endswitchon;
enddefine;
define handle_resize_event(widget,client,call_data);
lvars widget,button,client,ev,proc_table,proc,call_data;
{%
"resized",
abs(pwm_last_button),
exacc :XResizeRequestEvent call_data.width,
exacc :XResizeRequestEvent call_data.height
%} -> ev;
;;;get the widgets evant handlers
win_proc_table(pwm_widget_windows(widget)) -> proc_table;
unless proc_table and (proc_table("resized")->> proc) then
pwm_inputcatcher -> proc;
endunless;
;;;set the widget as the input source
pwm_widget_windows(widget) -> pwminputsource;
chain(ev,proc);
enddefine;
define handle_keyboard_event(widget,client,call_data);
lvars widget,client,ev,proc_table,proc,call_data,i,key;
lvars temps = inits(1);
;;;convert button to a pop int
if (XLookupString(call_data,temps,1,NULLptr,NULLptr) == 1) then
temps(1) -> key;
{%
"character",
key, 0, 0
%} -> ev;
;;;get the widgets evant handlers
win_proc_table(pwm_widget_windows(widget)) -> proc_table;
unless proc_table and (proc_table("character")->> proc) then
pwm_inputcatcher -> proc;
endunless;
;;;set the widget as the input source
pwm_widget_windows(widget) -> pwminputsource;
if proc.isprocedure then
proc(ev);
else
valof(proc)(ev);
endif;
endif;
enddefine;
define global pwm_eventhandler(pwm_id,type)->proc;
lvars type,proc,proc_table;
;;;get the widgets evant handlers
win_proc_table(pwm_id) -> proc_table;
unless proc_table and (proc_table(type)->> proc) then
pwm_inputcatcher -> proc;
endunless;
enddefine;
define updaterof global pwm_eventhandler(proc,pwm_id,type);
lvars type,proc,proc_table;
;;;get the widgets evant handlers
win_proc_table(pwm_id) -> proc_table;
unless proc_table then
newproperty([],10,false,"tmparg") -> proc_table;
proc_table -> win_proc_table(pwm_id);
endunless;
proc -> proc_table(type);
enddefine;
endsection;
endsection;
endsection;
/*----------------------------------------------------------------------------*/
section;
section $-library => pwm_make_menu pwm_menu_value;
section $-library$-pwmlib => pwm_make_menu pwm_menu_value;
uses xt_widget;
uses xt_widgetclass;
uses xt_widgetinfo;
uses xt_trans;
uses xt_action;
uses xt_event;
uses xt_popup;
uses xt_callback;
uses xlib;
uses pwm_make_execitem;
uses pwm_eventhandler;
uses conspwmitem;
loadinclude xt_constants;
define parse_menu_string(string) -> title -> labels;
lvars l_text = [],pos,len,line,height,start,i;
true -> pos;
1 -> start;
length(string) -> len;
while (start <= len) do
issubstring_lim('\t',start,len,false,string) -> pos;
if not(pos) then
substring(start,len-start+1,string) -> line;
start+len+1-start -> start;
else
substring(start,pos-start,string) -> line;
pos+1 -> start;
endif;
l_text <> [^line] -> l_text;
endwhile;
;;; Extract title
hd(l_text) -> title;
tl(l_text) -> labels;
enddefine;
define menu_wrapper(widget,clientdata,calldata,item);
lvars widget,clientdata,calldata,item;
clientdata -> ((item.pi_other)(1));
enddefine;
define pwm_menu_value(item);
lvars item;
return((item.pi_other)(1));
enddefine;
define updaterof pwm_menu_value(value,item);
lvars value,item;
dlocal 0 %,false -> (item.pi_other)(1) %;
if value and not((item.pi_other)(1)) then
unless value.isnumber then 1 -> value; endunless;
value -> (item.pi_other)(1);
endif;
enddefine;
define global pwm_make_menu(string) -> item;
lvars width, event;
lvars hsize,temp,trans,lines,i,item;
lvars menu_widget,widget;
lvars shell,popup_shell,menupane,control;
fast_XtAppCreateShell('dummy','dummy_class',basewindow_class,
XptDefaultDisplay,
XptArgList([{input ^true}])) -> shell;
parse_menu_string(string) -> title -> labels;
XtCreatePopupShell(title,menu_class,
shell,
XptArgList([{input ^true}
{pushpin ^OL_NONE}
{XtNmenuAugment ^false}
{title ^title}
])) -> menu_widget;
conspwmitem("menu",pwm_menu_value,menu_widget,false,false) -> item;
XtRealizeWidget(menu_widget);
XptValue(menu_widget,XtN menuPane, TYPESPEC(:XptWidget)) -> menupane;
{% false,
XtCreateManagedWidget('ControlArea',control_class,menupane,
XptArgList([{layoutType ^OL_FIXEDCOLS}])) ->> control;
for i from 1 to length(labels) do
XtCreateManagedWidget(labels(i),fancy_exec_class,control,XptArgList([])) ->> widget;
XtAddCallback(widget,'select', menu_wrapper(%item%),i);
endfor;
%} -> item.pi_other;
"menu" -> pwmidtype(item);
enddefine;
endsection;
endsection;
endsection;
/* ---------------------------------------------------------------------------*/
section;
uses XHouseKeeping;
section $-library Xsync => pwm_display_menu ;
section $-library$-pwmlib Xsync => pwm_display_menu;
uses pwm_make_menu;
uses conspwmitem;
define global pwm_display_menu(menu) ->response;
unless ispwmitem(menu) then
pwm_make_menu(menu) -> menu;
endunless;
false -> pwm_menu_value(menu);
OlMenuPost(pi_widget(menu));
XSync(XptDefaultDisplay,0);
;;; Loop until event recieved
while(pwm_menu_value(menu) == false) do
syssleep(100);
;;; Wait
endwhile;
pwm_menu_value(menu)-> response;
enddefine;
endsection;
endsection;
endsection;
|