--- rpl/src/encart.c 2011/06/21 15:26:28 1.21 +++ rpl/src/encart.c 2020/01/10 11:15:42 1.74 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.0.prerelease.2 - Copyright (C) 1989-2011 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.32 + Copyright (C) 1989-2020 Dr. BERTRAND Joël This file is part of RPL/2. @@ -24,28 +24,67 @@ #ifdef MOTIF_SUPPORT # include -# include -# 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); +} + +#ifdef MOTIF_SUPPORT +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; +} +#endif void -encart(struct_processus *s_etat_processus, unsigned long duree) +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; - - Pixel couleur_arriere_plan; - Pixel couleur_avant_plan; + 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; @@ -53,6 +92,8 @@ encart(struct_processus *s_etat_processu Position hauteur_popup; Position largeur_popup; + Screen *screen; + String *argv; struct timespec attente; @@ -61,8 +102,13 @@ encart(struct_processus *s_etat_processu struct timeval horodatage_initial; struct timeval horodatage_final; - unsigned long decor; - unsigned long fonctions; + long decor; + long fonctions; + + unsigned int mask_return; + + Window *root_windows; + Window window_returned; Widget cadre; Widget form; @@ -71,8 +117,12 @@ encart(struct_processus *s_etat_processu 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"); @@ -88,16 +138,31 @@ encart(struct_processus *s_etat_processu if (display != NULL) { - XCloseDisplay(display); - objet_principal = XtVaOpenApplication(&app, "rpl", - NULL, 0, &argc, argv, NULL, topLevelShellWidgetClass, NULL); + 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, @@ -112,14 +177,9 @@ encart(struct_processus *s_etat_processu XmNmarginHeight, 5, NULL); - XtVaGetValues(form, - XmNforeground, &couleur_avant_plan, - XmNbackground, &couleur_arriere_plan, - NULL); - - if ((erreur = XCreatePixmapFromData(XtDisplay(form), + if ((erreur = XpmCreatePixmapFromData(XtDisplay(form), DefaultRootWindow(XtDisplay(form)), rpl_xpm, - &pixmap_rpl, &pixmap_rpl_masque, NULL)) != 0) + &pixmap_rpl, &pixmap_rpl_masque, NULL)) != XpmSuccess) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; @@ -131,23 +191,98 @@ encart(struct_processus *s_etat_processu XmNlabelPixmap, pixmap_rpl, NULL); - XtVaGetValues(objet_principal, - XmNmwmDecorations, &decor, - XmNmwmFunctions, &fonctions, - NULL); + if (XineramaIsActive(display) == True) + { + // Récupération de la localisation des différents écrans + // physiques. - 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); + ts = XineramaQueryScreens(display, &ns); - largeur = WidthOfScreen(XtScreen(form)); - hauteur = HeightOfScreen(XtScreen(form)); + //XSetErrorHandler(_XlibErrorHandler); + nb_screens = XScreenCount(display); - XtVaSetValues(objet_principal, - XmNmwmDecorations, decor, - XmNmwmFunctions, fonctions, - NULL); + 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; + } #if 0 XtRealizeWidget(objet_principal); @@ -158,18 +293,18 @@ encart(struct_processus *s_etat_processu NULL); XtVaSetValues(objet_principal, - XmNx, (largeur - largeur_popup) / 2, - XmNy, (hauteur - hauteur_popup) / 2, + 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 = largeur_xpm + 28; - hauteur_popup = hauteur_xpm + 28; + largeur_popup = (Position) (largeur_xpm + 28); + hauteur_popup = (Position) (hauteur_xpm + 28); XtVaSetValues(objet_principal, - XmNx, (largeur - largeur_popup) / 2, - XmNy, (hauteur - hauteur_popup) / 2, + XmNx, offset_x + ((largeur - largeur_popup) / 2), + XmNy, offset_y + ((hauteur - hauteur_popup) / 2), NULL); XtRealizeWidget(objet_principal); @@ -203,19 +338,12 @@ encart(struct_processus *s_etat_processu temps_ecoule.tv_usec += 1000000; temps_ecoule.tv_sec--; } - } while (((temps_ecoule.tv_usec / ((double) 1000000)) - + temps_ecoule.tv_sec) < (duree / ((double) 1000000))); + } while (((((double) temps_ecoule.tv_usec) / ((double) 1000000)) + + ((double) temps_ecoule.tv_sec)) + < (((double) duree) / ((double) 1000000))); XtUnrealizeWidget(objet_principal); - XmDestroyPixmap(XtScreen(form), pixmap_rpl); - XmDestroyPixmap(XtScreen(form), pixmap_rpl_masque); - - XtDestroyWidget(pixmap); - XtDestroyWidget(cadre); - XtDestroyWidget(form); - XtDestroyWidget(objet_principal); - while(XtAppPending(app) == 0) { nanosleep(&attente, NULL); @@ -228,7 +356,19 @@ encart(struct_processus *s_etat_processu nanosleep(&attente, NULL); } + screen = XtScreen(form); + + XtDestroyWidget(pixmap); + XtDestroyWidget(cadre); + XtDestroyWidget(form); + XtDestroyWidget(objet_principal); + + XmDestroyPixmap(screen, pixmap_rpl); + XmDestroyPixmap(screen, pixmap_rpl_masque); + + XtAppSetWarningHandler(app, old_message_handler); XtDestroyApplicationContext(app); + XCloseDisplay(display); } # endif