Annotation of rpl/src/encart.c, revision 1.61

1.1       bertrand    1: /*
                      2: ================================================================================
1.60      bertrand    3:   RPL/2 (R) version 4.1.28
1.58      bertrand    4:   Copyright (C) 1989-2017 Dr. BERTRAND Joël
1.1       bertrand    5: 
                      6:   This file is part of RPL/2.
                      7: 
                      8:   RPL/2 is free software; you can redistribute it and/or modify it
                      9:   under the terms of the CeCILL V2 License as published by the french
                     10:   CEA, CNRS and INRIA.
                     11:  
                     12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
                     13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                     14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
                     15:   for more details.
                     16:  
                     17:   You should have received a copy of the CeCILL License
                     18:   along with RPL/2. If not, write to info@cecill.info.
                     19: ================================================================================
                     20: */
                     21: 
                     22: 
1.11      bertrand   23: #include "rpl-conv.h"
1.1       bertrand   24: 
                     25: #ifdef MOTIF_SUPPORT
                     26: #  include <X11/Xlib.h>
1.28      bertrand   27: #  include "X11/xpm.h"
                     28: #  include "Xm/XmAll.h"
1.61    ! bertrand   29: #  include <X11/extensions/Xinerama.h>
1.1       bertrand   30: #endif
                     31: 
1.61    ! bertrand   32: static int
        !            33: _XlibErrorHandler(Display *display, XErrorEvent *event)
        !            34: {
        !            35:     uprintf("An error occured detecting the mouse position\n");
        !            36:     return True;
        !            37: }
1.1       bertrand   38: 
                     39: void
