xref: /openbsd-src/gnu/usr.bin/perl/os2/OS2/OS2-Process/Process.pm (revision 9f11ffb7133c203312a01e4b986886bc88c7d74b)
1b39c5158Smillertpackage OS2::localMorphPM;
2b39c5158Smillert# use strict;
3b39c5158Smillert
4b39c5158Smillertsub new {
5b39c5158Smillert  my ($c,$f) = @_;
6b39c5158Smillert  OS2::MorphPM($f);
7b39c5158Smillert  # print STDERR ">>>>>\n";
8b39c5158Smillert  bless [$f], $c
9b39c5158Smillert}
10b39c5158Smillertsub DESTROY {
11b39c5158Smillert  # print STDERR "<<<<<\n";
12b39c5158Smillert  OS2::UnMorphPM(shift->[0])
13b39c5158Smillert}
14b39c5158Smillert
15b39c5158Smillertpackage OS2::Process;
16b39c5158Smillert
17b39c5158SmillertBEGIN {
18b39c5158Smillert  require Exporter;
19b39c5158Smillert  require XSLoader;
20b39c5158Smillert  #require AutoLoader;
21b39c5158Smillert
22b39c5158Smillert  our @ISA = qw(Exporter);
23*9f11ffb7Safresh1  our $VERSION = "1.12";
24b39c5158Smillert  XSLoader::load('OS2::Process', $VERSION);
25b39c5158Smillert}
26b39c5158Smillert
27b39c5158Smillert# Items to export into callers namespace by default. Note: do not export
28b39c5158Smillert# names by default without a very good reason. Use EXPORT_OK instead.
29b39c5158Smillert# Do not simply export all your public functions/methods/constants.
30b39c5158Smillertour @EXPORT = qw(
31b39c5158Smillert	P_BACKGROUND
32b39c5158Smillert	P_DEBUG
33b39c5158Smillert	P_DEFAULT
34b39c5158Smillert	P_DETACH
35b39c5158Smillert	P_FOREGROUND
36b39c5158Smillert	P_FULLSCREEN
37b39c5158Smillert	P_MAXIMIZE
38b39c5158Smillert	P_MINIMIZE
39b39c5158Smillert	P_NOCLOSE
40b39c5158Smillert	P_NOSESSION
41b39c5158Smillert	P_NOWAIT
42b39c5158Smillert	P_OVERLAY
43b39c5158Smillert	P_PM
44b39c5158Smillert	P_QUOTE
45b39c5158Smillert	P_SESSION
46b39c5158Smillert	P_TILDE
47b39c5158Smillert	P_UNRELATED
48b39c5158Smillert	P_WAIT
49b39c5158Smillert	P_WINDOWED
50b39c5158Smillert	my_type
51b39c5158Smillert	file_type
52b39c5158Smillert	T_NOTSPEC
53b39c5158Smillert	T_NOTWINDOWCOMPAT
54b39c5158Smillert	T_WINDOWCOMPAT
55b39c5158Smillert	T_WINDOWAPI
56b39c5158Smillert	T_BOUND
57b39c5158Smillert	T_DLL
58b39c5158Smillert	T_DOS
59b39c5158Smillert	T_PHYSDRV
60b39c5158Smillert	T_VIRTDRV
61b39c5158Smillert	T_PROTDLL
62b39c5158Smillert	T_32BIT
63b39c5158Smillert
64b39c5158Smillert	os2constant
65b39c5158Smillert
66b39c5158Smillert	ppid
67b39c5158Smillert	ppidOf
68b39c5158Smillert	sidOf
69b39c5158Smillert	scrsize
70b39c5158Smillert	scrsize_set
71b39c5158Smillert	kbdChar
72b39c5158Smillert	kbdhChar
73b39c5158Smillert	kbdStatus
74b39c5158Smillert	_kbdStatus_set
75b39c5158Smillert	kbdhStatus
76b39c5158Smillert	kbdhStatus_set
77b39c5158Smillert	vioConfig
78b39c5158Smillert	viohConfig
79b39c5158Smillert	vioMode
80b39c5158Smillert	viohMode
81b39c5158Smillert	viohMode_set
82b39c5158Smillert	_vioMode_set
83b39c5158Smillert	_vioState
84b39c5158Smillert	_vioState_set
85b39c5158Smillert	vioFont
86b39c5158Smillert	vioFont_set
87b39c5158Smillert	process_entry
88b39c5158Smillert	process_entries
89b39c5158Smillert	process_hentry
90b39c5158Smillert	process_hentries
91b39c5158Smillert	change_entry
92b39c5158Smillert	change_entryh
93b39c5158Smillert	process_hwnd
94b39c5158Smillert	Title_set
95b39c5158Smillert	Title
96b39c5158Smillert	winTitle_set
97b39c5158Smillert	winTitle
98b39c5158Smillert	swTitle_set
99b39c5158Smillert	bothTitle_set
100b39c5158Smillert	WindowText
101b39c5158Smillert	WindowText_set
102b39c5158Smillert	WindowPos
103b39c5158Smillert	WindowPos_set
104b39c5158Smillert	hWindowPos
105b39c5158Smillert	hWindowPos_set
106b39c5158Smillert	WindowProcess
107b39c5158Smillert	SwitchToProgram
108b39c5158Smillert	DesktopWindow
109b39c5158Smillert	ActiveWindow
110b39c5158Smillert	ActiveWindow_set
111b39c5158Smillert	ClassName
112b39c5158Smillert	FocusWindow
113b39c5158Smillert	FocusWindow_set
114b39c5158Smillert	ShowWindow
115b39c5158Smillert	PostMsg
116b39c5158Smillert	BeginEnumWindows
117b39c5158Smillert	EndEnumWindows
118b39c5158Smillert	GetNextWindow
119b39c5158Smillert	IsWindow
120b39c5158Smillert	ChildWindows
121b39c5158Smillert	out_codepage
122b39c5158Smillert	out_codepage_set
123b39c5158Smillert	process_codepage_set
124b39c5158Smillert	in_codepage
125b39c5158Smillert	in_codepage_set
126b39c5158Smillert	cursor
127b39c5158Smillert	cursor_set
128b39c5158Smillert	screen
129b39c5158Smillert	screen_set
130b39c5158Smillert	process_codepages
131b39c5158Smillert	QueryWindow
132b39c5158Smillert	WindowFromId
133b39c5158Smillert	WindowFromPoint
134b39c5158Smillert	EnumDlgItem
135b39c5158Smillert        EnableWindow
136b39c5158Smillert        EnableWindowUpdate
137b39c5158Smillert        IsWindowEnabled
138b39c5158Smillert        IsWindowVisible
139b39c5158Smillert        IsWindowShowing
140b39c5158Smillert        WindowPtr
141b39c5158Smillert        WindowULong
142b39c5158Smillert        WindowUShort
143b39c5158Smillert	WindowStyle
144b39c5158Smillert        SetWindowBits
145b39c5158Smillert        SetWindowPtr
146b39c5158Smillert        SetWindowULong
147b39c5158Smillert        SetWindowUShort
148b39c5158Smillert        WindowBits_set
149b39c5158Smillert        WindowPtr_set
150b39c5158Smillert        WindowULong_set
151b39c5158Smillert        WindowUShort_set
152b39c5158Smillert	TopLevel
153b39c5158Smillert	FocusWindow_set_keep_Zorder
154b39c5158Smillert
155b39c5158Smillert	ActiveDesktopPathname
156b39c5158Smillert	InvalidateRect
157b39c5158Smillert	CreateFrameControls
158b39c5158Smillert
159b39c5158Smillert	ClipbrdFmtInfo
160b39c5158Smillert	ClipbrdOwner
161b39c5158Smillert	ClipbrdViewer
162b39c5158Smillert	ClipbrdData
163b39c5158Smillert	OpenClipbrd
164b39c5158Smillert	CloseClipbrd
165b39c5158Smillert	ClipbrdData_set
166b39c5158Smillert	ClipbrdOwner_set
167b39c5158Smillert	ClipbrdViewer_set
168b39c5158Smillert	EnumClipbrdFmts
169b39c5158Smillert	EmptyClipbrd
170b39c5158Smillert	ClipbrdFmtNames
171b39c5158Smillert	ClipbrdFmtAtoms
172b39c5158Smillert	AddAtom
173b39c5158Smillert	FindAtom
174b39c5158Smillert	DeleteAtom
175b39c5158Smillert	AtomUsage
176b39c5158Smillert	AtomName
177b39c5158Smillert	AtomLength
178b39c5158Smillert	SystemAtomTable
179b39c5158Smillert	CreateAtomTable
180b39c5158Smillert	DestroyAtomTable
181b39c5158Smillert
182b39c5158Smillert	_ClipbrdData_set
183b39c5158Smillert	ClipbrdText
184b39c5158Smillert	ClipbrdText_set
185b39c5158Smillert	ClipbrdText_2byte
186b39c5158Smillert	ClipbrdTextUCS2le
187b39c5158Smillert	MemoryRegionSize
188b39c5158Smillert
189b39c5158Smillert	_MessageBox
190b39c5158Smillert	MessageBox
191b39c5158Smillert	_MessageBox2
192b39c5158Smillert	MessageBox2
193b39c5158Smillert	get_pointer
194b39c5158Smillert	LoadPointer
195b39c5158Smillert	SysPointer
196b39c5158Smillert	Alarm
197b39c5158Smillert	FlashWindow
198b39c5158Smillert
199b39c5158Smillert	get_title
200b39c5158Smillert	set_title
201b39c5158Smillert	io_term
202b39c5158Smillert);
203b39c5158Smillertour @EXPORT_OK = qw(
204b39c5158Smillert	ResetWinError
205b39c5158Smillert        MPFROMSHORT
206b39c5158Smillert        MPVOID
207b39c5158Smillert        MPFROMCHAR
208b39c5158Smillert        MPFROM2SHORT
209b39c5158Smillert        MPFROMSH2CH
210b39c5158Smillert        MPFROMLONG
211b39c5158Smillert);
212b39c5158Smillert
213b39c5158Smillertour $AUTOLOAD;
214b39c5158Smillert
215b39c5158Smillertsub AUTOLOAD {
216b39c5158Smillert    # This AUTOLOAD is used to 'autoload' constants from the constant()
217b39c5158Smillert    # XS function.  If a constant is not found then control is passed
218b39c5158Smillert    # to the AUTOLOAD in AutoLoader.
219b39c5158Smillert
220b39c5158Smillert    (my $constname = $AUTOLOAD) =~ s/.*:://;
221b39c5158Smillert    my $val = constant($constname, @_ ? $_[0] : 0);
222b39c5158Smillert    if ($! != 0) {
223b39c5158Smillert	if ($! =~ /Invalid/ || $!{EINVAL}) {
224b39c5158Smillert	    die "Unsupported function $AUTOLOAD"
225b39c5158Smillert	} else {
226b39c5158Smillert	    my ($pack,$file,$line) = caller;
227b39c5158Smillert	    die "Your vendor has not defined OS2::Process macro $constname, used at $file line $line.
228b39c5158Smillert";
229b39c5158Smillert	}
230b39c5158Smillert    }
231b39c5158Smillert    eval "sub $AUTOLOAD { $val }";
232b39c5158Smillert    goto &$AUTOLOAD;
233b39c5158Smillert}
234b39c5158Smillert
235b39c5158Smillertsub os2constant {
236b39c5158Smillert  require OS2::Process::Const;
237b39c5158Smillert  my $sym = shift;
238b39c5158Smillert  my ($err, $val) = OS2::Process::Const::constant($sym);
239b39c5158Smillert  die $err if $err;
240b39c5158Smillert  $val;
241b39c5158Smillert}
242b39c5158Smillert
243b39c5158Smillertsub const_import {
244b39c5158Smillert  require OS2::Process::Const;
245b39c5158Smillert  my $sym = shift;
246b39c5158Smillert  my $val = os2constant($sym);
247b39c5158Smillert  my $p = caller(1);
248b39c5158Smillert
249b39c5158Smillert  # no strict;
250b39c5158Smillert
251b39c5158Smillert  *{"$p\::$sym"} = sub () { $val };
252b39c5158Smillert  ();			# needed by import()
253b39c5158Smillert}
254b39c5158Smillert
255b39c5158Smillertsub import {
256b39c5158Smillert  my $class = shift;
257b39c5158Smillert  my $ini = @_;
258b39c5158Smillert  @_ = ($class,
259b39c5158Smillert	map {
260b39c5158Smillert	  /^(HWND|WM|SC|SWP|WC|PROG|QW|EDI|WS|QWS|QWP|QWL|FF|FI|LS|FS|FCF|BS|MS|TBM|CF|CFI|FID|MB|MBID|CF|CFI|SPTR)_/ ? const_import($_) : $_
261b39c5158Smillert	} @_);
262b39c5158Smillert  goto &Exporter::import if @_ > 1 or $ini == 0;
263b39c5158Smillert}
264b39c5158Smillert
265b39c5158Smillert# Preloaded methods go here.
266b39c5158Smillert
267b39c5158Smillertsub Title () { (process_entry())[0] }
268b39c5158Smillert
269b39c5158Smillert# *Title_set = \&sesmgr_title_set;
270b39c5158Smillert
271b39c5158Smillertsub swTitle_set_sw {
272b39c5158Smillert  my ($title, @sw) = @_;
273b39c5158Smillert  $sw[0] = $title;
274b39c5158Smillert  change_entry(@sw);
275b39c5158Smillert}
276b39c5158Smillert
277b39c5158Smillertsub swTitle_set ($) {
278b39c5158Smillert  my (@sw) = process_entry();
279b39c5158Smillert  swTitle_set_sw(shift, @sw);
280b39c5158Smillert}
281b39c5158Smillert
282b39c5158Smillertsub winTitle_set_sw {
283b39c5158Smillert  my ($title, @sw) = @_;
284b39c5158Smillert  my $h = OS2::localMorphPM->new(0);
285b39c5158Smillert  WindowText_set $sw[1], $title;
286b39c5158Smillert}
287b39c5158Smillert
288b39c5158Smillertsub winTitle_set ($) {
289b39c5158Smillert  my (@sw) = process_entry();
290b39c5158Smillert  winTitle_set_sw(shift, @sw);
291b39c5158Smillert}
292b39c5158Smillert
293b39c5158Smillertsub winTitle () {
294b39c5158Smillert  my (@sw) = process_entry();
295b39c5158Smillert  my $h = OS2::localMorphPM->new(0);
296b39c5158Smillert  WindowText $sw[1];
297b39c5158Smillert}
298b39c5158Smillert
299b39c5158Smillertsub bothTitle_set ($) {
300b39c5158Smillert  my (@sw) = process_entry();
301b39c5158Smillert  my $t = shift;
302b39c5158Smillert  winTitle_set_sw($t, @sw);
303b39c5158Smillert  swTitle_set_sw($t, @sw);
304b39c5158Smillert}
305b39c5158Smillert
306b39c5158Smillertsub Title_set ($) {
307b39c5158Smillert  my $t = shift;
308b39c5158Smillert  return 1 if sesmgr_title_set($t);
309b39c5158Smillert  return 0 unless $^E == 372;
310b39c5158Smillert  my (@sw) = process_entry();
311b39c5158Smillert  winTitle_set_sw($t, @sw);
312b39c5158Smillert  swTitle_set_sw($t, @sw);
313b39c5158Smillert}
314b39c5158Smillert
315b39c5158Smillertsub process_entry { swentry_expand(process_swentry(@_)) }
316b39c5158Smillert
317b39c5158Smillertour @hentry_fields = qw( title owner_hwnd icon_hwnd
318b39c5158Smillert			 owner_phandle owner_pid owner_sid
319b39c5158Smillert			 visible nonswitchable jumpable ptype sw_entry );
320b39c5158Smillert
321b39c5158Smillertsub swentry_hexpand ($) {
322b39c5158Smillert  my %h;
323b39c5158Smillert  @h{@hentry_fields} = swentry_expand(shift);
324b39c5158Smillert  \%h;
325b39c5158Smillert}
326b39c5158Smillert
327b39c5158Smillertsub process_hentry { swentry_hexpand(process_swentry(@_)) }
328b39c5158Smillertsub process_hwnd { process_hentry()->{owner_hwnd} }
329b39c5158Smillert
330b39c5158Smillertmy $swentry_size = swentry_size();
331b39c5158Smillert
332b39c5158Smillertsub sw_entries () {
333b39c5158Smillert  my $s = swentries_list();
334b39c5158Smillert  my ($c, $s1) = unpack 'La*', $s;
335898184e3Ssthen  die "Inconsistent size in swentries_list()" unless 4+$c*$swentry_size == length $s;
336b39c5158Smillert  my (@l, $e);
337b39c5158Smillert  push @l, $e while $e = substr $s1, 0, $swentry_size, '';
338b39c5158Smillert  @l;
339b39c5158Smillert}
340b39c5158Smillert
341b39c5158Smillertsub process_entries () {
342b39c5158Smillert  map [swentry_expand($_)], sw_entries;
343b39c5158Smillert}
344b39c5158Smillert
345b39c5158Smillertsub process_hentries () {
346b39c5158Smillert  map swentry_hexpand($_), sw_entries;
347b39c5158Smillert}
348b39c5158Smillert
349b39c5158Smillertsub change_entry {
350b39c5158Smillert  change_swentry(create_swentry(@_));
351b39c5158Smillert}
352b39c5158Smillert
353b39c5158Smillertsub create_swentryh ($) {
354b39c5158Smillert  my $h = shift;
355b39c5158Smillert  create_swentry(@$h{@hentry_fields});
356b39c5158Smillert}
357b39c5158Smillert
358b39c5158Smillertsub change_entryh ($) {
359b39c5158Smillert  change_swentry(create_swentryh(shift));
360b39c5158Smillert}
361b39c5158Smillert
362b39c5158Smillert# Massage entries into the same order as WindowPos_set:
363b39c5158Smillertsub WindowPos ($) {
364b39c5158Smillert  my ($fl, $h, $w, $y, $x, $behind, $hwnd, @rest)
365b39c5158Smillert	= unpack 'L l4 L4', WindowSWP(shift);
366b39c5158Smillert  ($x, $y, $fl, $w, $h, $behind, @rest);
367b39c5158Smillert}
368b39c5158Smillert
369b39c5158Smillert# Put them into a hash
370b39c5158Smillertsub hWindowPos ($) {
371b39c5158Smillert  my %h;
372b39c5158Smillert  @h{ qw(flags height width y x behind hwnd reserved1 reserved2) }
373b39c5158Smillert	= unpack 'L l4 L4', WindowSWP(shift);
374b39c5158Smillert  \%h;
375b39c5158Smillert}
376b39c5158Smillert
377b39c5158Smillertmy @SWP_keys = ( [qw(width height)],	# SWP_SIZE=1
378b39c5158Smillert		 [qw(x y)],		# SWP_MOVE=2
379b39c5158Smillert		 [qw(behind)] );	# SWP_ZORDER=3
380b39c5158Smillertmy %SWP_def;
381b39c5158Smillert@SWP_def{ map @$_, @SWP_keys }  = (0) x 20;
382b39c5158Smillert
383b39c5158Smillert# Get them from a hash
384b39c5158Smillertsub hWindowPos_set ($$) {
385b39c5158Smillert  my $hash = shift;
386b39c5158Smillert  my $hwnd = (@_ ? shift : $hash->{hwnd} );
387b39c5158Smillert  my $flags;
388b39c5158Smillert  if (exists $hash->{flags}) {
389b39c5158Smillert    $flags = $hash->{flags};
390b39c5158Smillert  } else {			# Set flags according to existing keys in $hash
391b39c5158Smillert    $flags = 0;
392b39c5158Smillert    for my $bit (0..2) {
393b39c5158Smillert      exists $hash->{$_} and $flags |= (1<<$bit) for @{$SWP_keys[$bit]};
394b39c5158Smillert    }
395b39c5158Smillert  }
396b39c5158Smillert  for my $bit (0..2) {		# Check for required keys
397b39c5158Smillert    next unless $flags & (1<<$bit);
398b39c5158Smillert    exists $hash->{$_}
399b39c5158Smillert      or die sprintf "key $_ required for flags=%#x", $flags
400b39c5158Smillert	for @{$SWP_keys[$bit]};
401b39c5158Smillert  }
402b39c5158Smillert  my %h = (%SWP_def, flags => $flags, %$hash);		# Avoid warnings
403b39c5158Smillert  my ($x, $y, $fl, $w, $h, $behind) = @h{ qw(x y flags width height behind) };
404b39c5158Smillert  WindowPos_set($hwnd, $x, $y, $fl, $w, $h, $behind);
405b39c5158Smillert}
406b39c5158Smillert
407b39c5158Smillertsub ChildWindows (;$) {
408b39c5158Smillert  my $hm = OS2::localMorphPM->new(0);
409b39c5158Smillert  my @kids;
410b39c5158Smillert  my $h = BeginEnumWindows(@_ ? shift : 1);	# HWND_DESKTOP
411b39c5158Smillert  my $w;
412b39c5158Smillert  push @kids, $w while $w = GetNextWindow $h;
413b39c5158Smillert  EndEnumWindows $h;
414b39c5158Smillert  @kids;
415b39c5158Smillert}
416b39c5158Smillert
417b39c5158Smillertsub TopLevel ($) {
418b39c5158Smillert  my $d = DesktopWindow;
419b39c5158Smillert  my $w = shift;
420b39c5158Smillert  while (1) {
421b39c5158Smillert    my $p = QueryWindow $w, 5;	# QW_PARENT;
422b39c5158Smillert    return $w if not $p or $p == $d;
423b39c5158Smillert    $w = $p;
424b39c5158Smillert  }
425b39c5158Smillert}
426b39c5158Smillert
427b39c5158Smillertsub FocusWindow_set_keep_Zorder ($) {
428b39c5158Smillert  my $w = shift;
429b39c5158Smillert  my $t = TopLevel $w;
430b39c5158Smillert  my $b = hWindowPos($t)->{behind}; # we are behind this
431b39c5158Smillert  EnableWindowUpdate($t, 0);
432b39c5158Smillert  FocusWindow_set($w);
433b39c5158Smillert# sleep 1;    # Make flicker stronger when present
434b39c5158Smillert  hWindowPos_set {behind => $b}, $t;
435b39c5158Smillert  EnableWindowUpdate($t, 1);
436b39c5158Smillert}
437b39c5158Smillert
438b39c5158Smillertsub WindowStyle ($) {
439b39c5158Smillert  WindowULong(shift,-2);	# QWL_STYLE
440b39c5158Smillert}
441b39c5158Smillert
442b39c5158Smillertsub OS2::localClipbrd::new {
443b39c5158Smillert  my ($c) = shift;
444b39c5158Smillert  my $morph = [];
445b39c5158Smillert  push @$morph, OS2::localMorphPM->new(0) unless shift;
446b39c5158Smillert  &OpenClipbrd;
447b39c5158Smillert  # print STDERR ">>>>>\n";
448b39c5158Smillert  bless $morph, $c
449b39c5158Smillert}
450b39c5158Smillertsub OS2::localClipbrd::DESTROY {
451b39c5158Smillert  # print STDERR "<<<<<\n";
452b39c5158Smillert  CloseClipbrd();
453b39c5158Smillert}
454b39c5158Smillert
455b39c5158Smillertsub OS2::localFlashWindow::new ($$) {
456b39c5158Smillert  my ($c, $w) = (shift, shift);
457b39c5158Smillert  my $morph = OS2::localMorphPM->new(0);
458b39c5158Smillert  FlashWindow($w, 1);
459b39c5158Smillert  # print STDERR ">>>>>\n";
460b39c5158Smillert  bless [$w, $morph], $c
461b39c5158Smillert}
462b39c5158Smillertsub OS2::localFlashWindow::DESTROY {
463b39c5158Smillert  # print STDERR "<<<<<\n";
464b39c5158Smillert  FlashWindow(shift->[0], 0);
465b39c5158Smillert}
466b39c5158Smillert
467b39c5158Smillert# Good for \0-terminated text (not "text/unicode" and other Firefox stuff)
468b39c5158Smillertsub ClipbrdText (@) {
469b39c5158Smillert  my $h = OS2::localClipbrd->new;
470b39c5158Smillert  my $data = ClipbrdData @_;
471b39c5158Smillert  return unless $data;
472b39c5158Smillert  my $lim = MemoryRegionSize($data);
473b39c5158Smillert  $lim = StrLen($data, $lim);			# Look for 1-byte 0
474b39c5158Smillert  return unpack "P$lim", pack 'L', $data;
475b39c5158Smillert}
476b39c5158Smillert
477b39c5158Smillertsub ClipbrdText_2byte (@) {
478b39c5158Smillert  my $h = OS2::localClipbrd->new;
479b39c5158Smillert  my $data = ClipbrdData @_;
480b39c5158Smillert  return unless $data;
481b39c5158Smillert  my $lim = MemoryRegionSize($data);
482b39c5158Smillert  $lim = StrLen($data, $lim, 2);		# Look for 2-byte 0
483b39c5158Smillert  return unpack "P$lim", pack 'L', $data;
484b39c5158Smillert}
485b39c5158Smillert
486b39c5158Smillertsub ClipbrdTextUCS2le (@) {
487b39c5158Smillert  my $txt = ClipbrdText_2byte @_;		# little-endian shorts
488b39c5158Smillert  #require Unicode::String;
489b39c5158Smillert  pack "U*", unpack "v*", $txt;
490b39c5158Smillert}
491b39c5158Smillert
492b39c5158Smillertsub ClipbrdText_set ($;@) {
493b39c5158Smillert  my $h = OS2::localClipbrd->new;
494b39c5158Smillert  EmptyClipbrd();				# It may contain other types
495b39c5158Smillert  my ($txt, $no_convert_nl) = (shift, shift);
496b39c5158Smillert  ClipbrdData_set($txt, !$no_convert_nl, @_);
497b39c5158Smillert}
498b39c5158Smillert
499b39c5158Smillertsub ClipbrdFmtAtoms {
500b39c5158Smillert  my $h = OS2::localClipbrd->new('nomorph');
501b39c5158Smillert  my $fmt = 0;
502b39c5158Smillert  my @formats;
503b39c5158Smillert  push @formats, $fmt while eval {$fmt = EnumClipbrdFmts $fmt};
504b39c5158Smillert  die $@ if $@ and $^E == 0x1001 and $fmt = 0;	# Croaks on empty list?
505b39c5158Smillert  @formats;
506b39c5158Smillert}
507b39c5158Smillert
508b39c5158Smillertsub ClipbrdFmtNames {
509b39c5158Smillert  map AtomName($_), ClipbrdFmtAtoms(@_);
510b39c5158Smillert}
511b39c5158Smillert
512b39c5158Smillertsub MessageBox ($;$$$$$) {
513b39c5158Smillert  my $morph = OS2::localMorphPM->new(0);
514b39c5158Smillert  die "MessageBox needs text" unless @_;
515b39c5158Smillert  push @_ , ($0 eq '-e' ? "Perl one-liner's message" : "$0 message") if @_ == 1;
516b39c5158Smillert  &_MessageBox;
517b39c5158Smillert}
518b39c5158Smillert
519b39c5158Smillertmy %pointers;
520b39c5158Smillert
521b39c5158Smillertsub get_pointer ($;$$) {
522b39c5158Smillert  my $id = $_[0];
523b39c5158Smillert  return $pointers{$id} if exists $pointers{$id};
524b39c5158Smillert  $pointers{$id} = &SysPointer;
525b39c5158Smillert}
526b39c5158Smillert
527b39c5158Smillert# $button needs to be of the form 'String', ['String'] or ['String', flag].
528b39c5158Smillert# If ['String'], it is assumed the default button; same for 'String' if $only
529b39c5158Smillert# is set.
530b39c5158Smillertsub process_MB2 ($$;$) {
531b39c5158Smillert  die "process_MB2() needs 2 arguments, got '@_'" unless @_ == 2 or @_ == 3;
532b39c5158Smillert  my ($button, $ret, $only) = @_;
533b39c5158Smillert  # default is BS_PUSHBUTTON, add BS_DEFAULT if $only is set
534b39c5158Smillert  $button = [$button, $only ? 0x400 : 0] unless ref $button eq 'ARRAY';
535b39c5158Smillert  push @$button, 0x400 if @$button == 1; # BS_PUSHBUTTON|BS_DEFAULT
536b39c5158Smillert  die "Button needs to be of the form 'String', ['String'] or ['String', flag]"
537b39c5158Smillert    unless @$button == 2;
538b39c5158Smillert  pack "Z71 x L l", $button->[0], $ret, $button->[1]; # name, retval, flag
539b39c5158Smillert}
540b39c5158Smillert
541b39c5158Smillert# If one button, make it the default one even if it is of 'String' => val form.
542b39c5158Smillert# If icon is of the form 'SP#<number>', load this via SysPointer.
543b39c5158Smillertsub process_MB2_INFO ($;$$$) {
544b39c5158Smillert  my $l = 0;
545b39c5158Smillert  my $out;
546b39c5158Smillert  die "process_MB2_INFO() needs 1..4 arguments" unless @_ and @_ < 5;
547b39c5158Smillert  my $buttons = shift;
548b39c5158Smillert  die "Buttons array should consist of pairs" if @$buttons % 2;
549b39c5158Smillert
550b39c5158Smillert  push @_, 0 unless @_;		# Icon id; non-0 ignored without MB_CUSTOMICON
551b39c5158Smillert  # Box flags (MB_MOVABLE and MB_INFORMATION or MB_CUSTOMICON)
552b39c5158Smillert  push @_, ($_[0] ? 0x4080 : 0x4030) unless @_ > 1;
553b39c5158Smillert  push @_, 0 unless @_ > 2;	# Notify window
554b39c5158Smillert
555b39c5158Smillert  my ($icon, $style, $notify) = (shift, shift, shift);
556b39c5158Smillert  $icon = get_pointer $1 if $icon =~ /^SP#(\d+)\z/;
557b39c5158Smillert  $out = pack "L L L L",	# icon, #buttons, style, notify, buttons
558b39c5158Smillert      $icon, @$buttons/2, $style, $notify;
559b39c5158Smillert  $out .= join '',
560b39c5158Smillert    map process_MB2($buttons->[2*$_], $buttons->[2*$_+1], @$buttons == 2),
561b39c5158Smillert      0..@$buttons/2-1;
562b39c5158Smillert  pack('L', length(pack 'L', 0) + length $out) . $out;
563b39c5158Smillert}
564b39c5158Smillert
565b39c5158Smillert# MessageBox2 'Try this', OS2::Process::process_MB2_INFO([['Dismiss', 0] => 0x1000], OS2::Process::get_pointer(22),0x4080,0), 'me', 1, 0, 0
566b39c5158Smillert# or the shortcut
567b39c5158Smillert# MessageBox2 'Try this', [[['Dismiss', 0] => 0x1000], 'SP#22'], 'me'
568b39c5158Smillert# 0x80 means MB_CUSTOMICON (does not focus?!).  This focuses:
569b39c5158Smillert# MessageBox2 'Try this', [[['Dismiss',0x400] => 0x1000], 0, 0x4030,0]
570b39c5158Smillert# 0x400 means BS_DEFAULT.  This is the same as the shortcut
571b39c5158Smillert# MessageBox2 'Try this', [[Dismiss => 0x1000]]
572b39c5158Smillertsub MessageBox2 ($;$$$$$) {
573b39c5158Smillert  my $morph = OS2::localMorphPM->new(0);
574b39c5158Smillert  die "MessageBox needs text" unless @_;
575b39c5158Smillert  push @_ , [[Dismiss => 0x1000], # Name, retval (style BS_PUSHBUTTON|BS_DEFAULT)
576b39c5158Smillert	     #0,		# e.g., get_pointer(11),# SPTR_ICONINFORMATION
577b39c5158Smillert	     #0x4030,		# = MB_MOVEABLE | MB_INFORMATION
578b39c5158Smillert	     #0,		# Notify window; was 1==HWND_DESKTOP
579b39c5158Smillert	    ] if @_ == 1;
580b39c5158Smillert  push @_ , ($0 eq '-e' ? "Perl one-liner" : $0). "'s message" if @_ == 2;
581b39c5158Smillert  $_[1] = &process_MB2_INFO(@{$_[1]}) if ref($_[1]) eq 'ARRAY';
582b39c5158Smillert  &_MessageBox2;
583b39c5158Smillert}
584b39c5158Smillert
585b39c5158Smillertmy %mbH_default = (
586b39c5158Smillert  text => 'Something happened',
587b39c5158Smillert  title => ($0 eq '-e' ? "Perl one-liner" : $0). "'s message",
588b39c5158Smillert  parent => 1,			# HWND_DESKTOP
589b39c5158Smillert  owner => 0,
590b39c5158Smillert  helpID => 0,
591b39c5158Smillert  buttons => ['Dismiss' => 0x1000],
592b39c5158Smillert  default_button => 1,
593b39c5158Smillert#  icon => 0x30,		# MB_INFORMATION
594b39c5158Smillert#  iconID => 0,			# XXX???
595b39c5158Smillert  flags => 0,			# XXX???
596b39c5158Smillert  notifyWindow => 0,		# XXX???
597b39c5158Smillert);
598b39c5158Smillert
599b39c5158Smillertsub MessageBoxH {
600b39c5158Smillert  die "MessageBoxH: even number of arguments expected" if @_ % 2;
601b39c5158Smillert  my %a = (%mbH_default, @_);
602b39c5158Smillert  die "MessageBoxH: even number of elts of button array expected"
603b39c5158Smillert    if @{$a{buttons}} % 2;
604b39c5158Smillert  if (defined $a{iconID}) {
605b39c5158Smillert    $a{flags} |= 0x80;		# MB_CUSTOMICON
606b39c5158Smillert  } else {
607b39c5158Smillert    $a{icon} = 0x30 unless defined $a{icon};
608b39c5158Smillert    $a{iconID} = 0;
609b39c5158Smillert    $a{flags} |= $a{icon};
610b39c5158Smillert  }
611b39c5158Smillert  # Mark default_button as MessageBox2() expects it:
612b39c5158Smillert  $a{buttons}[2*$a{default_button}] = [$a{buttons}[2*$a{default_button}]];
613b39c5158Smillert
614b39c5158Smillert  my $use_2 = 'ARRAY' eq ref $a{buttons};
615b39c5158Smillert  return
616b39c5158Smillert    MessageBox2 $a{text}, [@a{qw(buttons iconID flags notifyWindow)}],
617b39c5158Smillert      $a{parent}, $a{owner}, $a{helpID}
618b39c5158Smillert	if $use_2;
619b39c5158Smillert  die "MessageBoxH: unexpected format of argument 'buttons'";
620b39c5158Smillert}
621b39c5158Smillert
622b39c5158Smillert# backward compatibility
623b39c5158Smillert*set_title = \&Title_set;
624b39c5158Smillert*get_title = \&Title;
625b39c5158Smillert
626b39c5158Smillert# New (logical) names
627b39c5158Smillert*WindowBits_set = \&SetWindowBits;
628b39c5158Smillert*WindowPtr_set = \&SetWindowPtr;
629b39c5158Smillert*WindowULong_set = \&SetWindowULong;
630b39c5158Smillert*WindowUShort_set = \&SetWindowUShort;
631b39c5158Smillert
632b39c5158Smillert# adapter; display; cbMemory; Configuration; VDHVersion; Flags; HWBufferSize;
633b39c5158Smillert# FullSaveSize; PartSaveSize; EMAdaptersOFF; EMDisplaysOFF;
634b39c5158Smillertsub vioConfig (;$$) {
635b39c5158Smillert  my $data = &_vioConfig;
636b39c5158Smillert  my @out = unpack 'x[S]SSLSSSLLLSS', $data;
637b39c5158Smillert  # If present, offset points to S/S (with only the first work making sense)
638b39c5158Smillert  my (@adaptersEMU, @displayEMU);
639b39c5158Smillert  @displaysEMU = unpack("x[$out[10]]S/S", $data), pop @out if @out > 10;
640b39c5158Smillert  @adaptersEMU = unpack("x[$out[ 9]]S/S", $data), pop @out if @out > 9;
641b39c5158Smillert  $out[9] = $adaptersEMU[0] if @adaptersEMU;
642b39c5158Smillert  $out[10] = $displaysEMU[0] if @displaysEMU;
643b39c5158Smillert  @out;
644b39c5158Smillert}
645b39c5158Smillert
646b39c5158Smillertmy @vioConfig = qw(adapter display cbMemory Configuration VDHVersion Flags
647b39c5158Smillert		   HWBufferSize FullSaveSize PartSaveSize EMAdapters EMDisplays);
648b39c5158Smillert
649b39c5158Smillertsub viohConfig (;$$) {
650b39c5158Smillert  my %h;
651b39c5158Smillert  @h{@vioConfig} = &vioConfig;
652b39c5158Smillert  %h;
653b39c5158Smillert}
654b39c5158Smillert
655b39c5158Smillert# fbType; color; col; row; hres; vres; fmt_ID; attrib; buf_addr; buf_length;
656b39c5158Smillert# full_length; partial_length; ext_data_addr;
657b39c5158Smillertsub vioMode() {unpack 'x[S]CCSSSSCCLLLLL', _vioMode}
658b39c5158Smillert
659b39c5158Smillertmy @vioMode = qw( fbType color col row hres vres fmt_ID attrib buf_addr
660b39c5158Smillert		  buf_length full_length partial_length ext_data_addr);
661b39c5158Smillert
662b39c5158Smillertsub viohMode() {
663b39c5158Smillert  my %h;
664b39c5158Smillert  @h{@vioMode} = vioMode;
665b39c5158Smillert  %h;
666b39c5158Smillert}
667b39c5158Smillert
668b39c5158Smillertsub viohMode_set {
669b39c5158Smillert  my %h = (viohMode, @_);
670b39c5158Smillert  my $o = pack 'x[S]CCSSSSCCLLLLL', @h{@vioMode};
671b39c5158Smillert  $o = pack 'SCCSSSSCCLLLLL', length $o, @h{@vioMode};
672b39c5158Smillert  _vioMode_set($o);
673b39c5158Smillert}
674b39c5158Smillert
675b39c5158Smillertsub kbdChar (;$$) {unpack 'CCCCSL', &_kbdChar}
676b39c5158Smillert
677b39c5158Smillertmy @kbdChar = qw(ascii scancode status nlsstate shifts time);
678b39c5158Smillertsub kbdhChar (;$$) {
679b39c5158Smillert  my %h;
680b39c5158Smillert  @h{@kbdChar} = &kbdChar;
681b39c5158Smillert  %h
682b39c5158Smillert}
683b39c5158Smillert
684b39c5158Smillertsub kbdStatus (;$) {unpack 'x[S]SSSS', &_kbdStatus}
685b39c5158Smillertmy @kbdStatus = qw(state turnChar intCharFlags shifts);
686b39c5158Smillertsub kbdhStatus (;$) {
687b39c5158Smillert  my %h;
688b39c5158Smillert  @h{@kbdStatus} = &kbdStatus;
689b39c5158Smillert  %h
690b39c5158Smillert}
691b39c5158Smillertsub kbdhStatus_set {
692b39c5158Smillert  my $h = (@_ % 2 ? shift @_ : 0);
693b39c5158Smillert  my %h = (kbdhStatus($h), @_);
694b39c5158Smillert  my $o = pack 'x[S]SSSS', @h{@kbdStatus};
695b39c5158Smillert  $o = pack 'SSSSS', length $o, @h{@kbdStatus};
696b39c5158Smillert  _kbdStatus_set($o,$h);
697b39c5158Smillert}
698b39c5158Smillert
699b39c5158Smillert#sub DeleteAtom		{ !WinDeleteAtom(@_) }
700b39c5158Smillertsub DeleteAtom		{ !_DeleteAtom(@_) }
701b39c5158Smillertsub DestroyAtomTable    { !_DestroyAtomTable(@_) }
702b39c5158Smillert
703b39c5158Smillert# XXXX This is a wrong order: we start keyreader, then screenwriter; so it is
704b39c5158Smillert# the writer who gets signals.
705b39c5158Smillert
706b39c5158Smillert# XXXX Do we ever get a message "screenwriter killed"???  If reader HUPs us...
707b39c5158Smillert# Large buffer works at least for read from pipes; should we binmode???
708b39c5158Smillertsub __term_mirror_screen {   # Read from fd=$in and write to the console
709b39c5158Smillert  local $SIG{TERM} = $SIG{HUP} = $SIG{BREAK} = $SIG{INT} = # die() can stop END
710b39c5158Smillert    sub { my $s = shift; warn "screenwriter killed ($s)...\n";};
711b39c5158Smillert  my $in = shift;
712b39c5158Smillert  open IN, "<&=$in" or die "open <&=$in: $!";
713b39c5158Smillert  # Attempt to redirect to STDERR/OUT is not very useful, but try this anyway...
714b39c5158Smillert  open OUT, '>', '/dev/con' or open OUT, '>&STDERR' or open OUT, '>&STDOUT'
715b39c5158Smillert	and select OUT or die "Can't open /dev/con or STDERR/STDOUT for write";
716b39c5158Smillert  $| = 1; local $SIG{TERM} = sub { die "screenwriter exits...\n"};
717b39c5158Smillert  binmode IN; binmode OUT;
718b39c5158Smillert  eval { print $_ while sysread IN, $_, 1<<16; };	# print to OUT...
719b39c5158Smillert  warn $@ if $@;
720b39c5158Smillert  warn "Screenwriter can't read any more ($!, $^E), terminating...\n";
721b39c5158Smillert}
722b39c5158Smillert
723b39c5158Smillert# Does not automatically ends when the parent exits if related => 0
724b39c5158Smillert# copy from fd=$in to screen ; same for $out; or $in may be a named pipe
725b39c5158Smillertsub __term_mirror {
726b39c5158Smillert  my $pid;
727b39c5158Smillert  ### If related => 1, we get TERM when our parent exits...
728b39c5158Smillert  local $SIG{TERM} = sub { my $s = shift;
729b39c5158Smillert			   die "keyreader exits in a few secs ($s)...\n" };
730b39c5158Smillert  my ($in, $out) = (shift, shift);
731b39c5158Smillert  if (defined $out and length $out) {	# Allow '' for ease of @ARGV
732b39c5158Smillert    open OUT, ">&=$out" or die "Cannot open &=$out for write: $!";
733b39c5158Smillert    fcntl(OUT, 4, 1);		# F_SETFD, NOINHERIT
734b39c5158Smillert    open IN, "<&=$in" or die "Cannot open &=$in for read/ioctl: $!";
735b39c5158Smillert    fcntl(IN,  4, 0);		# F_SETFD, INHERIT
736b39c5158Smillert  } else {
737b39c5158Smillert    warn "Unexpected i/o pipe name: `$in'" unless $in =~ m,^[\\/]pipe[\\/],i;
738b39c5158Smillert    OS2::pipe $in, 'wait';
739b39c5158Smillert    open OUT, '+<', $in or die "Can't open `$in' for r/w: $!";
740b39c5158Smillert    fcntl(OUT,  4, 0);		# F_SETFD, INHERIT
741b39c5158Smillert    $in = fileno OUT;
742b39c5158Smillert    undef $out;
743b39c5158Smillert  }
744b39c5158Smillert  my %opt = @_;
745b39c5158Smillert  Title_set $opt{title}				if exists $opt{title};
746b39c5158Smillert  &scrsize_set(split /,/, $opt{scrsize})	if exists $opt{scrsize};
747b39c5158Smillert
748b39c5158Smillert  my @i = map +('-I', $_), @INC;	# Propagate @INC
749b39c5158Smillert
750b39c5158Smillert  # Careful unless PERL_SIGNALS=unsafe: SIGCHLD does not work...
751b39c5158Smillert  $SIG{CHLD} = sub {wait; die "Keyreader follows screenwriter...\n"}
752b39c5158Smillert	unless defined $out;
753b39c5158Smillert
754b39c5158Smillert  $pid = system 1, $^X, @i, '-MOS2::Process',
755b39c5158Smillert	 '-we', 'END {sleep 2} OS2::Process::__term_mirror_screen shift', $in;
756b39c5158Smillert  close IN if defined $out;
757b39c5158Smillert  $pid > 0 or die "Cannot start a grandkid";
758b39c5158Smillert
759*9f11ffb7Safresh1  open STDIN, '<', '/dev/con' or warn "reopen stdin: $!";
760b39c5158Smillert  select OUT;    $| = 1;  binmode OUT;	# need binmode: sysread() may be bin
761b39c5158Smillert  $SIG{PIPE} = sub { die "writing to a closed pipe" };
762b39c5158Smillert  $SIG{HUP} = $SIG{BREAK} = $SIG{INT} = $SIG{TERM};
763b39c5158Smillert  # Workaround: EMX v61 won't return pid on SESSION|UNRELATED after fork()...
764b39c5158Smillert  syswrite OUT, pack 'L', $$ or die "syswrite failed: $!" if $opt{writepid};
765b39c5158Smillert  # Turn Nodelay on kbd.  Pipe is automatically nodelay...
766b39c5158Smillert  if ($opt{read_by_key}) {
767b39c5158Smillert    if (eval {require Term::ReadKey; 1}) {
768b39c5158Smillert      Term::ReadKey::ReadMode(4);
769b39c5158Smillert    } else { warn "can't load Term::ReadKey; input by lines..." }
770b39c5158Smillert  }
771b39c5158Smillert  print while sysread STDIN, $_, 1<<($opt{smallbuffer} ? 0 : 16); # to OUT
772b39c5158Smillert}
773b39c5158Smillert
774b39c5158Smillertmy $c = 0;
775b39c5158Smillertsub io_term {	# arguments as hash: read_by_key/title/scrsize/related/writepid
776b39c5158Smillert  # read_by_key disables echo too...
777b39c5158Smillert  local $\  = '';
778b39c5158Smillert  my ($sysf, $in1, $out1, $in2, $out2, $f1, $f2, $fd) = 4;	# P_SESSION
779b39c5158Smillert  my %opt = @_;
780b39c5158Smillert
781b39c5158Smillert  if ($opt{related}) {
782b39c5158Smillert    pipe $in1, $out1 or die "pipe(): $!";
783b39c5158Smillert    pipe $in2, $out2 or do { close($in1), close($out1), die "pipe(): $!" };
784b39c5158Smillert    $f1 = fileno $in1; $f2 = fileno $out2;
785b39c5158Smillert    fcntl($in2, 4, 1); fcntl($out1, 4, 1);		# F_SETFD, NOINHERIT
786b39c5158Smillert    fcntl($in1, 4, 0); fcntl($out2, 4, 0);		# F_SETFD, INHERIT
787b39c5158Smillert  } else {
788b39c5158Smillert    $f1 = "/pipe/perlmodule/OS2/Process/$$-" . $c++;
789b39c5158Smillert    $out1 = OS2::pipe $f1, 'rw' or die "OS2::pipe(): $^E";
790b39c5158Smillert    #open $out1, "+<&=$fd" or die "dup($fd): $!, $^E";
791b39c5158Smillert    fcntl($out1, 4, 1);		# F_SETFD, NOINHERIT
792b39c5158Smillert    #$in2 = $out1;
793b39c5158Smillert    $f2 = '';
794b39c5158Smillert    $sysf |= 0x40000;		# P_UNRELATED
795b39c5158Smillert    $opt{writepid} = 1, unless exists $opt{writepid};
796b39c5158Smillert  }
797b39c5158Smillert
798b39c5158Smillert  # system P_SESSION will fail if there is another process
799b39c5158Smillert  # in the same session with a "related" asynchronous child session.
800b39c5158Smillert  my @i = map +('-I', $_), @INC;	# Propagate @INC
801b39c5158Smillert  my $krun = <<'EOS';
802b39c5158Smillert     END {sleep($sleep || 5)}
803b39c5158Smillert     use OS2::Process; $sleep = 1;
804b39c5158Smillert     OS2::Process::__term_mirror(@ARGV);
805b39c5158SmillertEOS
806b39c5158Smillert  my $kpid;
807b39c5158Smillert  if ($opt{related}) {
808b39c5158Smillert    $kpid = system $sysf, $^X, @i, '-we', $krun, $f1, $f2, %opt;
809b39c5158Smillert  } else {
810b39c5158Smillert    local $ENV{PERL_SIGNALS} = 'unsafe';
811b39c5158Smillert    $kpid = system $sysf, $^X, @i, '-we', $krun, $f1, $f2, %opt;
812b39c5158Smillert  }
813b39c5158Smillert  close $in1 or warn if defined $in1;
814b39c5158Smillert  close $out2 or warn if defined $out2;
815b39c5158Smillert  # EMX BUG with $kpid == 0 after fork()
816b39c5158Smillert  do { close($in2), ($out1 != $in2 and close($out1)),
817b39c5158Smillert       die "system $sysf, $^X: kid=$kpid, \$!=`$!', \$^E=`$^E'" }
818b39c5158Smillert     unless $kpid > 0 or $kpid == 0 and $opt{writepid};
819b39c5158Smillert  # Can't read or write until the kid opens the pipes
820b39c5158Smillert  OS2::pipeCntl $out1, 'connect', 'wait' unless length $f2;
821b39c5158Smillert  # Without duping: write after read (via termio) on the same fd dups input
822b39c5158Smillert  open $in2, '<&', $out1 or die "dup($out1): $^E" unless $opt{related};
823b39c5158Smillert  if ($opt{writepid}) {
824b39c5158Smillert    my $c = length pack 'L', 0;
825b39c5158Smillert    my $c1 = sysread $in2, (my $pid), $c;
826b39c5158Smillert    $c1 == $c or die "unexpected length read: $c1 vs $c";
827b39c5158Smillert    $kpid = unpack 'L', $pid;
828b39c5158Smillert  }
829b39c5158Smillert  return ($in2, $out1, $kpid);
830b39c5158Smillert}
831b39c5158Smillert
832b39c5158Smillert# Autoload methods go after __END__, and are processed by the autosplit program.
833b39c5158Smillert
834b39c5158Smillert1;
835b39c5158Smillert__END__
836b39c5158Smillert
837b39c5158Smillert=head1 NAME
838b39c5158Smillert
839b39c5158SmillertOS2::Process - exports constants for system() call, and process control on OS2.
840b39c5158Smillert
841b39c5158Smillert=head1 SYNOPSIS
842b39c5158Smillert
843b39c5158Smillert    use OS2::Process;
844b39c5158Smillert    $pid = system(P_PM | P_BACKGROUND, "epm.exe");
845b39c5158Smillert
846b39c5158Smillert=head1 DESCRIPTION
847b39c5158Smillert
848b39c5158Smillert=head2 Optional argument to system()
849b39c5158Smillert
850b39c5158Smillertthe builtin function system() under OS/2 allows an optional first
851b39c5158Smillertargument which denotes the mode of the process. Note that this argument is
852b39c5158Smillertrecognized only if it is strictly numerical.
853b39c5158Smillert
854b39c5158SmillertYou can use either one of the process modes:
855b39c5158Smillert
856b39c5158Smillert	P_WAIT (0)	= wait until child terminates (default)
857b39c5158Smillert	P_NOWAIT	= do not wait until child terminates
858b39c5158Smillert	P_SESSION	= new session
859b39c5158Smillert	P_DETACH	= detached
860b39c5158Smillert	P_PM		= PM program
861b39c5158Smillert
862b39c5158Smillertand optionally add PM and session option bits:
863b39c5158Smillert
864b39c5158Smillert	P_DEFAULT (0)	= default
865b39c5158Smillert	P_MINIMIZE	= minimized
866b39c5158Smillert	P_MAXIMIZE	= maximized
867b39c5158Smillert	P_FULLSCREEN	= fullscreen (session only)
868b39c5158Smillert	P_WINDOWED	= windowed (session only)
869b39c5158Smillert
870b39c5158Smillert	P_FOREGROUND	= foreground (if running in foreground)
871b39c5158Smillert	P_BACKGROUND	= background
872b39c5158Smillert
873b39c5158Smillert	P_NOCLOSE	= don't close window on exit (session only)
874b39c5158Smillert
875b39c5158Smillert	P_QUOTE		= quote all arguments
876b39c5158Smillert	P_TILDE		= MKS argument passing convention
877b39c5158Smillert	P_UNRELATED	= do not kill child when father terminates
878b39c5158Smillert
879b39c5158Smillert=head2 Access to process properties
880b39c5158Smillert
881b39c5158SmillertOn OS/2 processes have the usual I<parent/child> semantic;
882b39c5158Smillertadditionally, there is a hierarchy of sessions with their own
883b39c5158SmillertI<parent/child> tree.  A session is either a FS session, or a windowed
884b39c5158Smillertpseudo-session created by PM.  A session is a "unit of user
885b39c5158Smillertinteraction", a change to in/out settings in one of them does not
886b39c5158Smillertaffect other sessions.
887b39c5158Smillert
888b39c5158Smillert=over
889b39c5158Smillert
890b39c5158Smillert=item my_type()
891b39c5158Smillert
892b39c5158Smillertreturns the type of the current process (one of
893b39c5158Smillert"FS", "DOS", "VIO", "PM", "DETACH" and "UNKNOWN"), or C<undef> on error.
894b39c5158Smillert
895b39c5158Smillert=item C<file_type(file)>
896b39c5158Smillert
897b39c5158Smillertreturns the type of the executable file C<file>, or
898b39c5158Smillertdies on error.  The bits 0-2 of the result contain one of the values
899b39c5158Smillert
900b39c5158Smillert=over
901b39c5158Smillert
902b39c5158Smillert=item C<T_NOTSPEC> (0)
903b39c5158Smillert
904b39c5158SmillertApplication type is not specified in the executable header.
905b39c5158Smillert
906b39c5158Smillert=item C<T_NOTWINDOWCOMPAT> (1)
907b39c5158Smillert
908b39c5158SmillertApplication type is not-window-compatible.
909b39c5158Smillert
910b39c5158Smillert=item C<T_WINDOWCOMPAT> (2)
911b39c5158Smillert
912b39c5158SmillertApplication type is window-compatible.
913b39c5158Smillert
914b39c5158Smillert=item C<T_WINDOWAPI> (3)
915b39c5158Smillert
916b39c5158SmillertApplication type is window-API.
917b39c5158Smillert
918b39c5158Smillert=back
919b39c5158Smillert
920b39c5158SmillertThe remaining bits should be masked with the following values to
921b39c5158Smillertdetermine the type of the executable:
922b39c5158Smillert
923b39c5158Smillert=over
924b39c5158Smillert
925b39c5158Smillert=item C<T_BOUND> (8)
926b39c5158Smillert
927b39c5158SmillertSet to 1 if the executable file has been "bound" (by the BIND command)
928b39c5158Smillertas a Family API application. Bits 0, 1, and 2 still apply.
929b39c5158Smillert
930b39c5158Smillert=item C<T_DLL> (0x10)
931b39c5158Smillert
932b39c5158SmillertSet to 1 if the executable file is a dynamic link library (DLL)
933b39c5158Smillertmodule. Bits 0, 1, 2, 3, and 5 will be set to 0.
934b39c5158Smillert
935b39c5158Smillert=item C<T_DOS> (0x20)
936b39c5158Smillert
937b39c5158SmillertSet to 1 if the executable file is in PC/DOS format. Bits 0, 1, 2, 3,
938b39c5158Smillertand 4 will be set to 0.
939b39c5158Smillert
940b39c5158Smillert=item C<T_PHYSDRV> (0x40)
941b39c5158Smillert
942b39c5158SmillertSet to 1 if the executable file is a physical device driver.
943b39c5158Smillert
944b39c5158Smillert=item C<T_VIRTDRV> (0x80)
945b39c5158Smillert
946b39c5158SmillertSet to 1 if the executable file is a virtual device driver.
947b39c5158Smillert
948b39c5158Smillert=item C<T_PROTDLL> (0x100)
949b39c5158Smillert
950b39c5158SmillertSet to 1 if the executable file is a protected-memory dynamic link
951b39c5158Smillertlibrary module.
952b39c5158Smillert
953b39c5158Smillert=item C<T_32BIT> (0x4000)
954b39c5158Smillert
955b39c5158SmillertSet to 1 for 32-bit executable files.
956b39c5158Smillert
957b39c5158Smillert=back
958b39c5158Smillert
959b39c5158Smillertfile_type() may croak with one of the strings C<"Invalid EXE
960b39c5158Smillertsignature"> or C<"EXE marked invalid"> to indicate typical error
961b39c5158Smillertconditions.  If given non-absolute path, will look on C<PATH>, will
962b39c5158Smillertadd extension F<.exe> if no extension is present (add extension F<.>
963b39c5158Smillertto suppress).
964b39c5158Smillert
965b39c5158Smillert=item C<@list = process_codepages()>
966b39c5158Smillert
967b39c5158Smillertthe first element is the currently active codepage, up to 2 additional
968b39c5158Smillertentries specify the system's "prepared codepages": the codepages the
969b39c5158Smillertuser can switch to.  The active codepage of a process is one of the
970b39c5158Smillertprepared codepages of the system (if present).
971b39c5158Smillert
972b39c5158Smillert=item C<process_codepage_set($cp)>
973b39c5158Smillert
974b39c5158Smillertsets the currently active codepage.  [Affects printer output, in/out
975b39c5158Smillertcodepages of sessions started by this process, and the default
976b39c5158Smillertcodepage for drawing in PM; is inherited by kids.  Does not affect the
977b39c5158Smillertout- and in-codepages of the session.]
978b39c5158Smillert
979b39c5158Smillert=item ppid()
980b39c5158Smillert
981b39c5158Smillertreturns the PID of the parent process.
982b39c5158Smillert
983b39c5158Smillert=item C<ppidOf($pid = $$)>
984b39c5158Smillert
985b39c5158Smillertreturns the PID of the parent process of $pid.  -1 on error.
986b39c5158Smillert
987b39c5158Smillert=item C<sidOf($pid = $$)>
988b39c5158Smillert
989b39c5158Smillertreturns the session id of the process id $pid.  -1 on error.
990b39c5158Smillert
991b39c5158Smillert=back
992b39c5158Smillert
993b39c5158Smillert=head2 Control of VIO sessions
994b39c5158Smillert
995b39c5158SmillertVIO applications are applications running in a text-mode session.
996b39c5158Smillert
997b39c5158Smillert=over
998b39c5158Smillert
999b39c5158Smillert=item out_codepage()
1000b39c5158Smillert
1001b39c5158Smillertgets code page used for screen output (glyphs).  -1 means that a user font
1002b39c5158Smillertwas loaded.
1003b39c5158Smillert
1004b39c5158Smillert=item C<out_codepage_set($cp)>
1005b39c5158Smillert
1006b39c5158Smillertsets code page used for screen output (glyphs).  -1 switches to a preloaded
1007b39c5158Smillertuser font.  -2 switches off the preloaded user font.
1008b39c5158Smillert
1009b39c5158Smillert=item in_codepage()
1010b39c5158Smillert
1011b39c5158Smillertgets code page used for keyboard input.  0 means that a hardware codepage
1012b39c5158Smillertis used.
1013b39c5158Smillert
1014b39c5158Smillert=item C<in_codepage_set($cp)>
1015b39c5158Smillert
1016b39c5158Smillertsets code page used for keyboard input.
1017b39c5158Smillert
1018b39c5158Smillert=item C<($w, $h) = scrsize()>
1019b39c5158Smillert
1020b39c5158Smillertwidth and height of the given console window in character cells.
1021b39c5158Smillert
1022b39c5158Smillert=item C<scrsize_set([$w, ] $h)>
1023b39c5158Smillert
1024b39c5158Smillertset height (and optionally width) of the given console window in
1025b39c5158Smillertcharacter cells.  Use 0 size to keep the old size.
1026b39c5158Smillert
1027b39c5158Smillert=item C<($s, $e, $w, $a) = cursor()>
1028b39c5158Smillert
1029b39c5158Smillertgets start/end lines of the blinking cursor in the charcell, its width
1030b39c5158Smillert(1 on text modes) and attribute (-1 for hidden, in text modes other
1031b39c5158Smillertvalues mean visible, in graphic modes color).
1032b39c5158Smillert
1033b39c5158Smillert=item C<cursor_set($s, $e, [$w [, $a]])>
1034b39c5158Smillert
1035b39c5158Smillertsets start/end lines of the blinking cursor in the charcell.  Negative
1036b39c5158Smillertvalues mean percents of the character cell height.
1037b39c5158Smillert
1038b39c5158Smillert=item screen()
1039b39c5158Smillert
1040b39c5158Smillertgets a buffer with characters and attributes of the screen.
1041b39c5158Smillert
1042b39c5158Smillert=item C<screen_set($buffer)>
1043b39c5158Smillert
1044b39c5158Smillertrestores the screen given the result of screen().  E.g., if the file
1045b39c5158SmillertC<$file> contains the screen contents, then
1046b39c5158Smillert
1047*9f11ffb7Safresh1  open IN, '<', $file or die;
1048b39c5158Smillert  binmode IN;
1049b39c5158Smillert  read IN, $in, -s IN;
1050b39c5158Smillert  $s = screen;
1051b39c5158Smillert  $in .= qq(\0) x (length($s) - length $in);
1052b39c5158Smillert  substr($in, length $s) = '';
1053b39c5158Smillert  screen_set $in;
1054b39c5158Smillert
1055b39c5158Smillertwill restore the screen content even if the height of the window
1056b39c5158Smillertchanged (if the width changed, more manipulation is needed).
1057b39c5158Smillert
1058b39c5158Smillert=back
1059b39c5158Smillert
1060b39c5158Smillert=head2 Control of the process list
1061b39c5158Smillert
1062b39c5158SmillertWith the exception of Title_set(), all these calls require that PM is
1063b39c5158Smillertrunning, they would not work under alternative Session Managers.
1064b39c5158Smillert
1065b39c5158Smillert=over
1066b39c5158Smillert
1067b39c5158Smillert=item process_entry()
1068b39c5158Smillert
1069b39c5158Smillertreturns a list of the following data:
1070b39c5158Smillert
1071b39c5158Smillert=over
1072b39c5158Smillert
1073b39c5158Smillert=item *
1074b39c5158Smillert
1075b39c5158SmillertTitle of the process (in the C<Ctrl-Esc> list);
1076b39c5158Smillert
1077b39c5158Smillert=item *
1078b39c5158Smillert
1079b39c5158Smillertwindow handle of switch entry of the process (in the C<Ctrl-Esc> list);
1080b39c5158Smillert
1081b39c5158Smillert=item *
1082b39c5158Smillert
1083b39c5158Smillertwindow handle of the icon of the process;
1084b39c5158Smillert
1085b39c5158Smillert=item *
1086b39c5158Smillert
1087b39c5158Smillertprocess handle of the owner of the entry in C<Ctrl-Esc> list;
1088b39c5158Smillert
1089b39c5158Smillert=item *
1090b39c5158Smillert
1091b39c5158Smillertprocess id of the owner of the entry in C<Ctrl-Esc> list;
1092b39c5158Smillert
1093b39c5158Smillert=item *
1094b39c5158Smillert
1095b39c5158Smillertsession id of the owner of the entry in C<Ctrl-Esc> list;
1096b39c5158Smillert
1097b39c5158Smillert=item *
1098b39c5158Smillert
1099b39c5158Smillertwhether visible in C<Ctrl-Esc> list;
1100b39c5158Smillert
1101b39c5158Smillert=item *
1102b39c5158Smillert
1103b39c5158Smillertwhether item cannot be switched to (note that it is not actually
1104b39c5158Smillertgrayed in the C<Ctrl-Esc> list));
1105b39c5158Smillert
1106b39c5158Smillert=item *
1107b39c5158Smillert
1108b39c5158Smillertwhether participates in jump sequence;
1109b39c5158Smillert
1110b39c5158Smillert=item *
1111b39c5158Smillert
1112b39c5158Smillertprogram type.  Possible values are:
1113b39c5158Smillert
1114b39c5158Smillert     PROG_DEFAULT                       0
1115b39c5158Smillert     PROG_FULLSCREEN                    1
1116b39c5158Smillert     PROG_WINDOWABLEVIO                 2
1117b39c5158Smillert     PROG_PM                            3
1118b39c5158Smillert     PROG_VDM                           4
1119b39c5158Smillert     PROG_WINDOWEDVDM                   7
1120b39c5158Smillert
1121b39c5158SmillertAlthough there are several other program types for WIN-OS/2 programs,
1122b39c5158Smillertthese do not show up in this field. Instead, the PROG_VDM or
1123b39c5158SmillertPROG_WINDOWEDVDM program types are used. For instance, for
1124b39c5158SmillertPROG_31_STDSEAMLESSVDM, PROG_WINDOWEDVDM is used. This is because all
1125b39c5158Smillertthe WIN-OS/2 programs run in DOS sessions. For example, if a program
1126b39c5158Smillertis a windowed WIN-OS/2 program, it runs in a PROG_WINDOWEDVDM
1127b39c5158Smillertsession. Likewise, if it's a full-screen WIN-OS/2 program, it runs in
1128b39c5158Smillerta PROG_VDM session.
1129b39c5158Smillert
1130b39c5158Smillert=item *
1131b39c5158Smillert
1132b39c5158Smillertswitch-entry handle.
1133b39c5158Smillert
1134b39c5158Smillert=back
1135b39c5158Smillert
1136b39c5158SmillertOptional arguments: the pid and the window-handle of the application running
1137b39c5158Smillertin the OS/2 session to query.
1138b39c5158Smillert
1139b39c5158Smillert=item process_hentry()
1140b39c5158Smillert
1141b39c5158Smillertsimilar to process_entry(), but returns a hash reference, the keys being
1142b39c5158Smillert
1143b39c5158Smillert  title owner_hwnd icon_hwnd owner_phandle owner_pid owner_sid
1144b39c5158Smillert  visible nonswitchable jumpable ptype sw_entry
1145b39c5158Smillert
1146b39c5158Smillert(a copy of the list of keys is in @hentry_fields).
1147b39c5158Smillert
1148b39c5158Smillert=item process_entries()
1149b39c5158Smillert
1150b39c5158Smillertsimilar to process_entry(), but returns a list of array reference for all
1151b39c5158Smillertthe elements in the switch list (one controlling C<Ctrl-Esc> window).
1152b39c5158Smillert
1153b39c5158Smillert=item process_hentries()
1154b39c5158Smillert
1155b39c5158Smillertsimilar to process_hentry(), but returns a list of hash reference for all
1156b39c5158Smillertthe elements in the switch list (one controlling C<Ctrl-Esc> window).
1157b39c5158Smillert
1158b39c5158Smillert=item change_entry()
1159b39c5158Smillert
1160b39c5158Smillertchanges a process entry, arguments are the same as process_entry() returns.
1161b39c5158Smillert
1162b39c5158Smillert=item change_entryh()
1163b39c5158Smillert
1164b39c5158SmillertSimilar to change_entry(), but takes a hash reference as an argument.
1165b39c5158Smillert
1166b39c5158Smillert=item process_hwnd()
1167b39c5158Smillert
1168b39c5158Smillertreturns the C<owner_hwnd> of the process entry (for VIO windowed processes
1169b39c5158Smillertthis is the frame window of the session).
1170b39c5158Smillert
1171b39c5158Smillert=item Title()
1172b39c5158Smillert
1173b39c5158Smillertreturns the text of the task switch menu entry of the current session.
1174b39c5158Smillert(There is no way to get this info in non-standard Session Managers.  This
1175b39c5158Smillertimplementation is a shortcut via process_entry().)
1176b39c5158Smillert
1177b39c5158Smillert=item C<Title_set(newtitle)>
1178b39c5158Smillert
1179b39c5158Smillerttries two different interfaces.  The Session Manager one does not work
1180b39c5158Smillertwith some windows (if the title is set from the start).
1181b39c5158SmillertThis is a limitation of OS/2, in such a case $^E is set to 372 (type
1182b39c5158Smillert
1183b39c5158Smillert  help 372
1184b39c5158Smillert
1185b39c5158Smillertfor a funny - and wrong  - explanation ;-).  In such cases a
1186b39c5158Smillertdirect-manipulation of low-level entries is used (same as bothTitle_set()).
1187b39c5158SmillertKeep in mind that some versions of OS/2 leak memory with such a manipulation.
1188b39c5158Smillert
1189b39c5158Smillert=item winTitle()
1190b39c5158Smillert
1191b39c5158Smillertreturns text of the titlebar of the current process' window.
1192b39c5158Smillert
1193b39c5158Smillert=item C<winTitle_set(newtitle)>
1194b39c5158Smillert
1195b39c5158Smillertsets text of the titlebar of the current process' window.  The change does not
1196b39c5158Smillertaffect the text of the switch entry of the current window.
1197b39c5158Smillert
1198b39c5158Smillert=item C<swTitle_set(newtitle)>
1199b39c5158Smillert
1200b39c5158Smillertsets text of the task switch menu entry of the current process' window.  [There
1201b39c5158Smillertis no API to query this title.]  Does it via SwitchEntry interface,
1202b39c5158Smillertnot Session manager interface.  The change does not affect the text of the
1203b39c5158Smillerttitlebar of the current window.
1204b39c5158Smillert
1205b39c5158Smillert=item C<bothTitle_set(newtitle)>
1206b39c5158Smillert
1207b39c5158Smillertsets text of the titlebar and task switch menu of the current process' window
1208b39c5158Smillertvia direct manipulation of the windows' texts.
1209b39c5158Smillert
1210b39c5158Smillert=item C<SwitchToProgram([$sw_entry])>
1211b39c5158Smillert
1212b39c5158Smillertswitch to session given by a switch list handle (defaults to the entry of our process).
1213b39c5158Smillert
1214b39c5158SmillertUse of this function causes another window (and its related windows)
1215b39c5158Smillertof a PM session to appear on the front of the screen, or a switch to
1216b39c5158Smillertanother session in the case of a non-PM program. In either case,
1217b39c5158Smillertthe keyboard (and mouse for the non-PM case) input is directed to
1218b39c5158Smillertthe new program.
1219b39c5158Smillert
1220b39c5158Smillert=back
1221b39c5158Smillert
1222b39c5158Smillert=head2 Control of the PM windows
1223b39c5158Smillert
1224b39c5158SmillertSome of these API's require sending a message to the specified window.
1225b39c5158SmillertIn such a case the process needs to be a PM process, or to be morphed
1226b39c5158Smillertto a PM process via OS2::MorphPM().
1227b39c5158Smillert
1228898184e3SsthenFor a temporary morphing to PM use the L<OS2::localMorphPM|/OS2::localMorphPM,
1229898184e3SsthenOS2::localFlashWindow, and OS2::localClipbrd classes> class.
1230b39c5158Smillert
1231b39c5158SmillertKeep in mind that PM windows are engaged in 2 "orthogonal" window
1232b39c5158Smillerttrees, as well as in the z-order list.
1233b39c5158Smillert
1234b39c5158SmillertOne tree is given by the I<parent/child> relationship.  This
1235b39c5158Smillertrelationship affects drawing (child is drawn relative to its parent
1236b39c5158Smillert(lower-left corner), and the drawing is clipped by the parent's
1237b39c5158Smillertboundary; parent may request that I<it's> drawing is clipped to be
1238898184e3Ssthenconfined to the outsize of the child's and/or siblings' windows);
1239b39c5158Smillerthiding; minimizing/restoring; and destroying windows.
1240b39c5158Smillert
1241b39c5158SmillertAnother tree (not necessarily connected?) is given by I<ownership>
1242b39c5158Smillertrelationship.  Ownership relationship assumes cooperation of the
1243b39c5158Smillertengaged windows via passing messages on "important events"; e.g.,
1244b39c5158Smillertscrollbars send information messages when the "bar" is moved, menus
1245b39c5158Smillertsend messages when an item is selected; frames
1246b39c5158Smillertmove/hide/unhide/minimize/restore/change-z-order-of owned frames when
1247b39c5158Smillertthe owner is moved/etc., and destroy the owned frames (even when these
1248b39c5158Smillertframes are not descendants) when the owner is destroyed; etc.  [An
1249b39c5158Smillertimportant restriction on ownership is that owner should be created by
1250b39c5158Smillertthe same thread as the owned thread, so they engage in the same
1251b39c5158Smillertmessage queue.]
1252b39c5158Smillert
1253b39c5158SmillertWindows may be in many different state: Focused (take keyboard events) or not,
1254b39c5158SmillertActivated (=Frame windows in the I<parent/child> tree between the root and
1255b39c5158Smillertthe window with the focus; usually indicate such "active state" by titlebar
1256b39c5158Smillerthighlights, and take mouse events) or not, Enabled/Disabled (this influences
1257b39c5158Smillertthe ability to update the graphic, and may change appearance, as for
1258b39c5158Smillertenabled/disabled buttons), Visible/Hidden, Minimized/Maximized/Restored, Modal
1259b39c5158Smillertor not, etc.
1260b39c5158Smillert
1261b39c5158SmillertThe APIs below all die() on error with the message being $^E.
1262b39c5158Smillert
1263b39c5158Smillert=over
1264b39c5158Smillert
1265b39c5158Smillert=item C<WindowText($hwnd)>
1266b39c5158Smillert
1267b39c5158Smillertgets "a text content" of a window.  Requires (morphing to) PM.
1268b39c5158Smillert
1269b39c5158Smillert=item C<WindowText_set($hwnd, $text)>
1270b39c5158Smillert
1271b39c5158Smillertsets "a text content" of a window.  Requires (morphing to) PM.
1272b39c5158Smillert
1273b39c5158Smillert=item C<($x, $y, $flags, $width, $height, $behind, @rest) = WindowPos($hwnd)>
1274b39c5158Smillert
1275b39c5158Smillertgets window position info as 8 integers (of C<SWP>), in the order suitable
1276b39c5158Smillertfor WindowPos_set().  @rest is marked as "reserved" in PM docs.  $flags
1277b39c5158Smillertis a combination of C<SWP_*> constants.
1278b39c5158Smillert
1279b39c5158Smillert=item C<$hash = hWindowPos($hwnd)>
1280b39c5158Smillert
1281b39c5158Smillertgets window position info as a hash reference; the keys are C<flags width
1282b39c5158Smillertheight x y behind hwnd reserved1 reserved2>.
1283b39c5158Smillert
1284b39c5158SmillertExample:
1285b39c5158Smillert
1286b39c5158Smillert  exit unless $hash->{flags} & SWP_MAXIMIZE;	# Maximized
1287b39c5158Smillert
1288b39c5158Smillert=item C<WindowPos_set($hwnd, $x, $y, $flags = SWP_MOVE, $width = 0, $height = 0, $behind = HWND_TOP)>
1289b39c5158Smillert
1290b39c5158SmillertSet state of the window: position, size, zorder, show/hide, activation,
1291b39c5158Smillertminimize/maximize/restore etc.  Which of these operations to perform
1292b39c5158Smillertis governed by $flags.
1293b39c5158Smillert
1294b39c5158Smillert=item C<hWindowPos_set($hash, [$hwnd])>
1295b39c5158Smillert
1296b39c5158SmillertSame as C<WindowPos_set>, but takes the position from keys C<fl width height
1297b39c5158Smillertx y behind hwnd> of the hash referenced by $hash.  If $hwnd is explicitly
1298b39c5158Smillertspecified, it overrides C<< $hash->{hwnd} >>.  If $hash->{flags} is not specified,
1299b39c5158Smillertit is calculated basing on the existing keys of $hash.  Requires (morphing to) PM.
1300b39c5158Smillert
1301b39c5158SmillertExample:
1302b39c5158Smillert
1303b39c5158Smillert  hWindowPos_set {flags => SWP_MAXIMIZE}, $hwnd; # Maximize
1304b39c5158Smillert
1305b39c5158Smillert=item C<($pid, $tid) = WindowProcess($hwnd)>
1306b39c5158Smillert
1307b39c5158Smillertgets I<PID> and I<TID> of the process associated to the window.
1308b39c5158Smillert
1309b39c5158Smillert=item C<ClassName($hwnd)>
1310b39c5158Smillert
1311b39c5158Smillertreturns the class name of the window.
1312b39c5158Smillert
1313b39c5158SmillertIf this window is of any of the preregistered WC_* classes the class
1314b39c5158Smillertname returned is in the form "#nnnnn", where "nnnnn" is a group
1315b39c5158Smillertof up to five digits that corresponds to the value of the WC_* class name
1316b39c5158Smillertconstant.
1317b39c5158Smillert
1318b39c5158Smillert=item WindowStyle($hwnd)
1319b39c5158Smillert
1320b39c5158SmillertReturns the "window style" flags for window handle $hwnd.
1321b39c5158Smillert
1322b39c5158Smillert=item WindowULong($hwnd, $id), WindowPtr($hwnd, $id), WindowUShort($hwnd, $id)
1323b39c5158Smillert
1324b39c5158SmillertReturn data associated to window handle $hwnd.  $id should be one of
1325b39c5158SmillertC<QWL_*>, C<QWP_PFNWP>, C<QWS_*> constants, or a byte offset referencing
1326b39c5158Smillerta region (of length 4, 4, 2 correspondingly) fully inside C<0..cbWindowData-1>.
1327b39c5158SmillertHere C<cbWindowData> is the count of extra user-specified bytes reserved
1328b39c5158Smillertfor the given class of windows.
1329b39c5158Smillert
1330b39c5158Smillert=item WindowULong_set($hwnd, $id, $value), WindowPtr_set, WindowUShort_set
1331b39c5158Smillert
1332b39c5158SmillertSimilar to WindowULong(), WindowPtr(), WindowUShort(), but for assigning the
1333b39c5158Smillertvalue $value.
1334b39c5158Smillert
1335b39c5158Smillert=item WindowBits_set($hwnd, $id, $value, $mask)
1336b39c5158Smillert
1337b39c5158SmillertSimilar to WindowULong_set(), but will change only the bits which are
1338b39c5158Smillertset in $mask.
1339b39c5158Smillert
1340b39c5158Smillert=item FocusWindow()
1341b39c5158Smillert
1342b39c5158Smillertreturns the handle of the focus window.  Optional argument for specifying
1343b39c5158Smillertthe desktop to use.
1344b39c5158Smillert
1345b39c5158Smillert=item C<FocusWindow_set($hwnd)>
1346b39c5158Smillert
1347b39c5158Smillertset the focus window by handle.  Optional argument for specifying the desktop
1348b39c5158Smillertto use.  E.g, the first entry in program_entries() is the C<Ctrl-Esc> list.
1349b39c5158SmillertTo show an application, use either one of
1350b39c5158Smillert
1351b39c5158Smillert       WinShowWindow( $hwnd, 1 );
1352b39c5158Smillert       FocusWindow_set( $hwnd );
1353b39c5158Smillert       SwitchToProgram($switch_handle);
1354b39c5158Smillert
1355b39c5158Smillert(Which work with alternative focus-to-front policies?)  Requires
1356b39c5158Smillert(morphing to) PM.
1357b39c5158Smillert
1358b39c5158SmillertSwitching focus to currently-unfocused window moves the window to the
1359b39c5158Smillertfront in Z-order; use FocusWindow_set_keep_Zorder() to avoid this.
1360b39c5158Smillert
1361b39c5158Smillert=item C<FocusWindow_set_keep_Zorder($hwnd)>
1362b39c5158Smillert
1363b39c5158Smillertsame as FocusWindow_set(), but preserves the Z-order of windows.
1364b39c5158Smillert
1365b39c5158Smillert=item C<ActiveWindow([$parentHwnd])>
1366b39c5158Smillert
1367b39c5158Smillertgets the active subwindow's handle for $parentHwnd or desktop.
1368b39c5158SmillertReturns FALSE if none.
1369b39c5158Smillert
1370b39c5158Smillert=item C<ActiveWindow_set($hwnd, [$parentHwnd])>
1371b39c5158Smillert
1372b39c5158Smillertsets the active subwindow's handle for $parentHwnd or desktop.  Requires (morphing to) PM.
1373b39c5158Smillert
1374b39c5158Smillert=item C<ShowWindow($hwnd [, $show])>
1375b39c5158Smillert
1376b39c5158SmillertSet visible/hidden flag of the window.  Default: $show is TRUE.
1377b39c5158Smillert
1378b39c5158Smillert=item C<EnableWindowUpdate($hwnd [, $update])>
1379b39c5158Smillert
1380b39c5158SmillertSet window visibility state flag for the window for subsequent drawing.
1381b39c5158SmillertNo actual drawing is done at this moment.  Use C<ShowWindow($hwnd, $state)>
1382b39c5158Smillertwhen redrawing is needed.  While update is disabled, changes to the "window
1383b39c5158Smillertstate" do not change the appearance of the window.  Default: $update is TRUE.
1384b39c5158Smillert
1385b39c5158Smillert(What is manipulated is the bit C<WS_VISIBLE> of the window style.)
1386b39c5158Smillert
1387b39c5158Smillert=item C<EnableWindow($hwnd [, $enable])>
1388b39c5158Smillert
1389b39c5158SmillertSet the window enabled state.  Default: $enable is TRUE.
1390b39c5158Smillert
1391b39c5158SmillertResults in C<WM_ENABLED> message sent to the window.  Typically, this
1392898184e3Ssthenwould change the appearance of the window.  If at the moment of disabling
1393b39c5158Smillertfocus is in the window (or a descendant), focus is lost (no focus anywhere).
1394b39c5158SmillertIf focus is needed, it can be reassigned explicitly later.
1395b39c5158Smillert
1396b39c5158Smillert=item IsWindowEnabled(), IsWindowVisible(), IsWindowShowing()
1397b39c5158Smillert
1398b39c5158Smillertthese functions take $hwnd as an argument.  IsWindowEnabled() queries
1399b39c5158Smillertthe state changed by EnableWindow(), IsWindowVisible() the state changed
1400b39c5158Smillertby ShowWindow(), IsWindowShowing() is true if there is a part of the window
1401b39c5158Smillertvisible on the screen.
1402b39c5158Smillert
1403b39c5158Smillert=item C<PostMsg($hwnd, $msg, $mp1, $mp2)>
1404b39c5158Smillert
1405b39c5158Smillertpost message to a window.  The meaning of $mp1, $mp2 is specific for each
1406b39c5158Smillertmessage id $msg, they default to 0.  E.g.,
1407b39c5158Smillert
1408b39c5158Smillert  use OS2::Process qw(:DEFAULT WM_SYSCOMMAND WM_CONTEXTMENU
1409b39c5158Smillert		      WM_SAVEAPPLICATION WM_QUIT WM_CLOSE
1410b39c5158Smillert		      SC_MAXIMIZE SC_RESTORE);
1411b39c5158Smillert  $hwnd = process_hentry()->{owner_hwnd};
1412b39c5158Smillert  # Emulate choosing `Restore' from the window menu:
1413b8851fccSafresh1  PostMsg $hwnd, WM_SYSCOMMAND, MPFROMSHORT(SC_RESTORE); # Not
1414b8851fccSafresh1                                                         # immediate
1415b39c5158Smillert
1416b39c5158Smillert  # Emulate `Show-Contextmenu' (Double-Click-2), two ways:
1417b39c5158Smillert  PostMsg ActiveWindow, WM_CONTEXTMENU;
1418b39c5158Smillert  PostMsg FocusWindow, WM_CONTEXTMENU;
1419b39c5158Smillert
1420b39c5158Smillert  /* Emulate `Close' */
1421b39c5158Smillert  PostMsg ActiveWindow, WM_CLOSE;
1422b39c5158Smillert
1423b39c5158Smillert  /* Same but with some "warnings" to the application */
1424b39c5158Smillert  $hwnd = ActiveWindow;
1425b39c5158Smillert  PostMsg $hwnd, WM_SAVEAPPLICATION;
1426b39c5158Smillert  PostMsg $hwnd, WM_CLOSE;
1427b39c5158Smillert  PostMsg $hwnd, WM_QUIT;
1428b39c5158Smillert
1429b39c5158SmillertIn fact, MPFROMSHORT() may be omitted above.
1430b39c5158Smillert
1431b39c5158SmillertFor messages to other processes, messages which take/return a pointer are
1432b39c5158Smillertnot supported.
1433b39c5158Smillert
1434b39c5158Smillert=item C<MP*()>
1435b39c5158Smillert
1436b39c5158SmillertThe functions MPFROMSHORT(), MPVOID(), MPFROMCHAR(), MPFROM2SHORT(),
1437b39c5158SmillertMPFROMSH2CH(), MPFROMLONG() can be used the same way as from C.  Use them
1438b39c5158Smillertto construct parameters $m1, $m2 to PostMsg().
1439b39c5158Smillert
1440b39c5158SmillertThese functions are not exported by default.
1441b39c5158Smillert
1442b39c5158Smillert=item C<$eh = BeginEnumWindows($hwnd)>
1443b39c5158Smillert
1444b39c5158Smillertstarts enumerating immediate child windows of $hwnd in z-order.  The
1445b39c5158Smillertenumeration reflects the state at the moment of BeginEnumWindows() calls;
1446b39c5158Smillertuse IsWindow() to be sure.  All the functions in this group require (morphing to) PM.
1447b39c5158Smillert
1448b39c5158Smillert=item C<$kid_hwnd = GetNextWindow($eh)>
1449b39c5158Smillert
1450b39c5158Smillertgets the next kid in the list.  Gets 0 on error or when the list ends.
1451b39c5158Smillert
1452b39c5158Smillert=item C<EndEnumWindows($eh)>
1453b39c5158Smillert
1454b39c5158SmillertEnd enumeration and release the list.
1455b39c5158Smillert
1456b39c5158Smillert=item C<@list = ChildWindows([$hwnd])>
1457b39c5158Smillert
1458b39c5158Smillertreturns the list of child windows at the moment of the call.  Same remark
1459b39c5158Smillertas for enumeration interface applies.  Defaults to HWND_DESKTOP.
1460b39c5158SmillertExample of usage:
1461b39c5158Smillert
1462b39c5158Smillert  sub l {
1463b39c5158Smillert    my ($o,$h) = @_;
1464b39c5158Smillert    printf ' ' x $o . "%#x\n", $h;
1465b39c5158Smillert    l($o+2,$_) for ChildWindows $h;
1466b39c5158Smillert  }
1467b39c5158Smillert  l 0, $HWND_DESKTOP
1468b39c5158Smillert
1469b39c5158Smillert=item C<IsWindow($hwnd)>
1470b39c5158Smillert
1471b39c5158Smillerttrue if the window handle is still valid.
1472b39c5158Smillert
1473b39c5158Smillert=item C<QueryWindow($hwnd, $type)>
1474b39c5158Smillert
1475b39c5158Smillertgets the handle of a related window.  $type should be one of C<QW_*> constants.
1476b39c5158Smillert
1477b39c5158Smillert=item C<IsChild($hwnd, $parent)>
1478b39c5158Smillert
1479b39c5158Smillertreturn TRUE if $hwnd is a descendant of $parent.
1480b39c5158Smillert
1481b39c5158Smillert=item C<WindowFromId($hwnd, $id)>
1482b39c5158Smillert
1483b39c5158Smillertreturn a window handle of a child of $hwnd with the given $id.
1484b39c5158Smillert
1485b39c5158Smillert  hwndSysMenu = WinWindowFromID(hwndDlg, FID_SYSMENU);
1486b39c5158Smillert  WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
1487b39c5158Smillert      MPFROM2SHORT(SC_CLOSE, TRUE),
1488b39c5158Smillert      MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
1489b39c5158Smillert
1490b39c5158Smillert=item C<WindowFromPoint($x, $y [, $hwndParent [, $descedantsToo]])>
1491b39c5158Smillert
1492b39c5158Smillertgets a handle of a child of $hwndParent at C<($x,$y)>.  If $descedantsToo
1493b39c5158Smillert(defaulting to 1) then children of children may be returned too.  May return
1494b39c5158Smillert$hwndParent (defaults to desktop) if no suitable children are found,
1495b39c5158Smillertor 0 if the point is outside the parent.
1496b39c5158Smillert
1497b39c5158Smillert$x and $y are relative to $hwndParent.
1498b39c5158Smillert
1499b39c5158Smillert=item C<EnumDlgItem($dlgHwnd, $type [, $relativeHwnd])>
1500b39c5158Smillert
1501b39c5158Smillertgets a dialog item window handle for an item of type $type of $dlgHwnd
1502b39c5158Smillertrelative to $relativeHwnd, which is descendant of $dlgHwnd.
1503b39c5158Smillert$relativeHwnd may be specified if $type is EDI_FIRSTTABITEM or
1504b39c5158SmillertEDI_LASTTABITEM.
1505b39c5158Smillert
1506b39c5158SmillertThe return is always an immediate child of hwndDlg, even if hwnd is
1507b39c5158Smillertnot an immediate child window.  $type may be
1508b39c5158Smillert
1509b39c5158Smillert=over
1510b39c5158Smillert
1511b39c5158Smillert=item EDI_FIRSTGROUPITEM
1512b39c5158Smillert
1513b39c5158SmillertFirst item in the same group.
1514b39c5158Smillert
1515b39c5158Smillert=item EDI_FIRSTTABITEM
1516b39c5158Smillert
1517b39c5158SmillertFirst item in dialog with style WS_TABSTOP. hwnd is ignored.
1518b39c5158Smillert
1519b39c5158Smillert=item EDI_LASTGROUPITEM
1520b39c5158Smillert
1521b39c5158SmillertLast item in the same group.
1522b39c5158Smillert
1523b39c5158Smillert=item EDI_LASTTABITEM
1524b39c5158Smillert
1525b39c5158SmillertLast item in dialog with style WS_TABSTOP. hwnd is ignored.
1526b39c5158Smillert
1527b39c5158Smillert=item EDI_NEXTGROUPITEM
1528b39c5158Smillert
1529b39c5158SmillertNext item in the same group. Wraps around to beginning of group when
1530b39c5158Smillertthe end of the group is reached.
1531b39c5158Smillert
1532b39c5158Smillert=item EDI_NEXTTABITEM
1533b39c5158Smillert
1534b39c5158SmillertNext item with style WS_TABSTOP. Wraps around to beginning of dialog
1535b39c5158Smillertitem list when end is reached.
1536b39c5158Smillert
1537b39c5158Smillert=item EDI_PREVGROUPITEM
1538b39c5158Smillert
1539b39c5158SmillertPrevious item in the same group. Wraps around to end of group when the
1540b39c5158Smillertstart of the group is reached. For information on the WS_GROUP style,
1541b39c5158Smillertsee Window Styles.
1542b39c5158Smillert
1543b39c5158Smillert=item EDI_PREVTABITEM
1544b39c5158Smillert
1545b39c5158SmillertPrevious item with style WS_TABSTOP. Wraps around to end of dialog
1546b39c5158Smillertitem list when beginning is reached.
1547b39c5158Smillert
1548b39c5158Smillert=back
1549b39c5158Smillert
1550b39c5158Smillert=item DesktopWindow()
1551b39c5158Smillert
1552b39c5158Smillertgets the actual window handle of the PM desktop; most APIs accept the
1553b39c5158Smillertpseudo-handle C<HWND_DESKTOP> instead.  Keep in mind that the WPS
1554b39c5158Smillertdesktop (one with WindowText() being C<"Desktop">) is a different beast?!
1555b39c5158Smillert
1556b39c5158Smillert=item TopLevel($hwnd)
1557b39c5158Smillert
1558b39c5158Smillertgets the toplevel window of $hwnd.
1559b39c5158Smillert
1560b39c5158Smillert=item ResetWinError()
1561b39c5158Smillert
1562b39c5158SmillertResets $^E.  One may need to call it before the C<Win*>-class APIs which may
1563b39c5158Smillertreturn 0 during normal operation.  In such a case one should check both
1564b39c5158Smillertfor return value being zero and $^E being non-zero.  The following APIs
1565b39c5158Smillertdo ResetWinError() themselves, thus do not need an explicit one:
1566b39c5158Smillert
1567b39c5158Smillert  WindowPtr
1568b39c5158Smillert  WindowULong
1569b39c5158Smillert  WindowUShort
1570b39c5158Smillert  WindowTextLength
1571b39c5158Smillert  ActiveWindow
1572b39c5158Smillert  PostMsg
1573b39c5158Smillert
1574b39c5158SmillertThis function is normally not needed.  Not exported by default.
1575b39c5158Smillert
1576b39c5158Smillert=back
1577b39c5158Smillert
1578b39c5158Smillert=head2 Control of the PM data
1579b39c5158Smillert
1580b39c5158Smillert=over
1581b39c5158Smillert
1582b39c5158Smillert=item ActiveDesktopPathname()
1583b39c5158Smillert
1584b39c5158Smillertgets the path of the directory which corresponds to Desktop.
1585b39c5158Smillert
1586b39c5158Smillert=item 	InvalidateRect
1587b39c5158Smillert
1588b39c5158Smillert=item	CreateFrameControls
1589b39c5158Smillert
1590b39c5158Smillert=back
1591b39c5158Smillert
1592b39c5158Smillert=head2 Control of the PM clipboard
1593b39c5158Smillert
1594b39c5158Smillert=over
1595b39c5158Smillert
1596b39c5158Smillert=item ClipbrdText()
1597b39c5158Smillert
1598b39c5158Smillertgets the content of the clipboard.  An optional argument is the format
1599b39c5158Smillertof the data in the clipboard (defaults to C<CF_TEXT>).  May croak with error
1600b39c5158SmillertC<PMERR_INVALID_HWND> if no data of given $fmt is present.
1601b39c5158Smillert
1602b39c5158SmillertNote that the usual convention is to have clipboard data with
1603b39c5158SmillertC<"\r\n"> as line separators.  This function will only work with clipboard
1604b39c5158Smillertdata types which are delimited by C<"\0"> byte (not included in the result).
1605b39c5158Smillert
1606b39c5158Smillert=item ClipbrdText_2byte
1607b39c5158Smillert
1608b39c5158SmillertSame as ClipbrdText(), but will only work with clipboard
1609b39c5158Smillertdata types which are collection of C C<shorts> delimited by C<0> short
1610b39c5158Smillert(not included in the result).
1611b39c5158Smillert
1612b39c5158Smillert=item ClipbrdTextUCS2le
1613b39c5158Smillert
1614b39c5158SmillertSame as ClipbrdText_2byte(), but will assume that the shorts represent
1615b39c5158Smillertan Unicode string in I<UCS-2le> format (little-endian 2-byte representation
1616b39c5158Smillertof Unicode), and will provide the result in Perl internal C<utf8> format
1617b39c5158Smillert(one short of input represents one Perl character).
1618b39c5158Smillert
1619b39c5158SmillertNote that Firefox etc. export their selection in unicode types of this format.
1620b39c5158Smillert
1621b39c5158Smillert=item ClipbrdText_set($txt, [$no_convert_nl, [$fmt, [$fmtinfo, [$hab] ] ] ] )
1622b39c5158Smillert
1623b39c5158Smillertsets the text content of the clipboard after removing old contents.  Unless the
1624b39c5158Smillertoptional argument  $no_convert_nl is TRUE, will convert newlines to C<"\r\n">.  Another optional
1625b39c5158Smillertargument $fmt is the format of the data in the clipboard (should be an
1626b39c5158Smillertatom, defaults to C<CF_TEXT>).  Other arguments are as for C<ClipbrdData_set>.
1627b39c5158SmillertCroaks on failure.
1628b39c5158Smillert
1629b39c5158Smillert=item	ClipbrdFmtInfo( [$fmt, [ $hab ] ])
1630b39c5158Smillert
1631b39c5158Smillertreturns the $fmtInfo flags set by the application which filled the
1632b39c5158Smillertformat $fmt of the clipboard.  $fmt defaults to C<CF_TEXT>.
1633b39c5158Smillert
1634b39c5158Smillert=item	ClipbrdOwner( [ $hab ] )
1635b39c5158Smillert
1636b39c5158SmillertReturns window handle of the current clipboard owner.
1637b39c5158Smillert
1638b39c5158Smillert=item	ClipbrdViewer( [ $hab ] )
1639b39c5158Smillert
1640b39c5158SmillertReturns window handle of the current clipboard viewer.
1641b39c5158Smillert
1642b39c5158Smillert=item	ClipbrdData( [$fmt, [ $hab ] ])
1643b39c5158Smillert
1644b39c5158SmillertReturns a handle to clipboard data of the given format as an integer.
1645b39c5158SmillertFormat defaults to C<CF_TEXT> (in this case the handle is a memory address).
1646b39c5158Smillert
1647b39c5158SmillertClipboard should be opened before calling this function.  May croak with error
1648b39c5158SmillertC<PMERR_INVALID_HWND> if no data of given $fmt is present.
1649b39c5158Smillert
1650b39c5158SmillertThe result should not be used after clipboard is closed.  Hence a return handle
1651b39c5158Smillertof type C<CLI_POINTER> may need to be converted to a string and stored for
1652b39c5158Smillertfuture usage.  Use MemoryRegionSize() to get a high estimate on the length
1653b39c5158Smillertof region addressed by this pointer; the actual length inside this region
1654b39c5158Smillertshould be obtained by knowing particular format of data.  E.g., it may be
1655b39c5158Smillert0-byte terminated for string types, or 0-short terminated for wide-char string
1656b39c5158Smillerttypes.
1657b39c5158Smillert
1658b39c5158Smillert=item	OpenClipbrd( [ $hab ] )
1659b39c5158Smillert
1660b39c5158Smillertclaim read access to the clipboard.  May need a message queue to operate.
1661b39c5158SmillertMay block until other processes finish dealing with clipboard.
1662b39c5158Smillert
1663b39c5158Smillert=item	CloseClipbrd( [ $hab ] )
1664b39c5158Smillert
1665b39c5158SmillertAllow other processes access to clipboard.
1666b39c5158SmillertClipboard should be opened before calling this function.
1667b39c5158Smillert
1668b39c5158Smillert=item	ClipbrdData_set($data, [$convert_nl, [$fmt, [$fmtInfo, [ $hab] ] ] ] )
1669b39c5158Smillert
1670b39c5158SmillertSets the clipboard data of format given by atom $fmt.  Format defaults to
1671b39c5158SmillertCF_TEXT.
1672b39c5158Smillert
1673b39c5158Smillert$fmtInfo should declare what type of handle $data is; it should be either
1674b39c5158SmillertC<CFI_POINTER>, or C<CFI_HANDLE> (possibly qualified by C<CFI_OWNERFREE>
1675b39c5158Smillertand C<CFI_OWNERDRAW> flags).  It defaults to C<CFI_HANDLE> for $fmt being
1676b39c5158Smillertstandard bitmap, metafile, and palette (undocumented???) formats;
1677b39c5158Smillertotherwise defaults to C<CFI_POINTER>.  If format is C<CFI_POINTER>, $data
1678b39c5158Smillertshould contain the string to copy to clipboard; otherwise it should be an
1679b39c5158Smillertinteger handle.
1680b39c5158Smillert
1681b39c5158SmillertIf $convert_nl is TRUE (the default), C<"\n"> in $data are converted to
1682b39c5158SmillertC<"\r\n"> pairs if $fmt is C<CFI_POINTER> (as is the convention for text
1683b39c5158Smillertformat of the clipboard) unless they are already in such a pair.
1684b39c5158Smillert
1685b39c5158Smillert=item	_ClipbrdData_set($data, [$fmt, [$fmtInfo, [ $hab] ] ] )
1686b39c5158Smillert
1687b39c5158SmillertSets the clipboard data of format given by atom $fmt.  Format defaults to
1688b39c5158SmillertCF_TEXT.  $data should be an address (in givable unnamed shared memory which
1689b39c5158Smillertshould not be accessed or manipulated after this call) or a handle in a form
1690b39c5158Smillertof an integer.
1691b39c5158Smillert
1692b39c5158Smillert$fmtInfo has the same semantic as for ClipbrdData_set().
1693b39c5158Smillert
1694b39c5158Smillert=item	ClipbrdOwner_set( $hwnd, [ $hab ] )
1695b39c5158Smillert
1696b39c5158SmillertSets window handle of the current clipboard owner (window which gets messages
1697b39c5158Smillertwhen content of clipboard is retrieved).
1698b39c5158Smillert
1699b39c5158Smillert=item	ClipbrdViewer_set( $hwnd, [ $hab ] )
1700b39c5158Smillert
1701b39c5158SmillertSets window handle of the current clipboard owner (window which gets messages
1702b39c5158Smillertwhen content of clipboard is changed).
1703b39c5158Smillert
1704b39c5158Smillert=item	ClipbrdFmtNames()
1705b39c5158Smillert
1706b39c5158SmillertReturns list of names of formats currently available in the clipboard.
1707b39c5158Smillert
1708b39c5158Smillert=item	ClipbrdFmtAtoms()
1709b39c5158Smillert
1710b39c5158SmillertReturns list of atoms of formats currently available in the clipboard.
1711b39c5158Smillert
1712b39c5158Smillert=item	EnumClipbrdFmts($fmt [, $hab])
1713b39c5158Smillert
1714b39c5158SmillertLow-level access to the list of formats currently available in the clipboard.
1715b39c5158SmillertReturns the atom for the format of clipboard after $fmt.  If $fmt is 0, returns
1716b39c5158Smillertthe first format of clipboard.  Returns 0 if $fmt is the last format.  Example:
1717b39c5158Smillert
1718b39c5158Smillert  {
1719b39c5158Smillert    my $h = OS2::localClipbrd->new('nomorph');
1720b39c5158Smillert    my $fmt = 0;
1721b39c5158Smillert    push @formats, AtomName $fmt
1722b39c5158Smillert      while $fmt = EnumClipbrdFmts $fmt;
1723b39c5158Smillert  }
1724b39c5158Smillert
1725b39c5158SmillertClipboard should be opened before calling this function.  May croak if
1726b39c5158Smillertno format is present.
1727b39c5158Smillert
1728b39c5158Smillert=item	EmptyClipbrd( [ $hab ] )
1729b39c5158Smillert
1730b39c5158SmillertRemove all the data handles in the clipboard.  croak()s on failure.
1731b39c5158SmillertClipboard should be opened before calling this function.
1732b39c5158Smillert
1733b39c5158SmillertRecommended before assigning a value to clipboard to remove extraneous
1734b39c5158Smillertformats of data from clipboard.
1735b39c5158Smillert
1736b39c5158Smillert=item ($size, $flags) = MemoryRegionSize($addr, [$size_lim, [ $interrupt ]])
1737b39c5158Smillert
1738b39c5158Smillert$addr should be a memory address (encoded as integer).  This call finds
1739b39c5158Smillertthe largest continuous region of memory belonging to the same memory object
1740b39c5158Smillertas $addr, and having the same memory flags as $addr. $flags is the value of
1741b39c5158Smillertthe memory flag of $addr (see docs of DosQueryMem(3) for details).  If
1742898184e3Ssthenoptional argument $size_lim is given, the search is restricted to the region
1743b39c5158Smillertthis many bytes long (after $addr).
1744b39c5158Smillert
1745b39c5158Smillert($addr and $size are rounded so that all the memory pages containing
1746b39c5158Smillertthe region are inspected.)  Optional argument $interrupt (defaults to 1)
1747898184e3Ssthenspecifies whether region scan should be interruptible by signals.
1748b39c5158Smillert
1749b39c5158Smillert=back
1750b39c5158Smillert
1751b39c5158SmillertUse class C<OS2::localClipbrd> to ensure that clipboard is closed even if
1752b39c5158Smillertthe code in the block made a non-local exit.
1753b39c5158Smillert
175491f110e0Safresh1See the L</OS2::localMorphPM, OS2::localFlashWindow, and OS2::localClipbrd classes>
1755b39c5158Smillert
1756b39c5158Smillert=head2 Control of the PM atom tables
1757b39c5158Smillert
1758b39c5158SmillertLow-level methods to access the atom table(s).  $atomtable defaults to
1759b39c5158Smillertthe SystemAtomTable().
1760b39c5158Smillert
1761b39c5158Smillert=over
1762b39c5158Smillert
1763b39c5158Smillert=item	AddAtom($name, [$atomtable])
1764b39c5158Smillert
1765b39c5158SmillertReturns the atom; increments the use count unless $name is a name of an
1766b39c5158Smillertinteger atom.
1767b39c5158Smillert
1768b39c5158Smillert=item	FindAtom($name, [$atomtable])
1769b39c5158Smillert
1770b39c5158SmillertReturns the atom if it exists, 0 otherwise (actually, croaks).
1771b39c5158Smillert
1772b39c5158Smillert=item	DeleteAtom($name, [$atomtable])
1773b39c5158Smillert
1774b39c5158SmillertDecrements the use count unless $name is a name of an integer atom.
1775b39c5158SmillertWhen count goes to 0, association of the name to an integer is removed.
1776b39c5158Smillert(Version with prepended underscore returns 0 on success.)
1777b39c5158Smillert
1778b39c5158Smillert=item	AtomName($atom, [$atomtable])
1779b39c5158Smillert
1780b39c5158SmillertReturns the name of the atom.  Integer atoms have names of format C<"#ddddd">
1781b39c5158Smillertof variable length up to 7 chars.
1782b39c5158Smillert
1783b39c5158Smillert=item	AtomLength($atom, [$atomtable])
1784b39c5158Smillert
1785b39c5158SmillertReturns the length of the name of the atom.  Return of 0 means that no
1786b39c5158Smillertsuch atom exists (but usually croaks in such a case).
1787b39c5158Smillert
1788b39c5158SmillertInteger atoms always return length 6.
1789b39c5158Smillert
1790b39c5158Smillert=item	AtomUsage($name, [$atomtable])
1791b39c5158Smillert
1792b39c5158SmillertReturns the usage count of the atom.
1793b39c5158Smillert
1794b39c5158Smillert=item	SystemAtomTable()
1795b39c5158Smillert
1796b39c5158SmillertReturns central atom table accessible to any process.
1797b39c5158Smillert
1798b39c5158Smillert=item	CreateAtomTable( [ $initial, [ $buckets ] ] )
1799b39c5158Smillert
1800b39c5158SmillertReturns new per-process atom table.  See docs for WinCreateAtomTable(3).
1801b39c5158Smillert
1802b39c5158Smillert=item	DestroyAtomTable($atomtable)
1803b39c5158Smillert
1804b39c5158SmillertDispose of the table. (Version with prepended underscore returns 0 on success.)
1805b39c5158Smillert
1806b39c5158Smillert
1807b39c5158Smillert=back
1808b39c5158Smillert
1809b39c5158Smillert=head2 Alerting the user
1810b39c5158Smillert
1811b39c5158Smillert=over
1812b39c5158Smillert
1813b39c5158Smillert=item Alarm([$type])
1814b39c5158Smillert
1815b39c5158SmillertAudible alarm of type $type (defaults to C<WA_ERROR=2>).  Other useful
1816b39c5158Smillertvalues are C<WA_WARNING=0>, C<WA_NOTE=1>.  (What is C<WA_CDEFALARMS=3>???)
1817b39c5158Smillert
1818b39c5158SmillertThe duration and frequency of the alarms can be changed by the
1819b39c5158SmillertOS2::SysValues_set(). The alarm frequency is defined to be in the range 0x0025
1820b39c5158Smillertthrough 0x7FFF. The alarm is not generated if system value SV_ALARM is set
1821b39c5158Smillertto FALSE. The alarms are dependent on the device capability.
1822b39c5158Smillert
1823b39c5158Smillert=item FlashWindow($hwnd, $doFlash)
1824b39c5158Smillert
1825b39c5158SmillertStarts/stops (depending on $doFlash being TRUE/FALSE) flashing the window
1826b39c5158Smillert$hwnd's borders and titlebar.  First 5 flashes are accompanied by alarm beeps.
1827b39c5158Smillert
1828b39c5158SmillertExample (for VIO applications):
1829b39c5158Smillert
1830b39c5158Smillert  { my $morph = OS2::localMorphPM->new(0);
1831b39c5158Smillert    print STDERR "Press ENTER!\n";
1832b39c5158Smillert    FlashWindow(process_hwnd, 1);
1833b39c5158Smillert    <>;
1834b39c5158Smillert    FlashWindow(process_hwnd, 0);
1835b39c5158Smillert  }
1836b39c5158Smillert
1837b39c5158SmillertSince flashing window persists even when application ends, it is very
1838b39c5158Smillertimportant to protect the switching off flashing from non-local exits.  Use
1839b39c5158Smillertthe class C<OS2::localFlashWindow> for this.  Creating the object of this
1840b39c5158Smillertclass starts flashing the window until the object is destroyed.  The above
1841b39c5158Smillertexample becomes:
1842b39c5158Smillert
1843b39c5158Smillert  print STDERR "Press ENTER!\n";
1844b39c5158Smillert  { my $flash = OS2::localFlashWindow->new( process_hwnd );
1845b39c5158Smillert    <>;
1846b39c5158Smillert  }
1847b39c5158Smillert
1848b39c5158SmillertB<Notes from IBM docs:> Flashing a window brings the user's attention to a
1849b39c5158Smillertwindow that is not the active window, where some important message or dialog
1850b39c5158Smillertmust be seen by the user.
1851b39c5158Smillert
1852b39c5158SmillertNote:  It should be used only for important messages, for example, where some
1853b39c5158Smillertcomponent of the system is failing and requires immediate attention to avoid
1854b39c5158Smillertdamage.
1855b39c5158Smillert
1856b39c5158Smillert=item MessageBox($text, [ $title, [$flags, ...] ])
1857b39c5158Smillert
1858b39c5158SmillertShows a simple messagebox with (optional) icon, message $text, and one or
1859b39c5158Smillertmore buttons to dismiss the box.  Returns the indicator of which action was
1860b39c5158Smillerttaken by the user.  If optional argument $title is not given,
1861b39c5158Smillertthe title is constructed from the application name.  The optional argument
1862b39c5158Smillert$flags describes the appearance of the box; the default is to have B<Cancel>
1863b39c5158Smillertbutton, I<INFO>-style icon, and a border for moving.  Flags should be
1864b39c5158Smillerta combination of
1865b39c5158Smillert
1866b39c5158Smillert Buttons on the box: or Button Group
1867b39c5158Smillert     MB_OK                 OK
1868b39c5158Smillert     MB_OKCANCEL           both OK and CANCEL
1869b39c5158Smillert     MB_CANCEL             CANCEL
1870b39c5158Smillert     MB_ENTER              ENTER
1871b39c5158Smillert     MB_ENTERCANCEL        both ENTER and CANCEL
1872b39c5158Smillert     MB_RETRYCANCEL        both RETRY and CANCEL
1873b39c5158Smillert     MB_ABORTRETRYIGNORE   ABORT, RETRY, and IGNORE
1874b39c5158Smillert     MB_YESNO              both YES and NO
1875b39c5158Smillert     MB_YESNOCANCEL        YES, NO, and CANCEL
1876b39c5158Smillert
1877b39c5158Smillert Color or Icon
1878b8851fccSafresh1     MB_ICONHAND           a small red circle with a red line across
1879b8851fccSafresh1                           it.
1880b8851fccSafresh1     MB_ERROR              a small red circle with a red line across
1881b8851fccSafresh1                           it.
1882b39c5158Smillert     MB_ICONASTERISK       an information (i) icon.
1883b39c5158Smillert     MB_INFORMATION        an information (i) icon.
1884b39c5158Smillert     MB_ICONEXCLAMATION    an exclamation point (!) icon.
1885b39c5158Smillert     MB_WARNING            an exclamation point (!) icon.
1886b39c5158Smillert     MB_ICONQUESTION       a question mark (?) icon.
1887b39c5158Smillert     MB_QUERY              a question mark (?) icon.
1888b39c5158Smillert     MB_NOICON             No icon.
1889b39c5158Smillert
1890b39c5158Smillert Default action (i.e., focussed button; default is MB_DEFBUTTON1)
1891b8851fccSafresh1     MB_DEFBUTTON1         The first button is the default
1892b8851fccSafresh1                           selection.
1893b8851fccSafresh1     MB_DEFBUTTON2         The second button is the default
1894b8851fccSafresh1                           selection.
1895b8851fccSafresh1     MB_DEFBUTTON3         The third button is the default
1896b8851fccSafresh1                           selection.
1897b39c5158Smillert
1898b39c5158Smillert Modality indicator
1899b8851fccSafresh1     MB_APPLMODAL                  Message box is application modal
1900b8851fccSafresh1                                   (default).
1901b39c5158Smillert     MB_SYSTEMMODAL                Message box is system modal.
1902b39c5158Smillert
1903b39c5158Smillert Mobility indicator
1904b39c5158Smillert     MB_MOVEABLE                   Message box is moveable.
1905b39c5158Smillert
1906b39c5158SmillertWith C<MB_MOVEABLE> the message box is displayed with a title bar and a
1907b39c5158Smillertsystem menu, which shows only the Move, Close, and Task Manager choices,
1908b39c5158Smillertwhich can be selected either by use of the pointing device or by
1909b39c5158Smillertaccelerator keys.  If the user selects Close, the message box is removed
1910b39c5158Smillertand the usResponse is set to C<MBID_CANCEL>, whether or not a cancel button
1911b39c5158Smillertexisted within the message box.
1912b39c5158Smillert
1913b39c5158SmillertC<Esc> key dismisses the dialogue only if C<CANCEL> button is present; the
1914b39c5158Smillertreturn value is C<MBID_CANCEL>.
1915b39c5158Smillert
1916b39c5158SmillertWith C<MB_APPLMODAL> the owner of the dialogue is disabled; therefore, do not
1917b39c5158Smillertspecify the owner as the parent if this option is used.
1918b39c5158Smillert
1919b39c5158SmillertAdditionally, the following flag is possible, but probably not very useful:
1920b39c5158Smillert
1921b39c5158Smillert Help button
1922b39c5158Smillert     MB_HELP            a HELP button appears, which sends a WM_HELP
1923b8851fccSafresh1                        message is sent to the window procedure of
1924b8851fccSafresh1                        the message box.
1925b39c5158Smillert
1926b39c5158SmillertOther optional arguments: $parent window, $owner_window, $helpID (used with
1927b39c5158SmillertC<WM_HELP> message if C<MB_HELP> style is given).
1928b39c5158Smillert
1929b39c5158SmillertThe return value is one of
1930b39c5158Smillert
1931b39c5158Smillert  MBID_ENTER           ENTER was selected
1932b39c5158Smillert  MBID_OK              OK was selected
1933b39c5158Smillert  MBID_CANCEL          CANCEL was selected
1934b39c5158Smillert  MBID_ABORT           ABORT was selected
1935b39c5158Smillert  MBID_RETRY           RETRY was selected
1936b39c5158Smillert  MBID_IGNORE          IGNORE was selected
1937b39c5158Smillert  MBID_YES             YES was selected
1938b39c5158Smillert  MBID_NO              NO was selected
1939b39c5158Smillert
1940b39c5158Smillert  0                    Function not successful; an error occurred.
1941b39c5158Smillert
1942b39c5158SmillertB<BUGS???> keyboard transversal by pressing C<TAB> key does not work.
1943b39c5158SmillertDo not appear in window list, so may be hard to find if covered by other
1944b39c5158Smillertwindows.
1945b39c5158Smillert
1946b39c5158Smillert=item _MessageBox($text, [ $title, [$flags, ...] ])
1947b39c5158Smillert
1948b39c5158SmillertSimilar to MessageBox(), but the default $title does not depend on the name
1949b39c5158Smillertof the script.
1950b39c5158Smillert
1951b39c5158Smillert=item MessageBox2($text, [ $buttons_Icon, [$title, ...] ])
1952b39c5158Smillert
1953b39c5158SmillertSimilar to MessageBox(), but allows more flexible choice of button texts
1954b39c5158Smillertand the icon. $buttons_Icon is a reference to an array with information about
1955b39c5158Smillertbuttons and the icon to use; the semantic of this array is the same as
1956b39c5158Smillertfor argument list of process_MB2_INFO().  The default value will show
1957b39c5158Smillertone button B<Dismiss> which will return C<0x1000>.
1958b39c5158Smillert
1959b39c5158SmillertOther optional arguments are the same as for MessageBox().
1960b39c5158Smillert
1961b39c5158SmillertB<NOTE.> Remark about C<MBID_CANCEL> in presence of C<MB_MOVABLE> is
1962b39c5158Smillertequally applicable to MessageBox() and MessageBox2().
1963b39c5158Smillert
1964b39c5158SmillertExample:
1965b39c5158Smillert
1966b39c5158Smillert  print MessageBox2
1967b39c5158Smillert    'Foo prints 100, Bar 101, Baz 102',
1968b39c5158Smillert    [['~Foo' => 100, 'B~ar' => 101, ['Ba~z'] => 102]],
1969b39c5158Smillert    'Choose a number to print';
1970b39c5158Smillert
1971b39c5158Smillertwill show a messagebox with
1972b39c5158Smillert
1973b39c5158Smillert=over 20
1974b39c5158Smillert
1975b39c5158Smillert=item Title
1976b39c5158Smillert
1977b39c5158SmillertB<Choose a number to print>,
1978b39c5158Smillert
1979b39c5158Smillert=item Text
1980b39c5158Smillert
1981b39c5158SmillertB<Foo prints 100, Bar 101, Baz 102>
1982b39c5158Smillert
1983b39c5158Smillert=item Icon
1984b39c5158Smillert
1985b39c5158SmillertINFORMATION ICON
1986b39c5158Smillert
1987b39c5158Smillert=item Buttons
1988b39c5158Smillert
1989b39c5158SmillertB<Foo>, B<Bar>, B<Baz>
1990b39c5158Smillert
1991b39c5158Smillert=item Default button
1992b39c5158Smillert
1993b39c5158SmillertB<Baz>
1994b39c5158Smillert
1995b39c5158Smillert=item accelerator keys
1996b39c5158Smillert
1997b39c5158SmillertB<F>, B<a>, and B<z>
1998b39c5158Smillert
1999b39c5158Smillert=item return values
2000b39c5158Smillert
2001b39c5158Smillert100, 101, and 102 correspondingly,
2002b39c5158Smillert
2003b39c5158Smillert=back
2004b39c5158Smillert
2005b39c5158SmillertUsing
2006b39c5158Smillert
2007b39c5158Smillert  print MessageBox2
2008b39c5158Smillert    'Foo prints 100, Bar 101, Baz 102',
2009b39c5158Smillert    [['~Foo' => 100, 'B~ar' => 101, ['Ba~z'] => 102], 'SP#22'],
2010b39c5158Smillert    'Choose a number to print';
2011b39c5158Smillert
2012b39c5158Smillertwill show the 22nd system icon as the dialog icon (small folder icon).
2013b39c5158Smillert
2014b39c5158Smillert=item _MessageBox2($text, $buttons_Icon_struct, [$title, ...])
2015b39c5158Smillert
20166fb12b70Safresh1low-level workhorse to implement MessageBox2().  Differs by the default
2017b39c5158Smillert$title, and that $buttons_Icon_struct is required, and is a string with
2018b39c5158Smillertlow-level C struct.
2019b39c5158Smillert
2020b39c5158Smillert=item process_MB2_INFO($buttons, [$iconID, [$flags, [$notifyWindow]]])
2021b39c5158Smillert
2022b39c5158Smillertlow-level workhorse to implement MessageBox2(); calculates the second
2023b39c5158Smillertargument of _MessageBox2().  $buttons is a reference
2024b39c5158Smillertto array of button descriptions.  $iconID is either an ID of icon for
2025b39c5158Smillertthe message box, or a string of the form C<"SP#number">; in the latter case
2026b39c5158Smillertthe number's system icon is chosen; this field is ignored unless
2027b39c5158Smillert$flags contains C<MB_CUSTOMICON> flag.  $flags has the same meaning as mobility,
2028b39c5158Smillertmodality, and icon flags for MessageBox() with addition of extra flags
2029b39c5158Smillert
2030b39c5158Smillert     MB_CUSTOMICON         Use a custom icon specified in hIcon.
2031b39c5158Smillert     MB_NONMODAL           Message box is nonmodal
2032b39c5158Smillert
2033b39c5158Smillert$flags defaults to C<MB_INFORMATION> or C<MB_CUSTOMICON> (depending on whether
2034b39c5158Smillert$iconID is non-0), combined with MB_MOVABLE.
2035b39c5158Smillert
2036b39c5158SmillertEach button's description takes two elements of the description array,
2037b39c5158Smillertappearance description, and the return value of MessageBox2() if this
2038b39c5158Smillertbutton is selected.  The appearance description is either an array reference
2039b39c5158Smillertof the form C<[$button_Text, $button_Style]>, or the same without
2040b39c5158Smillert$button_Style (then style is C<BS_DEFAULT>, making this button the default)
2041b39c5158Smillertor just $button_Text (with "normal" style).  E.g., the list
2042b39c5158Smillert
2043b39c5158Smillert  Foo => 100, Bar => 101, [Baz] => 102
2044b39c5158Smillert
2045b39c5158Smillertwill show three buttons B<Foo>, B<Bar>, B<Baz> with B<Baz> being the default
2046b39c5158Smillertbutton; pressing buttons return 100, 101, or 102 correspondingly.
2047b39c5158Smillert
2048b39c5158SmillertIn particular, exactly one button should have C<BS_DEFAULT> style (e.g.,
2049b39c5158Smillertgiven as C<[$button_Name]>); otherwise the message box will not have keyboard
2050b39c5158Smillertfocus!  (The only exception is the case of one button; then C<[$button_Name]>
2051b39c5158Smillertcan be replaced (for convenience) with plain C<$button_Name>.)
2052b39c5158Smillert
2053b39c5158SmillertIf text of the button contains character C<~>, the following character becomes
2054b39c5158Smillertthe keyboard accelerator for this button.  One can also get the handle
2055b39c5158Smillertof system icons directly, so C<'SP#22'> can be replaced by
2056b39c5158SmillertC<OS2::Process::get_pointer(22)>; see also C<SPTR_*> constants.
2057b39c5158Smillert
2058b39c5158SmillertB<NOTE> With C<MB_NONMODAL> the program continues after displaying the
2059b39c5158Smillertnonmodal message box.  The message box remains visible until the owner window
2060b39c5158Smillertdestroys it. Two notification messages, WM_MSGBOXINIT and WM_MSGBOXDISMISS,
2061b39c5158Smillertare used to support this non-modality.
2062b39c5158Smillert
2063b39c5158Smillert=item LoadPointer($id, [$module, [$hwnd]])
2064b39c5158Smillert
2065b39c5158SmillertLoads a handle for the pointer $id from the resources of the module
2066b39c5158Smillert$module on desktop $hwnd.  If $module is 0 (default), loads from the main
2067b39c5158Smillertexecutable; otherwise from a DLL with the handle $module.
2068b39c5158Smillert
2069b39c5158SmillertThe pointer is owned by the process, and is destroyed by
2070b39c5158SmillertDestroyPointer() call, or when the process terminates.
2071b39c5158Smillert
2072b39c5158Smillert=item SysPointer($id, [$copy, [$hwnd]])
2073b39c5158Smillert
2074b39c5158SmillertGets a handle for (a copy of) the system pointer $id (the value should
2075b39c5158Smillertbe one of C<SPTR_*> constants).  A copy is made if $copy is TRUE (the
2076b39c5158Smillertdefault).  $hwnd defaults to C<HWND_DESKTOP>.
2077b39c5158Smillert
2078b39c5158Smillert=item get_pointer($id, [$copy, [$hwnd]])
2079b39c5158Smillert
2080b39c5158SmillertGets (and caches) a copy of the system pointer.
2081b39c5158Smillert
2082b39c5158Smillert=back
2083b39c5158Smillert
2084b39c5158Smillert=head2 Constants used by OS/2 APIs
2085b39c5158Smillert
2086b39c5158SmillertFunction C<os2constant($name)> returns the value of the constant; to
2087b39c5158Smillertdecrease the memory usage of this package, only the constants used by
2088b39c5158SmillertAPIs called by Perl functions in this package are made available.
2089b39c5158Smillert
2090b39c5158SmillertFor direct access, see also the L<"EXPORTS"> section; the latter way
2091b39c5158Smillertmay also provide some performance advantages, since the value of the
2092b39c5158Smillertconstant is cached.
2093b39c5158Smillert
2094898184e3Ssthen=head1 OS2::localMorphPM, OS2::localFlashWindow, and OS2::localClipbrd classes
2095b39c5158Smillert
2096b39c5158SmillertThe class C<OS2::localMorphPM> morphs the process to PM for the duration of
2097b39c5158Smillertthe given scope.
2098b39c5158Smillert
2099b39c5158Smillert  {
2100b39c5158Smillert    my $h = OS2::localMorphPM->new(0);
2101b39c5158Smillert    # Do something
2102b39c5158Smillert  }
2103b39c5158Smillert
2104b39c5158SmillertThe argument has the same meaning as one to OS2::MorphPM().  Calls can
2105b39c5158Smillertnest with internal ones being NOPs.
2106b39c5158Smillert
2107b39c5158SmillertLikewise, C<OS2::localClipbrd> class opens the clipboard for the duration
2108b39c5158Smillertof the current scope; if TRUE optional argument is given, it would not
2109b39c5158Smillertmorph the application into PM:
2110b39c5158Smillert
2111b39c5158Smillert  {
2112b39c5158Smillert    my $handle = OS2::localClipbrd->new(1);	# Do not morph into PM
2113b39c5158Smillert    # Do something with clipboard here...
2114b39c5158Smillert  }
2115b39c5158Smillert
2116b39c5158SmillertC<OS2::localFlashWindow> behaves similarly; see
2117b39c5158SmillertL<FlashWindow($hwnd, $doFlash)>.
2118b39c5158Smillert
2119b39c5158Smillert=head1 EXAMPLES
2120b39c5158Smillert
2121b39c5158SmillertThe test suite for this module contains an almost comprehensive collection
2122b39c5158Smillertof examples of using the API of this module.
2123b39c5158Smillert
2124b39c5158Smillert=head1 TODO
2125b39c5158Smillert
2126b39c5158SmillertAdd tests for:
2127b39c5158Smillert
2128b39c5158Smillert	SwitchToProgram
2129b39c5158Smillert	ClassName
2130b39c5158Smillert	out_codepage
2131b39c5158Smillert	out_codepage_set
2132b39c5158Smillert	in_codepage
2133b39c5158Smillert	in_codepage_set
2134b39c5158Smillert	cursor
2135b39c5158Smillert	cursor_set
2136b39c5158Smillert	screen
2137b39c5158Smillert	screen_set
2138b39c5158Smillert	process_codepages
2139b39c5158Smillert	QueryWindow
2140b39c5158Smillert	EnumDlgItem
2141b39c5158Smillert        WindowPtr
2142b39c5158Smillert        WindowUShort
2143b39c5158Smillert        SetWindowBits
2144b39c5158Smillert        SetWindowPtr
2145b39c5158Smillert        SetWindowULong
2146b39c5158Smillert        SetWindowUShort
2147b39c5158Smillert	my_type
2148b39c5158Smillert	file_type
2149b39c5158Smillert	scrsize
2150b39c5158Smillert	scrsize_set
2151b39c5158Smillert
2152b39c5158SmillertDocument: InvalidateRect,
2153b39c5158SmillertCreateFrameControls, kbdChar, kbdhChar,
2154b39c5158SmillertkbdStatus, _kbdStatus_set, kbdhStatus, kbdhStatus_set,
2155b39c5158SmillertvioConfig, viohConfig, vioMode, viohMode, viohMode_set, _vioMode_set,
2156b39c5158Smillert_vioState, _vioState_set, vioFont, vioFont_set
2157b39c5158Smillert
2158b39c5158SmillertTest: SetWindowULong/Short/Ptr, SetWindowBits. InvalidateRect,
2159b39c5158SmillertCreateFrameControls, ClipbrdOwner_set, ClipbrdViewer_set, _ClipbrdData_set,
2160b39c5158SmillertAlarm, FlashWindow, _MessageBox, MessageBox, _MessageBox2, MessageBox2,
2161b39c5158SmillertLoadPointer, SysPointer, kbdChar, kbdhChar, kbdStatus, _kbdStatus_set,
2162b39c5158SmillertkbdhStatus,  kbdhStatus_set, vioConfig, viohConfig, vioMode, viohMode,
2163b39c5158SmillertviohMode_set, _vioMode_set, _vioState, _vioState_set, vioFont, vioFont_set
2164b39c5158Smillert
2165b39c5158SmillertImplement SOMETHINGFROMMR.
2166b39c5158Smillert
2167b39c5158Smillert
2168b39c5158Smillert  >But I wish to change the default button if the user enters some
2169b39c5158Smillert  >text into an entryfield.  I can detect the entry ok, but can't
2170b39c5158Smillert  >seem to get the button to change to default.
2171b39c5158Smillert  >
2172b39c5158Smillert  >No matter what message I send it, it's being ignored.
2173b39c5158Smillert
2174b8851fccSafresh1  You need to get the style of the buttons using
2175b8851fccSafresh1  WinQueryWindowULong/QWL_STYLE, set and reset the BS_DEFAULT bits as
2176b8851fccSafresh1  appropriate and then use WinSetWindowULong/QWL_STYLE to set the
2177b8851fccSafresh1  button style.  Something like this:
2178b39c5158Smillert    hwnd1 = WinWindowFromID (hwnd, id1);
2179b39c5158Smillert    hwnd2 = WinWindowFromID (hwnd, id2);
2180b39c5158Smillert    style1 = WinQueryWindowULong (hwnd1, QWL_STYLE);
2181b39c5158Smillert    style2 = WinQueryWindowULong (hwnd2, QWL_STYLE);
2182b39c5158Smillert    style1 |= style2 & BS_DEFAULT;
2183b39c5158Smillert    style2 &= ~BS_DEFAULT;
2184b39c5158Smillert    WinSetWindowULong (hwnd1, QWL_STYLE, style1);
2185b39c5158Smillert    WinSetWindowULong (hwnd2, QWL_STYLE, style2);
2186b39c5158Smillert
2187b8851fccSafresh1 > How to do query and change a frame creation flags for existing
2188b8851fccSafresh1 > window?
2189b39c5158Smillert
2190b39c5158Smillert Set the style bits that correspond to the FCF_* flag for the frame
2191b8851fccSafresh1 window and then send a WM_UPDATEFRAME message with the appropriate
2192b8851fccSafresh1 FCF_* flag in mp1.
2193b39c5158Smillert
2194b39c5158Smillert ULONG ulFrameStyle;
2195b39c5158Smillert ulFrameStyle = WinQueryWindowULong( WinQueryWindow(hwnd, QW_PARENT),
2196b39c5158Smillert QWL_STYLE );
2197b39c5158Smillert ulFrameStyle = (ulFrameStyle & ~FS_SIZEBORDER) | FS_BORDER;
2198b39c5158Smillert WinSetWindowULong(   WinQueryWindow(hwnd, QW_PARENT),
2199b39c5158Smillert                      QWL_STYLE,
2200b39c5158Smillert                      ulFrameStyle );
2201b39c5158Smillert WinSendMsg( WinQueryWindow(hwnd, QW_PARENT),
2202b39c5158Smillert             WM_UPDATEFRAME,
2203b39c5158Smillert             MPFROMP(FCF_SIZEBORDER),
2204b39c5158Smillert             MPVOID );
2205b39c5158Smillert
2206b8851fccSafresh1 If the FCF_* flags you want to change does not have a corresponding
2207b8851fccSafresh1 FS_* style (i.e. the FCF_* flag corresponds to the presence/lack of a
2208b8851fccSafresh1 frame control rather than a property of the frame itself) then you
2209b8851fccSafresh1 create or destroy the appropriate control window using the correct
2210b8851fccSafresh1 FID_* window identifier and then send the WM_UPDATEFRAME message with
2211b8851fccSafresh1 the appropriate FCF_* flag in mp1.
2212b39c5158Smillert
2213b8851fccSafresh1 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
2214b39c5158Smillert  |  SetFrameBorder()                                                 |
2215b39c5158Smillert  |    Changes a frame window's border to the requested type.         |
2216b39c5158Smillert  |                                                                   |
2217b39c5158Smillert  |  Parameters on entry:                                             |
2218b39c5158Smillert  |    hwndFrame     -> Frame window whose border is to be changed.   |
2219b39c5158Smillert  |    ulBorderStyle -> Type of border to change to.                  |
2220b39c5158Smillert  |                                                                   |
2221b39c5158Smillert  |  Returns:                                                         |
2222b39c5158Smillert  |    BOOL          -> Success indicator.                            |
2223b39c5158Smillert  |                                                                   |
2224b8851fccSafresh1  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2225b39c5158Smillert BOOL SetFrameBorder( HWND hwndFrame, ULONG ulBorderType )  {
2226b39c5158Smillert   ULONG  ulFrameStyle;
2227b39c5158Smillert   BOOL   fSuccess = TRUE;
2228b39c5158Smillert
2229b39c5158Smillert   ulFrameStyle = WinQueryWindowULong( hwndFrame, QWL_STYLE );
2230b39c5158Smillert
2231b39c5158Smillert   switch ( ulBorderType )  {
2232b39c5158Smillert     case FS_SIZEBORDER :
2233b39c5158Smillert       ulFrameStyle = (ulFrameStyle & ~(FS_DLGBORDER | FS_BORDER))
2234b39c5158Smillert                      | FS_SIZEBORDER;
2235b39c5158Smillert       break;
2236b39c5158Smillert
2237b39c5158Smillert     case FS_DLGBORDER :
2238b39c5158Smillert       ulFrameStyle = (ulFrameStyle & ~(FS_SIZEBORDER | FS_BORDER))
2239b39c5158Smillert                      | FS_DLGBORDER;
2240b39c5158Smillert       break;
2241b39c5158Smillert
2242b39c5158Smillert     case FS_BORDER :
2243b39c5158Smillert       ulFrameStyle = (ulFrameStyle & ~(FS_SIZEBORDER | FS_DLGBORDER))
2244b39c5158Smillert                      | FS_BORDER;
2245b39c5158Smillert       break;
2246b39c5158Smillert
2247b39c5158Smillert     default :
2248b39c5158Smillert       fSuccess = FALSE;
2249b39c5158Smillert       break;
2250b39c5158Smillert   }  // end switch
2251b39c5158Smillert
2252b39c5158Smillert   if ( fSuccess )  {
2253b39c5158Smillert     fSuccess = WinSetWindowULong( hwndFrame, QWL_STYLE, ulFrameStyle );
2254b39c5158Smillert
2255b39c5158Smillert     if ( fSuccess )  {
2256b39c5158Smillert       fSuccess = (BOOL)WinSendMsg( hwndFrame, WM_UPDATEFRAME, 0, 0 );
2257b39c5158Smillert       if ( fSuccess )
2258b39c5158Smillert         fSuccess = WinInvalidateRect( hwndFrame, NULL, TRUE );
2259b39c5158Smillert     }
2260b39c5158Smillert   }
2261b39c5158Smillert
2262b39c5158Smillert   return ( fSuccess );
2263b39c5158Smillert
2264b39c5158Smillert }  // End SetFrameBorder()
2265b39c5158Smillert
2266b39c5158Smillert         hwndMenu=WinLoadMenu(hwndParent,NULL,WND_IMAGE);
2267b39c5158Smillert         WinSetWindowUShort(hwndMenu,QWS_ID,FID_MENU);
2268b39c5158Smillert         ulStyle=WinQueryWindowULong(hwndMenu,QWL_STYLE);
2269b39c5158Smillert         WinSetWindowULong(hwndMenu,QWL_STYLE,ulStyle|MS_ACTIONBAR);
2270b39c5158Smillert         WinSendMsg(hwndParent,WM_UPDATEFRAME,MPFROMSHORT(FCF_MENU),0L);
2271b39c5158Smillert
2272b39c5158Smillert  OS/2-windows have another "parent" called the *owner*,
2273b39c5158Smillert  which must be set separately - to get a close relationship:
2274b39c5158Smillert
2275b39c5158Smillert    WinSetOwner (hwndFrameChild, hwndFrameMain);
2276b39c5158Smillert
2277b39c5158Smillert  Now your child should move with your main window!
2278b39c5158Smillert  And always stays on top of it....
2279b39c5158Smillert
2280b39c5158Smillert  To avoid this, for example for dialogwindows, you can
2281b39c5158Smillert  also "disconnect" this relationship with:
2282b39c5158Smillert
2283b39c5158Smillert    WinSetWindowBits (hwndFrameChild, QWL_STYLE
2284b39c5158Smillert                      , FS_NOMOVEWITHOWNER
2285b39c5158Smillert                      , FS_NOMOVEWITHOWNER);
2286b39c5158Smillert
2287b39c5158Smillert Adding a button icon later:
2288b39c5158Smillert
2289b39c5158Smillert /* switch the button style to BS_MINIICON */
2290b39c5158Smillert WinSetWindowBits(hwndBtn, QWL_STYLE, BS_MINIICON, BS_MINIICON) ;
2291b39c5158Smillert
2292b39c5158Smillert /* set up button control data */
2293b39c5158Smillert BTNCDATA    bcd;
2294b39c5158Smillert bcd.cb = sizeof(BTNCDATA);
2295b39c5158Smillert bcd.hImage = WinLoadPointer(HWND_DESKTOP, dllHandle, ID_ICON_BUTTON1) ;
2296b39c5158Smillert bcd.fsCheckState = bcd.fsHiliteState = 0 ;
2297b39c5158Smillert
2298b39c5158Smillert
2299b39c5158Smillert WNDPARAMS   wp;
2300b39c5158Smillert wp.fsStatus = WPM_CTLDATA;
2301b39c5158Smillert wp.pCtlData = &bcd;
2302b39c5158Smillert
2303b39c5158Smillert /* add the icon on the button */
2304b39c5158Smillert WinSendMsg(hwndBtn, WM_SETWINDOWPARAMS, (MPARAM)&wp, NULL);
2305b39c5158Smillert
2306b39c5158Smillert MO> Can anyone tell what OS/2 expects of an application to be properly
2307b39c5158Smillert MO> minimized to the desktop?
2308b39c5158Smillert case WM MINMAXFRAME :
2309b39c5158Smillert {
2310b39c5158Smillert   BOOL  fShow = ! (((PSWP) mp1)->fl & SWP MINIMIZE);
2311b39c5158Smillert   HENUM henum;
2312b39c5158Smillert
2313b39c5158Smillert   HWND  hwndChild;
2314b39c5158Smillert
2315b39c5158Smillert   WinEnableWindowUpdate ( hwnd, FALSE );
2316b39c5158Smillert
2317b39c5158Smillert   for (henum=WinBeginEnumWindows(hwnd);
2318b39c5158Smillert        (hwndChild = WinGetNextWindow (henum)) != 0; )
2319b39c5158Smillert   WinShowWindow ( hwndChild, fShow );
2320b39c5158Smillert
2321b39c5158Smillert   WinEndEnumWindows ( henum );
2322b39c5158Smillert   WinEnableWindowUpdate ( hwnd, TRUE );
2323b39c5158Smillert }
2324b39c5158Smillert break;
2325b39c5158Smillert
2326b39c5158SmillertWhy C<hWindowPos DesktopWindow> gives C<< behind => HWND_TOP >>?
2327b39c5158Smillert
2328b39c5158Smillert=head1 $^E
2329b39c5158Smillert
2330b39c5158Smillertthe majority of the APIs of this module set $^E on failure (no matter
2331b39c5158Smillertwhether they die() on failure or not).  By the semantic of PM API
2332b39c5158Smillertwhich returns something other than a boolean, it is impossible to
2333b39c5158Smillertdistinguish failure from a "normal" 0-return.  In such cases C<$^E ==
2334b39c5158Smillert0> indicates an absence of error.
2335b39c5158Smillert
2336b39c5158Smillert=head1 EXPORTS
2337b39c5158Smillert
2338b39c5158SmillertIn addition to symbols described above, the following constants (available
2339b39c5158Smillertalso via module C<OS2::Process::Const>) are exportable.  Note that these
2340b39c5158Smillertsymbols live in package C<OS2::Process::Const>, they are not available
2341b39c5158Smillertby full name through C<OS2::Process>!
2342b39c5158Smillert
2343b39c5158Smillert  HWND_*		Standard (abstract) window handles
2344b39c5158Smillert  WM_*			Message ids
2345b39c5158Smillert  SC_*			WM_SYSCOMMAND flavor
2346b39c5158Smillert  SWP_*			Size/move etc flag
2347b39c5158Smillert  WC_*			Standard window classes
2348b39c5158Smillert  PROG_*		Program category (PM, VIO etc)
2349b39c5158Smillert  QW_*			Query-Window flag
2350b39c5158Smillert  EDI_*			Enumerate-Dialog-Item code
2351b39c5158Smillert  WS_*			Window Style flag
2352b39c5158Smillert  QWS_*			Query-window-UShort offsets
2353b39c5158Smillert  QWP_*			Query-window-pointer offsets
2354b39c5158Smillert  QWL_*			Query-window-ULong offsets
2355b39c5158Smillert  FF_*			Frame-window state flags
2356b39c5158Smillert  FI_*			Frame-window information flags
2357b39c5158Smillert  LS_*			List box styles
2358b39c5158Smillert  FS_*			Frame style
2359b39c5158Smillert  FCF_*			Frame creation flags
2360b39c5158Smillert  BS_*			Button style
2361b39c5158Smillert  MS_*			Menu style
2362b39c5158Smillert  TBM_*			Title bar messages?
2363b39c5158Smillert  CF_*			Clipboard formats
2364b39c5158Smillert  CFI_*			Clipboard storage type
2365b39c5158Smillert  FID_*			ids of subwindows of frames
2366b39c5158Smillert
2367b39c5158Smillert=head1 BUGS
2368b39c5158Smillert
2369b39c5158Smillertwhether a given API dies or returns FALSE/empty-list on error may be
2370b39c5158Smillertconfusing.  This may change in the future.
2371b39c5158Smillert
2372b39c5158Smillert=head1 AUTHOR
2373b39c5158Smillert
2374b39c5158SmillertAndreas Kaiser <ak@ananke.s.bawue.de>,
2375b39c5158SmillertIlya Zakharevich <ilya@math.ohio-state.edu>.
2376b39c5158Smillert
2377b39c5158Smillert=head1 SEE ALSO
2378b39c5158Smillert
2379b39c5158SmillertC<spawn*>() system calls, L<OS2::Proc> and L<OS2::WinObject> modules.
2380b39c5158Smillert
2381b39c5158Smillert=cut
2382