src/video/x11/SDL_x11messagebox.c
changeset 6726 f2898757eaae
parent 6725 a7a99a9d419a
child 6758 2a218048b45f
equal deleted inserted replaced
6725:a7a99a9d419a 6726:f2898757eaae
    24 #if SDL_VIDEO_DRIVER_X11
    24 #if SDL_VIDEO_DRIVER_X11
    25 
    25 
    26 #include "SDL.h"
    26 #include "SDL.h"
    27 #include "SDL_x11video.h"
    27 #include "SDL_x11video.h"
    28 #include "SDL_x11dyn.h"
    28 #include "SDL_x11dyn.h"
       
    29 #include "SDL_assert.h"
    29 
    30 
    30 #include <locale.h>
    31 #include <locale.h>
       
    32 
       
    33 
       
    34 #define SDL_FORK_MESSAGEBOX 1
       
    35 
       
    36 #if SDL_FORK_MESSAGEBOX
       
    37 #include <sys/types.h>
       
    38 #include <sys/wait.h>
       
    39 #include <unistd.h>
       
    40 #include <errno.h>
       
    41 #endif
    31 
    42 
    32 #define MAX_BUTTONS             8       /* Maximum number of buttons supported */
    43 #define MAX_BUTTONS             8       /* Maximum number of buttons supported */
    33 #define MAX_TEXT_LINES          32      /* Maximum number of text lines supported */
    44 #define MAX_TEXT_LINES          32      /* Maximum number of text lines supported */
    34 #define MIN_BUTTON_WIDTH        64      /* Minimum button width */
    45 #define MIN_BUTTON_WIDTH        64      /* Minimum button width */
    35 #define MIN_DIALOG_WIDTH        200     /* Minimum dialog width */
    46 #define MIN_DIALOG_WIDTH        200     /* Minimum dialog width */
   623 
   634 
   624     XFreeGC( data->display, ctx );
   635     XFreeGC( data->display, ctx );
   625     return 0;
   636     return 0;
   626 }
   637 }
   627 
   638 
   628 /* Display an x11 message box. */
   639 static int
   629 int
   640 X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid)
   630 X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
       
   631 {
   641 {
   632     int ret;
   642     int ret;
   633     SDL_MessageBoxDataX11 data;
   643     SDL_MessageBoxDataX11 data;
   634     char *origlocale;
   644     char *origlocale;
   635 
   645 
   674     }
   684     }
   675 
   685 
   676     return ret;
   686     return ret;
   677 }
   687 }
   678 
   688 
       
   689 /* Display an x11 message box. */
       
   690 int
       
   691 X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
       
   692 {
       
   693 #if SDL_FORK_MESSAGEBOX
       
   694     /* Use a child process to protect against setlocale(). Annoying. */
       
   695     pid_t pid;
       
   696     int fds[2];
       
   697     int status = 0;
       
   698 
       
   699     if (pipe(fds) == -1) {
       
   700         return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */
       
   701     }
       
   702 
       
   703     pid = fork();
       
   704     if (pid == -1) {  /* failed */
       
   705         close(fds[0]);
       
   706         close(fds[1]);
       
   707         return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */
       
   708     } else if (pid == 0) {  /* we're the child */
       
   709         int exitcode = 0;
       
   710         close(fds[0]);
       
   711         status = X11_ShowMessageBoxImpl(messageboxdata, buttonid);
       
   712         if (write(fds[1], &status, sizeof (int)) != sizeof (int))
       
   713             exitcode = 1;
       
   714         else if (write(fds[1], buttonid, sizeof (int)) != sizeof (int))
       
   715             exitcode = 1;
       
   716         close(fds[1]);
       
   717         _exit(exitcode);  /* don't run atexit() stuff, static destructors, etc. */
       
   718     } else {  /* we're the parent */
       
   719         pid_t rc;
       
   720         close(fds[1]);
       
   721         do {
       
   722             rc = waitpid(pid, &status, 0);
       
   723         } while ((rc == -1) && (errno == EINTR));
       
   724 
       
   725         SDL_assert(rc == pid);  /* not sure what to do if this fails. */
       
   726 
       
   727         if ((rc == -1) || (!WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) {
       
   728             SDL_SetError("msgbox child process failed");
       
   729             return -1;
       
   730         }
       
   731 
       
   732         if (read(fds[0], &status, sizeof (int)) != sizeof (int))
       
   733             status = -1;
       
   734         else if (read(fds[0], buttonid, sizeof (int)) != sizeof (int))
       
   735             status = -1;
       
   736         close(fds[0]);
       
   737 
       
   738         return status;
       
   739     }
       
   740 #else
       
   741     return X11_ShowMessageBoxImpl(messageboxdata, buttonid);
       
   742 #endif
       
   743 }
   679 #endif /* SDL_VIDEO_DRIVER_X11 */
   744 #endif /* SDL_VIDEO_DRIVER_X11 */
   680 
   745 
   681 /* vi: set ts=4 sw=4 expandtab: */
   746 /* vi: set ts=4 sw=4 expandtab: */