IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

Créer une fenêtre transparente


Sujet :

Linux

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 10
    Points : 7
    Points
    7
    Par défaut Créer une fenêtre transparente
    Bonjour à tous !

    Je commence à m'intéresser à la programmation en OpenGL, et je m'amuse beaucoup Pour le moment je travaille avec glut comme système de fenêtre, mais je sens que je vais devoir vite passer à autre chose pour pouvoir faire des trucs plus complexes.

    En fait, j'aimerais pouvoir créer une fenêtre sans bords, et en partie transparente. Par exemple, pour pouvoir afficher, disons, un cube au dessus des autres fenêtres, mais sans avoir rien autour.

    J'ai déjà lu quelques trucs de transparence pour GTK+, mais j'aurais voulu savoir quels étaient les autres librairies qui permettent ce genre de choses (Qt, glut, ...), et comment y parvenir. Et s'il faut passer par quelque chose de non portable, tant pis..

    Merci !

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    Bonjour !

    Mon post ne semblant pas inspiré grand monde, je n'en ai pas moins baissé mes recherches. Et je me suis finalement tourné vers X Window et Xlib... Au début, c'est pas toujours évident de s'y lancer, mais finalement c'est assez intéressant comme fonctionnement.

    Enfin, si jamais ce sujet intéresse quelqu'un, ma solution est plus bas. Mais j'ai maintenant une autre question, c'est de voir comment on peut obtenir facilement une pseudo-transparence... Quelqu'un aurait-il une idée ?

    Pour la transparence complète et la décoration des fenêtres, voici ce qu'il faut.
    Supposons qu'on travaille avec un Display display, et une Window window. Pour supprimer la décoration de la fenêtre, on utilise ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Atom xa = XInternAtom(display, "_MOTIF_WM_HINTS", False);
    if (xa != None)
    {
        long prop[5] = { 2, 0, 0, 0, 0 };
        XChangeProperty(display, window, xa, xa, 32, PropModeReplace, (unsigned char *) prop, 5);
    }
    Pour en rendre une partie transparente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    XShapeCombineMask (display, window, ShapeBounding, 0, 0, pmap, ShapeSet);
    où pmap est un Pixmap d'une profondeur de 1 bit, dont les pixels noirs correspondent aux pixels transparents.

    Et pour illustrer tout ça, voici un petit bout de code très rudimentaire qui crée une fenêtre, lui enlève sa décoration, et y introduit un petit rectangle transparent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    /*
     * transpwin.c
     * Pour compiler : gcc -Wall -g transpwin.c -o transpwin -lX11 -lXext
     */
    #include <X11/Xlib.h>
    #include <X11/X.h>
    #include <X11/extensions/shape.h>
    #include <unistd.h>
     
    int main(int argc, char** argv)
    {
        Display* display = XOpenDisplay( NULL );
        if (display == NULL)
        {
            return -1;
        }
        // On crée la fenêtre
        Window window = XCreateSimpleWindow( display, DefaultRootWindow(display), 250, 300, 500, 300, 0, 0xFF0000, 0x0000FF );
     
        // On enlève la décoration
        Atom xa = XInternAtom(display, "_MOTIF_WM_HINTS", False);
        if (xa != None)
        {
            long prop[5] = { 2, 0, 0, 0, 0 };
            XChangeProperty(display, window, xa, xa, 32, PropModeReplace, (unsigned char *) prop, 5);
        }
     
        XGCValues xgcv;
        xgcv.foreground = WhitePixel(display, DefaultScreen(display));
        xgcv.line_width = 1;
        xgcv.line_style = LineSolid;
        // Création d'un pixmap d'une profondeur de 1 bit
        Pixmap pmap = XCreatePixmap(display, window, 500, 300, 1);
        // GC pour dessiner sur le pixmap
        GC shape_gc = XCreateGC(display, pmap, 0, &xgcv);
        // On remplit le rectangle pour qu'il soit visible
        XSetForeground(display, shape_gc, 1);
        XFillRectangle(display, pmap, shape_gc, 0, 0, 500, 300);
        // On rend transparent un petit rectangle
        XSetForeground(display, shape_gc, 0);
        XFillRectangle(display, pmap, shape_gc, 50, 50, 50, 100);
        // On applique le pixmap de transparence à la fenêtre
        XShapeCombineMask (display, window, ShapeBounding, 0, 0, pmap, ShapeSet);
        // Suppression du pixmap
        XFreePixmap(display, pmap);
     
        XMapWindow(display, window);
        XFlush(display);
        sleep(5);
     
        XDestroyWindow(display, window);
        XCloseDisplay(display);
        return 0;
    }
    Voilà, en espérant que ça puisse en aider certains !

  3. #3
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par calving Voir le message
    Et je me suis finalement tourné vers X Window et Xlib... Au début, c'est pas toujours évident de s'y lancer, mais finalement c'est assez intéressant comme fonctionnement.
    Bravo

    C'est surtout que c'est la base du multi-fenêtrage multi-stations multi-OS moderne, et de toute la conception graphique d'aujourd'hui (GTK, Qt, Java, Swing, WxWidgets, OpenGL, etc).

    A part M$ et Windows et ses primitives "fermées", c'est la base de tout. Et cela a tellement été bien pensé qu'en 24 ans il n'y a eu que 3 révisions, aucune ne modifiant l'original, chacune n'ajoutant que 2 ou 3 fonctions (dont le traitement des espaces de couleur pour graphistes et TV).

    Connaître X c'est être à l'aise avec tout le graphisme, comprendre la POO, et événementielle.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    @souviron34 : Oui, X est vraiment agréable à manipuler, enfin, pour c que j'en fais en tous cas, et une fois passés les débuts difficiles. Par contre je suis pas super fan de la documentation, mais c'est sans doute moi qui cherche pas au bon endroit... En particulier pour la description des Atoms, extensions...

    Sinon pour mon second problème, j'ai finalement aussi trouvé une solution. Elle permet de régler l'opacité générale de la fenêtre, et donc de la rendre translucide (mais globalement, pas une partie uniquement). De nouveau, supposons qu'on ait un Display display, et une Window window, on peut régler l'opacité de window via la valeur de opacity comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include "X11/Xlib.h"
    #include "X11/Xatom.h"
    (...)
     
    // Opacité, comprise entre 0x00 et 0xFFFFFFFF
    unsigned long opacity = 0x80000000;
    XChangeProperty(display, window, XInternAtom(display, "_NET_WM_WINDOW_OPACITY", False),
                XA_CARDINAL, 32, PropModeReplace,
                (unsigned char *) &opacity, 1L);
    De nouveau, j'espère que ça servira !

  5. #5
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    euh ...

    Les atomes, c'est pour la communication avec le WM ... en particulier pour la communication entre applis. A priori on ne s'en sert que pour : mettre des protocoles (callbacks) pour les boutons des décos du WM (close, maximize, minimize,restore), gérer le statut initial de l'appli (iconifiée ou non), gérer le cut and paste, et gérer la communication inter-appli (données persistentes dans le serveur)

    Les propriétés, oui, ça marche. Cependant, il me semble me souvenir (pas le temps de regarder dans des archives peut-être disparues) que l'on pouvait directement changer le GC.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2008
    Messages : 10
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Les atomes, c'est pour la communication avec le WM ...
    Ici je pense qu'on communique avec le gestionnaire de composition justement, non ?

    Citation Envoyé par souviron34 Voir le message
    Les propriétés, oui, ça marche. Cependant, il me semble me souvenir (pas le temps de regarder dans des archives peut-être disparues) que l'on pouvait directement changer le GC.
    Ah ça, j'aimerais vraiment bien, mais je n'ai rien trouvé d'autre...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Créer une fenêtre sans bords
    Par N3odyme dans le forum C++
    Réponses: 2
    Dernier message: 06/07/2006, 00h27
  2. [C# 2.0] Créer une fenêtre non redimensionnable
    Par sqlnoob dans le forum Windows Forms
    Réponses: 4
    Dernier message: 26/06/2006, 11h22
  3. Réponses: 2
    Dernier message: 08/06/2006, 15h49
  4. Créer une fenêtre
    Par RaygKross dans le forum Qt
    Réponses: 12
    Dernier message: 08/02/2006, 09h34
  5. Créer une fenêtre flottante qui ne peut avoir le focus
    Par BestofMac dans le forum Composants VCL
    Réponses: 4
    Dernier message: 17/07/2002, 10h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo