1 package OS2::localMorphPM;
3 sub new { my ($c,$f) = @_; OS2::MorphPM($f); bless [shift], $c }
4 sub DESTROY { OS2::UnMorphPM(shift->[0]) }
13 @ISA = qw(Exporter DynaLoader);
15 bootstrap OS2::Process;
18 # Items to export into callers namespace by default. Note: do not export
19 # names by default without a very good reason. Use EXPORT_OK instead.
20 # Do not simply export all your public functions/methods/constants.
103 # This AUTOLOAD is used to 'autoload' constants from the constant()
104 # XS function. If a constant is not found then control is passed
105 # to the AUTOLOAD in AutoLoader.
108 ($constname = $AUTOLOAD) =~ s/.*:://;
109 $val = constant($constname, @_ ? $_[0] : 0);
111 if ($! =~ /Invalid/ || $!{EINVAL}) {
112 $AutoLoader::AUTOLOAD = $AUTOLOAD;
113 goto &AutoLoader::AUTOLOAD;
116 ($pack,$file,$line) = caller;
117 die "Your vendor has not defined OS2::Process macro $constname, used at $file line $line.
121 eval "sub $AUTOLOAD { $val }";
125 # Preloaded methods go here.
127 sub Title () { (process_entry())[0] }
129 # *Title_set = \&sesmgr_title_set;
132 my ($title, @sw) = @_;
138 my (@sw) = process_entry();
139 swTitle_set_sw(shift, @sw);
142 sub winTitle_set_sw {
143 my ($title, @sw) = @_;
144 my $h = OS2::localMorphPM->new(0);
145 WindowText_set $sw[1], $title;
149 my (@sw) = process_entry();
150 winTitle_set_sw(shift, @sw);
154 my (@sw) = process_entry();
156 winTitle_set_sw($t, @sw);
157 swTitle_set_sw($t, @sw);
162 return 1 if sesmgr_title_set($t);
163 return 0 unless $^E == 372;
164 my (@sw) = process_entry();
165 winTitle_set_sw($t, @sw);
166 swTitle_set_sw($t, @sw);
169 sub process_entry { swentry_expand(process_swentry(@_)) }
171 our @hentry_fields = qw( title owner_hwnd icon_hwnd
172 owner_phandle owner_pid owner_sid
173 visible nonswitchable jumpable ptype sw_entry );
175 sub swentry_hexpand ($) {
177 @h{@hentry_fields} = swentry_expand(shift);
181 sub process_hentry { swentry_hexpand(process_swentry(@_)) }
183 my $swentry_size = swentry_size();
186 my $s = swentries_list();
187 my ($c, $s1) = unpack 'La*', $s;
188 die "Unconsistent size in swentries_list()" unless 4+$c*$swentry_size == length $s;
190 push @l, $e while $e = substr $s1, 0, $swentry_size, '';
194 sub process_entries () {
195 map [swentry_expand($_)], sw_entries;
198 sub process_hentries () {
199 map swentry_hexpand($_), sw_entries;
203 change_swentry(create_swentry(@_));
206 sub create_swentryh ($) {
208 create_swentry(@$h{@hentry_fields});
211 sub change_entryh ($) {
212 change_swentry(create_swentryh(shift));
215 # Massage entries into the same order as WindowPos_set:
217 my ($fl, $w, $h, $x, $y, $behind, $hwnd, @rest)
218 = unpack 'L l4 L4', WindowSWP(shift);
219 ($x, $y, $fl, $w, $h, $behind, @rest);
222 sub ChildWindows ($) {
224 my $h = BeginEnumWindows shift;
226 push @kids, $w while $w = GetNextWindow $h;
231 # backward compatibility
232 *set_title = \&Title_set;
233 *get_title = \&Title;
235 # Autoload methods go after __END__, and are processed by the autosplit program.
242 OS2::Process - exports constants for system() call, and process control on OS2.
247 $pid = system(P_PM | P_BACKGROUND, "epm.exe");
251 =head2 Optional argument to system()
253 the builtin function system() under OS/2 allows an optional first
254 argument which denotes the mode of the process. Note that this argument is
255 recognized only if it is strictly numerical.
257 You can use either one of the process modes:
259 P_WAIT (0) = wait until child terminates (default)
260 P_NOWAIT = do not wait until child terminates
261 P_SESSION = new session
265 and optionally add PM and session option bits:
267 P_DEFAULT (0) = default
268 P_MINIMIZE = minimized
269 P_MAXIMIZE = maximized
270 P_FULLSCREEN = fullscreen (session only)
271 P_WINDOWED = windowed (session only)
273 P_FOREGROUND = foreground (if running in foreground)
274 P_BACKGROUND = background
276 P_NOCLOSE = don't close window on exit (session only)
278 P_QUOTE = quote all arguments
279 P_TILDE = MKS argument passing convention
280 P_UNRELATED = do not kill child when father terminates
282 =head2 Access to process properties
284 On OS/2 processes have the usual I<parent/child> semantic;
285 additionally, there is a hierarchy of sessions with their own
286 I<parent/child> tree. A session is either a FS session, or a windowed
287 pseudo-session created by PM. A session is a "unit of user
288 interaction", a change to in/out settings in one of them does not
289 affect other sessions.
295 returns the type of the current process (one of
296 "FS", "DOS", "VIO", "PM", "DETACH" and "UNKNOWN"), or C<undef> on error.
298 =item C<file_type(file)>
300 returns the type of the executable file C<file>, or
301 dies on error. The bits 0-2 of the result contain one of the values
305 =item C<T_NOTSPEC> (0)
307 Application type is not specified in the executable header.
309 =item C<T_NOTWINDOWCOMPAT> (1)
311 Application type is not-window-compatible.
313 =item C<T_WINDOWCOMPAT> (2)
315 Application type is window-compatible.
317 =item C<T_WINDOWAPI> (3)
319 Application type is window-API.
323 The remaining bits should be masked with the following values to
324 determine the type of the executable:
330 Set to 1 if the executable file has been "bound" (by the BIND command)
331 as a Family API application. Bits 0, 1, and 2 still apply.
333 =item C<T_DLL> (0x10)
335 Set to 1 if the executable file is a dynamic link library (DLL)
336 module. Bits 0, 1, 2, 3, and 5 will be set to 0.
338 =item C<T_DOS> (0x20)
340 Set to 1 if the executable file is in PC/DOS format. Bits 0, 1, 2, 3,
341 and 4 will be set to 0.
343 =item C<T_PHYSDRV> (0x40)
345 Set to 1 if the executable file is a physical device driver.
347 =item C<T_VIRTDRV> (0x80)
349 Set to 1 if the executable file is a virtual device driver.
351 =item C<T_PROTDLL> (0x100)
353 Set to 1 if the executable file is a protected-memory dynamic link
356 =item C<T_32BIT> (0x4000)
358 Set to 1 for 32-bit executable files.
362 file_type() may croak with one of the strings C<"Invalid EXE
363 signature"> or C<"EXE marked invalid"> to indicate typical error
364 conditions. If given non-absolute path, will look on C<PATH>, will
365 add extention F<.exe> if no extension is present (add extension F<.>
368 =item C<@list = process_codepages()>
370 the first element is the currently active codepage, up to 2 additional
371 entries specify the system's "prepared codepages": the codepages the
372 user can switch to. The active codepage of a process is one of the
373 prepared codepages of the system (if present).
375 =item C<process_codepage_set($cp)>
377 sets the currently active codepage. [Affects printer output, in/out
378 codepages of sessions started by this process, and the default
379 codepage for drawing in PM; is inherited by kids. Does not affect the
380 out- and in-codepages of the session.]
384 returns the PID of the parent process.
386 =item C<ppidOf($pid = $$)>
388 returns the PID of the parent process of $pid. -1 on error.
390 =item C<sidOf($pid = $$)>
392 returns the session id of the process id $pid. -1 on error.
396 =head2 Control of VIO sessions
398 VIO applications are applications running in a text-mode session.
404 gets code page used for screen output (glyphs). -1 means that a user font
407 =item C<out_codepage_set($cp)>
409 sets code page used for screen output (glyphs). -1 switches to a preloaded
410 user font. -2 switches off the preloaded user font.
414 gets code page used for keyboard input. 0 means that a hardware codepage
417 =item C<in_codepage_set($cp)>
419 sets code page used for keyboard input.
421 =item C<($w, $h) = scrsize()>
423 width and height of the given console window in character cells.
425 =item C<scrsize_set([$w, ] $h)>
427 set height (and optionally width) of the given console window in
428 character cells. Use 0 size to keep the old size.
430 =item C<($s, $e, $w, $a) = cursor()>
432 gets start/end lines of the blinking cursor in the charcell, its width
433 (1 on text modes) and attribute (-1 for hidden, in text modes other
434 values mean visible, in graphic modes color).
436 =item C<cursor_set($s, $e, [$w [, $a]])>
438 sets start/end lines of the blinking cursor in the charcell. Negative
439 values mean percents of the character cell height.
443 gets a buffer with characters and attributes of the screen.
445 =item C<screen_set($buffer)>
447 restores the screen given the result of screen().
451 =head2 Control of the process list
453 With the exception of Title_set(), all these calls require that PM is
454 running, they would not work under alternative Session Managers.
458 =item process_entry()
460 returns a list of the following data:
466 Title of the process (in the C<Ctrl-Esc> list);
470 window handle of switch entry of the process (in the C<Ctrl-Esc> list);
474 window handle of the icon of the process;
478 process handle of the owner of the entry in C<Ctrl-Esc> list;
482 process id of the owner of the entry in C<Ctrl-Esc> list;
486 session id of the owner of the entry in C<Ctrl-Esc> list;
490 whether visible in C<Ctrl-Esc> list;
494 whether item cannot be switched to (note that it is not actually
495 grayed in the C<Ctrl-Esc> list));
499 whether participates in jump sequence;
503 program type. Possible values are:
512 Although there are several other program types for WIN-OS/2 programs,
513 these do not show up in this field. Instead, the PROG_VDM or
514 PROG_WINDOWEDVDM program types are used. For instance, for
515 PROG_31_STDSEAMLESSVDM, PROG_WINDOWEDVDM is used. This is because all
516 the WIN-OS/2 programs run in DOS sessions. For example, if a program
517 is a windowed WIN-OS/2 program, it runs in a PROG_WINDOWEDVDM
518 session. Likewise, if it's a full-screen WIN-OS/2 program, it runs in
527 Optional arguments: the pid and the window-handle of the application running
528 in the OS/2 session to query.
530 =item process_hentry()
532 similar to process_entry(), but returns a hash reference, the keys being
534 title owner_hwnd icon_hwnd owner_phandle owner_pid owner_sid
535 visible nonswitchable jumpable ptype sw_entry
537 (a copy of the list of keys is in @hentry_fields).
539 =item process_entries()
541 similar to process_entry(), but returns a list of array reference for all
542 the elements in the switch list (one controlling C<Ctrl-Esc> window).
544 =item process_hentries()
546 similar to process_hentry(), but returns a list of hash reference for all
547 the elements in the switch list (one controlling C<Ctrl-Esc> window).
551 changes a process entry, arguments are the same as process_entry() returns.
553 =item change_entryh()
555 Similar to change_entry(), but takes a hash reference as an argument.
559 returns a title of the current session. (There is no way to get this
560 info in non-standard Session Managers, this implementation is a
561 shortcut via process_entry().)
563 =item C<Title_set(newtitle)>
565 tries two different interfaces. The Session Manager one does not work
566 with some windows (if the title is set from the start).
567 This is a limitation of OS/2, in such a case $^E is set to 372 (type
571 for a funny - and wrong - explanation ;-). In such cases a
572 direct-manipulation of low-level entries is used. Keep in mind that
573 some versions of OS/2 leak memory with such a manipulation.
575 =item C<SwitchToProgram($sw_entry)>
577 switch to session given by a switch list handle.
579 Use of this function causes another window (and its related windows)
580 of a PM session to appear on the front of the screen, or a switch to
581 another session in the case of a non-PM program. In either case,
582 the keyboard (and mouse for the non-PM case) input is directed to
587 =head2 Control of the PM windows
589 Some of these API's require sending a message to the specified window.
590 In such a case the process needs to be a PM process, or to be morphed
591 to a PM process via OS2::MorphPM().
593 For a temporary morphing to PM use L<OS2::localMorphPM class>.
595 Keep in mind that PM windows are engaged in 2 "orthogonal" window
596 trees, as well as in the z-order list.
598 One tree is given by the I<parent/child> relationship. This
599 relationship affects drawing (child is drawn relative to its parent
600 (lower-left corner), and the drawing is clipped by the parent's
601 boundary; parent may request that I<it's> drawing is clipped to be
602 confined to the outsize of the childs and/or siblings' windows);
603 hiding; minimizing/restoring; and destroying windows.
605 Another tree (not necessarily connected?) is given by I<ownership>
606 relationship. Ownership relationship assumes cooperation of the
607 engaged windows via passing messages on "important events"; e.g.,
608 scrollbars send information messages when the "bar" is moved, menus
609 send messages when an item is selected; frames
610 move/hide/unhide/minimize/restore/change-z-order-of owned frames when
611 the owner is moved/etc., and destroy the owned frames (even when these
612 frames are not descendants) when the owner is destroyed; etc. [An
613 important restriction on ownership is that owner should be created by
614 the same thread as the owned thread, so they engage in the same
617 Windows may be in many different state: Focused, Activated (=Windows
618 in the I<parent/child> tree between the root and the window with
619 focus; usually indicate such "active state" by titlebar highlights),
620 Enabled/Disabled (this influences *an ability* to receive user input
621 (be focused?), and may change appearance, as for enabled/disabled
622 buttons), Visible/Hidden, Minimized/Maximized/Restored, Modal, etc.
626 =item C<WindowText($hwnd)>
628 gets "a text content" of a window.
630 =item C<WindowText_set($hwnd, $text)>
632 sets "a text content" of a window.
634 =item C<WindowPos($hwnd)>
636 gets window position info as 8 integers (of C<SWP>), in the order suitable
637 for WindowPos_set(): $x, $y, $fl, $w, $h, $behind, @rest.
639 =item C<WindowPos_set($hwnd, $x, $y, $flags = SWP_MOVE, $wid = 0, $h = 0, $behind = HWND_TOP)>
641 Set state of the window: position, size, zorder, show/hide, activation,
642 minimize/maximize/restore etc. Which of these operations to perform
643 is governed by $flags.
645 =item C<WindowProcess($hwnd)>
647 gets I<PID> and I<TID> of the process associated to the window.
649 =item ActiveWindow([$parentHwnd])
651 gets the active subwindow's handle for $parentHwnd or desktop.
652 Returns FALSE if none.
654 =item C<ClassName($hwnd)>
656 returns the class name of the window.
658 If this window is of any of the preregistered WC_* classes the class
659 name returned is in the form "#nnnnn", where "nnnnn" is a group
660 of up to five digits that corresponds to the value of the WC_* class name
665 returns the handle of the focus window. Optional argument for specifying the desktop
668 =item C<FocusWindow_set($hwnd)>
670 set the focus window by handle. Optional argument for specifying the desktop
671 to use. E.g, the first entry in program_entries() is the C<Ctrl-Esc> list.
674 WinShowWindow( wlhwnd, TRUE );
675 WinSetFocus( HWND_DESKTOP, wlhwnd );
676 WinSwitchToProgram(wlhswitch);
679 =item C<ShowWindow($hwnd [, $show])>
681 Set visible/hidden flag of the window. Default: $show is TRUE.
683 =item C<PostMsg($hwnd, $msg, $mp1, $mp2)>
685 post message to a window. The meaning of $mp1, $mp2 is specific for each
686 message id $msg, they default to 0. E.g., in C it is done similar to
688 /* Emulate `Restore' */
689 WinPostMsg(SwitchBlock.tswe[i].swctl.hwnd, WM_SYSCOMMAND,
690 MPFROMSHORT(SC_RESTORE), 0);
692 /* Emulate `Show-Contextmenu' (Double-Click-2) */
693 hwndParent = WinQueryFocus(HWND_DESKTOP);
694 hwndActive = WinQueryActiveWindow(hwndParent);
695 WinPostMsg(hwndActive, WM_CONTEXTMENU, MPFROM2SHORT(0,0), MPFROMLONG(0));
697 /* Emulate `Close' */
698 WinPostMsg(pSWB->aswentry[i].swctl.hwnd, WM_CLOSE, 0, 0);
700 /* Same but softer: */
701 WinPostMsg(hwndactive, WM_SAVEAPPLICATION, 0L, 0L);
702 WinPostMsg(hwndactive, WM_CLOSE, 0L, 0L));
703 WinPostMsg(hwndactive, WM_QUIT, 0L, 0L));
705 =item C<$eh = BeginEnumWindows($hwnd)>
707 starts enumerating immediate child windows of $hwnd in z-order. The
708 enumeration reflects the state at the moment of BeginEnumWindows() calls;
709 use IsWindow() to be sure.
711 =item C<$kid_hwnd = GetNextWindow($eh)>
713 gets the next kid in the list. Gets 0 on error or when the list ends.
715 =item C<EndEnumWindows($eh)>
717 End enumeration and release the list.
719 =item C<@list = ChildWindows($hwnd)>
721 returns the list of child windows at the moment of the call. Same remark
722 as for enumeration interface applies. Example of usage:
726 printf ' ' x $o . "%#x\n", $h;
727 l($o+2,$_) for ChildWindows $h;
731 =item C<IsWindow($hwnd)>
733 true if the window handle is still valid.
735 =item C<QueryWindow($hwnd, $type)>
737 gets the handle of a related window. $type should be one of C<QW_*> constants.
739 =item C<IsChild($hwnd, $parent)>
741 return TRUE if $hwnd is a descendant of $parent.
743 =item C<WindowFromId($hwnd, $id)>
745 return a window handle of a child of $hwnd with the given $id.
747 hwndSysMenu = WinWindowFromID(hwndDlg, FID_SYSMENU);
748 WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
749 MPFROM2SHORT(SC_CLOSE, TRUE),
750 MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
752 =item C<WindowFromPoint($x, $y [, $hwndParent [, $descedantsToo]])>
754 gets a handle of a child of $hwndParent at C<($x,$y)>. If $descedantsToo
755 (defaulting to 0) then children of children may be returned too. May return
756 $hwndParent (defaults to desktop) if no suitable children are found,
757 or 0 if the point is outside the parent.
759 $x and $y are relative to $hwndParent.
761 =item C<EnumDlgItem($dlgHwnd, $type [, $relativeHwnd])>
763 gets a dialog item window handle for an item of type $type of $dlgHwnd
764 relative to $relativeHwnd, which is descendant of $dlgHwnd.
765 $relativeHwnd may be specified if $type is EDI_FIRSTTABITEM or
768 The return is always an immediate child of hwndDlg, even if hwnd is
769 not an immediate child window. $type may be
773 =item EDI_FIRSTGROUPITEM
775 First item in the same group.
777 =item EDI_FIRSTTABITEM
779 First item in dialog with style WS_TABSTOP. hwnd is ignored.
781 =item EDI_LASTGROUPITEM
783 Last item in the same group.
785 =item EDI_LASTTABITEM
787 Last item in dialog with style WS_TABSTOP. hwnd is ignored.
789 =item EDI_NEXTGROUPITEM
791 Next item in the same group. Wraps around to beginning of group when
792 the end of the group is reached.
794 =item EDI_NEXTTABITEM
796 Next item with style WS_TABSTOP. Wraps around to beginning of dialog
797 item list when end is reached.
799 =item EDI_PREVGROUPITEM
801 Previous item in the same group. Wraps around to end of group when the
802 start of the group is reached. For information on the WS_GROUP style,
805 =item EDI_PREVTABITEM
807 Previous item with style WS_TABSTOP. Wraps around to end of dialog
808 item list when beginning is reached.
814 =head1 OS2::localMorphPM class
816 This class morphs the process to PM for the duration of the given context.
819 my $h = OS2::localMorphPM->new(0);
823 The argument has the same meaning as one to OS2::MorphPM(). Calls can
824 nest with internal ones being NOPs.
828 Constants (currently one needs to get them looking in a header file):
831 WM_* /* Separate module? */
840 Show/Hide, Enable/Disable (WinShowWindow(), WinIsWindowVisible(),
841 WinEnableWindow(), WinIsWindowEnabled()).
843 Maximize/minimize/restore via WindowPos_set(), check via checking
844 WS_MAXIMIZED/WS_MINIMIZED flags (how to get them?).
848 the majority of the APIs of this module set $^E on failure (no matter
849 whether they die() on failure or not). By the semantic of PM API
850 which returns something other than a boolean, it is impossible to
851 distinguish failure from a "normal" 0-return. In such cases C<$^E ==
852 0> indicates an absence of error.
856 whether a given API dies or returns FALSE/empty-list on error may be
857 confusing. This may change in the future.
861 Andreas Kaiser <ak@ananke.s.bawue.de>,
862 Ilya Zakharevich <ilya@math.ohio-state.edu>.
866 C<spawn*>() system calls, L<OS2::Proc> and L<OS2::WinObject> modules.