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