Very simple plugin- uptime.oml

Submitted by Phaul on Wed, 2007-03-07 13:21.
::

This is the uptime.oml from the cvs:

;;
;; uptime plugin
;;
;; Copyright (c) 2006, 2007 Sonkoly Pal 
;;
;; Permission to use, copy, modify, and distribute this software for any
;; purpose with or without fee is hereby granted, provided that the above
;; copyright notice and this permission notice appear in all copies.
;;
;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
;;

(include "omls/list.oml")
(include "omls/x.oml")

(progn

; set up ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   (declare textposx textposy titlecolour title)
   (set textposx 20) ; placement of Uptime : ... string in openmoni window
   (set textposy 40) ;                             -||-
   (set titlecolour 0x00bbbbbb)
   (set title "Uptime : ")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   (declare d day hour min washere)
   (set d (uptime))

   (if (not washere)
      (progn
         (set washere 1)
         (declare normcon backgc)
         (set normcon (xgetgc))
         (set backgc (setat normcon FOREGROUND titlecolour))
         (set backgc (setat backgc LAYER 0))
         (xsetgc backgc)
         (xdrawtext (list title textposx textposy))
         (xsetgc normcon) ; restore original context
         (set normcon nil)
         (set backgc nil)
         (set title nil)
      ); progn
   ); if

   (if (not (= min (nth 3 d)))
      (progn
         (declare area text)
         (set day (nth 1 d))
         (set hour (nth 2 d))
         (set min (nth 3 d))

         (if area (xcleararea area))
         (set text (ascii day))
         (if (> day 1)
            (set text (strcat text " days "))
            (set text (strcat text " day "))
         ); if
         (set text (strcat text (ascii hour)))
         (set text (strcat text ":"))
         (set text (strcat text (ascii min)))
         (set area (xdrawtext (list text (+ 60 textposx) textposy)))
      ); progn
   ); if
   (sleep 1200)
); progn

Let's see step-by-step what it does and how it works.
First of all openmoni executes the oml plugins in an infinite loop, so we don't have to write a loop inside the plugin.


The first (progn is completly unnecessary though it gives a nice frame to our plugin.
It's a good practise to predefine some variables to set up purposes, here they are clearly marked with comment.


The interesting part comes after the initial variables.

   (if (not washere)
      (progn
         (set washere 1)
         (declare normcon backgc)
         (set normcon (xgetgc))
         (set backgc (setat normcon FOREGROUND titlecolour))
         (set backgc (setat backgc LAYER 0))
         (xsetgc backgc)
         (xdrawtext (list title textposx textposy))
         (xsetgc normcon) ; restore original context
         (set normcon nil)
         (set backgc nil)
         (set title nil)
      ); progn
   ); if

We would like to do some initialization, but only once, so we protect the corresponding progn with (if (not washere). This only works with the (set washere 1).


At this step we load the current graphical context into normcon, and load a modified version into backgc. The setat function is defined in oml/list.oml and the FOREGROUND etc. in oml/x.oml. See includes at the top.

         (set normcon (xgetgc))
         (set backgc (setat normcon FOREGROUND titlecolour))
         (set backgc (setat backgc LAYER 0))

Than we change the graphical context to backgc. We have set the layer to 0 at the previous step because this is sg. that we want to draw only once. Next step is the actual drawing, and than we restore the original context.

         (xsetgc backgc)
         (xdrawtext (list title textposx textposy))
         (xsetgc normcon) ; restore original context

Here comes a small optimization hack. As we don't need some variables any more, we load nil into them, that actually sets them free. Note that graphical context is a rather long list, and it's a good practise to set it free.

         (set normcon nil)
         (set backgc nil)
         (set title nil)

Here comes the actual plugin body, that is executed periodically. But even that is prevented if the output had been remained the same. As we would like to get sg. like: Uptime : 0 day 3:26 It's ok if we check the minutes.

  (if (not (= min (nth 3 d)))
      (progn

A typical part: if area - the variable stores the coordinates of the affected area in a list- is defined, we clear it. We don't care what has changed inside the area, we clear the whole rectangle. (Note that layer 0 drawings cannot be cleared.)

        (if area (xcleararea area))

The remaining is straightforward enough, but note that xdrawtext returns the affected area in a list. Separated areas can be (geometrically) joined using the unionarea function from x.oml.

         (set area (xdrawtext (list text (+ 60 textposx) textposy)))

It is important to sleep some time in every round, unless we want to use up all CPU, and freeze the machine.

   (sleep 1200)