File:  [local] / rpl / src / encart.c
Revision 1.61: download - view: text, annotated - select for diffs - revision graph
Mon Aug 21 09:06:02 2017 UTC (6 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Modifications pour que le splash screen apparaisse au milieu de l'écran
ayant la souris en cas de multi-écran.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.28
    4:   Copyright (C) 1989-2017 Dr. BERTRAND Joël
    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: 
   23: #include "rpl-conv.h"
   24: 
   25: #ifdef MOTIF_SUPPORT
   26: #   include <X11/Xlib.h>
   27: #   include "X11/xpm.h"
   28: #   include "Xm/XmAll.h"
   29: #   include <X11/extensions/Xinerama.h>
   30: #endif
   31: 
   32: static int
   33: _XlibErrorHandler(Display *display, XErrorEvent *event)
   34: {
   35:     uprintf("An error occured detecting the mouse position\n");
   36:     return True;
   37: }
   38: 
   39: void
   40: encart(struct_processus *s_etat_processus, integer8 duree)
   41: {
   42: #   ifdef MOTIF_SUPPORT
   43: #   include "rpl.xpm"
   44: 
   45:     Bool                mouse_found;
   46: 
   47:     Display             *display;
   48: 
   49:     int                 argc;
   50:     int                 erreur;
   51:     int                 hauteur;
   52:     int                 hauteur_xpm;
   53:     int                 i;
   54:     int                 largeur;
   55:     int                 largeur_xpm;
   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;
   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: 
   86:     long                decor;
   87:     long                fonctions;
   88: 
   89:     unsigned int        mask_return;
   90: 
   91:     Window              *root_windows;
   92:     Window              window_returned;
   93: 
   94:     Widget              cadre;
   95:     Widget              form;
   96:     Widget              objet_principal;
   97:     Widget              pixmap;
   98: 
   99:     XEvent              evenement;
  100: 
  101:     XineramaScreenInfo  *ts;
  102: 
  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: 
  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: 
  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,
  274:                 XmNx, offset_x + ((largeur - largeur_popup) / 2),
  275:                 XmNy, offset_y + ((hauteur - hauteur_popup) / 2),
  276:                 NULL);
  277: #else
  278:         sscanf(rpl_xpm[0], "%d %d", &largeur_xpm, &hauteur_xpm);
  279: 
  280:         largeur_popup = (Position) (largeur_xpm + 28);
  281:         hauteur_popup = (Position) (hauteur_xpm + 28);
  282: 
  283:         XtVaSetValues(objet_principal,
  284:                 XmNx, offset_x + ((largeur - largeur_popup) / 2),
  285:                 XmNy, offset_y + ((hauteur - hauteur_popup) / 2),
  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:             }
  319:         } while (((((double) temps_ecoule.tv_usec) / ((double) 1000000))
  320:                 + ((double) temps_ecoule.tv_sec))
  321:                 < (((double) duree) / ((double) 1000000)));
  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>