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>