home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume1 / lpqtool / lpqtool.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-07-20  |  13.3 KB  |  434 lines

  1. /************************************************************************/
  2. /*    Copyright 1988 by Chuck Musciano and Harris Corporation        */
  3. /*                                    */
  4. /*    Permission to use, copy, modify, and distribute this software    */
  5. /*    and its documentation for any purpose and without fee is    */
  6. /*    hereby granted, provided that the above copyright notice    */
  7. /*    appear in all copies and that both that copyright notice and    */
  8. /*    this permission notice appear in supporting documentation, and    */
  9. /*    that the name of Chuck Musciano and Harris Corporation not be    */
  10. /*    used in advertising or publicity pertaining to distribution    */
  11. /*    of the software without specific, written prior permission.    */
  12. /*    Chuck Musciano and Harris Corporation make no representations    */
  13. /*    about the suitability of this software for any purpose.  It is    */
  14. /*    provided "as is" without express or implied warranty.        */
  15. /************************************************************************/
  16.  
  17.  
  18. #include    <suntool/sunview.h>
  19. #include    <suntool/panel.h>
  20. #include    <suntool/canvas.h>
  21.  
  22. #include    <stdio.h>
  23.  
  24. #define        LPQ            "/usr/ucb/lpq"
  25.  
  26. #define        ICON_PATH        "laserwriter.icon"
  27.  
  28. #define        NORMAL_FONT        "/usr/lib/fonts/fixedwidthfonts/screen.r.14"
  29. #define        BOLD_FONT        "/usr/lib/fonts/fixedwidthfonts/screen.b.14"
  30.  
  31. #define        NO_STATE        0
  32. #define        IDLE_STATE        1
  33. #define        ACTIVE_STATE        2
  34. #define        CHECK_STATE        3
  35.  
  36. static    char    *lp_usage = "usage: lpqtool [-a <interval>] [-c] [-i <interval>] [-o] [-r <rows>] [-t <idle threshold>] [ <printer> ]\n";
  37.  
  38. static    short    lp_icon_image[] = {
  39. #include    ICON_PATH
  40. };
  41. mpr_static(lp_icon_pixrect, 64, 30, 1, lp_icon_image);
  42.  
  43. struct    itimerval    active    = {{10, 0}, {10, 0}};
  44. struct    itimerval    idle    = {{60, 0}, {60, 0}};
  45. int    active_open        = FALSE;
  46. int    idle_closed        = FALSE;
  47. int    idle_threshold        = 6;
  48. int    queue_rows        = 5;
  49. int    idle_count, stay_idle;
  50. int    state            = NO_STATE;
  51. char    user[30];
  52. char    *printer_name;
  53.  
  54. Icon    icon;
  55. Frame    frame;
  56. Canvas    status, queue;
  57. Panel    panel;
  58. Pixwin    *spw, *qpw;
  59. struct    pixfont    *normal_font, *bold_font;
  60. Panel_item    a_item, i_item, a_light, i_light, c_light, a_button, i_button, c_button;
  61.  
  62. /************************************************************************/
  63. static    char    *right_str(val, width)
  64.  
  65. int    val;
  66. int    width;
  67.  
  68. {    static    char    buf[20];
  69.  
  70.     sprintf(buf, "%*d", width, val);
  71.     return(buf);
  72. }
  73.  
  74. /************************************************************************/
  75. static    set_status(st)
  76.  
  77. int    st;
  78.  
  79. {
  80.     panel_set(a_light, PANEL_SHOW_ITEM, FALSE, 0);
  81.     panel_set(i_light, PANEL_SHOW_ITEM, FALSE, 0);
  82.     panel_set(c_light, PANEL_SHOW_ITEM, FALSE, 0);
  83.     if (st == IDLE_STATE)
  84.        panel_set(i_light, PANEL_SHOW_ITEM, TRUE, 0);
  85.     else if (st == ACTIVE_STATE)
  86.        panel_set(a_light, PANEL_SHOW_ITEM, TRUE, 0);
  87.     else if (st == CHECK_STATE)
  88.        panel_set(c_light, PANEL_SHOW_ITEM, TRUE, 0);
  89. }
  90. /************************************************************************/
  91. static    update_queue()
  92.  
  93. {    FILE    *f;
  94.     char    buf[256];
  95.     int    line = 2, new_state = NO_STATE;
  96.  
  97.     set_status(CHECK_STATE);
  98.     sprintf(buf, "%s%s%s", LPQ, *printer_name? " -P" : "", printer_name);
  99.     if ((f = popen(buf, "r")) == NULL) {
  100.        pw_output(spw, 2, 5, TRUE, "Unable to obtain queue information");
  101.        pw_rop(qpw, 0, 0, window_get(queue, WIN_WIDTH), window_get(queue, WIN_HEIGHT), PIX_SRC | PIX_COLOR(0), NULL, 0, 0);
  102.        pclose(f);
  103.        return;
  104.        }
  105.     if (fgets(buf, 256, f) != NULL) {
  106.        buf[strlen(buf) - 1] = '\0';
  107.        pw_output(spw, 1, 1, TRUE, "Status:");
  108.        pw_output(spw, 2, 5, TRUE, buf);
  109.        pw_rop(qpw, 0, 0, window_get(queue, WIN_WIDTH), window_get(queue, WIN_HEIGHT), PIX_SRC | PIX_COLOR(0), NULL, 0, 0);
  110.        if (strcmp(buf, "no entries") == 0)
  111.           new_state = IDLE_STATE;
  112.        else
  113.           new_state = ACTIVE_STATE;
  114.        }
  115.     while (fgets(buf, 256, f) != NULL) {
  116.        buf[strlen(buf) - 1] = '\0';
  117.        if (strncmp(buf, "Rank", 4) == 0) {
  118.           if (new_state == IDLE_STATE)
  119.              new_state = ACTIVE_STATE;
  120.           continue;
  121.           }
  122.        else if (verify(buf, " \t\n\r"))
  123.           continue;
  124.        else {
  125.           if (line == 2)
  126.              pw_output(qpw, 1, 1, TRUE, "Rank   Owner      Job  Files                                 Total Size");
  127.           pw_output(qpw, line++, 1, strindex(buf, user), buf);
  128.           }
  129.        }
  130.     pclose(f);
  131.     if (new_state == IDLE_STATE) {
  132.        stay_idle = FALSE;
  133.        if (state == ACTIVE_STATE && --idle_count <= 0)
  134.           go_idle();
  135.        }
  136.     else if (new_state == ACTIVE_STATE && !stay_idle)
  137.        go_active();
  138.     set_status(state);
  139. }
  140.  
  141. /************************************************************************/
  142. static    Panel_setting    number_proc(item, event)
  143.  
  144. Panel_item    item;
  145. Event        *event;
  146.  
  147. {    char    buf[80];
  148.     int    val;
  149.  
  150.     strcpy(buf, panel_get_value(item));
  151.     val = atoi(buf);
  152.     if (event_id(event) >= '1' && event_id(event) <= '9') {
  153.        val = val * 10 + event_id(event) - '0';
  154.        panel_set(item, PANEL_VALUE, right_str(val, 5), 0);
  155.        return(PANEL_NONE);
  156.        }
  157.     else if (event_id(event) == '0')
  158.        if (item == a_item && val == 0)
  159.           return(PANEL_NONE);
  160.        else {
  161.           val = val * 10 + event_id(event) - '0';
  162.           panel_set(item, PANEL_VALUE, right_str(val, 5), 0);
  163.           return(PANEL_NONE);
  164.           }
  165.     else if (event_id(event) == '\010') {
  166.        val /= 10;
  167.        panel_set(item, PANEL_VALUE, right_str(val, 5), 0);
  168.        return(PANEL_NONE);
  169.        }
  170.     else if (event_id(event) == '\177') {
  171.        panel_set(item, PANEL_VALUE, "     ", 0);
  172.        return(PANEL_NONE);
  173.        }
  174.     else if (event_id(event) == '\n' || event_id(event) == '\r') {
  175.        if (item == a_item) {
  176.           active.it_value.tv_sec = active.it_interval.tv_sec = val;
  177.           if (state == ACTIVE_STATE)
  178.              notify_set_itimer_func(frame, update_queue, ITIMER_REAL, &active, NULL);
  179.           }
  180.        else {
  181.           idle.it_value.tv_sec = idle.it_interval.tv_sec = val;
  182.           if (state == IDLE_STATE)
  183.              notify_set_itimer_func(frame, update_queue, ITIMER_REAL, &idle, NULL);
  184.           }
  185.        return(PANEL_NONE);
  186.        }
  187.     else
  188.        return(PANEL_NONE);
  189. }
  190.     
  191. /************************************************************************/
  192. static    go_idle()
  193.  
  194. {
  195.     if (state == IDLE_STATE)
  196.        return;
  197.     state = IDLE_STATE;
  198.     if (idle_closed)
  199.        window_set(frame, FRAME_CLOSED, TRUE, 0);
  200.     if (idle.it_value.tv_sec != 0)
  201.        notify_set_itimer_func(frame, update_queue, ITIMER_REAL, &idle, NULL);
  202.     else
  203.        notify_set_itimer_func(frame, update_queue, ITIMER_REAL, NULL, NULL);
  204.     set_status(IDLE_STATE);
  205. }
  206.  
  207. /************************************************************************/
  208. static    go_active()
  209.  
  210. {
  211.     idle_count = idle_threshold;
  212.     if (state == ACTIVE_STATE)
  213.        return;
  214.     state = ACTIVE_STATE;
  215.     if (active_open)
  216.        window_set(frame, FRAME_CLOSED, FALSE, 0);
  217.     update_queue();
  218.     notify_set_itimer_func(frame, update_queue, ITIMER_REAL, &active, NULL);
  219.     set_status(ACTIVE_STATE);
  220. }
  221.  
  222. /************************************************************************/
  223. static    pw_output(pw, row, col, bold, str)
  224.  
  225. Pixwin    *pw;
  226. int    row;
  227. int    col;
  228. int    bold;
  229. char    *str;
  230.  
  231. {
  232.     row = (row - 1) * normal_font->pf_defaultsize.y;
  233.     col = (col - 1) * normal_font->pf_defaultsize.x + 4;
  234.     pw_text(pw, col, row - normal_font->pf_char['0'].pc_home.y, PIX_SRC, normal_font, str);
  235.     if (bold)
  236.        pw_text(pw, col + 1, row - normal_font->pf_char['0'].pc_home.y, PIX_SRC | PIX_DST, normal_font, str);
  237.     col += strlen(str) * normal_font->pf_defaultsize.x;
  238.     pw_rop(pw, col, row, pw->pw_pixrect->pr_size.x - col, normal_font->pf_defaultsize.y, PIX_SRC | PIX_COLOR(0), NULL, 0, 0);
  239. }
  240.  
  241. /************************************************************************/
  242. static    Notify_value    close_proc(frame, event, arg, type)
  243.  
  244. Frame    frame;
  245. Event    *event;
  246. Notify_arg    arg;
  247. Notify_event_type    type;
  248.  
  249. {    int    init_closed, curr_closed, is_resize;
  250.     Notify_value    value;
  251.     Rect    *temp;
  252.  
  253.     init_closed = (int) window_get(frame, FRAME_CLOSED);
  254.     value = notify_next_event_func(frame, event, arg, type);
  255.     curr_closed = (int) window_get(frame, FRAME_CLOSED);
  256.     if (init_closed != curr_closed)
  257.        if (curr_closed) {
  258.           stay_idle = (state == ACTIVE_STATE);
  259.           go_idle();
  260.           }
  261.        else
  262.           go_active();
  263.     return(value);
  264. }
  265.  
  266. /************************************************************************/
  267. main(argc, argv)
  268.  
  269. int    argc;
  270. char    **argv;
  271.  
  272. {    char    c, *s, **saveargs();
  273.     int    i, interval = 10;
  274.     Rect    *r;
  275.  
  276.     normal_font = pf_open(NORMAL_FONT);
  277.     bold_font = pf_open(BOLD_FONT);
  278.     icon = icon_create(ICON_IMAGE, &lp_icon_pixrect, 
  279.                ICON_LABEL, NULL, 
  280.                ICON_WIDTH, lp_icon_pixrect.pr_size.x, 
  281.                ICON_HEIGHT, lp_icon_pixrect.pr_size.y,
  282.                0);
  283.     frame = window_create(NULL, FRAME,
  284.                  FRAME_ICON, icon,
  285.                  FRAME_LABEL, "<< LaserWriter Queue Status >>",
  286.                      FRAME_ARGC_PTR_ARGV, &argc, argv,
  287.                   0);
  288.  
  289.     argv = saveargs(argc, argv);
  290.     while ((c = getopt(&argc, argv, "a:ci:or:t:", &s)) != EOF)
  291.        switch (c) {
  292.           case 'a' : if (verify(s, "0123456789")) {
  293.                       active.it_value.tv_sec = active.it_interval.tv_sec = atoi(s);
  294.                       if (active.it_value.tv_sec <= 0)
  295.                          abend("invalid active interval: %s\n", s);
  296.                       }
  297.                    else
  298.                       abend("invalid active interval: %s\n", s);
  299.                    break;
  300.           case 'c' : idle_closed = TRUE;
  301.                    break;
  302.           case 'i' : if (verify(s, "0123456789")) {
  303.                       idle.it_value.tv_sec = idle.it_interval.tv_sec = atoi(s);
  304.                       if (idle.it_value.tv_sec < 0)
  305.                          abend("invalid idle interval: %s\n", s);
  306.                       }
  307.                    else
  308.                       abend("invalid idle interval: %s\n", s);
  309.                    break;
  310.           case 'o' : active_open = TRUE;
  311.                    break;
  312.           case 'r' : if (verify(s, "0123456789")) {
  313.                       queue_rows = atoi(s);
  314.                       if (queue_rows <= 0)
  315.                          abend("invalid number of queue lines: %s\n", s);
  316.                       }
  317.                    else
  318.                       abend("invalid number of queue lines: %s\n", s);
  319.                    break;
  320.           case 't' : if (verify(s, "0123456789")) {
  321.                       idle_threshold = atoi(s);
  322.                       if (idle_threshold <= 0)
  323.                          abend("invalid idle thresold: %s\n", s);
  324.                       }
  325.                    else
  326.                       abend("invalid idle threshold: %s\n", s);
  327.                    break;
  328.           case '?' : fprintf(stderr, lp_usage);
  329.                    break;
  330.           default  : abend(lp_usage);
  331.                    break;
  332.           }
  333.  
  334.     panel = window_create(frame, PANEL,
  335.                  PANEL_FONT, normal_font,
  336.                  WIN_COLUMNS, 75,
  337.                   0);
  338.     a_item = panel_create_item(panel, PANEL_TEXT, 
  339.                       PANEL_LABEL_STRING, "Active Interval:",
  340.                       PANEL_LABEL_BOLD, TRUE,
  341.                       PANEL_ITEM_Y, ATTR_ROW(0) + 1,
  342.                       PANEL_VALUE_DISPLAY_LENGTH, 5,
  343.                       PANEL_VALUE, right_str(active.it_value.tv_sec, 5),
  344.                       PANEL_NOTIFY_PROC, number_proc,
  345.                       PANEL_NOTIFY_LEVEL, PANEL_ALL,
  346.                    0);
  347.     a_light = panel_create_item(panel, PANEL_MESSAGE,
  348.                        PANEL_LABEL_STRING, "Active",
  349.                        PANEL_LABEL_BOLD, TRUE,
  350.                     0);
  351.     i_light = panel_create_item(panel, PANEL_MESSAGE,
  352.                        PANEL_LABEL_STRING, "Idle",
  353.                        PANEL_LABEL_BOLD, TRUE,
  354.                     0);
  355.     c_light = panel_create_item(panel, PANEL_MESSAGE,
  356.                        PANEL_LABEL_STRING, "Checking",
  357.                        PANEL_LABEL_BOLD, TRUE,
  358.                     0);
  359.     i_item = panel_create_item(panel, PANEL_TEXT, 
  360.                       PANEL_LABEL_STRING, "Idle Interval:  ",
  361.                       PANEL_LABEL_BOLD, TRUE,
  362.                       PANEL_VALUE_DISPLAY_LENGTH, 5,
  363.                       PANEL_ITEM_X, ATTR_COL(0), 
  364.                       PANEL_ITEM_Y, ATTR_ROW(1) + 4,
  365.                       PANEL_VALUE, right_str(idle.it_value.tv_sec, 5),
  366.                       PANEL_NOTIFY_PROC, number_proc,
  367.                       PANEL_NOTIFY_LEVEL, PANEL_ALL,
  368.                    0);
  369.     a_button = panel_create_item(panel, PANEL_BUTTON,
  370.                     PANEL_ITEM_Y, ATTR_ROW(1),
  371.                     PANEL_ITEM_X, ATTR_COL(26),
  372.                     PANEL_LABEL_IMAGE, better_button_image(panel, "Go Active", 12, 5, bold_font),
  373.                     PANEL_NOTIFY_PROC, go_active,
  374.                      0);
  375.     i_button = panel_create_item(panel, PANEL_BUTTON,
  376.                     PANEL_ITEM_Y, ATTR_ROW(1),
  377.                     PANEL_LABEL_IMAGE, better_button_image(panel, "Go Idle", 12, 5, bold_font),
  378.                     PANEL_NOTIFY_PROC, go_idle,
  379.                      0);
  380.     c_button = panel_create_item(panel, PANEL_BUTTON,
  381.                     PANEL_ITEM_Y, ATTR_ROW(1),
  382.                     PANEL_LABEL_IMAGE, better_button_image(panel, "Check Queue", 12, 5, bold_font),
  383.                     PANEL_NOTIFY_PROC, update_queue,
  384.                      0);
  385.     r = (Rect *) panel_get(a_button, PANEL_ITEM_RECT);
  386.     i = r->r_left + r->r_width / 2;
  387.     r = (Rect *) panel_get(a_light, PANEL_ITEM_RECT);
  388.     panel_set(a_light, PANEL_ITEM_X, i - r->r_width / 2, 0);
  389.     r = (Rect *) panel_get(i_button, PANEL_ITEM_RECT);
  390.     i = r->r_left + r->r_width / 2;
  391.     r = (Rect *) panel_get(i_light, PANEL_ITEM_RECT);
  392.     panel_set(i_light, PANEL_ITEM_X, i - r->r_width / 2, 0);
  393.     r = (Rect *) panel_get(c_button, PANEL_ITEM_RECT);
  394.     i = r->r_left + r->r_width / 2;
  395.     r = (Rect *) panel_get(c_light, PANEL_ITEM_RECT);
  396.     panel_set(c_light, PANEL_ITEM_X, i - r->r_width / 2, 0);
  397.     window_fit_height(panel);
  398.  
  399.     status = window_create(frame, CANVAS,
  400.                   WIN_HEIGHT, normal_font->pf_defaultsize.y * 2,
  401.                   WIN_WIDTH, normal_font->pf_defaultsize.x * 75,
  402.                   WIN_X, 0,
  403.                   WIN_BELOW, panel,
  404.                    0);
  405.     spw = canvas_pixwin(status);
  406.     queue = window_create(frame, CANVAS,
  407.                  WIN_HEIGHT, normal_font->pf_defaultsize.y * (queue_rows + 1),
  408.                  WIN_WIDTH, normal_font->pf_defaultsize.x * 75,
  409.                  WIN_X, 0,
  410.                  WIN_BELOW, status,
  411.                   0);
  412.     qpw = canvas_pixwin(queue);
  413.     window_set(panel, WIN_WIDTH, window_get(queue, WIN_WIDTH), 0);
  414.     window_fit(frame);
  415.  
  416.     if (argc == 1)
  417.        printer_name = "";
  418.     else if (argc == 2)
  419.        printer_name = argv[1];
  420.     else
  421.        abend(lp_usage);
  422.  
  423.     strcpy(user, user_name());
  424.     set_status(NO_STATE);
  425.     if (window_get(frame, FRAME_CLOSED))
  426.        go_idle();
  427.     else
  428.        go_active();
  429.     notify_interpose_event_func(frame, close_proc, NOTIFY_SAFE);
  430.     window_main_loop(frame);
  431.     pf_close(normal_font);
  432.     pf_close(bold_font);
  433. }
  434.