[RPL/2] Major bug in encart.c

BERTRAND Joël joel.bertrand at systella.fr
Mar 2 Nov 11:05:42 CET 2004


	Hello,

	I have found two bugs since the announce of the last beta release
	(4.00pre7n). The first one is in the configure.in script. libXpm or
	libXm cannot be found if they are not in /usr/lib (fixed now in my
	tree). The second one is more critical : if RPL/2 is built with
	Motif support (Xpm and Xm) and launched without X, it hangs due to a
	mistake in encart.c. The new encart.c is now:

//----- Begin of encart.c

/*
================================================================================
  RPL/2 version 4.00
    Interpréteur du langage de programmation du calculateur HP-28S,

    Date de création    : 02 Avril 1.998

    Tous droits réservés à l'auteur, Joël BERTRAND
================================================================================
*/

/*
================================================================================
  Copyright (C) 2001 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 GNU General Public License as published by the
  Free Software Foundation; either version 2, or (at your option) any
  later version.
 
  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 GNU General Public License
  for more details.
 
  You should have received a copy of the GNU General Public License
  along with Octave; see the file COPYING.  If not, write to the Free
  Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
================================================================================
*/


#include "rpl.h"

#ifdef MOTIF_SUPPORT
#	include <X11/Xlib.h>
#	include <X11/xpm.h>
#	include <Xm/XmAll.h>
#endif


/*
================================================================================
  Fonction 'encart'
================================================================================
  Entrées : pointeur sur une structure struct_processus
--------------------------------------------------------------------------------
  Sorties :
--------------------------------------------------------------------------------
  Effets de bord : néant
================================================================================
*/

