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>