home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / xv / xvmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  28.7 KB  |  1,038 lines

  1. /* XView initialization.
  2.    Copyright (C) 1995 Jakub Jelinek.
  3.    
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.    
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <config.h>
  19. #include <stdarg.h>
  20.  
  21. #include <X11/Xlib.h>
  22. #include <xview/xview.h>
  23. #include <xview/frame.h>
  24. #include <xview/panel.h>
  25. #include <xview/screen.h>
  26. #include <xview/xv_xrect.h>
  27. #include <xview/cms.h>
  28. #include <xview/scrollbar.h>
  29. #include <xview/svrimage.h>
  30. #include <xview/cursor.h>
  31. #include <xview/defaults.h>
  32. #include <xview/dragdrop.h>
  33.  
  34. #include <stdio.h>
  35.  
  36. #include "fs.h"
  37. #include "dir.h"
  38. #include "mad.h"
  39. #include "dlg.h"
  40. #include "panel.h"
  41. #include "xvmain.h"
  42. #include "util.h"
  43.  
  44.  
  45. Frame mcframe;
  46. Frame menubarframe;
  47. Cursor splitcursor, dropcursor;
  48. Display *dpy;
  49. int fdXConnection;
  50. int displayWidth;
  51. int displayHeight;
  52. int defaultDepth;
  53. Server_image iconRegular [2];
  54. Server_image iconDirectory [2];
  55. Cms mccms;
  56. Cms cmsicon;
  57. static Xv_singlecolor icon_colors[] = {
  58.     {255, 255, 255},
  59.     {0, 0, 0},
  60.     {170, 68, 0},
  61.     {170, 170, 204},
  62.     {204, 102, 0},
  63.     {204, 204, 204},
  64.     {238, 0, 0},
  65.     {238, 204, 170},
  66.     {238, 238, 238},
  67.     {170, 0, 0},
  68.     {0, 136, 204},
  69.     {238, 153, 153},
  70.     {136, 68, 0},
  71.     {136, 136, 136},
  72.     {170, 102, 0},
  73.     {238, 170, 0},
  74.     {64, 64, 192}, /* the empty piece only */
  75.     {160, 64, 64}, /* the background color only */
  76.   };
  77.   
  78. #include "pictures.h"
  79.  
  80. int xv_error_handler (Xv_object object, Attr_avlist avlist);
  81. void x_setup_info (void);
  82. void xv_set_current_panel (WPanel *);
  83.  
  84. extern widget_data containers []; /* defined in main.c */
  85. extern int containers_no;
  86. extern int is_right;
  87. extern Dlg_head *midnight_dlg;
  88.  
  89. void get_panel_color (Cms cms, int i)
  90. {
  91.     static char *defcolors [] = {
  92.         "black", "gray75", /* normal */
  93.         "blue4", "gray75", /* marked */
  94.         "black", "gray50", /* selected */
  95.         "blue4", "gray50", /* marked selected */
  96.     };
  97.     static char *names [] = {"fg", "bg", "markfg", "markbg", 
  98.                              "selfg", "selbg", "markselfg", "markselbg" };
  99.     char *p, *q;
  100.     char buffer [40], buffer2 [40];
  101.     Xv_singlecolor col;
  102.     int red, green, blue;
  103.     
  104.     sprintf (buffer, "mxc.panelcolor.%s", names [i]);
  105.     sprintf (buffer2, "Mxc.PanelColor.%s", names [i]);
  106.     p = defaults_get_string (buffer, buffer2, "");
  107.     if (p != NULL)
  108.         while (*p == ' ' || *p == '\t')
  109.             p++;
  110.     if (p != NULL && *p) {
  111.         if (sscanf (p, "%i %i %i", &red, &green, &blue) == 3) {
  112.             col.red = (u_char) red;
  113.             col.green = (u_char) green;
  114.             col.blue = (u_char) blue;
  115.             p = NULL;
  116.         } else {
  117.             for (q = p; *q && *q != ' ' && *q != '\t'; q++);
  118.             *q = 0;
  119.         }
  120.     } else {
  121.         p = defcolors [i];
  122.     }
  123.     if (p == NULL)
  124.         xv_set (cms,
  125.             CMS_INDEX, CMS_CONTROL_COLORS + i,
  126.             CMS_COLOR_COUNT, 1,
  127.             CMS_COLORS, &col,
  128.             NULL);
  129.     else
  130.         xv_set (cms,
  131.             CMS_INDEX, CMS_CONTROL_COLORS + i,
  132.             CMS_COLOR_COUNT, 1,
  133.             CMS_NAMED_COLORS, 
  134.                 p, NULL,
  135.             NULL);
  136. }
  137.  
  138. int xtoolkit_init(int *argc, char **argv)
  139. {
  140.     int screen_no, i;
  141.  
  142.     xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, 
  143.         XV_ERROR_PROC, xv_error_handler,
  144.         NULL);
  145.     mcframe = (Frame) xv_create (XV_NULL, FRAME,
  146.         FRAME_LABEL, "The Midnight X Commander",
  147.         NULL);
  148.     if (mcframe == XV_NULL)
  149.         return -1;
  150.     dpy = (Display *) xv_get (mcframe, XV_DISPLAY);
  151.     screen_no = (int) xv_get ((Xv_Screen) xv_get (mcframe, XV_SCREEN),
  152.         SCREEN_NUMBER);
  153.     displayWidth = DisplayWidth (dpy, screen_no);
  154.     displayHeight = DisplayHeight (dpy, screen_no);
  155.     defaultDepth = DefaultDepth (dpy, screen_no);
  156.     fdXConnection = XConnectionNumber (dpy);
  157.     xv_dispatch_a_bit ();
  158.     mccms = (Cms) xv_create (XV_NULL, CMS,
  159.         CMS_CONTROL_CMS, TRUE,
  160.     CMS_SIZE, 33,
  161.     CMS_NAME, "mccms",
  162.         CMS_TYPE, XV_DYNAMIC_CMS,
  163.     CMS_NAMED_COLORS,
  164.         "LawnGreen", "gold", "brown", "sienna",
  165.         "salmon", "coral", "violet", "orchid",
  166.         "cornsilk", "azure", "misty rose", "snow",
  167.          "black", "red4", "green4", "yellow4",
  168.         "blue4", "magenta4", "cyan4", "gray75",
  169.         "gray50", "red", "green", "yellow",
  170.         "blue", "magenta", "cyan", "white",
  171.         "black",
  172.         NULL,
  173.     NULL);
  174.     
  175.      defaults_load_db (APP_DEFAULTS);
  176.      for (i = 0; i < 8; i++)
  177.          get_panel_color (mccms, i);
  178.  
  179.      cmsicon = (Cms) xv_create(XV_NULL, CMS,
  180.              CMS_TYPE, XV_DYNAMIC_CMS,
  181.              CMS_SIZE, 18,
  182.              CMS_COLORS, icon_colors,
  183.              CMS_NAME, "iconcms",
  184.              NULL);
  185.          
  186.     splitcursor = (Cursor) xv_create (XV_NULL, CURSOR,
  187.         CURSOR_XHOT, 15,
  188.         CURSOR_YHOT, 14,
  189.         CURSOR_IMAGE, xv_create (XV_NULL, SERVER_IMAGE,
  190.             XV_WIDTH, 32,
  191.         XV_HEIGHT, 32,
  192.         SERVER_IMAGE_X_BITS, splitcursor_bits,
  193.         NULL),
  194.     NULL);
  195.     dropcursor = (Cursor) xv_create (XV_NULL, CURSOR,
  196.         CURSOR_XHOT, 3,
  197.         CURSOR_YHOT, 15,
  198.         CURSOR_IMAGE, xv_create (XV_NULL, SERVER_IMAGE,
  199.             XV_WIDTH, 32,
  200.         XV_HEIGHT, 32,
  201.         SERVER_IMAGE_X_BITS, dropcursor_bits,
  202.         NULL),
  203.     NULL);
  204.     iconRegular [0] = (Server_image) xv_create (XV_NULL, SERVER_IMAGE,
  205.         XV_WIDTH, 16,
  206.     XV_HEIGHT, 16,
  207.         SERVER_IMAGE_COLORMAP, "mccms",
  208.     SERVER_IMAGE_DEPTH, 8,
  209.     SERVER_IMAGE_BITS, Regular_bits,
  210.     NULL);
  211.  
  212.     iconRegular [1] = (Server_image) xv_create (XV_NULL, SERVER_IMAGE,
  213.     XV_WIDTH, 16,
  214.     XV_HEIGHT, 16,
  215.     SERVER_IMAGE_X_BITS, Regular_mask,
  216.     NULL);
  217.  
  218.      iconDirectory [0] = (Server_image) xv_create (XV_NULL, SERVER_IMAGE,
  219.      XV_WIDTH, 16,
  220.      XV_HEIGHT, 16,
  221.      SERVER_IMAGE_COLORMAP, "mccms",
  222.      SERVER_IMAGE_DEPTH, 8,
  223.      SERVER_IMAGE_X_BITS, Directory_bits,
  224.          NULL);
  225.      iconDirectory [1] = (Server_image) xv_create (XV_NULL, SERVER_IMAGE,
  226.          XV_WIDTH, 16,
  227.          XV_HEIGHT, 16,
  228.          SERVER_IMAGE_X_BITS, Directory_mask,
  229.          NULL);
  230.     xv_set (splitcursor,
  231.         XV_INCREMENT_REF_COUNT,
  232.     NULL);
  233.     xv_set (iconRegular [0],
  234.     XV_INCREMENT_REF_COUNT,
  235.     NULL);
  236.     xv_set (iconRegular [1],
  237.     XV_INCREMENT_REF_COUNT,
  238.     NULL);
  239.     xv_set (iconDirectory [0], 
  240.          XV_INCREMENT_REF_COUNT, 
  241.          NULL);
  242.      xv_set (iconDirectory [1],
  243.          XV_INCREMENT_REF_COUNT, 
  244.          NULL);
  245.     xv_dispatch_something ();
  246.  
  247.     x_setup_info ();    
  248.     xv_dispatch_a_bit ();
  249.     
  250.     return 0;
  251. }
  252.  
  253. int xtoolkit_end(void)
  254. {
  255.     xv_destroy_safe (splitcursor);
  256.     xv_destroy_safe (iconRegular [0]);
  257.     xv_destroy_safe (iconRegular [1]);
  258.     xv_destroy_safe (iconDirectory [0]);
  259.     xv_destroy_safe (iconDirectory [1]);
  260.     return 0;
  261. }
  262.  
  263. /* These are only temporary routines. Should go into dlg.c, which should be
  264.    completely rewritten for XView */
  265.    
  266. #include <sys/types.h>
  267. #include <sys/time.h>
  268.  
  269. Notify_value my_destroy_func (Frame frame, Destroy_status status)
  270. {
  271.     if (status == DESTROY_PROCESS_DEATH || status == DESTROY_CLEANUP) {
  272.         Dlg_head *h = (Dlg_head *) xv_get (frame, 
  273.             XV_KEY_DATA, KEY_DATA_DLG_HEAD);
  274.         h->running = -1;
  275.     }
  276.     return notify_next_destroy_func (frame, status);
  277. }
  278.  
  279. void my_done_func (Frame frame)
  280. {
  281.     Dlg_head *h = (Dlg_head *) xv_get (frame, 
  282.         XV_KEY_DATA, KEY_DATA_DLG_HEAD);
  283.     h->running = 0;
  284.     h->ret_value = B_CANCEL;
  285. }
  286.  
  287. struct timeval timeout = { 0, 0 };
  288.  
  289. /*#define PARALELIZE*/
  290.  
  291. struct xv_dispatch_proc {
  292.     void (*callback)(void *);
  293.     void *arg;
  294. #ifdef PARALELIZE    
  295.     Dlg_head *h;
  296. #endif
  297.     struct xv_dispatch_proc *next;
  298. };
  299.  
  300. #ifndef PARALELIZE
  301. struct xv_dispatch_struct {
  302.     Dlg_head *h;
  303.     struct xv_dispatch_struct *next;
  304.     struct xv_dispatch_proc *proc;
  305. };
  306.  
  307. static struct xv_dispatch_struct *dispatch_current = NULL;
  308. #else
  309. static struct xv_dispatch_proc *dispatch_current = NULL;
  310. #endif
  311.  
  312. static Dlg_head *previous_dlg = NULL;
  313. int xvrundlg_event (Dlg_head *h)
  314. {
  315.     fd_set readfds;
  316.     struct xv_dispatch_proc *proc, *proc2;
  317.     struct Dlg_head *previous = previous_dlg;
  318.     int    v;
  319. #ifndef PARALELIZE    
  320.     struct xv_dispatch_struct *dispatch_new = xmalloc (
  321.         sizeof (struct xv_dispatch_struct), "XV dispatching");
  322. #else
  323.     struct xv_dispatch_proc *proc4;
  324. #endif
  325.  
  326.     previous_dlg = h;
  327.     if (previous == midnight_dlg) {
  328.         xv_set (menubarframe,
  329.             FRAME_BUSY, TRUE,
  330.             NULL);
  331.         for (v = 0; v < containers_no; v++) {
  332.             xv_set ((Frame) containers [v],
  333.                 FRAME_BUSY, TRUE,
  334.                 NULL);
  335.         }
  336.         
  337.     } else if (previous != (Dlg_head *) NULL) {
  338.         xv_set ((Frame) (previous->wdata),
  339.             FRAME_BUSY, TRUE,
  340.             NULL);
  341.     }
  342.     if (dispatch_current == NULL) {
  343.         h->wdata = mcframe;
  344.         xv_set (mcframe,
  345.             XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
  346.             NULL);
  347.     } else {
  348.         xv_set ((Frame) (h->wdata),
  349.             XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
  350.             NULL);
  351.     }
  352. #ifndef PARALELIZE
  353.     dispatch_new->next = dispatch_current;
  354.     dispatch_current = dispatch_new;
  355.     dispatch_current->h = h;
  356.     dispatch_current->proc = NULL;
  357. #endif 
  358.     h->running = 1;
  359.     if (h->wdata == mcframe) {
  360.         xv_post_proc (h, (void (*)(void *))xv_action_icons, (void *) NULL);
  361.     }
  362.     
  363.     notify_interpose_destroy_func ((Frame) (h->wdata), (Notify_func) my_destroy_func);
  364.     XFlush (dpy);
  365.     while (h->running >= 0) {
  366.     FD_ZERO (&readfds);
  367.         FD_SET (fdXConnection, &readfds);
  368.         v = select (FD_SETSIZE, &readfds, NULL, NULL, &timeout);
  369.     if (v > 0){
  370.             notify_dispatch ();
  371.         } else {
  372.         XFlush (dpy);
  373.         }
  374. #ifndef PARALELIZE        
  375.         if (dispatch_current->proc != NULL) {
  376.             proc = dispatch_current->proc;
  377.             dispatch_current->proc = proc->next;
  378. #else
  379.     if (dispatch_current != NULL) {
  380.         proc = dispatch_current;
  381.         dispatch_current = proc->next;
  382. #endif            
  383.         (*proc->callback)(proc->arg);
  384.         free (proc);
  385.         }
  386.         if (h->running == 0) {
  387.             xv_destroy_safe (h->wdata);
  388.         }
  389.     }
  390.     if (previous == midnight_dlg) {
  391.         xv_set (menubarframe,
  392.             FRAME_BUSY, FALSE,
  393.             NULL);
  394.         for (v = 0; v < containers_no; v++) {
  395.             xv_set ((Frame) containers [v],
  396.                 FRAME_BUSY, FALSE,
  397.                 NULL);
  398.         }
  399.         
  400.     } else if (previous != (Dlg_head *) NULL) {
  401.         xv_set ((Frame) (previous->wdata),
  402.             FRAME_BUSY, FALSE,
  403.             NULL);
  404.     }
  405.     previous_dlg = previous;
  406. #ifndef PARALELIZE    
  407.     dispatch_new = dispatch_current;
  408.     dispatch_current = dispatch_current->next;
  409.     for (proc = dispatch_new->proc; proc != NULL; proc = proc2) {
  410.         proc2 = proc->next;
  411.         free (proc);
  412.     }
  413.     free (dispatch_new);
  414. #else
  415.     proc = dispatch_current;
  416.     dispatch_current = NULL;
  417.     proc4 = NULL;
  418.     for (; proc != NULL; proc = proc2) {
  419.         proc2 = proc->next;
  420.         if (proc->h == h)
  421.             free (proc);
  422.         else {
  423.             if (dispatch_current == NULL)
  424.                 dispatch_current = proc4 = proc;
  425.             else {
  426.                 proc4->next = proc;
  427.                 proc4 = proc;
  428.             }
  429.         }
  430.     }
  431.     if (proc4 != NULL)
  432.         proc4->next = NULL;
  433. #endif    
  434.     return 0;
  435. }
  436.  
  437. void xv_dispatch_a_bit (void)
  438. {
  439.     fd_set readfds;
  440.     struct timeval timeout = { 0, 1 };
  441.     struct timeval zero_timeout = { 0, 0 };
  442.     int i;
  443.     int v;
  444.     Xv_Server server = XV_SERVER_FROM_WINDOW (mcframe);
  445.     
  446.     xv_set (server, SERVER_SYNC_AND_PROCESS_EVENTS, NULL);
  447.     
  448.     XFlush (dpy);
  449. #if 0
  450.     for (i = 0; i < 300; i++) {
  451.     int v;
  452.     
  453.         FD_SET (fdXConnection, &readfds);
  454.         v = select (FD_SETSIZE, &readfds, NULL, NULL, &timeout);
  455.     if (v == -1){
  456.         fprintf (stderr, "Fatal: fdXConnection lost\n");
  457.     }
  458.     if (v){
  459.             notify_dispatch ();
  460.         } else
  461.                break;
  462.     }
  463. #endif
  464.     for (v = 1; v;) {
  465.     FD_ZERO (&readfds);
  466.         FD_SET (fdXConnection, &readfds);
  467.         v = select (FD_SETSIZE, &readfds, NULL, NULL, &zero_timeout);
  468.     if (v == -1){
  469.         perror ("xv_dispatch\n");
  470.         exit (1);
  471.     }
  472.     if (v)
  473.             notify_dispatch ();
  474.     }
  475. }
  476.  
  477. void xv_dispatch_something (void)
  478. {
  479.     fd_set readfds;
  480.     struct timeval timeout = { 0, 1 };
  481.     Xv_Server server = XV_SERVER_FROM_WINDOW (mcframe);
  482.     int i;
  483.     
  484.     xv_set (server, SERVER_SYNC_AND_PROCESS_EVENTS, NULL);
  485.     
  486.     XFlush (dpy);
  487.     for (i = 0; i < 50; i++) {
  488.     FD_ZERO (&readfds);
  489.         FD_SET (fdXConnection, &readfds);
  490.         if (select (FD_SETSIZE, &readfds, NULL, NULL, &timeout)) {
  491.             notify_dispatch ();
  492.         } else
  493.                return;
  494.     }
  495. }
  496.  
  497. widget_data xtoolkit_create_dialog (Dlg_head *h)
  498. {
  499.     Frame frame;
  500.     Panel panel;
  501.     
  502.     frame = (Frame) xv_create (mcframe, FRAME_CMD,
  503.         FRAME_LABEL, "Dialog",
  504.         FRAME_DONE_PROC, my_done_func,
  505.         NULL);
  506.     xv_set (panel = (Panel) xv_get (frame, FRAME_CMD_PANEL),
  507.         XV_KEY_DATA, KEY_DATA_PANEL_LASTITEM, XV_NULL,
  508.     XV_KEY_DATA, KEY_DATA_PANEL_MAXX, 0,
  509.     XV_KEY_DATA, KEY_DATA_PANEL_MAXY, 0,
  510.     NULL);
  511.     return (widget_data) frame;
  512. }
  513.  
  514. /* Only needed when we run a dialog ourselves :) */
  515. void xtoolkit_kill_dialog (Dlg_head *h)
  516. {
  517.     h->running = 0;
  518.     xv_destroy_safe ((Frame) (h->wdata));
  519. }
  520.  
  521. void x_set_dialog_title (Dlg_head *h, char *title)
  522. {
  523.     xv_set ((Frame) (h->wdata),
  524.         FRAME_LABEL, title,
  525.     NULL);
  526. }
  527.  
  528. widget_data xtoolkit_get_main_dialog (Dlg_head *h)
  529. {
  530.     return (widget_data) mcframe;
  531. }
  532.  
  533. int quit_cmd (void);
  534. static void xv_container_done_proc (Frame frame)
  535. {
  536.     xv_post_proc (midnight_dlg, (void (*)(void *))quit_cmd, NULL);
  537. }
  538.  
  539. static void xv_division_repaint_proc (Canvas canvas, Xv_Window paint, 
  540.     Rectlist *repaint)
  541. {
  542.     int h;
  543.     Drawable xid = (Drawable) xv_get (paint, XV_XID);
  544.     GC gc = XCreateGC (dpy, xid, 0, 0);
  545.     unsigned long *xc;
  546.     XPoint xp [3];
  547.  
  548. #define DIVISION_LEFT 2
  549. #define DIVISION_TOP 0
  550. #define DIVISION_RIGHT 8
  551. #define DIVISION_BOTTOM (h - 4)
  552.     h = xv_get (paint, XV_HEIGHT);
  553.     xc = (unsigned long *) xv_get (mccms, CMS_INDEX_TABLE);
  554.     XSetLineAttributes (dpy, gc, 1, LineSolid, JoinRound, CapNotLast);
  555.     xp [0].x = DIVISION_LEFT;
  556.     xp [0].y = DIVISION_BOTTOM;
  557.     xp [1].x = DIVISION_LEFT;
  558.     xp [1].y = DIVISION_TOP;
  559.     xp [2].x = DIVISION_RIGHT - 1;
  560.     xp [2].y = DIVISION_TOP;
  561.     XSetForeground (dpy, gc, xc [2]);
  562.     XDrawLines (dpy, xid, gc, xp, 3, CoordModeOrigin);
  563.     xp [0].x = DIVISION_LEFT + 1;
  564.     xp [0].y = DIVISION_BOTTOM - 1;
  565.     xp [1].x = DIVISION_RIGHT - 1;
  566.     xp [1].y = DIVISION_BOTTOM - 1;
  567.     xp [2].x = DIVISION_RIGHT - 1;
  568.     xp [2].y = DIVISION_TOP;
  569.     XSetForeground (dpy, gc, xc [3]);
  570.     XDrawLines (dpy, xid, gc, xp, 3, CoordModeOrigin);
  571.     XFreeGC (dpy, gc);
  572. }
  573.  
  574. static void xv_division_resize_proc (Canvas canvas, int w, int h)
  575. {
  576.     xv_division_repaint_proc (canvas, 
  577.         xv_get (canvas, CANVAS_NTH_PAINT_WINDOW, 0), NULL);
  578. }
  579.  
  580. static void x_container_resize_proc (Frame frame)
  581. {
  582.     int w = xv_get (frame, XV_WIDTH);
  583.     int h = xv_get (frame, XV_HEIGHT);
  584.     int h1, h2, s;
  585.     Panel toppanel, bottompanel;
  586.     Canvas leftcanvas, rightcanvas;
  587.     Canvas division;
  588.                 
  589.     toppanel = (Panel) xv_get (frame, XV_KEY_DATA, KEY_DATA_AREA_TOP);
  590.     bottompanel = (Panel) xv_get (frame, XV_KEY_DATA, KEY_DATA_AREA_BOTTOM);
  591.     leftcanvas = (Canvas) xv_get (frame, XV_KEY_DATA, KEY_DATA_AREA_LEFT);
  592.     rightcanvas = (Canvas) xv_get (frame, XV_KEY_DATA, KEY_DATA_AREA_RIGHT);
  593.     division = (Canvas) xv_get (frame, XV_KEY_DATA, KEY_DATA_DIVISION);
  594.                 
  595.     h1 = xv_get (bottompanel, XV_HEIGHT);
  596.     h2 = xv_get (toppanel, XV_HEIGHT);
  597.     s = xv_get (frame, XV_KEY_DATA, KEY_DATA_PANEL_SPLITX);
  598.                 
  599.     xv_set (toppanel,
  600.         XV_X, 0,
  601.         XV_Y, 0,
  602.         XV_WIDTH, w,
  603.         XV_HEIGHT, h2,
  604.         NULL);
  605.     xv_set (bottompanel,
  606.         XV_X, 0,
  607.         XV_Y, h - h1,
  608.         XV_WIDTH, w,
  609.         XV_HEIGHT, h1,
  610.         NULL);
  611.     if (s > 30)
  612.         xv_set (leftcanvas,
  613.             XV_X, 0,
  614.             XV_Y, h2,
  615.             XV_HEIGHT, h - h1 - h2,
  616.             XV_WIDTH, s,
  617.             NULL);
  618.     if (w - s - 12 > 30)
  619.         xv_set (rightcanvas,
  620.             XV_X, s + 12,
  621.             XV_Y, h2,
  622.             XV_HEIGHT, h - h1 - h2,
  623.             XV_WIDTH, w - s - 12,
  624.             NULL);
  625.     xv_set (division,
  626.         XV_X, s,
  627.         XV_Y, h2,
  628.         XV_WIDTH, 12,
  629.         XV_HEIGHT, h - h1 - h2,
  630.         NULL);
  631. }
  632.  
  633. static Notify_value x_container_interpose_proc (Frame frame, Event *event, 
  634.     Notify_arg arg, Notify_event_type type)
  635. {
  636.     switch (event_action (event)) {
  637.         case WIN_RESIZE:
  638.             x_container_resize_proc (frame);
  639.             return XV_OK;
  640.         default:
  641.             return notify_next_event_func (frame, (Notify_event) event, 
  642.                 arg, type);
  643.     }
  644. }
  645.  
  646. int x_container_get_id (widget_data wcontainer)
  647. {
  648.     int i;
  649.     
  650.     for (i = 0; i < containers_no; i++)
  651.         if (wcontainer == containers [i])
  652.             return i;
  653.     return 0;
  654. }
  655.  
  656. static Notify_value x_container_item_interpos (Xv_opaque item, Event *event, 
  657.     Notify_arg arg, Notify_event_type type)
  658. {
  659.     Frame frame = (Frame) xv_get (item, XV_OWNER);
  660.  
  661.     switch (event_action (event)) {
  662.         case KBD_USE:
  663.     case ACTION_SELECT:
  664.     case ACTION_ADJUST:
  665.     case ACTION_MENU:
  666.         is_right = (x_container_get_id ((widget_data) frame) != 0);
  667.         default:
  668.             return notify_next_event_func (item, (Notify_event) event, 
  669.                 arg, type);
  670.     }
  671. }
  672.  
  673. extern Menu MenuBar []; /* from main.c */
  674.  
  675. widget_data x_create_panel_container (int which)
  676. {
  677.     Frame panelframe;
  678.     Panel toppanel, bottompanel;
  679.     Canvas leftcanvas, rightcanvas;
  680.     Canvas division;
  681.     int panelsplit = 0;
  682.     
  683.     panelframe = (Frame) xv_create (mcframe, FRAME,
  684.         XV_WIDTH, displayWidth * 2 / (3 * containers_no),
  685.         XV_HEIGHT, displayHeight / 2,
  686.         XV_X, displayWidth / 6 + 
  687.               which * (displayWidth * 2 / (3 * containers_no) + 30),
  688.         XV_Y, displayHeight / 4,
  689.         FRAME_LABEL, "/",
  690.         XV_KEY_DATA, KEY_DATA_PANEL_SPLITX, panelsplit,
  691.     FRAME_ICON, (Icon) xv_create(XV_NULL, ICON,
  692.         ICON_IMAGE, xv_create(XV_NULL, SERVER_IMAGE,
  693.             XV_WIDTH, 64,
  694.             XV_HEIGHT, 64,
  695.             SERVER_IMAGE_COLORMAP, "iconcms",
  696.             SERVER_IMAGE_DEPTH, 8,
  697.             SERVER_IMAGE_BITS, icon_bits,
  698.             NULL),
  699.         NULL),    
  700.         NULL);
  701.  
  702.     rightcanvas = (Canvas) xv_create (
  703.         panelframe, CANVAS,
  704.         WIN_CMS, mccms,
  705.         XV_X, 22,
  706.         XV_Y, 10,
  707.         XV_WIDTH, WIN_EXTEND_TO_EDGE,
  708.         XV_HEIGHT, 30,
  709.         NULL);
  710.         
  711.     leftcanvas = (Canvas) xv_create (
  712.         panelframe, CANVAS,
  713.         WIN_CMS, mccms,
  714.         XV_X, 0,
  715.         XV_Y, 10,
  716.         XV_WIDTH, 10,
  717.         XV_HEIGHT, 30,
  718.         NULL);
  719.         
  720.     toppanel = (Panel) xv_create (panelframe, PANEL,
  721.         XV_X, 0,
  722.         XV_Y, 0,
  723.         XV_WIDTH, WIN_EXTEND_TO_EDGE,
  724.         XV_HEIGHT, 10,
  725.         NULL);
  726.  
  727.     bottompanel = (Panel) xv_create (panelframe, PANEL,
  728.         XV_X, 0,
  729.         XV_Y, 40,
  730.         XV_WIDTH, WIN_EXTEND_TO_EDGE,
  731.         XV_HEIGHT, WIN_EXTEND_TO_EDGE,
  732.         NULL);
  733.  
  734.     division = (Canvas) xv_create (panelframe, CANVAS,
  735.         XV_X, 10,
  736.         XV_Y, 10,
  737.         XV_WIDTH, 12,
  738.         XV_HEIGHT, 30,
  739.         WIN_CMS, mccms,
  740.         WIN_FOREGROUND_COLOR, 0,
  741.  
  742.         CANVAS_PAINTWINDOW_ATTRS,
  743.             WIN_CURSOR, splitcursor,
  744.             NULL,
  745.         CANVAS_REPAINT_PROC, xv_division_repaint_proc,
  746.         CANVAS_X_PAINT_WINDOW, FALSE,
  747.         CANVAS_FIXED_IMAGE, FALSE,
  748.         CANVAS_AUTO_SHRINK, TRUE,
  749.         CANVAS_AUTO_EXPAND, TRUE,
  750.         CANVAS_RESIZE_PROC, xv_division_resize_proc,
  751.         CANVAS_VIEW_MARGIN, 0,
  752.         NULL);
  753.         
  754.     if (panelsplit < 30)
  755.         xv_set (leftcanvas,
  756.             XV_SHOW, FALSE,
  757.             NULL);
  758.         
  759.     xv_set (leftcanvas,
  760.         XV_KEY_DATA, KEY_DATA_SELREQ,
  761.             xv_create (leftcanvas, SELECTION_REQUESTOR,
  762.                 NULL),
  763.         NULL);
  764.  
  765.     xv_set (leftcanvas,
  766.         XV_KEY_DATA, KEY_DATA_HSCROLL,
  767.             xv_create (leftcanvas, SCROLLBAR,
  768.                 SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
  769.                 SCROLLBAR_SPLITTABLE, TRUE,
  770.                 NULL),
  771.         NULL);
  772.  
  773.     xv_set (leftcanvas,
  774.         XV_KEY_DATA, KEY_DATA_VSCROLL,
  775.             xv_create (leftcanvas, SCROLLBAR,
  776.                 SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
  777.                 SCROLLBAR_SPLITTABLE, TRUE,
  778.                 NULL),
  779.         NULL);
  780.  
  781.     xv_set (rightcanvas,
  782.         XV_KEY_DATA, KEY_DATA_SELREQ,
  783.             xv_create (rightcanvas, SELECTION_REQUESTOR,
  784.                 NULL),
  785.         NULL);
  786.  
  787.     xv_set (rightcanvas,
  788.         XV_KEY_DATA, KEY_DATA_HSCROLL,
  789.             xv_create (rightcanvas, SCROLLBAR,
  790.                 SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
  791.                 SCROLLBAR_SPLITTABLE, TRUE,
  792.                 NULL),
  793.         NULL);
  794.         
  795.     xv_set (rightcanvas,
  796.         XV_KEY_DATA, KEY_DATA_VSCROLL,
  797.             xv_create (rightcanvas, SCROLLBAR,
  798.                 SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
  799.                 SCROLLBAR_SPLITTABLE, TRUE,
  800.                 NULL),
  801.         NULL);
  802.  
  803.      xv_set (panelframe,
  804.          XV_KEY_DATA, KEY_DATA_AREA_TOP, toppanel,
  805.          XV_KEY_DATA, KEY_DATA_AREA_LEFT, leftcanvas,
  806.          XV_KEY_DATA, KEY_DATA_AREA_RIGHT, rightcanvas,
  807.          XV_KEY_DATA, KEY_DATA_AREA_BOTTOM, bottompanel,
  808.      XV_KEY_DATA, KEY_DATA_DIVISION, division,
  809.          NULL);
  810.  
  811.      notify_interpose_event_func (panelframe, x_container_interpose_proc, 
  812.          NOTIFY_SAFE);
  813.          
  814.      notify_interpose_event_func (toppanel, x_container_item_interpos, 
  815.          NOTIFY_SAFE);
  816.          
  817.      notify_interpose_event_func (bottompanel, x_container_item_interpos, 
  818.          NOTIFY_SAFE);
  819.          
  820.     return (widget_data) panelframe;
  821. }
  822.  
  823. void x_panel_container_show (widget_data wdata)
  824. {
  825.     window_fit_height 
  826.         ((Panel) xv_get ((Frame) wdata, XV_KEY_DATA, KEY_DATA_AREA_TOP));
  827.     window_fit_height
  828.         ((Panel) xv_get ((Frame) wdata, XV_KEY_DATA, KEY_DATA_AREA_BOTTOM));
  829.     x_container_resize_proc ((Frame) wdata); 
  830.     xv_set ((Frame) wdata,
  831.         XV_SHOW, TRUE,
  832.         NULL);
  833. }
  834.  
  835. void xv_center_layout (Panel panel)
  836. {
  837.     Panel_item item, item1, item2 = XV_NULL;
  838.     Widget *widget;
  839.     int y, shift;
  840.     
  841.     for (item = (Panel_item) xv_get (panel, PANEL_FIRST_ITEM); item != XV_NULL;
  842.         item = (Panel_item) xv_get (item, PANEL_NEXT_ITEM)) {
  843.         if (xv_get (item, PANEL_ITEM_OWNER))
  844.             continue;
  845.         widget = (Widget *) xv_get (item, PANEL_CLIENT_DATA);
  846.         if (widget->layout == XV_WLAY_CENTERROW) {
  847.             y = xv_get (item, XV_Y);
  848.             for (item1 = item; item1 != XV_NULL && (int) xv_get (item1, XV_Y) == y;
  849.                 item1 = (Panel_item) xv_get (item1, PANEL_NEXT_ITEM)) {
  850.                 item2 = item1;
  851.             }
  852.             shift = xv_get (panel, XV_WIDTH);
  853.             shift -= xv_get (item2, XV_X) + xv_get (item2, XV_WIDTH);
  854.             shift -= xv_get (item, XV_X);
  855.             shift /= 2;
  856.             for (item1 = item; item1 != XV_NULL; item1 = (Panel_item) 
  857.                 xv_get (item1, PANEL_NEXT_ITEM)) {
  858.                 xv_set (item1,
  859.                     XV_X, xv_get (item1, XV_X) + shift,
  860.                     NULL);
  861.                 if (item1 == item2)
  862.                     break;
  863.             }
  864.             item = item2;
  865.         } else if (widget->layout == XV_WLAY_EXTENDWIDTH) {
  866.             xv_set (item, 
  867.                 PANEL_LIST_WIDTH, xv_get (panel, XV_WIDTH) - 2 * xv_get (item, XV_X),
  868.                 NULL);
  869.         }
  870.     }
  871. }
  872.  
  873. void xvdlg_show (Dlg_head *dialog, widget_data wdata)
  874. {
  875.     Panel panel;
  876.     int w, h;
  877.  
  878.     panel = (Panel) xv_get ((Frame) wdata, FRAME_CMD_PANEL);
  879.     window_fit (panel);
  880.     if (xv_get (panel, XV_WIDTH) < 60)
  881.         xv_set (panel, XV_WIDTH, 60);
  882.     xv_set ((Frame) wdata,
  883.         XV_WIDTH, w = xv_get (panel, XV_WIDTH),
  884.         XV_HEIGHT, h = xv_get (panel, XV_HEIGHT),
  885.         NULL);
  886.     xv_center_layout (panel);
  887.     if (dialog->initfocus != NULL) {
  888.         Panel_item item = (Panel_item) dialog->initfocus->widget->wdata;
  889.        
  890.         if (xv_get (item, PANEL_ACCEPT_KEYSTROKE)) {
  891.         xv_set (panel, PANEL_CARET_ITEM, item);
  892.     }
  893.     }
  894.     xv_set ((Frame) wdata,
  895.         XV_X, (displayWidth - w) / 2,
  896.         XV_Y, (displayHeight - h) / 2,
  897.         XV_SHOW, TRUE,
  898.         NULL);
  899. }
  900.  
  901. void xv_post_proc (Dlg_head *h, void (*callback)(void *), void *arg)
  902. {
  903.     struct xv_dispatch_proc *proc, *proc_new;
  904.  
  905. #ifndef PARALELIZE
  906.     if (dispatch_current != NULL) {
  907. #endif    
  908.         proc_new = (struct xv_dispatch_proc *) xmalloc (
  909.             sizeof (struct xv_dispatch_proc), "XV post proc");
  910.         proc_new->callback = callback;
  911.         proc_new->arg = arg;
  912.         proc_new->next = NULL;
  913. #ifndef PARALELIZE            
  914.         if (dispatch_current->proc != NULL) {
  915.             for (proc = dispatch_current->proc; 
  916.                  proc->next != NULL; proc = proc->next);
  917.             proc->next = proc_new;
  918.         } else
  919.             dispatch_current->proc = proc_new;
  920.     }
  921. #else
  922.     proc_new->h = h;
  923.     if (dispatch_current != NULL) {
  924.         for (proc = dispatch_current; proc->next != NULL; 
  925.             proc = proc->next);
  926.         proc->next = proc_new;
  927.     } else
  928.         dispatch_current = proc_new;
  929. #endif    
  930. }
  931.  
  932. widget_data x_get_parent_object (Widget *w, widget_data wdata)
  933. {
  934.     if ((Frame) wdata == mcframe && w->wcontainer != (widget_data) NULL) {
  935.         switch (w->area) {
  936.             case AREA_TOP: 
  937.                 return (widget_data) xv_get ((Frame) (w->wcontainer), 
  938.                     XV_KEY_DATA, KEY_DATA_AREA_TOP);
  939.             case AREA_LEFT: 
  940.                 return (widget_data) xv_get ((Frame) (w->wcontainer), 
  941.                     XV_KEY_DATA, KEY_DATA_AREA_LEFT);
  942.             case AREA_RIGHT: 
  943.                 return (widget_data) xv_get ((Frame) (w->wcontainer), 
  944.                     XV_KEY_DATA, KEY_DATA_AREA_RIGHT);
  945.             case AREA_BOTTOM: 
  946.                 return (widget_data) xv_get ((Frame) (w->wcontainer), 
  947.                     XV_KEY_DATA, KEY_DATA_AREA_BOTTOM);
  948.         }
  949.     return (widget_data) NULL;
  950.     } else
  951.         return (widget_data) xv_get ((Frame) wdata, FRAME_CMD_PANEL);
  952. }
  953.  
  954. void xv_widget_layout (Panel_item item, WLay layout)
  955. {
  956.     Panel panel = (Panel) xv_get (item, XV_OWNER);
  957.     Panel_item lastitem = (Panel_item) xv_get (panel,
  958.         XV_KEY_DATA, KEY_DATA_PANEL_LASTITEM);
  959.     int maxx = (int) xv_get (panel, XV_KEY_DATA, KEY_DATA_PANEL_MAXX);
  960.     int maxy = (int) xv_get (panel, XV_KEY_DATA, KEY_DATA_PANEL_MAXY);
  961.     int w = (int) xv_get (item, XV_WIDTH);
  962.     int h = (int) xv_get (item, XV_HEIGHT);
  963.     int x = (int) xv_get (panel, PANEL_ITEM_X);
  964.     int y = (int) xv_get (panel, PANEL_ITEM_Y);
  965.  
  966.     if (lastitem != XV_NULL && layout != XV_WLAY_DONTCARE) {
  967.         switch (layout) {
  968.             case XV_WLAY_RIGHTOF:
  969.             case XV_WLAY_RIGHTDOWN:
  970.                 x = (int) xv_get (lastitem, XV_X) +
  971.                     (int) xv_get (lastitem, XV_WIDTH) +
  972.                     (int) xv_get (panel, PANEL_ITEM_X_GAP);
  973.                 if (layout == XV_WLAY_RIGHTOF) 
  974.                     y = (int) xv_get (lastitem, XV_Y);
  975.                 else {
  976.                     y = (int) xv_get (lastitem, XV_Y) + 
  977.                         (int) xv_get (lastitem, XV_HEIGHT) - h;
  978.                 }
  979.                 break;
  980.             case XV_WLAY_BELOWOF:
  981.                 x = (int) xv_get (lastitem, XV_X);
  982.         y = (int) xv_get (lastitem, XV_Y) +
  983.                     (int) xv_get (lastitem, XV_HEIGHT) +
  984.                     (int) xv_get (panel, PANEL_ITEM_Y_GAP);
  985.                 break;
  986.             case XV_WLAY_BELOWCLOSE:
  987.                 x = (int) xv_get (lastitem, XV_X);
  988.         y = (int) xv_get (lastitem, XV_Y) +
  989.                     (int) xv_get (lastitem, XV_HEIGHT);
  990.                 break;
  991.             case XV_WLAY_NEXTCOLUMN:
  992.                y = (int) xv_get (panel, XV_KEY_DATA, KEY_DATA_PANEL_MINY);
  993.                x = maxx + (int) xv_get (panel, PANEL_ITEM_X_GAP);
  994.                break;
  995.             case XV_WLAY_NEXTROW:
  996.             case XV_WLAY_CENTERROW:
  997.             case XV_WLAY_EXTENDWIDTH:
  998.                x = (int) xv_get (panel, XV_KEY_DATA, KEY_DATA_PANEL_MINX);
  999.                y = maxy + (int) xv_get (panel, PANEL_ITEM_Y_GAP);
  1000.                break;
  1001.             case XV_WLAY_DONTCARE:
  1002.                break;
  1003.         }
  1004.         xv_set (item,
  1005.                XV_X, x,
  1006.                XV_Y, y,
  1007.                NULL);
  1008.     } else if (lastitem == XV_NULL) {
  1009.         xv_set (item,
  1010.             XV_X, x,
  1011.             XV_Y, y,
  1012.             NULL);
  1013.         xv_set (panel, 
  1014.             XV_KEY_DATA, KEY_DATA_PANEL_MINX, x,
  1015.             NULL);
  1016.         xv_set (panel, 
  1017.             XV_KEY_DATA, KEY_DATA_PANEL_MINY, y,
  1018.             NULL);
  1019.     }
  1020.  
  1021.     if (maxx < x + w)
  1022.         xv_set (panel,
  1023.             XV_KEY_DATA, KEY_DATA_PANEL_MAXX, x + w,
  1024.             NULL);
  1025.     if (maxy < y + h)
  1026.         xv_set (panel,
  1027.             XV_KEY_DATA, KEY_DATA_PANEL_MAXY, y + h,
  1028.             NULL);
  1029.     xv_set (panel,
  1030.         XV_KEY_DATA, KEY_DATA_PANEL_LASTITEM, item,
  1031.         NULL);
  1032. }
  1033.  
  1034. int move (int y, int x)
  1035. {
  1036.     return 0;
  1037. }
  1038.