1.42      bertrand   40: encart(struct_processus *s_etat_processus, integer8 duree)
1.1       bertrand   41: {
                     42: #  ifdef MOTIF_SUPPORT
                     43: #  include "rpl.xpm"
                     44: 
1.61    ! bertrand   45:    Bool                mouse_found;
        !            46: 
1.1       bertrand   47:    Display             *display;
                     48: 
                     49:    int                 argc;
                     50:    int                 erreur;
                     51:    int                 hauteur;
                     52:    int                 hauteur_xpm;
1.61    ! bertrand   53:    int                 i;
1.1       bertrand   54:    int                 largeur;
                     55:    int                 largeur_xpm;
1.61    ! bertrand   56:    int                 ns;
        !            57:    int                 nb_screens;
        !            58:    int                 offset_x;
        !            59:    int                 offset_y;
        !            60:    int                 root_x;
        !            61:    int                 root_y;
        !            62:    int                 win_x;
        !            63:    int                 win_y;
        !            64:    int                 x_max;
        !            65:    int                 x_min;
        !            66:    int                 y_max;
        !            67:    int                 y_min;
1.1       bertrand   68: 
                     69:    Pixel               couleur_arriere_plan;
                     70:    Pixel               couleur_avant_plan;
                     71: 
                     72:    Pixmap              pixmap_rpl;
                     73:    Pixmap              pixmap_rpl_masque;
                     74: 
                     75:    Position            hauteur_popup;
                     76:    Position            largeur_popup;
                     77: 
                     78:    String              *argv;
                     79: 
                     80:    struct timespec     attente;
                     81: 
                     82:    struct timeval      temps_ecoule;
                     83:    struct timeval      horodatage_initial;
                     84:    struct timeval      horodatage_final;
                     85: 
1.42      bertrand   86:    long                decor;
                     87:    long                fonctions;
1.1       bertrand   88: 
1.61    ! bertrand   89:    unsigned int        mask_return;
        !            90: 
        !            91:    Window              *root_windows;
        !            92:    Window              window_returned;
        !            93: 
1.1       bertrand   94:    Widget              cadre;
                     95:    Widget              form;
                     96:    Widget              objet_principal;
                     97:    Widget              pixmap;
                     98: 
                     99:    XEvent              evenement;
                    100: 
1.61    ! bertrand  101:    XineramaScreenInfo  *ts;
        !           102: 
1.1       bertrand  103:    XtAppContext        app;
                    104: 
                    105:    if (strstr(XmVERSION_STRING, "LessTif") != NULL)
                    106:    {
                    107:        printf("Lesstif is broken, please consider an upgrade to OpenMotif.\n");
                    108:        return;
                    109:    }
                    110: 
                    111:    argc = 0;
                    112:    argv = NULL;
                    113: 
                    114:    display = XOpenDisplay(NULL);
                    115: 
                    116:    // Si display est nul, il n'y pas de serveur X.
                    117: 
                    118:    if (display != NULL)
                    119:    {
                    120:        objet_principal = XtVaOpenApplication(&app, "rpl",
                    121:                NULL, 0, &argc, argv, NULL, topLevelShellWidgetClass, NULL);
                    122:        XSynchronize(XtDisplay(objet_principal), False);
                    123: 
                    124:        form = XtVaCreateManagedWidget("rplSplashScreen",
                    125:                xmFormWidgetClass, objet_principal,
                    126:                NULL);
                    127: 
                    128:        cadre = XtVaCreateManagedWidget("rplExternalFrame",
                    129:                xmFrameWidgetClass, form,
                    130:                XmNtopAttachment, XmATTACH_FORM,
                    131:                XmNbottomAttachment, XmATTACH_FORM,
                    132:                XmNleftAttachment, XmATTACH_FORM,
                    133:                XmNrightAttachment, XmATTACH_FORM,
                    134:                XmNtopOffset, 5,
                    135:                XmNleftOffset, 5,
                    136:                XmNrightOffset, 5,
                    137:                XmNbottomOffset, 5,
                    138:                XmNmarginWidth, 5,
                    139:                XmNmarginHeight, 5,
                    140:                NULL);
                    141:        
                    142:        XtVaGetValues(form,
                    143:                XmNforeground, &couleur_avant_plan,
                    144:                XmNbackground, &couleur_arriere_plan,
                    145:                NULL);
                    146: 
                    147:        if ((erreur = XCreatePixmapFromData(XtDisplay(form),
                    148:                DefaultRootWindow(XtDisplay(form)), rpl_xpm,
                    149:                &pixmap_rpl, &pixmap_rpl_masque, NULL)) != 0)
                    150:        {
                    151:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    152:            return;
                    153:        }
                    154: 
                    155:        pixmap = XtVaCreateManagedWidget("rplPixmap",
                    156:                xmLabelWidgetClass, cadre,
                    157:                XmNlabelType, XmPIXMAP,
                    158:                XmNlabelPixmap, pixmap_rpl,
                    159:                NULL);
                    160: 
                    161:        XtVaGetValues(objet_principal,
                    162:                XmNmwmDecorations, &decor,
                    163:                XmNmwmFunctions, &fonctions,
                    164:                NULL);
                    165: 
                    166:        decor &= ~(MWM_DECOR_ALL + MWM_DECOR_MAXIMIZE + MWM_DECOR_RESIZEH
                    167:                + MWM_DECOR_TITLE + MWM_DECOR_MENU + MWM_DECOR_BORDER);
                    168:        fonctions &= ~(MWM_FUNC_ALL + MWM_FUNC_RESIZE + MWM_FUNC_CLOSE
                    169:                + MWM_FUNC_MINIMIZE + MWM_FUNC_MAXIMIZE);
                    170: 
                    171:        XtVaSetValues(objet_principal,
                    172:                XmNmwmDecorations, decor,
                    173:                XmNmwmFunctions, fonctions,
                    174:                NULL);
                    175: 
1.61    ! bertrand  176:        if (XineramaIsActive(display) == True)
        !           177:        {
        !           178:            // Récupération de la localisation des différents écrans
        !           179:            // physiques.
        !           180: 
        !           181:            ts = XineramaQueryScreens(display, &ns);
        !           182: 
        !           183:            XSetErrorHandler(_XlibErrorHandler);
        !           184:            nb_screens = XScreenCount(display);
        !           185: 
        !           186:            root_windows = sys_malloc(((unsigned) nb_screens) * sizeof(Window));
        !           187: 
        !           188:            for(i = 0; i < nb_screens; i++)
        !           189:            {
        !           190:                root_windows[i] = XRootWindow(display, i);
        !           191:            }
        !           192: 
        !           193:            for(i = 0; i < nb_screens; i++)
        !           194:            {
        !           195:                if ((mouse_found = XQueryPointer(display, root_windows[i],
        !           196:                        &window_returned, &window_returned,
        !           197:                        &root_x, &root_y, &win_x, &win_y, &mask_return))
        !           198:                        == True)
        !           199:                {
        !           200:                    break;
        !           201:                }
        !           202:            }
        !           203: 
        !           204:            if (mouse_found == True)
        !           205:            {
        !           206:                mouse_found = False;
        !           207: 
        !           208:                for(i = 0; i < ns; i++)
        !           209:                {
        !           210:                    x_min = ts[i].x_org;
        !           211:                    x_max = x_min + ts[i].width;
        !           212:                    y_min = ts[i].y_org;
        !           213:                    y_max = y_min + ts[i].height;
        !           214: 
        !           215:                    if ((root_x >= x_min) && (root_x <= x_max) &&
        !           216:                            (root_y >= y_min) && (root_y <= y_max))
        !           217:                    {
        !           218:                        largeur = ts[i].width;
        !           219:                        hauteur = ts[i].height;
        !           220:                        offset_x = ts[i].x_org;
        !           221:                        offset_y = ts[i].y_org;
        !           222: 
        !           223:                        mouse_found = True;
        !           224:                        break;
        !           225:                    }
        !           226:                }
        !           227: 
        !           228:                if (mouse_found == False)
        !           229:                {
        !           230:                    // Aucune souris sur un écran physique.
        !           231: 
        !           232:                    largeur = ts[0].width;
        !           233:                    hauteur = ts[0].height;
        !           234:                    offset_x = 0;
        !           235:                    offset_y = 0;
        !           236:                }
        !           237:            }
        !           238:            else
        !           239:            {
        !           240:                // Aucune souris, on considère le premier écran physique
        !           241:                // géré par Xinerama.
        !           242: 
        !           243:                largeur = ts[0].width;
        !           244:                hauteur = ts[0].height;
        !           245:                offset_x = 0;
        !           246:                offset_y = 0;
        !           247:            }
        !           248: 
        !           249:            sys_free(root_windows);
        !           250:            XFree(ts);
        !           251:        }
        !           252:        else
        !           253:        {
        !           254:            // Xinerama inactif, on considère qu'il n'y a qu'un seul
        !           255:            // écran physique.
        !           256:    
        !           257:            largeur = WidthOfScreen(XtScreen(form));
        !           258:            hauteur = HeightOfScreen(XtScreen(form));
        !           259:            offset_x = 0;
        !           260:            offset_y = 0;
        !           261:        }
        !           262: 
        !           263:        XCloseDisplay(display);
        !           264: 
1.1       bertrand  265: #if 0
                    266:        XtRealizeWidget(objet_principal);
                    267: 
                    268:        XtVaGetValues(objet_principal,
                    269:                XmNheight, &hauteur_popup,
                    270:                XmNwidth, &largeur_popup,
                    271:                NULL);
                    272: 
                    273:        XtVaSetValues(objet_principal,
1.61    ! bertrand  274:                XmNx, offset_x + ((largeur - largeur_popup) / 2),
        !           275:                XmNy, offset_y + ((hauteur - hauteur_popup) / 2),
1.1       bertrand  276:                NULL);
                    277: #else
                    278:        sscanf(rpl_xpm[0], "%d %d", &largeur_xpm, &hauteur_xpm);
                    279: 
1.42      bertrand  280:        largeur_popup = (Position) (largeur_xpm + 28);
                    281:        hauteur_popup = (Position) (hauteur_xpm + 28);
1.1       bertrand  282: 
                    283:        XtVaSetValues(objet_principal,
1.61    ! bertrand  284:                XmNx, offset_x + ((largeur - largeur_popup) / 2),
        !           285:                XmNy, offset_y + ((hauteur - hauteur_popup) / 2),
1.1       bertrand  286:                NULL);
                    287: 
                    288:        XtRealizeWidget(objet_principal);
                    289: #endif
                    290: 
                    291:        XFlush(XtDisplay(form));
                    292: 
                    293:        attente.tv_sec = 0;
                    294:        attente.tv_nsec = 1000;
                    295: 
                    296:        gettimeofday(&horodatage_initial, NULL);
                    297: 
                    298:        do
                    299:        {
                    300:            if (XtAppPending(app) != 0)
                    301:            {
                    302:                XtAppNextEvent(app, &evenement);
                    303:                XtDispatchEvent(&evenement);
                    304:            }
                    305: 
                    306:            nanosleep(&attente, NULL);
                    307:            gettimeofday(&horodatage_final, NULL);
                    308: 
                    309:            temps_ecoule.tv_sec = horodatage_final.tv_sec
                    310:                    - horodatage_initial.tv_sec;
                    311:            temps_ecoule.tv_usec = horodatage_final.tv_usec
                    312:                    - horodatage_initial.tv_usec;
                    313: 
                    314:            if (temps_ecoule.tv_usec < 0)
                    315:            {
                    316:                temps_ecoule.tv_usec += 1000000;
                    317:                temps_ecoule.tv_sec--;
                    318:            }
1.42      bertrand  319:        } while (((((double) temps_ecoule.tv_usec) / ((double) 1000000))
                    320:                + ((double) temps_ecoule.tv_sec))
                    321:                < (((double) duree) / ((double) 1000000)));
1.1       bertrand  322: 
                    323:        XtUnrealizeWidget(objet_principal);
                    324: 
                    325:        XmDestroyPixmap(XtScreen(form), pixmap_rpl);
                    326:        XmDestroyPixmap(XtScreen(form), pixmap_rpl_masque);
                    327: 
                    328:        XtDestroyWidget(pixmap);
                    329:        XtDestroyWidget(cadre);
                    330:        XtDestroyWidget(form);
                    331:        XtDestroyWidget(objet_principal);
                    332: 
                    333:        while(XtAppPending(app) == 0)
                    334:        {
                    335:            nanosleep(&attente, NULL);
                    336:        }
                    337: 
                    338:        while(XtAppPending(app) != 0)
                    339:        {
                    340:            XtAppNextEvent(app, &evenement);
                    341:            XtDispatchEvent(&evenement);
                    342:            nanosleep(&attente, NULL);
                    343:        }
                    344: 
                    345:        XtDestroyApplicationContext(app);
                    346:    }
                    347: #  endif
                    348: 
                    349:    return;
                    350: }
                    351: 
                    352: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>