/* ================================================================================ RPL/2 (R) version 4.1.28 Copyright (C) 1989-2017 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" #ifdef MOTIF_SUPPORT # include # include "X11/xpm.h" # include "Xm/XmAll.h" # include #endif static logical1 valeur_erreur(logical1 nouvelle_valeur) { static logical1 erreur = d_faux; logical1 registre; registre = erreur; erreur = nouvelle_valeur; return(registre); } static int _XlibErrorHandler(Display *display, XErrorEvent *event) { valeur_erreur(d_vrai); uprintf("An error occured detecting the mouse position\n"); return True; } static void _XtWarningHandler(String message) { return; } void encart(struct_processus *s_etat_processus, integer8 duree) { # ifdef MOTIF_SUPPORT # include "rpl.xpm" Bool mouse_found; Display *display; int argc; int erreur; int hauteur; int hauteur_xpm; int i; int largeur; int largeur_xpm; int ns; int nb_screens; int offset_x; int offset_y; int root_x; int root_y; int win_x; int win_y; int x_max; int x_min; int y_max; int y_min; Pixmap pixmap_rpl; Pixmap pixmap_rpl_masque; Position hauteur_popup; Position largeur_popup; String *argv; struct timespec attente; struct timeval temps_ecoule; struct timeval horodatage_initial; struct timeval horodatage_final; long decor; long fonctions; unsigned int mask_return; Window *root_windows; Window window_returned; Widget cadre; Widget form; Widget objet_principal; Widget pixmap; XEvent evenement; XineramaScreenInfo *ts; XtAppContext app; XtErrorHandler old_message_handler; if (strstr(XmVERSION_STRING, "LessTif") != NULL) { printf("Lesstif is broken, please consider an upgrade to OpenMotif.\n"); return; } argc = 0; argv = NULL; display = XOpenDisplay(NULL); // Si display est nul, il n'y pas de serveur X. if (display != NULL) { objet_principal = XtVaOpenApplication(&app, "rpl", NULL, 0, &argc, argv, NULL, overrideShellWidgetClass, NULL); XSynchronize(XtDisplay(objet_principal), False); old_message_handler = XtAppSetWarningHandler(app, _XtWarningHandler); form = XtVaCreateManagedWidget("rplSplashScreen", xmFormWidgetClass, objet_principal, NULL); XtVaGetValues(objet_principal, XmNmwmDecorations, &decor, XmNmwmFunctions, &fonctions, NULL); decor &= ~(MWM_DECOR_ALL + MWM_DECOR_MAXIMIZE + MWM_DECOR_RESIZEH + MWM_DECOR_TITLE + MWM_DECOR_MENU + MWM_DECOR_BORDER); fonctions &= ~(MWM_FUNC_ALL + MWM_FUNC_RESIZE + MWM_FUNC_CLOSE + MWM_FUNC_MINIMIZE + MWM_FUNC_MAXIMIZE); XtVaSetValues(objet_principal, XmNmwmDecorations, decor, XmNmwmFunctions, fonctions, NULL); cadre = XtVaCreateManagedWidget("rplExternalFrame", xmFrameWidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNtopOffset, 5, XmNleftOffset, 5, XmNrightOffset, 5, XmNbottomOffset, 5, XmNmarginWidth, 5, XmNmarginHeight, 5, NULL); uprintf("0\n"); if ((erreur = XpmCreatePixmapFromData(XtDisplay(form), DefaultRootWindow(XtDisplay(form)), rpl_xpm, &pixmap_rpl, &pixmap_rpl_masque, NULL)) != 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } pixmap = XtVaCreateManagedWidget("rplPixmap", xmLabelWidgetClass, cadre, XmNlabelType, XmPIXMAP, XmNlabelPixmap, pixmap_rpl, NULL); uprintf("1\n"); if (XineramaIsActive(display) == True) { // Récupération de la localisation des différents écrans // physiques. ts = XineramaQueryScreens(display, &ns); //XSetErrorHandler(_XlibErrorHandler); nb_screens = XScreenCount(display); root_windows = sys_malloc(((unsigned) nb_screens) * sizeof(Window)); for(i = 0; i < nb_screens; i++) { root_windows[i] = XRootWindow(display, i); } for(i = 0; i < nb_screens; i++) { valeur_erreur(d_faux); do { mouse_found = XQueryPointer(display, root_windows[i], &window_returned, &window_returned, &root_x, &root_y, &win_x, &win_y, &mask_return); } while(valeur_erreur(d_faux) == d_vrai); if (mouse_found == True) { break; } } if (mouse_found == True) { mouse_found = False; for(i = 0; i < ns; i++) { x_min = ts[i].x_org; x_max = x_min + ts[i].width; y_min = ts[i].y_org; y_max = y_min + ts[i].height; if ((root_x >= x_min) && (root_x <= x_max) && (root_y >= y_min) && (root_y <= y_max)) { largeur = ts[i].width; hauteur = ts[i].height; offset_x = ts[i].x_org; offset_y = ts[i].y_org; mouse_found = True; break; } } if (mouse_found == False) { // Aucune souris sur un écran physique. largeur = ts[0].width; hauteur = ts[0].height; offset_x = 0; offset_y = 0; } } else { // Aucune souris, on considère le premier écran physique // géré par Xinerama. largeur = ts[0].width; hauteur = ts[0].height; offset_x = 0; offset_y = 0; } sys_free(root_windows); XFree(ts); } else { // Xinerama inactif, on considère qu'il n'y a qu'un seul // écran physique. largeur = WidthOfScreen(XtScreen(form)); hauteur = HeightOfScreen(XtScreen(form)); offset_x = 0; offset_y = 0; } uprintf("2\n"); #if 0 XtRealizeWidget(objet_principal); XtVaGetValues(objet_principal, XmNheight, &hauteur_popup, XmNwidth, &largeur_popup, NULL); XtVaSetValues(objet_principal, XmNx, offset_x + ((largeur - largeur_popup) / 2), XmNy, offset_y + ((hauteur - hauteur_popup) / 2), NULL); #else sscanf(rpl_xpm[0], "%d %d", &largeur_xpm, &hauteur_xpm); largeur_popup = (Position) (largeur_xpm + 28); hauteur_popup = (Position) (hauteur_xpm + 28); XtVaSetValues(objet_principal, XmNx, offset_x + ((largeur - largeur_popup) / 2), XmNy, offset_y + ((hauteur - hauteur_popup) / 2), NULL); XtRealizeWidget(objet_principal); #endif uprintf("3\n"); XFlush(XtDisplay(form)); uprintf("3a\n"); attente.tv_sec = 0; attente.tv_nsec = 1000; gettimeofday(&horodatage_initial, NULL); do { uprintf("3b\n"); if (XtAppPending(app) != 0) { uprintf("3c\n"); XtAppNextEvent(app, &evenement); uprintf("3d\n"); XtDispatchEvent(&evenement); uprintf("3e\n"); } uprintf("3f\n"); nanosleep(&attente, NULL); gettimeofday(&horodatage_final, NULL); temps_ecoule.tv_sec = horodatage_final.tv_sec - horodatage_initial.tv_sec; temps_ecoule.tv_usec = horodatage_final.tv_usec - horodatage_initial.tv_usec; if (temps_ecoule.tv_usec < 0) { temps_ecoule.tv_usec += 1000000; temps_ecoule.tv_sec--; } } while (((((double) temps_ecoule.tv_usec) / ((double) 1000000)) + ((double) temps_ecoule.tv_sec)) < (((double) duree) / ((double) 1000000))); uprintf("4\n"); XtUnrealizeWidget(objet_principal); uprintf("5\n"); while(XtAppPending(app) == 0) { nanosleep(&attente, NULL); } while(XtAppPending(app) != 0) { XtAppNextEvent(app, &evenement); XtDispatchEvent(&evenement); nanosleep(&attente, NULL); } XtDestroyWidget(pixmap); XtDestroyWidget(cadre); XtDestroyWidget(form); XtDestroyWidget(objet_principal); uprintf("6\n"); XmDestroyPixmap(XtScreen(form), pixmap_rpl); XmDestroyPixmap(XtScreen(form), pixmap_rpl_masque); XtAppSetWarningHandler(app, old_message_handler); XtDestroyApplicationContext(app); XCloseDisplay(display); uprintf("7\n"); } # endif return; } // vim: ts=4