winpm(3tcl) 0.1 winpm "Windows Power and Session Management for Tcl/Tk"

NAME

winpm - Windows Power and Session Management for Tcl/Tk

TABLE OF CONTENTS

    TABLE OF CONTENTS
    SYNOPSIS
    DESCRIPTION
    BINDING TO EVENTS
    INTROSPECTION OF EVENT/SYSTEM INFO
    OTHER COMMANDS
    WRITING CALLBACK SCRIPTS
    EXAMPLES
    BUGS
    AUTHORS
    SEE ALSO
    KEYWORDS
    COPYRIGHT

SYNOPSIS

package require Tcl ?8.1?
package require Tk ?8.1?
package require winpm ?0.1?

winpm bind
winpm bind event
winpm bind event script
winpm info events
winpm info lastmessage
winpm info session
winpm info power
winpm info id
winpm _injectwm uMsg wParam lParam

DESCRIPTION

This package provides Tcl command which allows binding of Tcl scripts to Windows power management and session management events (broadcasted messages). Also this command can be used to acquire the information about the system's power state and particular events being processed by callback scripts.

Binding semantics are analogous to those of Tk's bindings provided by the bind command.

Currently bindings to the following Windows messages are supported:

WM_QUERYENDSESSION
This message is broadcasted when the system wants to shut down or reboot. It's possible to cancel this process from the user's callback script (see WRITING CALLBACK SCRIPTS).

WM_ENDSESSION
Broadcasted when the system is about to shut down or reboot and this process is irreversible.

WM_POWERBROADCAST
This message is broadcasted when the system's power state changes such as the system prepares to suspend or just resumed normal operation after having been suspended. This messaage have several distinguished "classes" (or "topics") referring to different power management events and it's possible to bind to them independently for convenience; these are:

PBT_APMPOWERSTATUSCHANGE
Broadcasted when the status of the system's power changes. This event occurs when the system transitions from the AC power line to the battery power or vice-versa; also changes in the battery capacity are reported using this event.

PBT_APMRESUMEAUTOMATIC
Broadcasted when the system is resumed from the suspended state and thus resumes its automatic work.

PBT_APMRESUMESUSPEND
This event occurs when the system awakes from the suspended state due to a user's intervention so that the running programs may resume their interaction with the user.

PBT_APMSUSPEND
This event indicates the the system is entering the suspended state.
Also supported several classes of the power broadcast messages which are deprecated since Windows XP/Windows Server 2003:

PBT_APMBATTERYLOW
PBT_APMOEMEVENT
PBT_APMQUERYSUSPEND
PBT_APMQUERYSUSPENDFAILED
PBT_APMRESUMECRITICAL
Note that bindings to the WM_POWERBROADCAST event itself and its classes are disjoint, i.e. if scripts are bound to WM_POWERBROADCAST and to any (or all) of its classes then when the WM_POWERBROADCAST message is processed two scripts are run: one for the WM_QUERYENDSESSION itself and then one for the specific event class specified in the message, in this order.
Consult the MSDN documentation for the explanations of precise meanings of these events and their classes.

