home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume1 / calctool / part02 / screen.c < prev   
Encoding:
C/C++ Source or Header  |  1989-06-29  |  16.1 KB  |  432 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. /*                                    */
  19. /*    Module:        screen.c                    */
  20. /*                                    */
  21. /*    Function:    Create calculator display            */
  22. /*                                    */
  23. /*    Public Names:    create_screen    create the screen        */
  24. /*            invert_proc    invert the keyboard        */
  25. /*            blink        flash a key            */
  26. /*            main        entry point            */
  27. /*                                    */
  28. /*    Change History:    11 Nov 86    Creation            */
  29. /*                                    */
  30. /************************************************************************/
  31.  
  32. #include    <stdio.h>
  33.  
  34. #include    <suntool/sunview.h>
  35. #include    <suntool/panel.h>
  36. #include    <suntool/canvas.h>
  37.  
  38. #include    "manifest.h"
  39. #include    "globals.h"
  40. #include    "keys.h"
  41.  
  42. #define        CLOSE_KEY            key[0]
  43. #define        INVERSE_KEY            key[1]
  44. #define        CLEAR_KEY            key[2]
  45. #define        FIRST_KEY            3
  46. #define        LAST_KEY            37
  47.  
  48. #define        k(s1, s2, s3, s4, o1, o2, o3, o4, p)    {{s1, s2, s3, s4}, {o1, o2, o3, o4}, {NULL, NULL, NULL, NULL}, NULL, p}
  49. #define        valid_key(x)                ((x) > DIGIT_F || (x) < curr_base)
  50.  
  51. PRIVATE    close_proc();
  52. PRIVATE    event_proc();
  53. PRIVATE    key_proc();
  54. PRIVATE    radix_proc();
  55. PRIVATE    kb_proc();
  56.  
  57. PUBLIC    store_proc();
  58. PUBLIC    recall_proc();
  59. PUBLIC    exchange_proc();
  60. PUBLIC    fix_proc();
  61. PUBLIC    invert_proc();
  62.  
  63. typedef    struct    key_rec    *key_ptr;
  64.  
  65. struct    key_rec    {char        *label[4];
  66.          int        opcode[4];
  67.          struct    pixrect    *image[4];
  68.          Panel_item    item;
  69.          int        (*proc)();
  70.         };
  71.  
  72. Frame    bf;
  73. Panel    keys, sw;
  74. Canvas    display;
  75. struct    pixfont    *key_font;
  76.  
  77. PRIVATE    short    mask_bits[] = {0xaaaa, 0x5555};
  78. mpr_static(mask, 16, 2, 1, mask_bits);
  79.  
  80. PRIVATE    struct    key_rec    key[] = {
  81.     k(       "Close",         "Quit",        "Close",         "Quit",  CLOSE_OP,   QUIT_OP,  CLOSE_OP,   QUIT_OP,    close_proc),
  82.     k(     "Inverse",      "Inverse",      "Inverse",      "Inverse", INVERT_OP, INVERT_OP, INVERT_OP, INVERT_OP,   invert_proc),
  83.     k(       "Erase",        "Clear",        "Erase",        "Clear",  ERASE_OP,  CLEAR_OP,  ERASE_OP,  CLEAR_OP,      key_proc),
  84.     k(         "Sto",             "",          "Sto",             "",    STO_OP,     NO_OP,    STO_OP,     NO_OP,    store_proc),
  85.     k(         "Rcl",             "",          "Rcl",             "",    RCL_OP,     NO_OP,    RCL_OP,     NO_OP,   recall_proc),
  86.     k(         "Exc",             "",          "Exc",             "",    EXC_OP,     NO_OP,    EXC_OP,     NO_OP, exchange_proc),
  87.     k(           "(",             "",            "(",             "", LPAREN_OP,     NO_OP, LPAREN_OP,     NO_OP,      key_proc),
  88.     k(           ")",             "",            ")",             "", RPAREN_OP,     NO_OP, RPAREN_OP,     NO_OP,      key_proc),
  89.     k(          "EE",           "EE",             "",             "",  DIGIT_EE,  INVEE_OP,     NO_OP,     NO_OP,      key_proc),
  90.     k(           "X",             "",            "X",             "",    MUL_OP,     NO_OP,    MUL_OP,     NO_OP,      key_proc),
  91.     k(         "log",       "10\200",            "D",             "",    LOG_OP,    POW_OP,   DIGIT_D,     NO_OP,      key_proc),
  92.     k(          "ln",        "e\200",            "E",             "",     LN_OP,    EXP_OP,   DIGIT_E,     NO_OP,      key_proc),
  93.     k(       "y\200",     "\203\204",            "F",             "",    Y2X_OP,   ROOT_OP,   DIGIT_F,     NO_OP,      key_proc),
  94.     k(           "7",             "",            "7",             "",   DIGIT_7,     NO_OP,   DIGIT_7,     NO_OP,      key_proc),
  95.     k(           "8",             "",            "8",             "",   DIGIT_8,     NO_OP,   DIGIT_8,     NO_OP,      key_proc),
  96.     k(           "9",             "",            "9",             "",   DIGIT_9,     NO_OP,   DIGIT_9,     NO_OP,      key_proc),
  97.     k(        "\214",             "",         "\214",             "",    DIV_OP,     NO_OP,    DIV_OP,     NO_OP,      key_proc),
  98.     k(         "sin",       "sn\205",            "A",             "",    SIN_OP,   ISIN_OP,   DIGIT_A,     NO_OP,      key_proc),
  99.     k(         "cos",       "cs\205",            "B",             "",    COS_OP,   ICOS_OP,   DIGIT_B,     NO_OP,      key_proc),
  100.     k(         "tan",       "tn\205",            "C",             "",    TAN_OP,   ITAN_OP,   DIGIT_C,     NO_OP,      key_proc),
  101.     k(           "4",             "",            "4",             "",   DIGIT_4,     NO_OP,   DIGIT_4,     NO_OP,      key_proc),
  102.     k(           "5",             "",            "5",             "",   DIGIT_5,     NO_OP,   DIGIT_5,     NO_OP,      key_proc),
  103.     k(           "6",             "",            "6",             "",   DIGIT_6,     NO_OP,   DIGIT_6,     NO_OP,      key_proc),
  104.     k(           "+",             "",            "+",             "",    ADD_OP,     NO_OP,    ADD_OP,     NO_OP,      key_proc),
  105.     k(    "\202\201",        "x\206",           "<<",     "\217\220",   SQRT_OP,    SQR_OP,    LSL_OP,    ROL_OP,      key_proc),
  106.     k(    "\210\211",             "",          "Not",       "\221>>",   OVER_OP,     NO_OP,    NOT_OP,    RSA_OP,      key_proc),
  107.     k(          "x!",             "",           ">>",     "\215\216",   FACT_OP,     NO_OP,    RSL_OP,    ROR_OP,      key_proc),
  108.     k(           "1",             "",            "1",             "",   DIGIT_1,     NO_OP,   DIGIT_1,     NO_OP,      key_proc),
  109.     k(           "2",             "",            "2",             "",   DIGIT_2,     NO_OP,   DIGIT_2,     NO_OP,      key_proc),
  110.     k(           "3",             "",            "3",             "",   DIGIT_3,     NO_OP,   DIGIT_3,     NO_OP,      key_proc),
  111.     k(           "-",             "",            "-",             "",    SUB_OP,     NO_OP,    SUB_OP,     NO_OP,      key_proc),
  112.     k(        "\207",            "e",          "And",             "",     PI_OP,      E_OP,    AND_OP,     NO_OP,      key_proc),
  113.     k(         "Int",          "Trc",           "Or",          "Xor",    INT_OP,  TRUNC_OP,     OR_OP,    XOR_OP,      key_proc),
  114.     k(         "Fix",          "DRG",          "Fix",             "",    FIX_OP,    FIX_OP,    FIX_OP,     NO_OP,      fix_proc),
  115.     k(           ".",             "",             "",             "", DIGIT_DOT,     NO_OP,     NO_OP,     NO_OP,      key_proc),
  116.     k(           "0",             "",            "0",             "",   DIGIT_0,     NO_OP,   DIGIT_0,     NO_OP,      key_proc),
  117.     k(    "\212\213",             "",     "\212\213",             "", DIGIT_CHS,     NO_OP, DIGIT_CHS,     NO_OP,      key_proc),
  118.     k(           "=",             "",            "=",             "",  EQUAL_OP,     NO_OP,  EQUAL_OP,     NO_OP,      key_proc)
  119.     };
  120.  
  121. static    short    ct_icon_image[] = {
  122. #include    "calc.icon"
  123. };
  124. mpr_static(ct_icon_pixrect, 47, 64, 1, ct_icon_image);
  125.  
  126. PUBLIC    create_screen(argc, argv)
  127.  
  128. int    argc;
  129. char    **argv;
  130.  
  131. {    int    i, j;
  132.     Icon    icon;
  133.  
  134.     icon = icon_create(ICON_IMAGE, &ct_icon_pixrect, ICON_LABEL, NULL, ICON_WIDTH, 47, ICON_HEIGHT, 64, 0);
  135.     bf = window_create(NULL, FRAME,
  136.                   FRAME_ARGS, argc, argv,
  137.                   FRAME_LABEL, "<< Calctool >>",
  138.                   FRAME_ICON, icon,
  139.                   FRAME_SUBWINDOWS_ADJUSTABLE, FALSE,
  140.                   FRAME_NO_CONFIRM, TRUE,
  141.                0);
  142.     sw = window_create(bf, PANEL, 0);
  143.     display = window_create(bf, CANVAS, 0);
  144.     keys = window_create(bf, PANEL, 
  145.                 WIN_WIDTH, 360,
  146.                 PANEL_ACCEPT_KEYSTROKE, TRUE,
  147.                 PANEL_BACKGROUND_PROC, kb_proc,
  148.                  0);
  149.  
  150.     if ((key_font = pf_open(KEY_FONT)) == NULL) {
  151.        fprintf(stderr, "calctool: could not open font %s\n", KEY_FONT);
  152.        exit(1);
  153.        }
  154.     for (i = 0; i < FIRST_KEY; i++)
  155.        for (j = 0; j < 4; j++)
  156.           key[i].image[j] = panel_button_image((i == 0)? sw : keys, key[i].label[j], 7, key_font);
  157.     for (i = FIRST_KEY; i <= LAST_KEY; i++)
  158.        for (j = 0; j < 4; j += 2)
  159.           if (key[i].opcode[j] != NO_OP) {
  160.              key[i].image[j] = panel_button_image(sw, key[i].label[j], 3, key_font);
  161.              if (key[i].opcode[j + 1] == NO_OP) {
  162.                 key[i].image[j + 1] = panel_button_image(sw, key[i].label[j], 3, key_font);
  163.                 pr_replrop(key[i].image[j+1], 0, 0, key[i].image[j+1]->pr_width, key[i].image[j+1]->pr_height,
  164.                        PIX_SRC & PIX_DST, &mask, 0, 0);
  165.                 }
  166.              else
  167.                 key[i].image[j+1] = panel_button_image(sw, key[i].label[j+1], 3, key_font);
  168.              }
  169.  
  170.     CLOSE_KEY.item = panel_create_item(sw, PANEL_BUTTON,
  171.                           PANEL_LABEL_IMAGE, CLOSE_KEY.image[0],
  172.                           PANEL_NOTIFY_PROC, CLOSE_KEY.proc,
  173.                           PANEL_EVENT_PROC, event_proc,
  174.                           PANEL_CLIENT_DATA, &(CLOSE_KEY),
  175.                        0);
  176.     window_fit(sw);
  177.  
  178.     INVERSE_KEY.item = panel_create_item(keys, PANEL_BUTTON,
  179.                         PANEL_LABEL_IMAGE, INVERSE_KEY.image[0],
  180.                         PANEL_NOTIFY_PROC, INVERSE_KEY.proc,
  181.                             PANEL_EVENT_PROC, event_proc,
  182.                         PANEL_CLIENT_DATA, &(INVERSE_KEY),
  183.                          0);
  184.     key[FIRST_KEY].item = panel_create_item(keys, PANEL_BUTTON,
  185.                            PANEL_LABEL_IMAGE, key[FIRST_KEY].image[0],
  186.                            PANEL_NOTIFY_PROC, key[FIRST_KEY].proc,
  187.                                PANEL_EVENT_PROC, event_proc,
  188.                                PANEL_ACCEPT_KEYSTROKE, TRUE,
  189.                            PANEL_ITEM_X, panel_get(INVERSE_KEY.item, PANEL_ITEM_X),
  190.                            PANEL_ITEM_Y, panel_get(INVERSE_KEY.item, PANEL_ITEM_Y) + 
  191.                                     INVERSE_KEY.image[0]->pr_height + 4,
  192.                            PANEL_CLIENT_DATA, &(key[FIRST_KEY]),
  193.                         0);
  194.     for (i = FIRST_KEY + 1; i <= LAST_KEY; i++)
  195.        key[i].item = panel_create_item(keys, PANEL_BUTTON,
  196.                              PANEL_LABEL_IMAGE, key[i].image[0],
  197.                              PANEL_NOTIFY_PROC, key[i].proc,
  198.                           PANEL_EVENT_PROC, event_proc,
  199.                           PANEL_ACCEPT_KEYSTROKE, TRUE,
  200.                              PANEL_CLIENT_DATA, &(key[i]),
  201.                           0);
  202.     CLEAR_KEY.item = panel_create_item(keys, PANEL_BUTTON,
  203.                           PANEL_LABEL_IMAGE, CLEAR_KEY.image[0],
  204.                           PANEL_NOTIFY_PROC, CLEAR_KEY.proc,
  205.                           PANEL_EVENT_PROC, event_proc,
  206.                           PANEL_ITEM_X, panel_get(key[LAST_KEY].item, PANEL_ITEM_X) + 
  207.                                 key[LAST_KEY].image[0]->pr_width - CLEAR_KEY.image[0]->pr_width,
  208.                           PANEL_ITEM_Y, panel_get(INVERSE_KEY.item, PANEL_ITEM_Y),
  209.                           PANEL_CLIENT_DATA, &(CLEAR_KEY),
  210.                        0);
  211.     panel_create_item(keys, PANEL_CHOICE,
  212.                  PANEL_LABEL_STRING, "",
  213.                  PANEL_DISPLAY_LEVEL, PANEL_CURRENT,
  214.                  PANEL_CHOICE_IMAGES, panel_button_image(keys, "Scientific", 13, key_font),
  215.                                panel_button_image(keys, "Engineering", 13, key_font),
  216.                                panel_button_image(keys, "Binary", 13, key_font),
  217.                                panel_button_image(keys, "Octal", 13, key_font),
  218.                                panel_button_image(keys, "Hexadecimal", 13, key_font),
  219.                                0,
  220.                  PANEL_CHOICE_XS, panel_get(key[FIRST_KEY + 2].item, PANEL_ITEM_X), 0,
  221.                  PANEL_CHOICE_YS, panel_get(INVERSE_KEY.item, PANEL_ITEM_Y), 0,
  222. /*                 PANEL_CHOICE_FONTS, key_font, 0,*/
  223.                  PANEL_NOTIFY_PROC, radix_proc,
  224.               0);
  225.     window_fit(keys);
  226.  
  227.     window_set(sw,
  228.               WIN_X, 0,
  229.               WIN_Y, 0,
  230.            0);
  231.     window_set(display,
  232.               WIN_RIGHT_OF, sw,
  233.               WIN_Y, 0,
  234.               WIN_WIDTH, window_get(keys, WIN_WIDTH) - window_get(sw, WIN_WIDTH) - 5,
  235.               WIN_HEIGHT, window_get(sw, WIN_HEIGHT),
  236.            0);
  237.     window_set(keys,
  238.               WIN_X, 0,
  239.               WIN_BELOW, sw,
  240.            0);
  241.     window_fit(bf);
  242.     window_set(sw, 
  243.               WIN_WIDTH, window_get(sw, WIN_WIDTH),
  244.               WIN_HEIGHT, window_get(sw, WIN_HEIGHT),
  245.            0);
  246.     window_set(display, 
  247.               WIN_WIDTH, window_get(display, WIN_WIDTH),
  248.               WIN_HEIGHT, window_get(display, WIN_HEIGHT),
  249.            0);
  250.     window_set(keys, 
  251.               WIN_WIDTH, window_get(keys, WIN_WIDTH),
  252.               WIN_HEIGHT, window_get(keys, WIN_HEIGHT),
  253.            0);
  254.     update_display();
  255.     window_main_loop(bf);
  256. }
  257.  
  258. PRIVATE    close_proc()
  259.  
  260. {
  261.     if (inverted ^ temp_inverted) {
  262.        window_destroy(bf);
  263.        exit(0);
  264.        }
  265.     else {
  266.        window_set(bf, FRAME_CLOSED, TRUE, 0);
  267.        temp_inverted = FALSE;
  268.        if (inverted)
  269.           invert_proc();
  270.        }
  271. }
  272.  
  273. PUBLIC    invert_proc()
  274.  
  275. {    int    i;
  276.  
  277.     temp_inverted = FALSE;
  278.     inverted = !inverted;
  279.     for (i = 0; i <= LAST_KEY; i++)
  280.        if (key[i].image[curr_mode + (inverted? 1 : 0)] && valid_key(key[i].opcode[curr_mode]))
  281.           panel_set(key[i].item, PANEL_LABEL_IMAGE, key[i].image[curr_mode + (inverted? 1 : 0)], PANEL_SHOW_ITEM, TRUE, 0);
  282.        else
  283.           panel_set(key[i].item, PANEL_SHOW_ITEM, FALSE, 0);
  284. }
  285.  
  286. PRIVATE    radix_proc(item, value, event)
  287.  
  288. Panel_item    item;
  289. int        value;
  290. Event        *event;
  291.  
  292. {    int    i;
  293.     static    int    bases[] = {DECIMAL, DECIMAL, BINARY, OCTAL, HEXADECIMAL};
  294.  
  295.     convert_display();
  296.     if (value == 0) {
  297.        curr_mode = SCIENTIFIC;
  298.        eng_mode = FALSE;
  299.        }
  300.     else if (value == 1) {
  301.        curr_mode = SCIENTIFIC;
  302.        eng_mode = TRUE;
  303.        }
  304.     else
  305.        curr_mode = PROGRAMMER;
  306.     curr_base = bases[value];
  307.     inverted = temp_inverted = FALSE;
  308.     for (i = FIRST_KEY; i <= LAST_KEY; i++)
  309.        if (key[i].opcode[curr_mode] != NO_OP && valid_key(key[i].opcode[curr_mode]))
  310.           panel_set(key[i].item, PANEL_LABEL_IMAGE, key[i].image[curr_mode], PANEL_SHOW_ITEM, TRUE, 0);
  311.        else
  312.           panel_set(key[i].item, PANEL_SHOW_ITEM, FALSE, 0);
  313.     update_display();
  314. }
  315.  
  316. PRIVATE    event_proc(item, event)
  317.  
  318. Panel_item    item;
  319. Event        *event;
  320.  
  321. {    key_ptr    ky;
  322.     static    key_ptr    curr_key;
  323.     int    op;
  324.  
  325.     if (event_id(event) >= ASCII_FIRST && event_id(event) <= ASCII_LAST) {
  326.        keyboard(event_id(event));
  327.        return;
  328.        }
  329.     ky = (key_ptr) panel_get(item, PANEL_CLIENT_DATA);
  330.     switch (event_id(event)) {
  331.        case MS_LEFT            : if (ky->opcode[curr_mode + (inverted? 1 : 0)] != NO_OP)
  332.                     if (event_is_down(event)) {
  333.                        panel_begin_preview(item, event);
  334.                        curr_key = ky;
  335.                        }
  336.                     else if (curr_key == ky) {
  337.                        panel_accept_preview(item, event);
  338.                        curr_key = NULL;
  339.                        }
  340.                      break;
  341.        case MS_MIDDLE          : if (ky->opcode[curr_mode + (inverted? 0 : 1)] != NO_OP)
  342.                     if (event_is_down(event)) {
  343.                        panel_set(item, PANEL_LABEL_IMAGE, ky->image[curr_mode + (inverted? 0 : 1)], 0);
  344.                        panel_begin_preview(item, event);
  345.                        curr_key = ky;
  346.                        }
  347.                     else if (curr_key == ky) {
  348.                        temp_inverted = TRUE;
  349.                        panel_accept_preview(item, event);
  350.                        panel_set(item, PANEL_LABEL_IMAGE, ky->image[curr_mode + (inverted? 1 : 0)], 0);
  351.                        curr_key = NULL;
  352.                        }
  353.                            break;
  354.        case MS_RIGHT       : if (event_is_down(event))
  355.                     if ((op = ky->opcode[curr_mode + (inverted? 1 : 0)]) == STO_OP ||
  356.                          op == RCL_OP ||
  357.                          op == EXC_OP ||
  358.                          op == FIX_OP) {
  359.                        panel_begin_preview(item, event);
  360.                        panel_accept_preview(item, event);
  361.                        }
  362.                      break;
  363.        case PANEL_EVENT_CANCEL : if (curr_key == ky) {
  364.                     panel_cancel_preview(item, event);
  365.                     panel_set(item, PANEL_LABEL_IMAGE, ky->image[curr_mode + (inverted? 1 : 0)], 0);
  366.                     curr_key = NULL;
  367.                     }
  368.                      break;
  369.        }
  370. }
  371.  
  372. PRIVATE    key_proc(item, event)
  373.  
  374. Panel_item    item;
  375. Event        *event;
  376.  
  377. {    key_ptr    ky;
  378.     int    op;
  379.  
  380.     ky = (key_ptr) panel_get(item, PANEL_CLIENT_DATA);
  381.     op = ky->opcode[curr_mode + ((inverted? 1 : 0) ^ temp_inverted)];
  382.     if (is_digit(op))
  383.        do_digit(op);
  384.     else if (is_binary(op))
  385.        do_binary(op);
  386.     else
  387.        do_unary(op);
  388.     temp_inverted = FALSE;
  389.     if (inverted)
  390.        invert_proc();
  391. }
  392.  
  393. PRIVATE    kb_proc(item, event)
  394.  
  395. Panel_item    item;
  396. Event        *event;
  397.  
  398. {
  399.     if (event_id(event) >= ASCII_FIRST && event_id(event) <= ASCII_LAST)
  400.        keyboard(event_id(event));
  401. }
  402.  
  403. PUBLIC    int    blink(op)
  404.  
  405. int    op;
  406.  
  407. {    int    i, j;
  408.     struct    pixrect    *old, *new;
  409.  
  410.     for (i = FIRST_KEY; i <= LAST_KEY; i++)
  411.        if (op == key[i].opcode[curr_mode])
  412.           break;
  413.     old = (struct pixrect *) panel_get(key[i].item, PANEL_LABEL_IMAGE);
  414.     new = mem_create(old->pr_width, old->pr_height, 1);
  415.     pr_rop(new, 0, 0, new->pr_width, new->pr_height, PIX_NOT(PIX_SRC), old, 0, 0);
  416.     panel_set(key[i].item, PANEL_LABEL_IMAGE, new, 0);
  417.     for (j = 25000; j; j--)
  418.        ;
  419.     panel_set(key[i].item, PANEL_LABEL_IMAGE, old, 0);
  420.     pr_destroy(new);
  421.     return(op);
  422. }
  423.  
  424. main(argc, argv)
  425.  
  426. int    argc;
  427. char    **argv;
  428.  
  429. {
  430.     create_screen(argc, argv);
  431. }
  432.