Changeset 4549


Ignore:
Timestamp:
07/22/08 21:30:16 (5 years ago)
Author:
zecke
Message:

app_restarter: Use some e_alert.c code to provide a X11 interface to ask the user

Ask the user if an application should be restarted or not

Location:
developers/zecke/app_restarter
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • developers/zecke/app_restarter/app_restarter.c

    r4548 r4549  
    1515#include <stdio.h> 
    1616#include <stdlib.h> 
     17#include <string.h> 
    1718#include <unistd.h> 
    1819 
     20#include <X11/Xlib.h> 
     21#include <X11/X.h> 
     22 
    1923static void usage(char* name) 
    2024{ 
     
    2226} 
    2327 
    24 void fork_and_exec(char* file, int argc, char** argv) 
     28/* 
     29 * handle a crash. Open a display connection... create windows... 
     30 * ... 
     31 */ 
     32static void handle_crash(int status, const char* question) 
     33{ 
     34    Display* display; 
     35    Font font; 
     36    XFontStruct *fs = NULL; 
     37    GC gc = 0; 
     38    Window  win = 0, b1 = 0, b2 = 0; 
     39    char *title, *button1, *button2; 
     40    int wid, hih, mask, fw, fh, mh, button; 
     41    int ww = 320, hh = 240; 
     42    char line[1024]; 
     43    int w, i, j, k; 
     44    XSetWindowAttributes att; 
     45    XGCValues gcv; 
     46    XEvent ev; 
     47    KeyCode              key; 
     48 
     49    /* create the user interface */ 
     50    display = XOpenDisplay(NULL); 
     51    if (!display) { 
     52        fprintf(stderr, "Opening the X display failed\n"); 
     53        exit(-1); 
     54    } 
     55 
     56    font = XLoadFont(display, "fixed"); 
     57    fs = XQueryFont(display, font); 
     58    if (!fs) { 
     59        fprintf(stderr, "XQueryFont failed\n"); 
     60        exit(-1); 
     61    } 
     62 
     63    title = "Application Error"; 
     64    button1 = "(F1) Restart"; 
     65    button2 = "(F2) Exit"; 
     66 
     67    wid = DisplayWidth(display, DefaultScreen(display)); 
     68    hih = DisplayHeight(display, DefaultScreen(display)); 
     69     
     70 
     71    att.background_pixel = WhitePixel(display, DefaultScreen(display)); 
     72    att.border_pixel     = BlackPixel(display, DefaultScreen(display)); 
     73    att.override_redirect = True; 
     74    mask = CWBackPixel | CWBorderPixel | CWOverrideRedirect; 
     75 
     76    win = XCreateWindow(display, DefaultRootWindow(display),  
     77                        (wid - ww) / 2, (hih - hh) / 2, ww, hh, 0, 
     78                        CopyFromParent, InputOutput, 
     79                        CopyFromParent, mask, &att); 
     80 
     81    b1 = XCreateWindow(display, win, -100, -100, 1, 1, 0, CopyFromParent, 
     82                       InputOutput, CopyFromParent, mask, &att); 
     83    b2 = XCreateWindow(display, win, -100, -100, 1, 1, 0, CopyFromParent, 
     84                       InputOutput, CopyFromParent, mask, &att); 
     85    XMapWindow(display, b1); 
     86    XMapWindow(display, b2); 
     87 
     88    gc = XCreateGC(display, win, 0, &gcv); 
     89    XSetForeground(display, gc, att.border_pixel); 
     90    XSelectInput(display, win, KeyPressMask | KeyReleaseMask | ExposureMask); 
     91 
     92    /* place the dialog */ 
     93    XMapWindow(display, win); 
     94 
     95 
     96    /* handle the events */ 
     97    fh = fs->ascent + fs->descent; 
     98    mh = ((ww - 20) / 2) - 20; 
     99 
     100    /* fixed size... */ 
     101    w = 20; 
     102    XMoveResizeWindow(display, b1, w, hh - 15 - fh, mh + 10, fh + 10); 
     103    XSelectInput(display, b1, ButtonPressMask | ButtonReleaseMask | ExposureMask); 
     104    w = ww - 20 - mh; 
     105    XMoveResizeWindow(display, b2, w, hh - 15 - fh, mh + 10, fh + 10); 
     106    XSelectInput(display, b2, ButtonPressMask | ButtonReleaseMask | ExposureMask); 
     107 
     108    XMapWindow(display, win); 
     109    XGrabPointer(display, win, True, ButtonPressMask | ButtonReleaseMask, 
     110            GrabModeAsync, GrabModeAsync, None, None, CurrentTime); 
     111    XGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); 
     112    XSetInputFocus(display, win, RevertToPointerRoot, CurrentTime); 
     113    XSync(display, False); 
     114 
     115    button = 0; 
     116    for (; button == 0;) { 
     117        XNextEvent(display, &ev); 
     118        switch (ev.type) { 
     119        case KeyPress: 
     120            key = XKeysymToKeycode(display, XStringToKeysym("F1")); 
     121            if (key == ev.xkey.keycode) { 
     122                button = 1; 
     123                break; 
     124            } 
     125            key = XKeysymToKeycode(display, XStringToKeysym("F2")); 
     126            if (key == ev.xkey.keycode) { 
     127                button = 2; 
     128                break; 
     129            } 
     130            break; 
     131        case ButtonPress: 
     132            if (ev.xbutton.window == b1) 
     133                button = 1; 
     134            else if (ev.xbutton.window == b2) 
     135                button = 2; 
     136            break; 
     137        case Expose: 
     138            while (XCheckTypedWindowEvent(display, ev.xexpose.window, Expose, &ev)); 
     139 
     140            /* outline */ 
     141            XDrawRectangle(display, win, gc, 0, 0, ww - 1, hh - 1); 
     142 
     143            XDrawRectangle(display, win, gc, 2, 2, ww - 4 - 1, fh + 4 - 1); 
     144 
     145            fw = XTextWidth(fs, title, strlen(title)); 
     146            XDrawString(display, win, gc, 2 + 2 + ((ww - 4 - 4 - fw) / 2) , 2 + 2 + fs->ascent, title, strlen(title)); 
     147 
     148            i = 0; 
     149            j = 0; 
     150            k = 2 + fh + 4 + 2; 
     151            while (question[i]) { 
     152                line[j++] = question[i++]; 
     153                if (line[j - 1] == '\n') { 
     154                    line[j - 1] = 0; 
     155                    j = 0; 
     156                    XDrawString(display, win, gc, 4, k + fs->ascent, line, strlen(line)); 
     157                    k += fh + 2; 
     158                } 
     159            } 
     160            fw = XTextWidth(fs, button2, strlen(button1)); 
     161            XDrawRectangle(display, b1, gc, 0, 0, mh - 1, fh + 10 - 1); 
     162            XDrawString(display, b1, gc, 5 + ((mh - fw) / 2), 5 + fs->ascent, button1, strlen(button1)); 
     163 
     164            fw = XTextWidth(fs, button2, strlen(button2)); 
     165            XDrawRectangle(display, b2, gc, 0, 0, mh - 1, fh + 10 - 1); 
     166            XDrawString(display, b2, gc, 5 + ((mh - fw) / 2), 5 + fs->ascent, button2, strlen(button2)); 
     167 
     168            XSync(display, False); 
     169            break; 
     170 
     171        default: 
     172            break; 
     173        } 
     174    } 
     175 
     176 
     177    /* destruct the X connection and give up the resources */ 
     178    XDestroyWindow(display, win); 
     179    XFreeGC(display, gc); 
     180    XFreeFont(display, fs); 
     181    XSync(display, False); 
     182    XCloseDisplay(display); 
     183 
     184    switch (button) { 
     185    case 2: 
     186        fprintf(stderr, "Was asked to quit. Bye Bye\n"); 
     187        exit(-11); 
     188    case 1: 
     189    default: 
     190        break; 
     191    } 
     192} 
     193 
     194 
     195/* 
     196 * Fork and execute the command, wait for the command to finish. 
     197 * On any kind of exit ask the user to restart 
     198 */ 
     199int fork_and_exec(char* file, int argc, char** argv) 
    25200{ 
    26201    pid_t pid = vfork(); 
     
    37212 
    38213        fprintf(stderr, "The process exited: %d normal: %d\n", status, WIFEXITED(status)); 
    39     } 
     214        return status; 
     215    } 
     216 
     217    assert(0); 
    40218} 
    41219 
     
    46224    if (argc < 3) { 
    47225        usage(argv[0]); 
     226        return EXIT_FAILURE; 
     227    } 
     228 
     229    if (strlen(argv[1]) >= 1024) { 
     230        fprintf(stderr, "The comment string has to be less than 1024 bytes\n"); 
    48231        return EXIT_FAILURE; 
    49232    } 
     
    56239    command_arguments[commands] = NULL; 
    57240 
    58     for (;;) 
    59         fork_and_exec(argv[2], commands, command_arguments); 
    60 } 
     241    for (;;) { 
     242        int status = fork_and_exec(argv[2], commands, command_arguments); 
     243        handle_crash(status, argv[1]); 
     244    } 
     245} 
Note: See TracChangeset for help on using the changeset viewer.