To be able to receive these messages this library creates a hidden top-level window managed by a custom window procedure (it's called "the monitoring window" throughout this manual). It should be noted that only the messages listed above are processed directly, all others are handed off to the DefWindowProc standard system procedure.

All the functionality is encapsulated in the single command winpm created in the global namespace when the package is loaded. Different kinds of action are achieved by using different subcommands of this command. They are described below.

BINDING TO EVENTS

Before delving into the details, it should be noted that all the options to winpm and the names of all events in any context may be abbreviated while such an abbreviation is not ambiguous.

winpm bind
Returns a list of events to which scripts are currently bound.

winpm bind event
Returns a script which is bound to event or an empty string is no script is bound to that event.

winpm bind event script
Binds script to event. After this operation script will be evaluated in the global scope each time event is processed by the monitoring window.

If the script starts with the "+" character, this script is appended to the script which is already bound to event if any, otherwise it's just installed as usually. The "+" character is removed in any case before installing.

If script is an empty string then the currently bound script if removed, if any, otherwise this command does nothing.

This command returns an empty string.

INTROSPECTION OF EVENT/SYSTEM INFO

winpm info events
Returns a list of all known events to which user's scripts can be bound.

winpm info lastmessage
Returns a list of three integers corresponding to the uMsg, wParam and lParam parameters, in that order, of the last processed power management or session management event. This command is most useful to be used by a script bound to an event when the author of such a script for some reason wants to get his/her hands on the raw message that script is processing.

You must observe several things when using this facility:

Before the first relevant message hits the monitoring window, this form of the command returns a list of three zero integers.

winpm info session
Returns a list of two elements describing either the last WM_QUERYENDSESSION or the last WM_ENDSESSION message processed by the monitoring window. The elements of this list are, in order:

  1. A boolean value indicating that the system is being shut down and this process cannot be cancelled, i.e. the system may shut down at any moment after processing of this message is over. This flag is only relevant for the WM_ENDSESSION message, for which it can take values 0 or 1; for the WM_QUERYENDSESSION message this flag is always 0.

    This list element corresponds to the wParam parameter of the message.

  2. A list containing variable number of elements (0..2 currently) which are string flags providing additional information about how the system is being shut down. If a particular flag is present in the list then the contition it represents holds. These flags are:

    ENDSESSION_CLOSEAPP
    The application is holding a file that must be replaced and the system asks the application to close itself.

    ENDSESSION_LOGOFF
    The user is logging off.
    This list element corresponds to the lParam parameter of the message.
For more information about how to intepret this information read the MSDN documentation regarding the WM_QUERYENDSESSION and WM_ENDSESSION Windows messages.

winpm info power
Retrieves the current state of the system's power sources as a list of five elements wich are, in order:

  1. Status of the AC line (if any). This string parameter can take these values:

    ONLINE
    The AC line is active, the system runs on AC power source.

    OFFLINE
    The AC line is offline, the system runs on battery.

    UNKNOWN
    The state of AC line is unknown.
  2. The system's battery charge status (if any). This string parameter can take these values:

    HIGH
    The battery is at more than 66% of its capacity.

    LOW
    The battery's capacity is less than 33%.

    CRITICAL
    The battery's capacity is below 5%.

    CHARGING
    The battery is charging.

    NONE
    No system battry present.

    UNKNOWN
    The state of the system battery is unknown.
  3. The percentage of full battery life remaining. This integer parameter can take values from 0 to 100, or -1 when this information is unavailable.

  4. The integer number of seconds of the estimated remaining battery life. If this value is -1, the information is unavailable.

  5. The integer number of seconds of the full battery life (when at full capacity) or -1 if it's unknown.
This form of the command is a wrapper around the GetSystemPowerStatus Win32 API procedure and the information returned is parsed from the SYSTEM_POWER_STATUS structure returned by that procedure. Refer to the relevant parts of MSDN documentation for more info.

OTHER COMMANDS

winpm info id
This form of the command returns a system "window id" of the monitoring window just as the winfo command does for arbitrary Tk windows. Since this package is Windows-only, returned window id is actually a Windows handle to the monitoring window.

Returned value is formatted in the same way winfo command formats its return value: an uppercased string representing a hexadecimal number prefixed with "0x".

winpm _injectwm uMsg wParam lParam
This form of the command is provided for testing purposes and it allows to construct and send any Windows message to the monitoring window. The message is constructed from the arguments of this command (which must be integer values) and is sent using the SendMessage Windows API procedure.

This command returns an integer which is the result code of the SendMessage call.

WRITING CALLBACK SCRIPTS

The key points regarding callback scripts are:

Since the current version of this library doesn't support "precent substitutions" in callback scripts, if the script wants to inspect an information pertaining to the event it's bound to it must use the introspection subcommands of the winpm command (see INTROSPECTION OF EVENT/SYSTEM INFO).

Two events are used by the system to query the running application about whether it's OK to proceed with the operation in question, these are WM_QUERYENDSESSION message and the PBT_APMQUERYSUSPEND class of the WM_POWERBROADCAST message. The callback script bound to such event can prevent the system from committing the requested operation by returning the TCL_CONTINUE Tcl return code which is typically achieved by calling the continue Tcl command. (This approach was chosen since in both cases the system effectively asks the application to interrupt it's normal course of action in one way or another and the application may opt to continue its work.)