void
encart(struct_processus *s_etat_processus, unsigned long duree)
{
#	ifdef MOTIF_SUPPORT
#	include "rpl.xpm"

	Display				*display;

	int					argc;
	int					erreur;
	int					hauteur;
	int					largeur;

	pid_t				pid;
	pid_t				pid_motif;

	Pixel				couleur_arriere_plan;
	Pixel				couleur_avant_plan;

	Pixmap				pixmap_rpl;
	Pixmap				pixmap_rpl_masque;

	Position			hauteur_popup;
	Position			largeur_popup;

	unsigned long		decor;
	unsigned long		fonctions;

	String				*argv;

	struct sigaction	action_courante;
	struct sigaction	action_passee;

	Widget				cadre;
	Widget				form;
	Widget				objet_principal;
	Widget				pixmap;
	Widget				popup;

	XtAppContext		app;

	argc = 0;
	argv = NULL;

	display = XOpenDisplay(NULL);

	if (display != NULL)
	{
		XCloseDisplay(display);

		action_courante.sa_handler = SIG_IGN;
		action_courante.sa_flags = SA_NOMASK | SA_ONSTACK;
		
		if (sigaction(SIGINT, &action_courante, &action_passee) != 0)
		{
			(*s_etat_processus).erreur_systeme = d_es_signal;
			return;
		}

		pid_motif = fork();

		if (pid_motif > 0)
		{
			if (waitpid(pid_motif, NULL, 0) == -1)
			{
				(*s_etat_processus).erreur_systeme = d_es_processus;
				return;
			}

			if (sigaction(SIGINT, &action_passee, NULL) != 0)
			{
				(*s_etat_processus).erreur_systeme = d_es_signal;
				return;
			}
		}
		else if (pid_motif == 0)
		{
			objet_principal = XtVaAppInitialize(&app, "",
					NULL, 0, &argc, argv, NULL, NULL);
			XSynchronize(XtDisplay(objet_principal), 0);

			popup = XtVaCreatePopupShell("fenêtre principale",
					transientShellWidgetClass, objet_principal, NULL);
			XtManageChild(popup);

			form = XtVaCreateWidget("form",
					xmFormWidgetClass, popup,
					NULL);
			XtManageChild(form);

			cadre = XtVaCreateWidget("cadre extérieur",
					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);
			XtManageChild(cadre);
			
			XtVaGetValues(popup,
					XmNforeground, &couleur_avant_plan,
					XmNbackground, &couleur_arriere_plan,
					NULL);

			if ((erreur = XCreatePixmapFromData(XtDisplay(popup),
					DefaultRootWindow(XtDisplay(popup)), rpl_xpm,
					&pixmap_rpl, &pixmap_rpl_masque, NULL)) != 0)
			{
				if (sigaction(SIGINT, &action_passee, NULL) != 0)
				{
					(*s_etat_processus).erreur_systeme = d_es_signal;
					return;
				}

				if ((*s_etat_processus).langue == 'F')
				{
					(*s_etat_processus).erreur_systeme =
							d_es_allocation_memoire;
					return;
				}
			}

			pixmap = XtVaCreateWidget("pixmap RPL/2",
					xmLabelWidgetClass, cadre,
					XmNlabelType, XmPIXMAP,
					XmNlabelPixmap, pixmap_rpl,
					NULL);
			XtManageChild(pixmap);

			XtVaGetValues(popup,
					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);

			largeur = WidthOfScreen(XtScreen(popup));
			hauteur = HeightOfScreen(XtScreen(popup));

			XtVaSetValues(popup,
					XmNmwmDecorations, decor,
					XmNmwmFunctions, fonctions,
					NULL);

			XtPopup(popup, XtGrabNone);

			XtVaGetValues(popup,
					XmNheight, &hauteur_popup,
					XmNwidth, &largeur_popup,
					NULL);
			XtVaSetValues(popup,
					XmNx, (largeur - largeur_popup) / 2,
					XmNy, (hauteur - hauteur_popup) / 2,
					NULL);

			XFlush(XtDisplay(popup));

			pid = fork();

			if (pid > 0)
			{
				usleep(duree);

				XtPopdown(popup);

				if (kill(pid, SIGTERM) != 0)
				{
					if (sigaction(SIGINT, &action_passee, NULL) != 0)
					{
						(*s_etat_processus).erreur_systeme = d_es_signal;
						return;
					}

					if ((*s_etat_processus).langue == 'F')
					{
						(*s_etat_processus).erreur_systeme = d_es_signal;
						return;
					}
				}

				if (waitpid(pid, NULL, 0) == -1)
				{
					if (sigaction(SIGINT, &action_passee, NULL) != 0)
					{
						(*s_etat_processus).erreur_systeme = d_es_signal;
						return;
					}

					(*s_etat_processus).erreur_systeme = d_es_processus;
					return;
				}
			}
			else if (pid == 0)
			{
				XtAppMainLoop(app);
			}
			else
			{
				if (sigaction(SIGINT, &action_passee, NULL) != 0)
				{
					(*s_etat_processus).erreur_systeme = d_es_signal;
					return;
				}

				if ((*s_etat_processus).langue == 'F')
				{
					(*s_etat_processus).erreur_systeme = d_es_signal;
					return;
				}
			}

			XtDestroyWidget(pixmap);
			XtDestroyWidget(cadre);
			XtDestroyWidget(form);
			XtDestroyWidget(popup);
			XtDestroyWidget(objet_principal);

			XmDestroyPixmap(XtScreen(popup), pixmap_rpl);
			XmDestroyPixmap(XtScreen(popup), pixmap_rpl_masque);

			if (sigaction(SIGINT, &action_passee, NULL) != 0)
			{
				(*s_etat_processus).erreur_systeme = d_es_signal;
				return;
			}

			exit(0);
		}
		else
		{
			if (sigaction(SIGINT, &action_passee, NULL) != 0)
			{
				(*s_etat_processus).erreur_systeme = d_es_signal;
				return;
			}

			if ((*s_etat_processus).langue == 'F')
			{
				(*s_etat_processus).erreur_systeme = d_es_signal;
				return;
			}
		}
	}
#	endif

	return;
}

// vim: ts=4


//-- End of encart.c

	Regards,

	JKB



Plus d'informations sur la liste de diffusion RPL2