home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / pop / 42 < prev    next >
Encoding:
Internet Message Format  |  1992-11-17  |  13.7 KB

  1. Path: sparky!uunet!mcsun!uknet!reading!frodo!kr1
  2. From: kr1@csug.cs.reading.ac.uk (Kevin Richards [METOFF])
  3. Newsgroups: comp.lang.pop
  4. Subject: X and Pop
  5. Keywords: pwm OpenLook X
  6. Message-ID: <Bxv74C.K1q@csug.cs.reading.ac.uk>
  7. Date: 17 Nov 92 14:33:47 GMT
  8. Sender: news@csug.cs.reading.ac.uk
  9. Reply-To: kr1@csug.cs.reading.ac.uk
  10. Organization: Dept. of Comp. Sci., University of Reading
  11. Lines: 496
  12. Nntp-Posting-Host: frodo
  13.  
  14.  
  15. hello,
  16.  
  17. Calling all those people (yes both of you), who know anything about X and pop11.
  18. We have been trying to emulate pwm, under X, and  have built up a number of 
  19. procedures which do pwm things, only using the OpenLook widget set.
  20.  
  21. The eventhandling is carried out similarly to pop using pwm_eventhandler,
  22. two procedures which we are trying to get right are pwm_make_menu, 
  23. and pwm_display_menu (The code for these procedures is included at the end). The 
  24. question I want answering is why pwm_display_menu will work from a command line,
  25. but fail when used in the eventhandler 
  26.     i.e. -
  27.  
  28.     : pwm_make_gfxwin('tst',100,100) -> win;
  29.     : procedure(ev);
  30.       pwm_display_menu('Test\tHello\tWorld\t') =>
  31.       endprocedure -> pwm_eventhandler(win,"press");
  32.  
  33. /* Okay calling it on its own works */
  34.     : pwm_display_menu('Test\tHello\tWorld\t') =>
  35.     ** 1
  36.  
  37. But when you press a button in 'win' the menu is created but appears blank
  38. and no events are processed. Pop siezes up and you need a kill -QUIT to get
  39. rid of the menu.
  40.  
  41. 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
  42.  
  43.  
  44.     
  45.     Cheers Kev
  46.     
  47.  
  48.   ____________________________________________________________________
  49.   Kevin Richards                              K.Richards@reading.ac.uk        
  50.  
  51.                 University of Reading, Whiteknights, 
  52.                        Reading, Berkshire, Uk
  53.  
  54.                     Phone +44 734 875123 ext 7642
  55.  
  56.  
  57.  
  58.  
  59. /* CODE ----------------------------------------------------------------*/
  60. /*  --- Copyright Intelligent Systems Group at University of Reading --------
  61.     --- 1991.  All rights reserved. -----------------------------------------
  62.  > File:           pwm_eventhandler.p
  63.  > Purpose:        provide an event handler for X pwm windows
  64.  > Documentation:  HELP * dummy
  65.  > Related Files:  MAN  * rcsintro
  66.  > RCS Information
  67.  >     $Author: adw $
  68.  >     $Date: 92/11/14 18:14:44 $
  69.  >     $RCSfile: pwm_eventhandler.p,v $
  70.  >     $Revision: 1.2 $
  71.  >     $State: Exp $
  72.  >     $Locker:  $
  73.  
  74.          CONTENTS - (Use <ENTER> gd to access required procedure)
  75.  
  76.  define pwm_inputcatcher(ev);
  77.  define handle_button_event(widget,client,call_data);
  78.  define handle_resize_event(widget,client,call_data);
  79.  define handle_keyboard_event(widget,client,call_data);
  80.  define global pwm_eventhandler(widget,type)->proc;
  81.  define updaterof global pwm_eventhandler(proc,widget,type);
  82.  
  83.  */
  84.  
  85. uses pwm_windowtype;
  86. uses popxlib;
  87. uses xt_widget;
  88. uses xt_callback;
  89. uses xt_event;
  90. uses XolConstants;
  91. uses xlib;
  92. uses XWindowAttributes;
  93. uses XHouseKeeping;
  94. uses XWindowConstants;
  95. uses XKeyboard;
  96. uses XEvents;
  97. loadinclude xpt_xevent.ph;
  98.  
  99.  
  100.  
  101.  
  102. section;
  103.  
  104. section $-library XLookupString => pwm_eventhandler handle_resize_event handle_keyboard_event handle_button_event handle_move_event handle_status_event;
  105. section $-library$-pwmlib XLookupString => pwm_eventhandler handle_resize_event handle_keyboard_event handle_button_event handle_move_event handle_status_event;
  106.  
  107. global vars  pwm_last_button = 1;
  108. global vars  pwmreport = false;
  109.  
  110. ;;;defined in pwm_track_mouse
  111. vars report_motion   = false;
  112. vars tracking_motion = false;
  113. vars handle_tracking exit_tracking;
  114.  
  115. define global pwm_inputcatcher(ev);
  116. lvars ev message;
  117.     switchon subscrv(1,ev) ==
  118.         case "quitrequest" then
  119.  
  120.                 pwm_kill_window(pwminputsource);
  121.                 pwminputsource <> ' killed';
  122.         case "release"
  123.         orcase "press"
  124.         orcase "move"
  125.         orcase "mouseexit"
  126.         orcase "character" then
  127.             ('message ' >< ev) >< ' received from ' >< pwminputsource;
  128.             else
  129.             false;
  130.     endswitchon  -> message;
  131.  
  132.     if message and pwmreport then
  133.             if vedediting then
  134.                 vedputmessage(message);
  135.             else
  136.                 pr(';;; ' <> message <> '\n');
  137.             endif;
  138.     endif;
  139. enddefine;
  140.  
  141.  
  142. vars win_proc_table = newproperty([],32,false,"tmparg");
  143.  
  144. define handle_move_event(widget,client,call_data);
  145.     lvars widget,button,client,ev,proc_table,proc,call_data;
  146.  
  147.     if (pwm_last_button>0) and (exacc :XEvent call_data.type == MotionNotify)
  148.     then
  149.         {%
  150.             "move",
  151.             abs(pwm_last_button),
  152.             exacc :XMotionEvent call_data.x,
  153.             exacc :XMotionEvent call_data.y
  154.         %} -> ev;
  155.  
  156.         ;;;get the widgets evant handlers
  157.         win_proc_table(pwm_widget_windows(widget)) -> proc_table;
  158.  
  159.         if tracking_motion then
  160.             handle_tracking(ev);
  161.  
  162.             if report_motion then
  163.                 unless proc_table and (proc_table("move")->> proc) then
  164.                     pwm_inputcatcher -> proc;
  165.                 endunless;
  166.  
  167.                 ;;;set the widget as the input source
  168.                 pwm_widget_windows(widget) -> pwminputsource;
  169.                 chain(ev,proc);
  170.             endif;
  171.         endif;
  172.     endif;
  173. enddefine;
  174.  
  175. define handle_button_event(widget,client,call_data);
  176. lvars widget,button,client,ev,proc_table,proc,call_data,type,x,y;
  177.     ;;;convert button to a pop int
  178.     if exacc :XButtonEvent call_data.type =  5 then
  179.         ( exacc :XButtonReleasedEvent call_data.button ) * (-1)-> button;
  180.         exacc :XButtonReleasedEvent call_data.x -> x;
  181.         exacc :XButtonReleasedEvent call_data.y -> y;
  182.     else
  183.         exacc :XButtonPressedEvent call_data.button -> button;
  184.         exacc :XButtonPressedEvent call_data.x -> x;
  185.         exacc :XButtonPressedEvent call_data.y -> y;
  186.     endif;
  187.     button -> pwm_last_button;
  188.  
  189.     if button < 0 then
  190.         if x =< 0 or x >= XptValue(widget,XtN width, "short")
  191.         or y =< 0 or y >= XptValue(widget,XtN height, "short")
  192.         then
  193.             "mouseexit" -> type;
  194.             0 ->> x -> y;
  195.         else
  196.             "release" -> type;
  197.         endif;
  198.     else
  199.         "press" -> type;
  200.     endif;
  201.  
  202.     {% type, abs(button), x, y %} -> ev;
  203.  
  204.     if tracking_motion then
  205.         exit_tracking(ev);
  206.     endif;
  207.  
  208.     ;;;get the widgets evant handlers
  209.     win_proc_table(pwm_widget_windows(widget)) -> proc_table;
  210.  
  211.     unless proc_table and (proc_table(type)->> proc) then
  212.         pwm_inputcatcher -> proc;
  213.     endunless;
  214.  
  215.     ;;;set the widget as the input source
  216.     pwm_widget_windows(widget) -> pwminputsource;
  217.  
  218.     proc(ev);
  219. enddefine;
  220.  
  221. define handle_status_event(widget,client,call_data);
  222. lvars widget,button,client,ev,proc_table,proc,call_data;
  223.     ;;; Windows opening and closing and destroying
  224.     ;;; pr('Status');
  225.     switchon exacc :XEvent call_data.type ==
  226.     case FocusIn then
  227.         {% "focusin",
  228.             0,0,0
  229.         %} -> ev;
  230.             pwm_widget_windows(widget) -> pwminputsource;
  231.                 ;;;get the widgets evant handlers
  232.                 win_proc_table(pwm_widget_windows(widget)) -> proc_table;
  233.                 unless proc_table and (proc_table("focusin")->> proc) then
  234.                         pwm_inputcatcher -> proc;
  235.                 endunless;
  236.  
  237.             ;;;set the widget as the input source
  238.             pwm_widget_windows(widget) -> pwminputsource;
  239.             chain(ev,proc);
  240.     case FocusOut then
  241.         {% "focusout",
  242.             0,0,0
  243.         %} -> ev;
  244.                 ;;;get the widgets evant handlers
  245.             pwm_widget_windows(widget) -> pwminputsource;
  246.                 win_proc_table(pwm_widget_windows(widget)) -> proc_table;
  247.             unless proc_table and (proc_table("focusout")->> proc) then
  248.                 pwm_inputcatcher -> proc;
  249.             endunless;
  250.             chain(ev,proc);
  251.     case DestroyNotify then
  252.         {%
  253.           "quitrequest",
  254.           0,0,0
  255.         %} -> ev;
  256.         pr('Destroy\n');
  257.  
  258.             ;;;get the widgets evant handlers
  259.             win_proc_table(pwm_widget_windows(widget)) -> proc_table;
  260.             unless proc_table and (proc_table("quitrequest")->> proc) then
  261.                 pwm_inputcatcher -> proc;
  262.             endunless;
  263.             chain(ev,proc);
  264.     else
  265.         ;;; ignore
  266.     endswitchon;
  267.  
  268. enddefine;
  269.  
  270.  
  271. define handle_resize_event(widget,client,call_data);
  272. lvars widget,button,client,ev,proc_table,proc,call_data;
  273.  
  274.     {%
  275.         "resized",
  276.         abs(pwm_last_button),
  277.     exacc :XResizeRequestEvent call_data.width,
  278.         exacc :XResizeRequestEvent call_data.height
  279.     %} -> ev;
  280.  
  281.     ;;;get the widgets evant handlers
  282.     win_proc_table(pwm_widget_windows(widget)) -> proc_table;
  283.  
  284.     unless proc_table and (proc_table("resized")->> proc) then
  285.         pwm_inputcatcher -> proc;
  286.     endunless;
  287.  
  288.     ;;;set the widget as the input source
  289.     pwm_widget_windows(widget) -> pwminputsource;
  290.  
  291.     chain(ev,proc);
  292. enddefine;
  293.  
  294. define handle_keyboard_event(widget,client,call_data);
  295. lvars widget,client,ev,proc_table,proc,call_data,i,key;
  296. lvars temps = inits(1);
  297.  
  298.     ;;;convert button to a pop int
  299.     if (XLookupString(call_data,temps,1,NULLptr,NULLptr) == 1) then
  300.             temps(1) -> key;
  301.  
  302.  
  303.             {%
  304.                 "character",
  305.                 key, 0, 0
  306.                 %} -> ev;
  307.  
  308.             ;;;get the widgets evant handlers
  309.             win_proc_table(pwm_widget_windows(widget)) -> proc_table;
  310.  
  311.             unless proc_table and (proc_table("character")->> proc) then
  312.                 pwm_inputcatcher -> proc;
  313.             endunless;
  314.  
  315.             ;;;set the widget as the input source
  316.             pwm_widget_windows(widget) -> pwminputsource;
  317.  
  318.             if proc.isprocedure then
  319.                 proc(ev);
  320.             else
  321.                 valof(proc)(ev);
  322.             endif;
  323.     endif;
  324. enddefine;
  325.  
  326. define global pwm_eventhandler(pwm_id,type)->proc;
  327. lvars type,proc,proc_table;
  328.  
  329.     ;;;get the widgets evant handlers
  330.     win_proc_table(pwm_id) -> proc_table;
  331.  
  332.     unless proc_table and (proc_table(type)->> proc) then
  333.         pwm_inputcatcher -> proc;
  334.     endunless;
  335. enddefine;
  336.  
  337. define updaterof global pwm_eventhandler(proc,pwm_id,type);
  338. lvars type,proc,proc_table;
  339.     ;;;get the widgets evant handlers
  340.     win_proc_table(pwm_id) -> proc_table;
  341.  
  342.     unless proc_table then
  343.         newproperty([],10,false,"tmparg") -> proc_table;
  344.         proc_table -> win_proc_table(pwm_id);
  345.     endunless;
  346.  
  347.     proc -> proc_table(type);
  348. enddefine;
  349.  
  350. endsection;
  351. endsection;
  352.  
  353. endsection;
  354.  
  355. /*----------------------------------------------------------------------------*/
  356.  
  357.  
  358.  
  359. section;
  360.  
  361. section $-library => pwm_make_menu  pwm_menu_value;
  362. section $-library$-pwmlib => pwm_make_menu  pwm_menu_value;
  363.  
  364. uses xt_widget;
  365. uses xt_widgetclass;
  366. uses xt_widgetinfo;
  367. uses xt_trans;
  368. uses xt_action;
  369. uses xt_event;
  370. uses xt_popup;
  371. uses xt_callback;
  372. uses xlib;
  373. uses pwm_make_execitem;
  374. uses pwm_eventhandler;
  375. uses conspwmitem;
  376.  
  377. loadinclude xt_constants;
  378.  
  379.  
  380. define parse_menu_string(string) -> title -> labels;
  381. lvars l_text = [],pos,len,line,height,start,i;
  382.         true -> pos;
  383.         1 -> start;
  384.         length(string) -> len;
  385.         while (start <= len) do
  386.                 issubstring_lim('\t',start,len,false,string) -> pos;
  387.                 if not(pos) then
  388.                         substring(start,len-start+1,string) -> line;
  389.                         start+len+1-start -> start;
  390.                 else
  391.                         substring(start,pos-start,string) -> line;
  392.                         pos+1 -> start;
  393.                 endif;
  394.                 l_text <> [^line] -> l_text;
  395.         endwhile;
  396.     
  397.     ;;; Extract title
  398.     hd(l_text) -> title;
  399.     tl(l_text) -> labels;
  400.     
  401. enddefine;
  402.  
  403. define menu_wrapper(widget,clientdata,calldata,item);
  404. lvars widget,clientdata,calldata,item;
  405.     clientdata -> ((item.pi_other)(1));
  406. enddefine;
  407.  
  408. define pwm_menu_value(item);
  409. lvars item;
  410.     return((item.pi_other)(1));
  411. enddefine;
  412.  
  413.  
  414. define updaterof pwm_menu_value(value,item);
  415. lvars value,item;
  416. dlocal 0 %,false -> (item.pi_other)(1) %;
  417.     if value and not((item.pi_other)(1)) then
  418.         unless value.isnumber then 1 -> value; endunless;
  419.         value -> (item.pi_other)(1);
  420.     endif;
  421. enddefine;
  422.  
  423. define global pwm_make_menu(string) -> item;
  424. lvars width, event;
  425. lvars hsize,temp,trans,lines,i,item;
  426. lvars menu_widget,widget;
  427. lvars shell,popup_shell,menupane,control;
  428.  
  429.     fast_XtAppCreateShell('dummy','dummy_class',basewindow_class,
  430.             XptDefaultDisplay,
  431.                         XptArgList([{input ^true}])) -> shell;
  432.  
  433.     parse_menu_string(string) -> title -> labels;
  434.  
  435.     XtCreatePopupShell(title,menu_class,
  436.             shell,
  437.             XptArgList([{input ^true}
  438.                     {pushpin ^OL_NONE}
  439.                     {XtNmenuAugment ^false}
  440.                     {title ^title}
  441.                 ])) -> menu_widget;
  442.  
  443.  
  444.    conspwmitem("menu",pwm_menu_value,menu_widget,false,false) -> item;
  445.    XtRealizeWidget(menu_widget);
  446.    XptValue(menu_widget,XtN menuPane, TYPESPEC(:XptWidget))  -> menupane;
  447.  
  448.    {% false,
  449.     XtCreateManagedWidget('ControlArea',control_class,menupane,
  450.         XptArgList([{layoutType ^OL_FIXEDCOLS}])) ->> control;
  451.     for i from 1 to length(labels) do
  452.         XtCreateManagedWidget(labels(i),fancy_exec_class,control,XptArgList([])) ->> widget;
  453.         XtAddCallback(widget,'select', menu_wrapper(%item%),i);
  454.     endfor;
  455.    %} -> item.pi_other;
  456.  
  457.   "menu" -> pwmidtype(item);
  458.  
  459. enddefine;
  460.  
  461. endsection;
  462. endsection;
  463.  
  464. endsection;
  465.  
  466.  
  467.  
  468.  
  469. /* ---------------------------------------------------------------------------*/
  470.  
  471.  
  472.  
  473. section;
  474.  
  475. uses XHouseKeeping;
  476.  
  477. section $-library Xsync => pwm_display_menu  ;
  478. section $-library$-pwmlib Xsync  => pwm_display_menu;
  479.  
  480. uses pwm_make_menu;
  481. uses conspwmitem;
  482.  
  483.  
  484.  
  485. define global pwm_display_menu(menu) ->response;
  486.  
  487.    unless ispwmitem(menu) then
  488.     pwm_make_menu(menu) -> menu;
  489.    endunless;
  490.  
  491.    false -> pwm_menu_value(menu);
  492.    OlMenuPost(pi_widget(menu));
  493.  
  494.    XSync(XptDefaultDisplay,0);
  495.  
  496.    ;;; Loop until event recieved
  497.    while(pwm_menu_value(menu) == false) do
  498.     syssleep(100);
  499.         ;;; Wait
  500.    endwhile;
  501.  
  502.    pwm_menu_value(menu)-> response;
  503.  
  504. enddefine;
  505.  
  506. endsection;
  507. endsection;
  508.  
  509. endsection;
  510.