EXAMPLES

Binding to the WM_ENDSESSION event and inspecting the session information:

 
  winpm bind WM_ENDSESSION {
    lassign [winpm info session] final flags
    if {[lsearch $flags *LOGOFF] >= 0} {
      set msg "The user is logging off"
    } else {
      set msg "The system is being shut down"
    }
    if {$final} { append msg " NOW!" }
    warn user -with $msg
    network disconnect
    workplace save_all
    quit
  }

Binding to a specific WM_POWERBROADCAST event classes:

 
  winpm bind PBT_APMSUSPEND {
    warn user -with "suspending..."
    network save_active_connections
    network disconnect
    workplace save_all
  }

  winpm bind PBT_APMRESUMEAUTOMATIC {
    network restore_saved_connections
  }

Binding to the WM_POWERBROADCAST event and inspecting the last message parameters:

 
  winpm bind WM_POWERBROADCAST {
    lassign [winpm info lastmessage] uMsg wParam lParam
    if {$wParam == 666} { # Some undocumented vendor event class
      # Do special processing...
    } else {
      # Just bail out -- known event classes will trigger
      # running of their respective callback scripts, if any...
   }
  }

Watching the battery using the introspection of the system's power status:

 
  winpm bind PBT_APMPOWERSTATUSCHANGE {
    lassign [winpm info power] ac batt capa sec full
    if {[string equal $ac OFFLINE]
        && ![string equal $batt UNKNOWN]} {
      set msg "Battery remaining: $capa%"
      if {$sec >= 0} {
        append msg " (estimated $sec seconds to go)"
      }
      puts $msg
    }
  }

Interactive session sketch:

 
  % package require winpm
  0.1
  %
 
  # Inspecting events being processed:
  % winpm bind
  %
 
  # No events are processed currently. What events are available?
  % winpm info events
  WM_QUERYENDSESSION WM_ENDSESSION WM_POWERBROADCAST
  PBT_APMPOWERSTATUSCHANGE PBT_APMRESUMEAUTOMATIC PBT_APMRESUMESUSPEND
  PBT_APMSUSPEND PBT_APMBATTERYLOW PBT_APMOEMEVENT PBT_APMQUERYSUSPEND
  PBT_APMQUERYSUSPENDFAILED PBT_APMRESUMECRITICAL
  %

  # Let's bind a script to an event using an abbreviation
  # of the WM_QUERYENDSESSION event:
  % winpm bind WM_Q {puts one}
  %

  # Now inspect processed events again:
  % winpm bind
  WM_QUERYENDSESSION
  %

  # What's bound to WM_QUERYENDSESSION?
  % winpm b WM_QUERY
  puts one
  %

  # Let's add to this script:
  % winpm bind WM_QUERYENDSESSION {+puts two}
  %

  # What do we have now?
  % winpm bind WM_QUERY
  puts one
  puts two
  %

  # Smoke test (uMsg = 0x0011 is the code of WM_QUERYENDSESSION):
  % winpm _inject 0x0011 0 1
  puts one
  puts two
  1
  %

  # Bind to another event:
  % winpm bind PBT_APMSUSPEND { puts suspended }

  # What events are processed now?
  % winpm bind
  PBT_APMSUSPEND WM_QUERYENDSESSION
  %

  # Unbind WM_QUERYENDSESSION:
  % winpm bind WM_QUERYEND {}
  %

  # And again:
  % winpm bind WM_QUERYENDSESSION
  %
 
  % winpm bind
  PBT_APMSUSPEND
  %

BUGS

AUTHORS

This extension is created by Konstantin Khomoutov <flatworm@users.sourceforge.net>

SEE ALSO

bgerror, continue, ffidl, twapi, wm

KEYWORDS

Windows, battery, event, management, power, resume, session, suspend

COPYRIGHT

Copyright © 2007 Konstantin Khomoutov <flatworm@users.sourceforge.net>