1#! /usr/bin/perl -w
2
3#END {
4#  sleep 10;
5#}
6
7sub propagate_INC {
8  my $inc = $ENV{PERL5LIB};
9  $inc = $ENV{PERLLIB} unless defined $inc;
10  $inc = '' unless defined $inc;
11  $ENV{PERL5LIB} = join ';', @INC, split /;/, $inc;
12}
13
14my $separate_session;
15BEGIN {			# Remap I/O to the parent's window
16 $separate_session = $ENV{OS2_PROCESS_TEST_SEPARATE_SESSION};
17 propagate_INC, return unless $separate_session; # done by the parent
18 my @fn = split " ", $ENV{NEW_FD};
19 my @fh = (*STDOUT, *STDERR);
20 my @how = qw( > > );
21 # warn $_ for @fn;
22 open $fh[$_], "$how[$_]&=$fn[$_]"
23   or warn "Cannot reopen $fh[$_], $how[$_]&=$fn[$_]: $!" for 0..1;
24}
25
26use strict;
27use Test::More tests => 235;
28use OS2::Process;
29
30sub SWP_flags ($) {
31  my @nkpos = WindowPos shift;
32  $nkpos[2];
33}
34
35my $interactive_wait = @ARGV && $ARGV[0] eq 'wait';
36
37my @l = OS2::Process::process_entry();
38ok(@l == 11, 'all the fields of the process_entry() are there');
39
40# 1: FS 2: Window-VIO
41ok( ($l[9] == 1 or $l[9] == 2), 'we are FS or Windowed-VIO');
42
43#print "# $_\n" for @l;
44
45eval <<'EOE' or die;
46#use OS2::Process qw(WM_SYSCOMMAND WM_DBCSLAST FID_CLIENT HWND_DESKTOP);
47use OS2::Process qw(WM_SYSCOMMAND WM_DBCSLAST HWND_DESKTOP);
48
49ok( WM_SYSCOMMAND == 0x0021, 'correct WM_SYSCOMMAND' );
50ok( WM_DBCSLAST   == 0x00cf,  'correct WM_DBCSLAST' );
51#ok( FID_CLIENT    == 0x8008 );
52ok( HWND_DESKTOP  == 0x0001,  'correct HWND_DESKTOP' );
531;
54EOE
55
56my $t = Title;
57my $wint = winTitle;
58
59ok($t, 'got session title');
60ok($wint, 'got titlebar text');
61
62my $newt = "test OS2::Process $$";
63ok(Title_set($newt), 'successfully set Title');
64is(Title, $newt, 'correctly set Title');
65my $wt = winTitle or warn "winTitle: $!, $^E";
66is(winTitle, $newt, 'winTitle changed its value too');
67ok(Title_set $t, 'successfully set Title back');
68is(Title, $t, 'correctly set Title back');
69is(winTitle, $wint, 'winTitle restored its value too');
70
71$newt = "test OS2::Process both-$$";
72ok(bothTitle_set($newt), 'successfully set both titles via Win* API');
73is(Title, $newt, 'session title correctly set');
74is(winTitle, $newt, 'winTitle correctly set');
75ok(bothTitle_set($t), 'successfully reset both titles via Win* API');
76is(Title, $t, 'session title correctly reset');
77is(winTitle, $wint, 'winTitle correctly reset');
78
79$newt = "test OS2::Process win-$$";
80ok(winTitle_set($newt), 'successfully set titlebar title via Win* API');
81is(Title, $t, 'session title remained the same');
82is(winTitle, $newt, 'winTitle changed value');
83ok(winTitle_set($wint), 'successfully reset titlebar title via Win* API');
84is(Title, $t, 'session title remained the same');
85is(winTitle, $wint, 'winTitle restored value');
86
87$newt = "test OS2::Process sw-$$";
88ok(swTitle_set($newt), 'successfully set session title via Win* API');
89is(Title, $newt, 'session title correctly set');
90is(winTitle, $wint, 'winTitle has unchanged value');
91ok(swTitle_set($t), 'successfully reset session title via Win* API');
92is(Title, $t, 'session title correctly set');
93is(winTitle, $wint, 'winTitle has unchanged value');
94
95$newt = "test OS2::Process again-$$";
96ok(Title_set($newt), 'successfully set Title again');
97is(Title, $newt, 'correctly set Title again');
98is(winTitle, $newt, 'winTitle changed its value too again');
99ok(Title_set($t), 'successfully set Title back');
100is(Title, $t, 'correctly set Title back');
101is(winTitle, $wint, 'winTitle restored its value too again');
102
103my $hwnd = process_hwnd;
104ok($hwnd, 'found session owner hwnd');
105my $c_subhwnd = WindowFromId $hwnd, 0x8008;	# FID_CLIENT;
106ok($c_subhwnd, 'found client hwnd');
107my $a_subhwnd = ActiveWindow $hwnd;	# or $^E and warn $^E;
108ok((not $a_subhwnd and not $^E), 'No active subwindow in a VIO frame');
109
110my $ahwnd = ActiveWindow;
111ok($ahwnd, 'found active window');
112my $fhwnd = FocusWindow;
113ok($fhwnd, 'found focus window');
114
115# This call without morphing results in VIO window with active highlight, but
116# no keyboard focus (even after Alt-Tabbing to it; you cannot Alt-Tab off it!)
117
118# Interestingly, Desktop is active on the switch list, but the
119# switch list is not acting on keyboard events.
120
121# Give up focus
122{ my $force_PM = OS2::localMorphPM->new(0);
123  ok $force_PM, 'morphed to PM locally';
124  ok FocusWindow_set(1), 'set focus to DESKTOP';	# HWND_DESKTOP
125}
126my $dtop = DesktopWindow;
127ok($dtop, 'found the desktop window');
128
129#OS2::Process::ResetWinError;			# XXXX Should not be needed!
130$ahwnd = ActiveWindow or $^E and warn $^E;
131ok( (not $ahwnd and not $^E), 'desktop is not active');
132$fhwnd = FocusWindow;
133ok($fhwnd, 'there is a focus window');
134is($fhwnd, $dtop, 'which is the desktop');
135
136# XXXX Well, no need to skip it now...
137SKIP: {
138  skip 'We already have focus', 4 if $hwnd == $ahwnd;
139  my $force_PM = OS2::localMorphPM->new(0);
140  ok $force_PM, 'morphed to PM locally again';
141  ok FocusWindow_set($c_subhwnd), 'set focus to the client of the session owner';
142  # If we do not morph, then when the focus is in another VIO frame,
143  # we get two VIO frames with activated titlebars.
144  # The only (?) way to take the activated state from another frame
145  # is to switch to it via the switch list
146  $ahwnd = ActiveWindow;
147  ok($ahwnd, 'there is an active window');
148  $fhwnd = FocusWindow;
149  ok($fhwnd, 'there is a focus window');
150  is($hwnd, $ahwnd, 'the active window is the session owner');
151  is($fhwnd, $c_subhwnd, 'the focus window is the client of the session owner');
152}
153
154# Give up focus again
155{ my $force_PM = OS2::localMorphPM->new(0);
156  ok $force_PM, 'morphed to PM locally again';
157  ok FocusWindow_set(1), 'set focus to DESKTOP again';	# HWND_DESKTOP
158}
159
160$ahwnd = ActiveWindow or $^E and warn $^E;
161ok( (not $ahwnd and not $^E), 'desktop is not active again');
162$fhwnd = FocusWindow;
163ok($fhwnd, 'there is a focus window');
164is($fhwnd, $dtop, 'which is the desktop');
165
166# XXXX Well, no need to skip it now...
167SKIP: {
168  skip 'We already have focus', 4 if $hwnd == $ahwnd;
169  my $force_PM = OS2::localMorphPM->new(0);
170  ok $force_PM, 'morphed to PM locally again';
171  ok ActiveWindow_set($hwnd), 'activate the session owner';
172  $ahwnd = ActiveWindow;
173  ok($ahwnd, 'there is an active window');
174  $fhwnd = FocusWindow;
175  ok($fhwnd, 'there is a focus window');
176  is($hwnd, $ahwnd, 'the active window is the session owner');
177}
178
179# XXXX Well, no need to skip it now...
180SKIP: {
181  skip 'Tests assume we have focus', 1 unless $hwnd == $ahwnd;
182  # We have focus
183  # is($fhwnd, $ahwnd);
184  # is($a_subhwnd, $c_subhwnd);
185  is($fhwnd, $c_subhwnd, 'the focus window is the client of the session owner');
186}
187
188# Check enumeration of switch entries:
189my $skid_title = "temporary s-kid ppid=$$";
190my $spid = system P_SESSION, $^X, '-wle', "END {sleep 25} use OS2::Process; eval {Title_set '$skid_title'} or warn \$@; \$SIG{TERM} = sub {exit 0}";
191ok ($spid, 'start the new VIO session with unique title');
192sleep 1;
193my @sw = grep $_->{title} eq $skid_title, process_hentries;
194sleep 1000 unless @sw;
195is(scalar @sw, 1, 'exactly one session with this title');
196my $sw = $sw[0];
197ok $sw, 'have the data about the session';
198is($sw->{owner_pid}, $spid, 'session has a correct pid');
199my $k_hwnd = $sw->{owner_hwnd};
200ok $k_hwnd, 'found the session window handle';
201is sidOf($spid), $sw->{owner_sid}, 'we know sid of the session';
202
203# Give up focus again
204{ my $force_PM = OS2::localMorphPM->new(0);
205  ok $force_PM, 'morphed to PM locally again';
206  ok FocusWindow_set($k_hwnd), 'set focus to kid session window';
207}
208
209$ahwnd = ActiveWindow;
210ok $ahwnd, 'there is an active window';
211is $ahwnd, $k_hwnd, 'after focusing the active window is the owner_hwnd';
212$fhwnd = FocusWindow;
213ok $fhwnd, 'there is a focus window';
214my $c_sub_ahwnd = WindowFromId $ahwnd, 0x8008;	# FID_CLIENT;
215ok $c_sub_ahwnd, 'the active window has a FID_CLIENT';
216is($fhwnd, $ahwnd, 'the focus window = the active window');
217
218ok hWindowPos_set({behind => 3}, $k_hwnd),	# HWND_TOP
219  'put kid to the front';
220
221# After Alt-Tab a WS_TOPMOST, WS_DISABLED window of class 'AltTabWindow' exists
222my $top = (hWindowPos $k_hwnd)->{behind};
223ok(($top == 3 or WindowStyle($top) & 0x200000),	# HWND_TOP, WS_TOPMOST
224   'kid is at front');
225# is((hWindowPos $k_hwnd)->{behind}, 3, 'kid is at front');
226
227my ($enum_handle, $first_zorder, $first_non_TOPMOST);
228{ my $force_PM = OS2::localMorphPM->new(0);
229  ok $force_PM, 'morphed to PM locally again';
230  $enum_handle = BeginEnumWindows 1;		# HWND_DESKTOP
231  ok $enum_handle, 'start enumeration';
232  $first_non_TOPMOST = $first_zorder = GetNextWindow $enum_handle;
233  ok $first_zorder, 'GetNextWindow works';
234  my $f = WindowStyle $first_non_TOPMOST;
235  ok $f, 'WindowStyle works';
236  $f = WindowStyle($first_non_TOPMOST = GetNextWindow $enum_handle)
237    while $f & 0x200000;				# WS_TOPMOST
238  ok($first_non_TOPMOST, 'There is non-TOPMOST window');
239  ok(!(WindowStyle($first_non_TOPMOST) & 0x200000), 'Indeed non-TOPMOST');
240  ok EndEnumWindows($enum_handle), 'end enumeration';
241}
242is ($first_non_TOPMOST, $k_hwnd, 'kid is the first in z-order enumeration');
243
244ok hWindowPos_set({behind => 4}, $k_hwnd),	# HWND_BOTTOM
245  'put kid to the back';
246
247# This does not work, the result is the handle of "Window List"
248# is((hWindowPos $k_hwnd)->{behind}, 4, 'kis is at back');
249
250my (@list, $next, @list1);
251{ my $force_PM = OS2::localMorphPM->new(0);
252  ok $force_PM, 'morphed to PM locally again';
253  $enum_handle = BeginEnumWindows 1;		# HWND_DESKTOP
254  ok $enum_handle, 'start enumeration';
255  push @list, $next while $next = GetNextWindow $enum_handle;
256  @list1 = ChildWindows;
257  ok 1, 'embedded ChildWindows()';
258  ok EndEnumWindows($enum_handle), 'end enumeration';
259
260  is_deeply \@list, \@list1, 'Manual list same as by ChildWindows()';
261  # Apparently, the 'Desktop' window is still behind us;
262  # Note that this window is *not* what is returned by DesktopWindow
263  pop @list if WindowText($list[-1]) eq 'Desktop';
264}
265is ($list[-1], $k_hwnd, 'kid is the last in z-order enumeration');
266# print "# kid=$k_hwnd in @list\n";
267@list = ChildWindows;
268is_deeply \@list, \@list1, 'Other ChildWindows(), same result';
269ok scalar @list, 'ChildWindows works';
270is $list[-2], $k_hwnd, 'kid is the last but one in ChildWindows';
271
272ok hWindowPos_set({behind => 3}, $k_hwnd),	# HWND_TOP
273  'put kid to the front again';
274
275$top = (hWindowPos $k_hwnd)->{behind};
276ok(($top == 3 or WindowStyle($top) & 0x200000),	# WS_TOPMOST
277   'kid is at front again');
278sleep 5 if $interactive_wait;
279
280ok IsWindow($k_hwnd), 'IsWindow works';
281#print "# win=$k_hwnd => err=$^E\n";
282my $c_sub_khwnd = WindowFromId $k_hwnd, 0x8008;	# FID_CLIENT
283ok $c_sub_khwnd, 'have kids client window';
284ok IsWindow($c_sub_khwnd), 'IsWindow works on the client';
285#print "# win=$c_sub_khwnd => IsWindow err=$^E\n";
286my ($pkid,$tkid) = WindowProcess $c_sub_khwnd;
287my ($pkid1,$tkid1) = WindowProcess $hwnd;
288ok($pkid1 > 0, 'our window has a governing process');
289ok($tkid1 > 0, 'our window has a governing thread');
290is($pkid, $pkid1, 'kid\'s window is governed by the same process as our (PMSHELL:1)');
291is($tkid, $tkid1, 'likewise for threads');
292is $pkid, ppidOf($spid), 'the governor is the parent of the kid session';
293
294my $my_pos = hWindowPos($hwnd);
295ok $my_pos, 'got my position';
296{ my $force_PM = OS2::localMorphPM->new(0);
297  ok $force_PM, 'morphed to PM locally again';
298  my @pos = WindowPos $hwnd;
299  my @ppos = WindowPos $k_hwnd;
300  # ok hWindowPos_set({%$my_pos, behind => $hwnd}, $k_hwnd), 'hide the kid behind us';
301  # Hide it completely behind our window
302  ok hWindowPos_set({x => $my_pos->{x}, y => $my_pos->{y}, behind => $hwnd,
303		     width => $my_pos->{width}, height => $my_pos->{height}},
304		    $k_hwnd), 'hide the kid behind us';
305  # ok WindowPos_set($k_hwnd, $pos[0], $pos[1]), 'hide the kid behind us';
306  my @kpos = WindowPos $k_hwnd;
307  # print "# kidpos=@ppos\n";
308  # print "#  mypos=@pos\n";
309  # print "# kidpos=@kpos\n";
310# kidpos=252 630 4111 808 478 3 66518088 502482793
311#  mypos=276 78 4111 491 149 2147484137 66518060 502532977
312# kidpos=276 78 4111 491 149 2147484255 1392374582 213000
313  print "# Before window position\n" if $interactive_wait;
314  sleep 5 if $interactive_wait;
315
316  my $w_at = WindowFromPoint($kpos[0] + 5, $kpos[0] + 5, 1, 0); # HWND_DESKTOP, no grandchildren
317  ok $w_at, 'got window near LL corner of the kid';
318  print "# we=$hwnd, our client=$c_subhwnd, kid=$k_hwnd, kid's client=$c_sub_khwnd\n";
319  #is $w_at, $c_sub_khwnd, 'it is the kids client';
320  #is $w_at, $k_hwnd, 'it is the kids frame';
321  # Apparently, this result is accidental only...
322#  is $w_at, $hwnd, 'it is our frame - is on top, but no focus';
323  #is $w_at, $c_subhwnd, 'it is our client';
324  print "# text: `", WindowText $w_at, "'.\n";
325  $w_at = WindowFromPoint($kpos[0] + 5, $kpos[0] + 5); # HWND_DESKTOP, grandchildren too
326  ok $w_at, 'got grandkid window near LL corner of the kid';
327  # Apparently, this result is accidental only...
328#  is $w_at, $c_subhwnd, 'it is our client';
329  print "# text: `", WindowText $w_at, "'.\n";
330  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
331  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
332  ok IsWindowShowing $hwnd, 'we are showing';
333  ok ((not IsWindowShowing $k_hwnd), 'kid is not showing');
334  ok ((not eval { IsWindowShowing 12; 1 }), 'wrong kid causes errors');
335  is $^E+0, 0x1001, 'error is 0x1001';
336  like $@, qr/\Q[Win]IsWindowShowing/, 'error message shows function';
337  like $@, qr/SYS4097\b/, 'error message shows error number';
338  like $@, qr/\b0x1001\b/, 'error message shows error number in hex';
339
340  ok WindowPos_set($k_hwnd, @ppos[0..5]), 'restore the kid position';
341  my @nkpos = WindowPos $k_hwnd;
342  my $fl = $nkpos[2];
343  is_deeply([@ppos[0..5]], [@nkpos[0..5]], 'position restored');
344  ok IsWindowShowing $k_hwnd, 'kid is showing';
345  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
346  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
347  sleep 5 if $interactive_wait;
348  ok EnableWindow($k_hwnd, 0), 'disable the kid';
349  ok IsWindowShowing $k_hwnd, 'kid is showing';
350  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
351  ok !IsWindowEnabled $k_hwnd, 'kid is flaged as not enabled';
352  ok EnableWindow($k_hwnd), 'enable the kid';
353  ok IsWindowShowing $k_hwnd, 'kid is showing';
354  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
355  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
356  ok ShowWindow($k_hwnd, 0), 'hide the kid';
357  ok !IsWindowShowing $k_hwnd, 'kid is not showing';
358  ok !IsWindowVisible $k_hwnd, 'kid is flaged as not visible';
359  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
360  ok ShowWindow($k_hwnd), 'show the kid';
361  ok IsWindowShowing $k_hwnd, 'kid is showing';
362  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
363  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
364  ok( ($fl & 0x1800), 'window is maximized or restored'); # SWP_MAXIMIZE SWP_RESTORE
365  ok( ($fl & 0x1800) != 0x1800, 'window is not maximized AND restored'); # SWP_MAXIMIZE SWP_RESTORE
366
367  ok PostMsg( $k_hwnd, 0x21,	# WM_SYSCOMMAND, SC_MINIMIZE
368	      OS2::Process::MPFROMSHORT 0x8002), 'post minimize message';
369  sleep 1;
370  ok !IsWindowShowing $k_hwnd, 'kid is not showing';
371  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
372  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
373  is 0x1c00 & SWP_flags $k_hwnd, 0x400, 'kid is minimized'; # SWP_MINIMIZE
374
375  ok PostMsg($k_hwnd, 0x21,	# WM_SYSCOMMAND, SC_RESTORE
376	     OS2::Process::MPFROMSHORT 0x8008), 'post restore message';
377  sleep 1;
378  ok IsWindowShowing $k_hwnd, 'kid is showing';
379  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
380  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
381  is 0x1c00 & SWP_flags $k_hwnd, 0x1000, 'kid is restored'; # SWP_RESTORE
382
383  ok PostMsg($k_hwnd, 0x21,	# WM_SYSCOMMAND, SC_MAXIMIZE
384	    OS2::Process::MPFROMSHORT 0x8003), 'post maximize message';
385  sleep 1;
386  ok IsWindowShowing $k_hwnd, 'kid is showing';
387  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
388  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
389  is 0x1c00 & SWP_flags $k_hwnd, 0x800, 'kid is maximized'; # SWP_MAXIMIZE
390
391  ok PostMsg( $k_hwnd, 0x21,	# WM_SYSCOMMAND, SC_MINIMIZE
392	      OS2::Process::MPFROMSHORT 0x8002), 'post minimize message again';
393  sleep 1;
394  ok !IsWindowShowing $k_hwnd, 'kid is not showing';
395  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
396  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
397  is 0x1c00 & SWP_flags $k_hwnd, 0x400, 'kid is minimized'; # SWP_MINIMIZE
398
399  ok PostMsg($k_hwnd, 0x21,	# WM_SYSCOMMAND, SC_RESTORE
400	     OS2::Process::MPFROMSHORT 0x8008), 'post restore message again';
401  sleep 1;
402  ok IsWindowShowing $k_hwnd, 'kid is showing';
403  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
404  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
405  is 0x1c00 & SWP_flags $k_hwnd, 0x1000, 'kid is restored'; # SWP_RESTORE
406
407  ok PostMsg( $k_hwnd, 0x21,	# WM_SYSCOMMAND, SC_MINIMIZE
408	      OS2::Process::MPFROMSHORT 0x8002), 'post minimize message again';
409  sleep 1;
410  ok !IsWindowShowing $k_hwnd, 'kid is not showing';
411  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
412  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
413  is 0x1c00 & SWP_flags $k_hwnd, 0x400, 'kid is minimized'; # SWP_MINIMIZE
414
415  ok PostMsg($k_hwnd, 0x21,	# WM_SYSCOMMAND, SC_RESTORE
416	     OS2::Process::MPFROMSHORT (($fl & 0x800) ? 0x8003 : 0x8008)), # SWP_MAXIMIZE
417	'return back to the initial MAXIMIZE/RESTORE state';
418  sleep 1;
419  ok IsWindowShowing $k_hwnd, 'kid is showing';
420  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
421  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
422  SKIP: {
423    skip 'if defaultVIO=MAXIMIZED, new windows are shifted, but maximize to UL corner', 1 unless $fl & 0x800;
424    ok hWindowPos_set({x => $ppos[0], y => $ppos[1]}, $k_hwnd), 'x,y-restore for de-minimization of MAXIMIZED';
425  }
426  @nkpos = WindowPos $k_hwnd;
427  is_deeply([@ppos[0..5]], [@nkpos[0..5]], 'position restored');
428
429
430  # Now the other way
431  ok hWindowPos_set( {flags => 0x400}, $k_hwnd), 'set to minimized';
432  ok !IsWindowShowing $k_hwnd, 'kid is not showing';
433  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
434  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
435  is 0x1c00 & SWP_flags $k_hwnd, 0x400, 'kid is minimized'; # SWP_MINIMIZE
436
437  ok hWindowPos_set( {flags => 0x1000}, $k_hwnd), 'set to restore';
438  ok IsWindowShowing $k_hwnd, 'kid is showing';
439  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
440  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
441  is 0x1c00 & SWP_flags $k_hwnd, 0x1000, 'kid is restored'; # SWP_RESTORE
442
443  ok hWindowPos_set( {flags => 0x800}, $k_hwnd), 'set to maximized';
444  ok IsWindowShowing $k_hwnd, 'kid is showing';
445  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
446  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
447  is 0x1c00 & SWP_flags $k_hwnd, 0x800, 'kid is maximized'; # SWP_MAXIMIZE
448
449  ok hWindowPos_set( {flags => 0x400}, $k_hwnd), 'set to minimized again';
450  ok !IsWindowShowing $k_hwnd, 'kid is not showing';
451  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
452  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
453  is 0x1c00 & SWP_flags $k_hwnd, 0x400, 'kid is minimized'; # SWP_MINIMIZE
454
455  ok hWindowPos_set( {flags => 0x1000}, $k_hwnd), 'set to restore again';
456  ok IsWindowShowing $k_hwnd, 'kid is showing';
457  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
458  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
459  is 0x1c00 & SWP_flags $k_hwnd, 0x1000, 'kid is restored'; # SWP_RESTORE
460
461  ok hWindowPos_set( {flags => 0x400}, $k_hwnd), 'set to minimized again';
462  ok !IsWindowShowing $k_hwnd, 'kid is not showing';
463  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
464  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
465  is 0x1c00 & SWP_flags $k_hwnd, 0x400, 'kid is minimized'; # SWP_MINIMIZE
466
467  ok hWindowPos_set( {flags => ($fl & 0x1800)}, $k_hwnd),
468	'set back to the initial MAXIMIZE/RESTORE state';
469  ok IsWindowShowing $k_hwnd, 'kid is showing';
470  ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
471  ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
472  SKIP: {
473    skip 'if defaultVIO=MAXIMIZED, new windows are shifted, but maximize to UL corner', 1 unless $fl & 0x800;
474    ok hWindowPos_set({x => $ppos[0], y => $ppos[1]}, $k_hwnd), 'x,y-restore for de-minimization of MAXIMIZED';
475  }
476  @nkpos = WindowPos $k_hwnd;
477  is_deeply([@ppos[0..5]], [@nkpos[0..5]], 'position restored');
478
479}
480
481# XXXX Well, no need to skip it now...
482SKIP: {
483  skip 'We already have focus', 4 if $hwnd == $ahwnd;
484  my $force_PM = OS2::localMorphPM->new(0);
485  ok($force_PM, 'morphed to catch focus again');
486  ok FocusWindow_set($c_subhwnd), 'set focus to the client of the session owner';
487  # If we do not morph, then when the focus is in another VIO frame,
488  # we get two VIO frames with activated titlebars.
489  # The only (?) way to take the activated state from another frame
490  # is to switch to it via the switch list
491  $ahwnd = ActiveWindow;
492  ok($ahwnd, 'there is an active window');
493  $fhwnd = FocusWindow;
494  ok($fhwnd, 'there is a focus window');
495  is($hwnd, $ahwnd, 'the active window is the session owner');
496  is($fhwnd, $c_subhwnd, 'the focus window is the client of the session owner');
497}
498
499SKIP: {
500  skip 'Potentially destructive session modifications, done in a separate session only',
501    12, unless $separate_session;
502  # Manipulate process' hentry
503  my $he = process_hentry;
504  ok($he, 'got process hentry');
505  ok($he->{visible}, 'session switch is visible');# 4? Assume nobody manipulated it...
506
507  ok change_entryh($he), 'can change it (without modifications)';
508  my $nhe = process_hentry;
509  ok $nhe, 'could refetch the process hentry';
510  is_deeply($nhe, $he, 'it did not change');
511
512  sleep 5 if $interactive_wait;
513  # Try removing the process entry from the switch list
514  $nhe->{visible} = 0;
515  ok change_entryh($nhe), 'can change it to be invisible';
516  my $nnhe = process_hentry;
517  ok($nnhe, 'could refetch the process hentry');
518  is_deeply($nnhe, $nhe, 'it is modified as expected');
519  is($nnhe->{visible}, 0, 'it is not visible');
520
521  sleep 5 if $interactive_wait;
522
523  $nhe->{visible} = 1;
524  ok change_entryh ($nhe), 'can change it to be visible';
525  $nnhe = process_hentry;
526  ok($nnhe, 'could refetch the process hentry');
527  ok($nnhe->{visible}, 'it is visible');
528  sleep 5 if $interactive_wait;
529}
530