next up previous contents index
Next: Améliorations Up: Informations système Previous: Timer   Contents   Index

Subsections

Le programme

Fonction principale

La fonction principale est chargée de déclarer un certain nombre de constantes, créer la fenêtre du moniteur et d'initialiser le timer. Nous avons :

; initialisation des bibliothèques

(use 'r4rs) ; bibliothèque standard
(use 'ok)   ; fonctions graphiques
(use 'ot)   ; timer

; constantes
; position (x,y) de la fenêtre
(define X                0)
(define Y                0)

; largeur de la fenêtre
(define WIDTH            50)

; hauteur de chacune des jauges
(define HEIGHT           10)

; marges entre les bords de la fenêtre 
; les jauges
(define MARGIN           2)

; couleur du fond de la fenêtre
(define BACKGROUND/COLOR ok:white)

; couleur de la jauge processeur
(define LOAD/COLOR       ok:red)

; couleur de la jauge batterie
(define APM/COLOR        ok:blue)

; couleur de la jauge de la batterie
; lorsque la batterie n'est pas en 
; charge
(define APM/BAT/COLOR    ok:red)

; fonction principale
(define (main)
  (ok:init)
  (let* (; création de la fenêtre
         [win   (ok:create-window
                 #t
                 BACKGROUND/COLOR
                 X
                 Y
                 WIDTH
                 (+ HEIGHT HEIGHT 
                    MARGIN MARGIN MARGIN))]
         ; création du timer
         [timer (timer:new (lambda ()
                             (refresh win))
                           1000)])
    ; fonction de rappel pour les touches 
    ; relâchées au dessus de la fenêtre
    (ok:release-callback! win
                          (lambda (key)
                            (timer:stop timer)
                            (ok:stop)))
    ; fonction de rappel pour le
    ; rafraîchissement
    (ok:refresh-callback! win 
                          (lambda ()
                            (refresh win)))
    ; la fenêtre est affichée normalement
    (ok:show win ok:show:normal)
    ; le timer est démarré
    (timer:start timer)
    ; les événements graphiques sont
    ; traités
    (ok:exec)))

La fonction commence par initialiser la bibliothèque de fonctions graphiques en appelant ok:init. Puis elle crée la fenêtre de l'application. Le premier argument est la fenêtre parente, ici #t. Lorsque le parent est #t, la fenêtre est créée sans être gérée par le gestionnaire de fenêtres ; elle sera donc affichée sans décorations et échappe à la gestion standard. Si le parent est #f, la fenêtre est gérée par le gestionnaire de fenêtres. Les arguments suivants sont la couleur du fond de la fenêtre, la position (x,y) du coin en haut à gauche de la fenêtre, la largeur et la hauteur de la fenêtre.

Le timer est créé avec une fonction de rappel invoquée toutes les secondes. Cette fonction rafraîchit le contenu de la fenêtre avec la fonction refresh définie plus loin. Le timer n'est pas encore actif ; il le sera après l'appel à la fonction timer:start.

Lorsqu'une touche est relâchée au-dessus de la fenêtre du moniteur, la fonction de rappel correspondante à l'appel à ok:release-callback! est invoquée. La fonction de rappel stoppe le timer est incoque ok:stop, ce qui a pour effet de stopper aussi le traitement des événements initié par l'appel à ok:exec ; la fonction main se termine donc entraînant l'arrêt du programme.

L'affichage du contenu de la fenêtre est confié à la fonction de rappel positionnée par l'appel à ok:refresh-callback!. Là, nous appelons la fonction refresh, définie plus bas.

Rafraîchissement

Le rafraîchissement de la fenêtre se contente d'appeler deux fonctions d'affichage définies plus loin, l'une pour les informations du processeur, l'autre pour les informations de la batterie :

(define (refresh win)
  (let* (; dimensions de la fenêtre
         [rec (ok:rectangle win)]
         ; largeur de la fenêtre
         [w   (vector-ref rec 2)])
    ; affichage des jauges
    (draw-load win w 0)
    (draw-apm  win w (+ MARGIN HEIGHT))
    ; force le traitement des événements
    (ok:show win ok:show:normal)))

Les fonctions d'affichage sont invoquées avec la fenêtre comme argument, ainsi que la largeur de la fenêtre et la position y où l'affichage doit avoir lieu. La fonction ok:show est invoquée pour forcer le traitement des événements par le gestionnaire d'affichage. En effet, la plupart des affichages dans la fenêtre vont être effectués suite à l'activation du timer ; hors sans cet appel, le gestionnaire risque de placer les événements générés dans un tampon et de ne traiter que les derniers événements, rendant du même coup l'affichage incohérent.

Informations du processeur

Cette fonction est chargée d'effectuer l'affichage des informations du processeur. Elle est définie par :

(define (draw-load win w y)
  (let (; lecture de la valeur
        [load (with-input-from-file
                  "/proc/loadavg"
                read)])
    ; interdire le 0 pour la division
    (if (zero? load)
        (set! load 0.001))
    ; dessine la jauge
    (draw-slider win w y
                 (inexact->exact
                  (/ (* (- w MARGIN MARGIN)
                        load)
                     (ceiling load)))
                 LOAD/COLOR)
    ; dessin des unités
    (let ([l (quotient (- w MARGIN MARGIN)
                       (ceiling load))])
      (do ([i 1           (+ i 1)]
           [x (+ MARGIN l)(+ x l)])
          ((> i (floor load)))
        (ok:draw-line win
                      x MARGIN
                      0 HEIGHT)))))

La première partie de la fonction lit la valeur de cette jauge directement dans le fichier loadavg dans /proc. Cette lecture est effectuée avec la fonction with-input-from-file qui prend comme argument un nom de fichier et une procédure sans argument. Le corps de cette procédure est invoqué avec comme fichier standard d'entrée le contenu du fichier donné. Ici, la procédure est la fonction read qui lit un objet Scheme. Comme le premier champ du fichier est celui qui nous intéresse, un seul appel à read est nécessaire. Si la valeur retournée dans load est nulle, nous la plaçons à une valeur presque nulle de manière à éviter les divisions par zéro.

Ensuite la fonction invoque draw-slider définie plus bas, avec comme arguments la fenêtre, sa largeur et la position ou la jauge dit être dessinée, la largeur de la valeur à indiquer dans la jauge, et enfin sa couleur.

Ensuite, nous traçons des lignes verticales pour indiquer les unités.

Remarquons que la fonction ceilling renvoie la plus petite valeur entière plus grande que la valeur passée en argument, et que la fonction floor renvoie la plus grande valeur entière plus petite que l'argument.

Informations de la batterie

L'affichage des informations relatives à la batterie s'effectue de la même manière que dans la fonction précédente :

(define (draw-apm win w y)
  (let (; valeurs à lire
        [bat    #f]
        [charge #f])
    ; lecture dans le fichier
    (with-input-from-file
        "/proc/apm"
      (lambda ()
        (read)
        (read)
        (read)
        ; conversion en booléen
        (set! bat (eq? (read) '0x00))
        (read)
        (read)
        ; conversion en entier
        (set! charge
             (string->number
              (substring (symbol->string (read))
                          0 
                          2)))))
    ; dessin de la jauge
    (draw-slider win w y
                 (if (negative? charge)
                     0
                     (quotient (* (- w MARGIN MARGIN)
                                  charge)
                               100))
                 (if bat APM/BAT/COLOR APM/COLOR))))

La seule difficulté est que la lecture des informations relatives à la batterie à partir du fichier /proc/apm ne peut être effectuée avec un seul read. De plus les valeurs qui nous intéresse dans fichier /proc/apm ne sont pas de objets Scheme ; aussi, il nous faut les convertir.

En ce qui concerne l'affichage, nous utilisons une couleur différente si la batterie est ou non connectée au secteur.

Affichage de la jauge

La dernière fonction du programme dessine une jauge :

(define (draw-slider win w y width color)
  ; dessin de la jauge
  (ok:foreground! win color)
  (ok:background! win color)
  (ok:draw-rectangle win
                     MARGIN (+ y MARGIN)
                     width
                     HEIGHT)
  ; dessin du cadre autour de la jauge
  (ok:foreground! win ok:black)
  (ok:background! win ok:transparent)
  (ok:draw-rectangle win
                     MARGIN (+ y MARGIN)
                     (- w MARGIN MARGIN)
                     HEIGHT))

Les arguments sont la fenêtre sur laquelle la jauge doit être dessinée, la largeur de la fenêtre, la position y de la jauge, la largeur de la valeur de la jauge et sa couleur. La seule remarque concerne l'utilisation de la couleur transparent qui permet de dessiner le rectangle sans fond.

Exécution

Il ne reste plus qu'à invoquer la fonction main à la fin du fichier :

(main)

Pour exécuter le programme, nous tapons sur la ligne de commande du shell la commande suivante :

$ ./osm --exec cpuinf.osm

Il est aussi possible de placer en haut du fichier la ligne suivante :

#! ./osm --exec

De cette manière, et en rendant le fichier exécutable, il est possible d'invoquer le programme directement.


next up previous contents index
Next: Améliorations Up: Informations système Previous: Timer   Contents   Index
© 1993 to 2001 Erian Concept