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.
100 # This AUTOLOAD is used to 'autoload' constants from the constant()
101 # XS function. If a constant is not found then control is passed
102 # to the AUTOLOAD in AutoLoader.
105 ($constname = $AUTOLOAD) =~ s/.*:://;
106 $val = constant($constname, @_ ? $_[0] : 0);
108 if ($! =~ /Invalid/ || $!{EINVAL}) {
109 $AutoLoader::AUTOLOAD = $AUTOLOAD;
110 goto &AutoLoader::AUTOLOAD;
113 ($pack,$file,$line) = caller;
114 die "Your vendor has not defined OS2::Process macro $constname, used at $file line $line.
118 eval "sub $AUTOLOAD { $val }";
122 # Preloaded methods go here.
124 sub Title () { (process_entry())[0] }
126 # *Title_set = \&sesmgr_title_set;
129 my ($title, @sw) = @_;
135 my (@sw) = process_entry();
136 swTitle_set_sw(shift, @sw);
139 sub winTitle_set_sw {
140 my ($title, @sw) = @_;
141 my $h = OS2::localMorphPM->new(0);
142 WindowText_set $sw[1], $title;
146 my (@sw) = process_entry();
147 winTitle_set_sw(shift, @sw);
151 my (@sw) = process_entry();
153 winTitle_set_sw($t, @sw);
154 swTitle_set_sw($t, @sw);
159 return 1 if sesmgr_title_set($t);
160 return 0 unless $^E == 372;
161 my (@sw) = process_entry();
162 winTitle_set_sw($t, @sw);
163 swTitle_set_sw($t, @sw);
166 sub process_entry { swentry_expand(process_swentry(@_)) }
168 our @hentry_fields = qw( title owner_hwnd icon_hwnd
169 owner_phandle owner_pid owner_sid
170 visible nonswitchable jumpable ptype sw_entry );
172 sub swentry_hexpand ($) {
174 @h{@hentry_fields} = swentry_expand(shift);
178 sub process_hentry { swentry_hexpand(process_swentry(@_)) }
180 my $swentry_size = swentry_size();
183 my $s = swentries_list();
184 my ($c, $s1) = unpack 'La*', $s;
185 die "Unconsistent size in swentries_list()" unless 4+$c*$swentry_size == length $s;
187 push @l, $e while $e = substr $s1, 0, $swentry_size, '';
191 sub process_entries () {
192 map [swentry_expand($_)], sw_entries;
195 sub process_hentries () {
196 map swentry_hexpand($_), sw_entries;
200 change_swentry(create_swentry(@_));
203 sub create_swentryh ($) {
205 create_swentry(@$h{@hentry_fields});
208 sub change_entryh ($) {
209 change_swentry(create_swentryh(shift));
212 # Massage entries into the same order as WindowPos_set:
214 my ($fl, $w, $h, $x, $y, $behind, $hwnd, @rest)
215 = unpack 'L l4 L4', WindowSWP(shift);
216 ($x, $y, $fl, $w, $h, $behind, @rest);
219 sub ChildWindows ($) {
221 my $h = BeginEnumWindows shift;
223 push @kids, $w while $w = GetNextWindow $h;
228 # Autoload methods go after __END__, and are processed by the autosplit program.
235 OS2::Process - exports constants for system() call, and process control on OS2.
240 $pid = system(P_PM | P_BACKGROUND, "epm.exe");
244 =head2 Optional argument to system()
246 the builtin function system() under OS/2 allows an optional first
247 argument which denotes the mode of the process. Note that this argument is
248 recognized only if it is strictly numerical.
250 You can use either one of the process modes:
252 P_WAIT (0) = wait until child terminates (default)
253 P_NOWAIT = do not wait until child terminates
254 P_SESSION = new session
258 and optionally add PM and session option bits:
260 P_DEFAULT (0) = default
261 P_MINIMIZE = minimized
262 P_MAXIMIZE = maximized
263 P_FULLSCREEN = fullscreen (session only)
264 P_WINDOWED = windowed (session only)
266 P_FOREGROUND = foreground (if running in foreground)
267 P_BACKGROUND = background
269 P_NOCLOSE = don't close window on exit (session only)
271 P_QUOTE = quote all arguments
272 P_TILDE = MKS argument passing convention
273 P_UNRELATED = do not kill child when father terminates
275 =head2 Access to process properties
277 On OS/2 processes have the usual I<parent/child> semantic;
278 additionally, there is a hierarchy of sessions with their own
279 I<parent/child> tree. A session is either a FS session, or a windowed
280 pseudo-session created by PM. A session is a "unit of user
281 interaction", a change to in/out settings in one of them does not
282 affect other sessions.
288 returns the type of the current process (one of
289 "FS", "DOS", "VIO", "PM", "DETACH" and "UNKNOWN"), or C<undef> on error.
291 =item C<file_type(file)>
293 returns the type of the executable file C<file>, or
294 dies on error. The bits 0-2 of the result contain one of the values
298 =item C<T_NOTSPEC> (0)
300 Application type is not specified in the executable header.
302 =item C<T_NOTWINDOWCOMPAT> (1)
304 Application type is not-window-compatible.
306 =item C<T_WINDOWCOMPAT> (2)
308 Application type is window-compatible.
310 =item C<T_WINDOWAPI> (3)
312 Application type is window-API.
316 The remaining bits should be masked with the following values to
317 determine the type of the executable:
323 Set to 1 if the executable file has been "bound" (by the BIND command)
324 as a Family API application. Bits 0, 1, and 2 still apply.
326 =item C<T_DLL> (0x10)
328 Set to 1 if the executable file is a dynamic link library (DLL)
329 module. Bits 0, 1, 2, 3, and 5 will be set to 0.
331 =item C<T_DOS> (0x20)
333 Set to 1 if the executable file is in PC/DOS format. Bits 0, 1, 2, 3,
334 and 4 will be set to 0.
336 =item C<T_PHYSDRV> (0x40)
338 Set to 1 if the executable file is a physical device driver.
340 =item C<T_VIRTDRV> (0x80)
342 Set to 1 if the executable file is a virtual device driver.
344 =item C<T_PROTDLL> (0x100)
346 Set to 1 if the executable file is a protected-memory dynamic link
349 =item C<T_32BIT> (0x4000)
351 Set to 1 for 32-bit executable files.
355 file_type() may croak with one of the strings C<"Invalid EXE
356 signature"> or C<"EXE marked invalid"> to indicate typical error
357 conditions. If given non-absolute path, will look on C<PATH>, will
358 add extention F<.exe> if no extension is present (add extension F<.>
361 =item C<@list = process_codepages()>
363 the first element is the currently active codepage, up to 2 additional
364 entries specify the system's "prepared codepages": the codepages the
365 user can switch to. The active codepage of a process is one of the
366 prepared codepages of the system (if present).
368 =item C<process_codepage_set($cp)>
370 sets the currently active codepage. [Affects printer output, in/out
371 codepages of sessions started by this process, and the default
372 codepage for drawing in PM; is inherited by kids. Does not affect the
373 out- and in-codepages of the session.]
377 returns the PID of the parent process.
379 =item C<ppidOf($pid = $$)>
381 returns the PID of the parent process of $pid. -1 on error.
383 =item C<sidOf($pid = $$)>
385 returns the session id of the process id $pid. -1 on error.
389 =head2 Control of VIO sessions
391 VIO applications are applications running in a text-mode session.
397 gets code page used for screen output (glyphs). -1 means that a user font
400 =item C<out_codepage_set($cp)>
402 sets code page used for screen output (glyphs). -1 switches to a preloaded
403 user font. -2 switches off the preloaded user font.
407 gets code page used for keyboard input. 0 means that a hardware codepage
410 =item C<in_codepage_set($cp)>
412 sets code page used for keyboard input.
414 =item C<($w, $h) = scrsize()>
416 width and height of the given console window in character cells.
418 =item C<scrsize_set([$w, ] $h)>
420 set height (and optionally width) of the given console window in
421 character cells. Use 0 size to keep the old size.
423 =item C<($s, $e, $w, $a) = cursor()>
425 gets start/end lines of the blinking cursor in the charcell, its width
426 (1 on text modes) and attribute (-1 for hidden, in text modes other
427 values mean visible, in graphic modes color).
429 =item C<cursor_set($s, $e, [$w [, $a]])>
431 sets start/end lines of the blinking cursor in the charcell. Negative
432 values mean percents of the character cell height.
436 gets a buffer with characters and attributes of the screen.
438 =item C<screen_set($buffer)>
440 restores the screen given the result of screen().
444 =head2 Control of the process list
446 With the exception of Title_set(), all these calls require that PM is
447 running, they would not work under alternative Session Managers.
451 =item process_entry()
453 returns a list of the following data:
459 Title of the process (in the C<Ctrl-Esc> list);
463 window handle of switch entry of the process (in the C<Ctrl-Esc> list);
467 window handle of the icon of the process;
471 process handle of the owner of the entry in C<Ctrl-Esc> list;
475 process id of the owner of the entry in C<Ctrl-Esc> list;
479 session id of the owner of the entry in C<Ctrl-Esc> list;
483 whether visible in C<Ctrl-Esc> list;
487 whether item cannot be switched to (note that it is not actually
488 grayed in the C<Ctrl-Esc> list));
492 whether participates in jump sequence;
496 program type. Possible values are:
505 Although there are several other program types for WIN-OS/2 programs,
506 these do not show up in this field. Instead, the PROG_VDM or
507 PROG_WINDOWEDVDM program types are used. For instance, for
508 PROG_31_STDSEAMLESSVDM, PROG_WINDOWEDVDM is used. This is because all
509 the WIN-OS/2 programs run in DOS sessions. For example, if a program
510 is a windowed WIN-OS/2 program, it runs in a PROG_WINDOWEDVDM
511 session. Likewise, if it's a full-screen WIN-OS/2 program, it runs in
520 Optional arguments: the pid and the window-handle of the application running
521 in the OS/2 session to query.
523 =item process_hentry()
525 similar to process_entry(), but returns a hash reference, the keys being
527 title owner_hwnd icon_hwnd owner_phandle owner_pid owner_sid
528 visible nonswitchable jumpable ptype sw_entry
530 (a copy of the list of keys is in @hentry_fields).
532 =item process_entries()
534 similar to process_entry(), but returns a list of array reference for all
535 the elements in the switch list (one controlling C<Ctrl-Esc> window).
537 =item process_hentries()
539 similar to process_hentry(), but returns a list of hash reference for all
540 the elements in the switch list (one controlling C<Ctrl-Esc> window).
544 changes a process entry, arguments are the same as process_entry() returns.
546 =item change_entryh()
548 Similar to change_entry(), but takes a hash reference as an argument.
552 returns a title of the current session. (There is no way to get this
553 info in non-standard Session Managers, this implementation is a
554 shortcut via process_entry().)
556 =item C<Title_set(newtitle)>
558 tries two different interfaces. The Session Manager one does not work
559 with some windows (if the title is set from the start).
560 This is a limitation of OS/2, in such a case $^E is set to 372 (type
564 for a funny - and wrong - explanation ;-). In such cases a
565 direct-manipulation of low-level entries is used. Keep in mind that
566 some versions of OS/2 leak memory with such a manipulation.
568 =item C<SwitchToProgram($sw_entry)>
570 switch to session given by a switch list handle.
572 Use of this function causes another window (and its related windows)
573 of a PM session to appear on the front of the screen, or a switch to
574 another session in the case of a non-PM program. In either case,
575 the keyboard (and mouse for the non-PM case) input is directed to
580 =head2 Control of the PM windows
582 Some of these API's require sending a message to the specified window.
583 In such a case the process needs to be a PM process, or to be morphed
584 to a PM process via OS2::MorphPM().
586 For a temporary morphing to PM use L<OS2::localMorphPM class>.
588 Keep in mind that PM windows are engaged in 2 "orthogonal" window
589 trees, as well as in the z-order list.
591 One tree is given by the I<parent/child> relationship. This
592 relationship affects drawing (child is drawn relative to its parent
593 (lower-left corner), and the drawing is clipped by the parent's
594 boundary; parent may request that I<it's> drawing is clipped to be
595 confined to the outsize of the childs and/or siblings' windows);
596 hiding; minimizing/restoring; and destroying windows.
598 Another tree (not necessarily connected?) is given by I<ownership>
599 relationship. Ownership relationship assumes cooperation of the
600 engaged windows via passing messages on "important events"; e.g.,
601 scrollbars send information messages when the "bar" is moved, menus
602 send messages when an item is selected; frames
603 move/hide/unhide/minimize/restore/change-z-order-of owned frames when
604 the owner is moved/etc., and destroy the owned frames (even when these
605 frames are not descendants) when the owner is destroyed; etc. [An
606 important restriction on ownership is that owner should be created by
607 the same thread as the owned thread, so they engage in the same
610 Windows may be in many different state: Focused, Activated (=Windows
611 in the I<parent/child> tree between the root and the window with
612 focus; usually indicate such "active state" by titlebar highlights),
613 Enabled/Disabled (this influences *an ability* to receive user input
614 (be focused?), and may change appearance, as for enabled/disabled
615 buttons), Visible/Hidden, Minimized/Maximized/Restored, Modal, etc.
619 =item C<WindowText($hwnd)>
621 gets "a text content" of a window.
623 =item C<WindowText_set($hwnd, $text)>
625 sets "a text content" of a window.
627 =item C<WindowPos($hwnd)>
629 gets window position info as 8 integers (of C<SWP>), in the order suitable
630 for WindowPos_set(): $x, $y, $fl, $w, $h, $behind, @rest.
632 =item C<WindowPos_set($hwnd, $x, $y, $flags = SWP_MOVE, $wid = 0, $h = 0, $behind = HWND_TOP)>
634 Set state of the window: position, size, zorder, show/hide, activation,
635 minimize/maximize/restore etc. Which of these operations to perform
636 is governed by $flags.
638 =item C<WindowProcess($hwnd)>
640 gets I<PID> and I<TID> of the process associated to the window.
642 =item ActiveWindow([$parentHwnd])
644 gets the active subwindow's handle for $parentHwnd or desktop.
645 Returns FALSE if none.
647 =item C<ClassName($hwnd)>
649 returns the class name of the window.
651 If this window is of any of the preregistered WC_* classes the class
652 name returned is in the form "#nnnnn", where "nnnnn" is a group
653 of up to five digits that corresponds to the value of the WC_* class name
658 returns the handle of the focus window. Optional argument for specifying the desktop
661 =item C<FocusWindow_set($hwnd)>
663 set the focus window by handle. Optional argument for specifying the desktop
664 to use. E.g, the first entry in program_entries() is the C<Ctrl-Esc> list.
667 WinShowWindow( wlhwnd, TRUE );
668 WinSetFocus( HWND_DESKTOP, wlhwnd );
669 WinSwitchToProgram(wlhswitch);
672 =item C<ShowWindow($hwnd [, $show])>
674 Set visible/hidden flag of the window. Default: $show is TRUE.
676 =item C<PostMsg($hwnd, $msg, $mp1, $mp2)>
678 post message to a window. The meaning of $mp1, $mp2 is specific for each
679 message id $msg, they default to 0. E.g., in C it is done similar to
681 /* Emulate `Restore' */
682 WinPostMsg(SwitchBlock.tswe[i].swctl.hwnd, WM_SYSCOMMAND,
683 MPFROMSHORT(SC_RESTORE), 0);
685 /* Emulate `Show-Contextmenu' (Double-Click-2) */
686 hwndParent = WinQueryFocus(HWND_DESKTOP);
687 hwndActive = WinQueryActiveWindow(hwndParent);
688 WinPostMsg(hwndActive, WM_CONTEXTMENU, MPFROM2SHORT(0,0), MPFROMLONG(0));
690 /* Emulate `Close' */
691 WinPostMsg(pSWB->aswentry[i].swctl.hwnd, WM_CLOSE, 0, 0);
693 /* Same but softer: */
694 WinPostMsg(hwndactive, WM_SAVEAPPLICATION, 0L, 0L);
695 WinPostMsg(hwndactive, WM_CLOSE, 0L, 0L));
696 WinPostMsg(hwndactive, WM_QUIT, 0L, 0L));
698 =item C<$eh = BeginEnumWindows($hwnd)>
700 starts enumerating immediate child windows of $hwnd in z-order. The
701 enumeration reflects the state at the moment of BeginEnumWindows() calls;
702 use IsWindow() to be sure.
704 =item C<$kid_hwnd = GetNextWindow($eh)>
706 gets the next kid in the list. Gets 0 on error or when the list ends.
708 =item C<EndEnumWindows($eh)>
710 End enumeration and release the list.
712 =item C<@list = ChildWindows($hwnd)>
714 returns the list of child windows at the moment of the call. Same remark
715 as for enumeration interface applies. Example of usage:
719 printf ' ' x $o . "%#x\n", $h;
720 l($o+2,$_) for ChildWindows $h;
724 =item C<IsWindow($hwnd)>
726 true if the window handle is still valid.
728 =item C<QueryWindow($hwnd, $type)>
730 gets the handle of a related window. $type should be one of C<QW_*> constants.
732 =item C<IsChild($hwnd, $parent)>
734 return TRUE if $hwnd is a descendant of $parent.
736 =item C<WindowFromId($hwnd, $id)>
738 return a window handle of a child of $hwnd with the given $id.
740 hwndSysMenu = WinWindowFromID(hwndDlg, FID_SYSMENU);
741 WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
742 MPFROM2SHORT(SC_CLOSE, TRUE),
743 MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
745 =item C<WindowFromPoint($x, $y [, $hwndParent [, $descedantsToo]])>
747 gets a handle of a child of $hwndParent at C<($x,$y)>. If $descedantsToo
748 (defaulting to 0) then children of children may be returned too. May return
749 $hwndParent (defaults to desktop) if no suitable children are found,
750 or 0 if the point is outside the parent.
752 $x and $y are relative to $hwndParent.
754 =item C<EnumDlgItem($dlgHwnd, $type [, $relativeHwnd])>
756 gets a dialog item window handle for an item of type $type of $dlgHwnd
757 relative to $relativeHwnd, which is descendant of $dlgHwnd.
758 $relativeHwnd may be specified if $type is EDI_FIRSTTABITEM or
761 The return is always an immediate child of hwndDlg, even if hwnd is
762 not an immediate child window. $type may be
766 =item EDI_FIRSTGROUPITEM
768 First item in the same group.
770 =item EDI_FIRSTTABITEM
772 First item in dialog with style WS_TABSTOP. hwnd is ignored.
774 =item EDI_LASTGROUPITEM
776 Last item in the same group.
778 =item EDI_LASTTABITEM
780 Last item in dialog with style WS_TABSTOP. hwnd is ignored.
782 =item EDI_NEXTGROUPITEM
784 Next item in the same group. Wraps around to beginning of group when
785 the end of the group is reached.
787 =item EDI_NEXTTABITEM
789 Next item with style WS_TABSTOP. Wraps around to beginning of dialog
790 item list when end is reached.
792 =item EDI_PREVGROUPITEM
794 Previous item in the same group. Wraps around to end of group when the
795 start of the group is reached. For information on the WS_GROUP style,
798 =item EDI_PREVTABITEM
800 Previous item with style WS_TABSTOP. Wraps around to end of dialog
801 item list when beginning is reached.
807 =head1 OS2::localMorphPM class
809 This class morphs the process to PM for the duration of the given context.
812 my $h = OS2::localMorphPM->new(0);
816 The argument has the same meaning as one to OS2::MorphPM(). Calls can
817 nest with internal ones being NOPs.
821 Constants (currently one needs to get them looking in a header file):
824 WM_* /* Separate module? */
833 Show/Hide, Enable/Disable (WinShowWindow(), WinIsWindowVisible(),
834 WinEnableWindow(), WinIsWindowEnabled()).
836 Maximize/minimize/restore via WindowPos_set(), check via checking
837 WS_MAXIMIZED/WS_MINIMIZED flags (how to get them?).
841 the majority of the APIs of this module set $^E on failure (no matter
842 whether they die() on failure or not). By the semantic of PM API
843 which returns something other than a boolean, it is impossible to
844 distinguish failure from a "normal" 0-return. In such cases C<$^E ==
845 0> indicates an absence of error.
849 whether a given API dies or returns FALSE/empty-list on error may be
850 confusing. This may change in the future.
854 Andreas Kaiser <ak@ananke.s.bawue.de>,
855 Ilya Zakharevich <ilya@math.ohio-state.edu>.
859 C<spawn*>() system calls, L<OS2::Proc> and L<OS2::WinObject> modules.