mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-23 12:56:51 +03:00
39f1ef7136
not submitted because they are very brutal)
1119 lines
30 KiB
C
1119 lines
30 KiB
C
/* XView initialization.
|
|
Copyright (C) 1995 Jakub Jelinek.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
|
|
#include <config.h>
|
|
#include <stdarg.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <xview/xview.h>
|
|
#include <xview/frame.h>
|
|
#include <xview/panel.h>
|
|
#include <xview/screen.h>
|
|
#include <xview/xv_xrect.h>
|
|
#include <xview/cms.h>
|
|
#include <xview/scrollbar.h>
|
|
#include <xview/svrimage.h>
|
|
#include <xview/cursor.h>
|
|
#include <xview/defaults.h>
|
|
#include <xview/dragdrop.h>
|
|
#include <X11/xpm.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "fs.h"
|
|
#include "dir.h"
|
|
#include "mad.h"
|
|
#include "dlg.h"
|
|
#include "panel.h"
|
|
#include "xvmain.h"
|
|
#include "util.h"
|
|
|
|
|
|
Frame mcframe;
|
|
Frame menubarframe;
|
|
Cursor splitcursor, dropcursor;
|
|
Display *dpy;
|
|
int fdXConnection;
|
|
int displayWidth;
|
|
int displayHeight;
|
|
int defaultDepth;
|
|
int screen_no;
|
|
Server_image iconRegular [2];
|
|
Server_image iconDirectory [2];
|
|
Cms mccms;
|
|
Cms cmsicon;
|
|
static Xv_singlecolor icon_colors[] = {
|
|
{255, 255, 255},
|
|
{0, 0, 0},
|
|
{170, 68, 0},
|
|
{170, 170, 204},
|
|
{204, 102, 0},
|
|
{204, 204, 204},
|
|
{238, 0, 0},
|
|
{238, 204, 170},
|
|
{238, 238, 238},
|
|
{170, 0, 0},
|
|
{0, 136, 204},
|
|
{238, 153, 153},
|
|
{136, 68, 0},
|
|
{136, 136, 136},
|
|
{170, 102, 0},
|
|
{238, 170, 0},
|
|
{64, 64, 192}, /* the empty piece only */
|
|
{160, 64, 64}, /* the background color only */
|
|
};
|
|
|
|
#include "pictures.h"
|
|
|
|
int xv_error_handler (Xv_object object, Attr_avlist avlist);
|
|
void x_setup_info (void);
|
|
void xv_set_current_panel (WPanel *);
|
|
|
|
extern widget_data containers []; /* defined in main.c */
|
|
extern int containers_no;
|
|
extern int is_right;
|
|
extern Dlg_head *midnight_dlg;
|
|
|
|
void get_panel_color (Xv_Singlecolor *colors, int i)
|
|
{
|
|
static char *defcolors [] = {
|
|
"black", "gray75", /* normal */
|
|
"blue4", "gray75", /* marked */
|
|
"black", "gray50", /* selected */
|
|
"blue4", "gray50", /* marked selected */
|
|
};
|
|
static char *names [] = {"fg", "bg", "markfg", "markbg",
|
|
"selfg", "selbg", "markselfg", "markselbg" };
|
|
char *p, *q;
|
|
char buffer [40], buffer2 [40];
|
|
Xv_singlecolor col;
|
|
int red, green, blue;
|
|
XColor xcolor, scolor;
|
|
|
|
sprintf (buffer, "mxc.panelcolor.%s", names [i]);
|
|
sprintf (buffer2, "Mxc.PanelColor.%s", names [i]);
|
|
p = defaults_get_string (buffer, buffer2, "");
|
|
if (p != NULL) {
|
|
while (*p == ' ' || *p == '\t')
|
|
p++;
|
|
}
|
|
|
|
if (p != NULL && *p) {
|
|
if (sscanf (p, "%i %i %i", &red, &green, &blue) == 3) {
|
|
col.red = (u_char) red;
|
|
col.green = (u_char) green;
|
|
col.blue = (u_char) blue;
|
|
p = NULL;
|
|
} else {
|
|
for (q = p; *q && *q != ' ' && *q != '\t'; q++);
|
|
*q = 0;
|
|
}
|
|
} else {
|
|
p = defcolors [i];
|
|
}
|
|
|
|
if (p == NULL) {
|
|
colors->red = col.red;
|
|
colors->green = col.green;
|
|
colors->blue = col.blue;
|
|
}
|
|
else {
|
|
XLookupColor (dpy, DefaultColormap(dpy, screen_no), p,
|
|
&xcolor, &scolor);
|
|
colors->red = (unsigned char)(xcolor.red >> 8);
|
|
colors->green = (unsigned char)(xcolor.green >> 8);
|
|
colors->blue = (unsigned char)(xcolor.blue >> 8);
|
|
}
|
|
}
|
|
|
|
#include "Directory.xpm"
|
|
#include "Regular.xpm"
|
|
|
|
int xtoolkit_init(int *argc, char **argv)
|
|
{
|
|
int i;
|
|
char *mycolors[] = {
|
|
"LawnGreen", "gold", "brown", "sienna",
|
|
"salmon", "coral", "violet", "orchid",
|
|
"cornsilk", "azure", "misty rose", "snow",
|
|
"black", "red4", "green4", "yellow4",
|
|
"blue4", "magenta4", "cyan4", "gray75",
|
|
"gray50", "red", "green", "yellow",
|
|
"blue", "magenta", "cyan", "white", "black" };
|
|
Xv_singlecolor my_xv_colors[29];
|
|
XColor exact_c, screen_c;
|
|
Pixmap pixmap, shapemask;
|
|
|
|
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv,
|
|
XV_ERROR_PROC, xv_error_handler,
|
|
NULL);
|
|
mcframe = (Frame) xv_create (XV_NULL, FRAME,
|
|
FRAME_LABEL, "The Midnight X Commander",
|
|
NULL);
|
|
if (mcframe == XV_NULL)
|
|
return -1;
|
|
dpy = (Display *) xv_get (mcframe, XV_DISPLAY);
|
|
screen_no = (int) xv_get ((Xv_Screen) xv_get (mcframe, XV_SCREEN),
|
|
SCREEN_NUMBER);
|
|
displayWidth = DisplayWidth (dpy, screen_no);
|
|
displayHeight = DisplayHeight (dpy, screen_no);
|
|
defaultDepth = DefaultDepth (dpy, screen_no);
|
|
fdXConnection = XConnectionNumber (dpy);
|
|
xv_dispatch_a_bit ();
|
|
|
|
/* set up the array of Xv_singlecolors */
|
|
for (i = 0; i < 29; ++i) {
|
|
XLookupColor (dpy, DefaultColormap(dpy, screen_no), mycolors[i],
|
|
&exact_c, &screen_c);
|
|
my_xv_colors[i].red = (unsigned char)(exact_c.red >> 8);
|
|
my_xv_colors[i].green = (unsigned char)(exact_c.green >> 8);
|
|
my_xv_colors[i].blue = (unsigned char)(exact_c.blue >> 8);
|
|
}
|
|
|
|
defaults_load_db (APP_DEFAULTS);
|
|
for (i = 0; i < 8; i++)
|
|
get_panel_color (&my_xv_colors[i], i);
|
|
|
|
mccms = (Cms) xv_create (XV_NULL, CMS,
|
|
CMS_CONTROL_CMS, TRUE,
|
|
CMS_SIZE, 29 + CMS_CONTROL_COLORS,
|
|
CMS_NAME, "mccms",
|
|
CMS_COLORS, my_xv_colors,
|
|
NULL);
|
|
|
|
/* this seems never to be used ?? -- BD */
|
|
cmsicon = (Cms) xv_create(XV_NULL, CMS,
|
|
CMS_SIZE, 18,
|
|
CMS_COLORS, icon_colors,
|
|
CMS_NAME, "iconcms",
|
|
NULL);
|
|
|
|
splitcursor = (Cursor) xv_create (XV_NULL, CURSOR,
|
|
CURSOR_XHOT, 15,
|
|
CURSOR_YHOT, 14,
|
|
CURSOR_IMAGE, xv_create (XV_NULL, SERVER_IMAGE,
|
|
XV_WIDTH, 32,
|
|
XV_HEIGHT, 32,
|
|
SERVER_IMAGE_X_BITS, splitcursor_bits,
|
|
NULL),
|
|
NULL);
|
|
dropcursor = (Cursor) xv_create (XV_NULL, CURSOR,
|
|
CURSOR_XHOT, 3,
|
|
CURSOR_YHOT, 15,
|
|
CURSOR_IMAGE, xv_create (XV_NULL, SERVER_IMAGE,
|
|
XV_WIDTH, 32,
|
|
XV_HEIGHT, 32,
|
|
SERVER_IMAGE_X_BITS, dropcursor_bits,
|
|
NULL),
|
|
NULL);
|
|
|
|
XpmCreatePixmapFromData (dpy, (Drawable)xv_get(mcframe, XV_XID),
|
|
Regular_xpm, &pixmap, &shapemask, NULL);
|
|
|
|
iconRegular [0] = (Server_image) xv_create (XV_NULL, SERVER_IMAGE,
|
|
XV_WIDTH, 16,
|
|
XV_HEIGHT, 16,
|
|
SERVER_IMAGE_COLORMAP, "mccms",
|
|
SERVER_IMAGE_DEPTH, defaultDepth,
|
|
SERVER_IMAGE_PIXMAP, pixmap,
|
|
NULL);
|
|
|
|
iconRegular [1] = (Server_image) xv_create (XV_NULL, SERVER_IMAGE,
|
|
XV_WIDTH, 16,
|
|
XV_HEIGHT, 16,
|
|
SERVER_IMAGE_PIXMAP, shapemask,
|
|
NULL);
|
|
|
|
XpmCreatePixmapFromData (dpy, (Drawable)xv_get(mcframe, XV_XID),
|
|
Directory_xpm, &pixmap, &shapemask, NULL);
|
|
|
|
iconDirectory [0] = (Server_image) xv_create (XV_NULL, SERVER_IMAGE,
|
|
XV_WIDTH, 16,
|
|
XV_HEIGHT, 16,
|
|
SERVER_IMAGE_COLORMAP, "mccms",
|
|
SERVER_IMAGE_DEPTH, defaultDepth,
|
|
SERVER_IMAGE_PIXMAP, pixmap,
|
|
NULL);
|
|
|
|
iconDirectory [1] = (Server_image) xv_create (XV_NULL, SERVER_IMAGE,
|
|
XV_WIDTH, 16,
|
|
XV_HEIGHT, 16,
|
|
SERVER_IMAGE_PIXMAP, shapemask,
|
|
NULL);
|
|
|
|
xv_set (splitcursor,
|
|
XV_INCREMENT_REF_COUNT,
|
|
NULL);
|
|
xv_set (iconRegular [0],
|
|
XV_INCREMENT_REF_COUNT,
|
|
NULL);
|
|
xv_set (iconRegular [1],
|
|
XV_INCREMENT_REF_COUNT,
|
|
NULL);
|
|
xv_set (iconDirectory [0],
|
|
XV_INCREMENT_REF_COUNT,
|
|
NULL);
|
|
xv_set (iconDirectory [1],
|
|
XV_INCREMENT_REF_COUNT,
|
|
NULL);
|
|
xv_dispatch_something ();
|
|
|
|
x_setup_info ();
|
|
xv_dispatch_a_bit ();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int xtoolkit_end(void)
|
|
{
|
|
xv_destroy_safe (splitcursor);
|
|
xv_destroy_safe (iconRegular [0]);
|
|
xv_destroy_safe (iconRegular [1]);
|
|
xv_destroy_safe (iconDirectory [0]);
|
|
xv_destroy_safe (iconDirectory [1]);
|
|
return 0;
|
|
}
|
|
|
|
/* These are only temporary routines. Should go into dlg.c, which should be
|
|
completely rewritten for XView */
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
|
|
Notify_value my_destroy_func (Frame frame, Destroy_status status)
|
|
{
|
|
if (status == DESTROY_PROCESS_DEATH || status == DESTROY_CLEANUP) {
|
|
Dlg_head *h = (Dlg_head *) xv_get (frame,
|
|
XV_KEY_DATA, KEY_DATA_DLG_HEAD);
|
|
h->running = -1;
|
|
}
|
|
return notify_next_destroy_func (frame, status);
|
|
}
|
|
|
|
void my_done_func (Frame frame)
|
|
{
|
|
Dlg_head *h = (Dlg_head *) xv_get (frame,
|
|
XV_KEY_DATA, KEY_DATA_DLG_HEAD);
|
|
h->running = 0;
|
|
h->ret_value = B_CANCEL;
|
|
}
|
|
|
|
struct timeval timeout = { 0, 0 };
|
|
|
|
/*#define PARALELIZE*/
|
|
|
|
struct xv_dispatch_proc {
|
|
void (*callback)(void *);
|
|
void *arg;
|
|
#ifdef PARALELIZE
|
|
Dlg_head *h;
|
|
#endif
|
|
struct xv_dispatch_proc *next;
|
|
};
|
|
|
|
#ifndef PARALELIZE
|
|
struct xv_dispatch_struct {
|
|
Dlg_head *h;
|
|
struct xv_dispatch_struct *next;
|
|
struct xv_dispatch_proc *proc;
|
|
};
|
|
|
|
static struct xv_dispatch_struct *dispatch_current = NULL;
|
|
#else
|
|
static struct xv_dispatch_proc *dispatch_current = NULL;
|
|
#endif
|
|
|
|
static Dlg_head *previous_dlg = NULL;
|
|
int xvrundlg_event (Dlg_head *h)
|
|
{
|
|
fd_set readfds;
|
|
struct xv_dispatch_proc *proc, *proc2;
|
|
struct Dlg_head *previous = previous_dlg;
|
|
int v;
|
|
#ifndef PARALELIZE
|
|
struct xv_dispatch_struct *dispatch_new = xmalloc (
|
|
sizeof (struct xv_dispatch_struct), "XV dispatching");
|
|
#else
|
|
struct xv_dispatch_proc *proc4;
|
|
#endif
|
|
|
|
previous_dlg = h;
|
|
if (previous == midnight_dlg) {
|
|
xv_set (menubarframe,
|
|
FRAME_BUSY, TRUE,
|
|
NULL);
|
|
for (v = 0; v < containers_no; v++) {
|
|
xv_set ((Frame) containers [v],
|
|
FRAME_BUSY, TRUE,
|
|
NULL);
|
|
}
|
|
|
|
} else if (previous != (Dlg_head *) NULL) {
|
|
xv_set ((Frame) (previous->wdata),
|
|
FRAME_BUSY, TRUE,
|
|
NULL);
|
|
}
|
|
if (dispatch_current == NULL) {
|
|
h->wdata = mcframe;
|
|
xv_set (mcframe,
|
|
XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
|
|
NULL);
|
|
} else {
|
|
xv_set ((Frame) (h->wdata),
|
|
XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
|
|
NULL);
|
|
}
|
|
#ifndef PARALELIZE
|
|
dispatch_new->next = dispatch_current;
|
|
dispatch_current = dispatch_new;
|
|
dispatch_current->h = h;
|
|
dispatch_current->proc = NULL;
|
|
#endif
|
|
h->running = 1;
|
|
if (h->wdata == mcframe) {
|
|
xv_post_proc (h, (void (*)(void *))xv_action_icons, (void *) NULL);
|
|
}
|
|
|
|
notify_interpose_destroy_func ((Frame) (h->wdata), (Notify_func) my_destroy_func);
|
|
XFlush (dpy);
|
|
while (h->running >= 0) {
|
|
FD_ZERO (&readfds);
|
|
FD_SET (fdXConnection, &readfds);
|
|
v = select (FD_SETSIZE, &readfds, NULL, NULL, &timeout);
|
|
if (v > 0){
|
|
notify_dispatch ();
|
|
} else {
|
|
XFlush (dpy);
|
|
}
|
|
#ifndef PARALELIZE
|
|
if (dispatch_current->proc != NULL) {
|
|
proc = dispatch_current->proc;
|
|
dispatch_current->proc = proc->next;
|
|
#else
|
|
if (dispatch_current != NULL) {
|
|
proc = dispatch_current;
|
|
dispatch_current = proc->next;
|
|
#endif
|
|
(*proc->callback)(proc->arg);
|
|
free (proc);
|
|
}
|
|
if (h->running == 0) {
|
|
xv_destroy_safe (h->wdata);
|
|
}
|
|
}
|
|
if (previous == midnight_dlg) {
|
|
xv_set (menubarframe,
|
|
FRAME_BUSY, FALSE,
|
|
NULL);
|
|
for (v = 0; v < containers_no; v++) {
|
|
xv_set ((Frame) containers [v],
|
|
FRAME_BUSY, FALSE,
|
|
NULL);
|
|
}
|
|
|
|
} else if (previous != (Dlg_head *) NULL) {
|
|
xv_set ((Frame) (previous->wdata),
|
|
FRAME_BUSY, FALSE,
|
|
NULL);
|
|
}
|
|
previous_dlg = previous;
|
|
#ifndef PARALELIZE
|
|
dispatch_new = dispatch_current;
|
|
dispatch_current = dispatch_current->next;
|
|
for (proc = dispatch_new->proc; proc != NULL; proc = proc2) {
|
|
proc2 = proc->next;
|
|
free (proc);
|
|
}
|
|
free (dispatch_new);
|
|
#else
|
|
proc = dispatch_current;
|
|
dispatch_current = NULL;
|
|
proc4 = NULL;
|
|
for (; proc != NULL; proc = proc2) {
|
|
proc2 = proc->next;
|
|
if (proc->h == h)
|
|
free (proc);
|
|
else {
|
|
if (dispatch_current == NULL)
|
|
dispatch_current = proc4 = proc;
|
|
else {
|
|
proc4->next = proc;
|
|
proc4 = proc;
|
|
}
|
|
}
|
|
}
|
|
if (proc4 != NULL)
|
|
proc4->next = NULL;
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
void xv_dispatch_a_bit (void)
|
|
{
|
|
fd_set readfds;
|
|
struct timeval timeout = { 0, 1 };
|
|
struct timeval zero_timeout = { 0, 0 };
|
|
int i;
|
|
int v;
|
|
Xv_Server server = XV_SERVER_FROM_WINDOW (mcframe);
|
|
|
|
xv_set (server, SERVER_SYNC_AND_PROCESS_EVENTS, NULL);
|
|
|
|
XFlush (dpy);
|
|
#if 0
|
|
for (i = 0; i < 300; i++) {
|
|
int v;
|
|
|
|
FD_SET (fdXConnection, &readfds);
|
|
v = select (FD_SETSIZE, &readfds, NULL, NULL, &timeout);
|
|
if (v == -1){
|
|
fprintf (stderr, "Fatal: fdXConnection lost\n");
|
|
}
|
|
if (v){
|
|
notify_dispatch ();
|
|
} else
|
|
break;
|
|
}
|
|
#endif
|
|
for (v = 1; v;) {
|
|
FD_ZERO (&readfds);
|
|
FD_SET (fdXConnection, &readfds);
|
|
v = select (FD_SETSIZE, &readfds, NULL, NULL, &zero_timeout);
|
|
if (v == -1){
|
|
perror ("xv_dispatch\n");
|
|
exit (1);
|
|
}
|
|
if (v)
|
|
notify_dispatch ();
|
|
}
|
|
}
|
|
|
|
void xv_dispatch_something (void)
|
|
{
|
|
fd_set readfds;
|
|
struct timeval timeout = { 0, 1 };
|
|
Xv_Server server = XV_SERVER_FROM_WINDOW (mcframe);
|
|
int i;
|
|
|
|
xv_set (server, SERVER_SYNC_AND_PROCESS_EVENTS, NULL);
|
|
|
|
XFlush (dpy);
|
|
for (i = 0; i < 50; i++) {
|
|
FD_ZERO (&readfds);
|
|
FD_SET (fdXConnection, &readfds);
|
|
if (select (FD_SETSIZE, &readfds, NULL, NULL, &timeout)) {
|
|
notify_dispatch ();
|
|
} else
|
|
return;
|
|
}
|
|
}
|
|
|
|
widget_data xtoolkit_create_dialog (Dlg_head *h, int with_grid)
|
|
{
|
|
Frame frame;
|
|
Panel panel;
|
|
|
|
frame = (Frame) xv_create (mcframe, FRAME_CMD,
|
|
FRAME_LABEL, "Dialog",
|
|
FRAME_DONE_PROC, my_done_func,
|
|
NULL);
|
|
xv_set (panel = (Panel) xv_get (frame, FRAME_CMD_PANEL),
|
|
XV_KEY_DATA, KEY_DATA_PANEL_LASTITEM, XV_NULL,
|
|
XV_KEY_DATA, KEY_DATA_PANEL_MAXX, 0,
|
|
XV_KEY_DATA, KEY_DATA_PANEL_MAXY, 0,
|
|
NULL);
|
|
return (widget_data) frame;
|
|
}
|
|
|
|
/* Only needed when we run a dialog ourselves :) */
|
|
void xtoolkit_kill_dialog (Dlg_head *h)
|
|
{
|
|
h->running = 0;
|
|
xv_destroy_safe ((Frame) (h->wdata));
|
|
}
|
|
|
|
void x_set_dialog_title (Dlg_head *h, char *title)
|
|
{
|
|
xv_set ((Frame) (h->wdata),
|
|
FRAME_LABEL, title,
|
|
NULL);
|
|
}
|
|
|
|
widget_data xtoolkit_get_main_dialog (Dlg_head *h)
|
|
{
|
|
return (widget_data) mcframe;
|
|
}
|
|
|
|
int quit_cmd (void);
|
|
static void xv_container_done_proc (Frame frame)
|
|
{
|
|
xv_post_proc (midnight_dlg, (void (*)(void *))quit_cmd, NULL);
|
|
}
|
|
|
|
static void xv_division_repaint_proc (Canvas canvas, Xv_Window paint,
|
|
Rectlist *repaint)
|
|
{
|
|
int h;
|
|
Drawable xid = (Drawable) xv_get (paint, XV_XID);
|
|
GC gc = XCreateGC (dpy, xid, 0, 0);
|
|
unsigned long *xc;
|
|
XPoint xp [3];
|
|
|
|
#define DIVISION_LEFT 2
|
|
#define DIVISION_TOP 0
|
|
#define DIVISION_RIGHT 8
|
|
#define DIVISION_BOTTOM (h - 4)
|
|
h = xv_get (paint, XV_HEIGHT);
|
|
xc = (unsigned long *) xv_get (mccms, CMS_INDEX_TABLE);
|
|
XSetLineAttributes (dpy, gc, 1, LineSolid, JoinRound, CapNotLast);
|
|
xp [0].x = DIVISION_LEFT;
|
|
xp [0].y = DIVISION_BOTTOM;
|
|
xp [1].x = DIVISION_LEFT;
|
|
xp [1].y = DIVISION_TOP;
|
|
xp [2].x = DIVISION_RIGHT - 1;
|
|
xp [2].y = DIVISION_TOP;
|
|
XSetForeground (dpy, gc, xc [2]);
|
|
XDrawLines (dpy, xid, gc, xp, 3, CoordModeOrigin);
|
|
xp [0].x = DIVISION_LEFT + 1;
|
|
xp [0].y = DIVISION_BOTTOM - 1;
|
|
xp [1].x = DIVISION_RIGHT - 1;
|
|
xp [1].y = DIVISION_BOTTOM - 1;
|
|
xp [2].x = DIVISION_RIGHT - 1;
|
|
xp [2].y = DIVISION_TOP;
|
|
XSetForeground (dpy, gc, xc [3]);
|
|
XDrawLines (dpy, xid, gc, xp, 3, CoordModeOrigin);
|
|
XFreeGC (dpy, gc);
|
|
}
|
|
|
|
static void xv_division_resize_proc (Canvas canvas, int w, int h)
|
|
{
|
|
xv_division_repaint_proc (canvas,
|
|
xv_get (canvas, CANVAS_NTH_PAINT_WINDOW, 0), NULL);
|
|
}
|
|
|
|
static void x_container_resize_proc (Frame frame)
|
|
{
|
|
int w = xv_get (frame, XV_WIDTH);
|
|
int h = xv_get (frame, XV_HEIGHT);
|
|
int h1, h2, s;
|
|
Panel toppanel, bottompanel;
|
|
Canvas leftcanvas, rightcanvas;
|
|
Canvas division;
|
|
|
|
toppanel = (Panel) xv_get (frame, XV_KEY_DATA, KEY_DATA_AREA_TOP);
|
|
bottompanel = (Panel) xv_get (frame, XV_KEY_DATA, KEY_DATA_AREA_BOTTOM);
|
|
leftcanvas = (Canvas) xv_get (frame, XV_KEY_DATA, KEY_DATA_AREA_LEFT);
|
|
rightcanvas = (Canvas) xv_get (frame, XV_KEY_DATA, KEY_DATA_AREA_RIGHT);
|
|
division = (Canvas) xv_get (frame, XV_KEY_DATA, KEY_DATA_DIVISION);
|
|
|
|
h1 = xv_get (bottompanel, XV_HEIGHT);
|
|
h2 = xv_get (toppanel, XV_HEIGHT);
|
|
s = xv_get (frame, XV_KEY_DATA, KEY_DATA_PANEL_SPLITX);
|
|
|
|
xv_set (toppanel,
|
|
XV_X, 0,
|
|
XV_Y, 0,
|
|
XV_WIDTH, w,
|
|
XV_HEIGHT, h2,
|
|
NULL);
|
|
xv_set (bottompanel,
|
|
XV_X, 0,
|
|
XV_Y, h - h1,
|
|
XV_WIDTH, w,
|
|
XV_HEIGHT, h1,
|
|
NULL);
|
|
if (s > 30)
|
|
xv_set (leftcanvas,
|
|
XV_X, 0,
|
|
XV_Y, h2,
|
|
XV_HEIGHT, h - h1 - h2,
|
|
XV_WIDTH, s,
|
|
NULL);
|
|
if (w - s - 12 > 30)
|
|
xv_set (rightcanvas,
|
|
XV_X, s + 12,
|
|
XV_Y, h2,
|
|
XV_HEIGHT, h - h1 - h2,
|
|
XV_WIDTH, w - s - 12,
|
|
NULL);
|
|
xv_set (division,
|
|
XV_X, s,
|
|
XV_Y, h2,
|
|
XV_WIDTH, 12,
|
|
XV_HEIGHT, h - h1 - h2,
|
|
NULL);
|
|
}
|
|
|
|
static Notify_value x_container_interpose_proc (Frame frame, Event *event,
|
|
Notify_arg arg, Notify_event_type type)
|
|
{
|
|
switch (event_action (event)) {
|
|
case WIN_RESIZE:
|
|
x_container_resize_proc (frame);
|
|
return XV_OK;
|
|
default:
|
|
return notify_next_event_func (frame, (Notify_event) event,
|
|
arg, type);
|
|
}
|
|
}
|
|
|
|
int x_container_get_id (widget_data wcontainer)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < containers_no; i++)
|
|
if (wcontainer == containers [i])
|
|
return i;
|
|
return 0;
|
|
}
|
|
|
|
static Notify_value x_container_item_interpos (Xv_opaque item, Event *event,
|
|
Notify_arg arg, Notify_event_type type)
|
|
{
|
|
Frame frame = (Frame) xv_get (item, XV_OWNER);
|
|
|
|
switch (event_action (event)) {
|
|
case KBD_USE:
|
|
case ACTION_SELECT:
|
|
case ACTION_ADJUST:
|
|
case ACTION_MENU:
|
|
is_right = (x_container_get_id ((widget_data) frame) != 0);
|
|
default:
|
|
return notify_next_event_func (item, (Notify_event) event,
|
|
arg, type);
|
|
}
|
|
}
|
|
|
|
extern Menu MenuBar []; /* from main.c */
|
|
#include "panel_icon.xpm"
|
|
|
|
widget_data x_create_panel_container (int which)
|
|
{
|
|
Frame panelframe;
|
|
Panel toppanel, bottompanel;
|
|
Canvas leftcanvas, rightcanvas;
|
|
Canvas division;
|
|
int panelsplit = 0;
|
|
Pixmap pixmap, mask;
|
|
|
|
XpmCreatePixmapFromData (dpy, (Drawable)xv_get(mcframe, XV_XID),
|
|
panel_icon_xpm, &pixmap, &mask, NULL);
|
|
|
|
panelframe = (Frame) xv_create (mcframe, FRAME,
|
|
XV_WIDTH, displayWidth * 2 / (3 * containers_no),
|
|
XV_HEIGHT, displayHeight / 2,
|
|
XV_X, displayWidth / 6 +
|
|
which * (displayWidth * 2 / (3 * containers_no) + 30),
|
|
XV_Y, displayHeight / 4,
|
|
FRAME_LABEL, "/",
|
|
XV_KEY_DATA, KEY_DATA_PANEL_SPLITX, panelsplit,
|
|
FRAME_ICON, (Icon) xv_create(XV_NULL, ICON,
|
|
ICON_IMAGE, xv_create(XV_NULL, SERVER_IMAGE,
|
|
XV_WIDTH, 64,
|
|
XV_HEIGHT, 64,
|
|
SERVER_IMAGE_COLORMAP, "iconcms",
|
|
SERVER_IMAGE_DEPTH, defaultDepth,
|
|
SERVER_IMAGE_PIXMAP, pixmap,
|
|
NULL),
|
|
NULL),
|
|
NULL);
|
|
|
|
rightcanvas = (Canvas) xv_create (
|
|
panelframe, CANVAS,
|
|
WIN_CMS, mccms,
|
|
XV_X, 22,
|
|
XV_Y, 10,
|
|
XV_WIDTH, WIN_EXTEND_TO_EDGE,
|
|
XV_HEIGHT, 30,
|
|
NULL);
|
|
|
|
leftcanvas = (Canvas) xv_create (
|
|
panelframe, CANVAS,
|
|
WIN_CMS, mccms,
|
|
XV_X, 0,
|
|
XV_Y, 10,
|
|
XV_WIDTH, 10,
|
|
XV_HEIGHT, 30,
|
|
NULL);
|
|
|
|
toppanel = (Panel) xv_create (panelframe, PANEL,
|
|
XV_X, 0,
|
|
XV_Y, 0,
|
|
XV_WIDTH, WIN_EXTEND_TO_EDGE,
|
|
XV_HEIGHT, 10,
|
|
NULL);
|
|
|
|
bottompanel = (Panel) xv_create (panelframe, PANEL,
|
|
XV_X, 0,
|
|
XV_Y, 40,
|
|
XV_WIDTH, WIN_EXTEND_TO_EDGE,
|
|
XV_HEIGHT, WIN_EXTEND_TO_EDGE,
|
|
NULL);
|
|
|
|
division = (Canvas) xv_create (panelframe, CANVAS,
|
|
XV_X, 10,
|
|
XV_Y, 10,
|
|
XV_WIDTH, 12,
|
|
XV_HEIGHT, 30,
|
|
WIN_CMS, mccms,
|
|
WIN_FOREGROUND_COLOR, 0,
|
|
|
|
CANVAS_PAINTWINDOW_ATTRS,
|
|
WIN_CURSOR, splitcursor,
|
|
NULL,
|
|
CANVAS_REPAINT_PROC, xv_division_repaint_proc,
|
|
CANVAS_X_PAINT_WINDOW, FALSE,
|
|
CANVAS_FIXED_IMAGE, FALSE,
|
|
CANVAS_AUTO_SHRINK, TRUE,
|
|
CANVAS_AUTO_EXPAND, TRUE,
|
|
CANVAS_RESIZE_PROC, xv_division_resize_proc,
|
|
CANVAS_VIEW_MARGIN, 0,
|
|
NULL);
|
|
|
|
if (panelsplit < 30)
|
|
xv_set (leftcanvas,
|
|
XV_SHOW, FALSE,
|
|
NULL);
|
|
|
|
xv_set (leftcanvas,
|
|
XV_KEY_DATA, KEY_DATA_SELREQ,
|
|
xv_create (leftcanvas, SELECTION_REQUESTOR,
|
|
NULL),
|
|
NULL);
|
|
|
|
xv_set (leftcanvas,
|
|
XV_KEY_DATA, KEY_DATA_HSCROLL,
|
|
xv_create (leftcanvas, SCROLLBAR,
|
|
SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
|
|
SCROLLBAR_SPLITTABLE, TRUE,
|
|
NULL),
|
|
NULL);
|
|
|
|
xv_set (leftcanvas,
|
|
XV_KEY_DATA, KEY_DATA_VSCROLL,
|
|
xv_create (leftcanvas, SCROLLBAR,
|
|
SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
|
|
SCROLLBAR_SPLITTABLE, TRUE,
|
|
NULL),
|
|
NULL);
|
|
|
|
xv_set (rightcanvas,
|
|
XV_KEY_DATA, KEY_DATA_SELREQ,
|
|
xv_create (rightcanvas, SELECTION_REQUESTOR,
|
|
NULL),
|
|
NULL);
|
|
|
|
xv_set (rightcanvas,
|
|
XV_KEY_DATA, KEY_DATA_HSCROLL,
|
|
xv_create (rightcanvas, SCROLLBAR,
|
|
SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
|
|
SCROLLBAR_SPLITTABLE, TRUE,
|
|
NULL),
|
|
NULL);
|
|
|
|
xv_set (rightcanvas,
|
|
XV_KEY_DATA, KEY_DATA_VSCROLL,
|
|
xv_create (rightcanvas, SCROLLBAR,
|
|
SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
|
|
SCROLLBAR_SPLITTABLE, TRUE,
|
|
NULL),
|
|
NULL);
|
|
|
|
xv_set (panelframe,
|
|
XV_KEY_DATA, KEY_DATA_AREA_TOP, toppanel,
|
|
XV_KEY_DATA, KEY_DATA_AREA_LEFT, leftcanvas,
|
|
XV_KEY_DATA, KEY_DATA_AREA_RIGHT, rightcanvas,
|
|
XV_KEY_DATA, KEY_DATA_AREA_BOTTOM, bottompanel,
|
|
XV_KEY_DATA, KEY_DATA_DIVISION, division,
|
|
NULL);
|
|
|
|
notify_interpose_event_func (panelframe, x_container_interpose_proc,
|
|
NOTIFY_SAFE);
|
|
|
|
notify_interpose_event_func (toppanel, x_container_item_interpos,
|
|
NOTIFY_SAFE);
|
|
|
|
notify_interpose_event_func (bottompanel, x_container_item_interpos,
|
|
NOTIFY_SAFE);
|
|
|
|
return (widget_data) panelframe;
|
|
}
|
|
|
|
void x_panel_container_show (widget_data wdata)
|
|
{
|
|
window_fit_height
|
|
((Panel) xv_get ((Frame) wdata, XV_KEY_DATA, KEY_DATA_AREA_TOP));
|
|
window_fit_height
|
|
((Panel) xv_get ((Frame) wdata, XV_KEY_DATA, KEY_DATA_AREA_BOTTOM));
|
|
x_container_resize_proc ((Frame) wdata);
|
|
xv_set ((Frame) wdata,
|
|
XV_SHOW, TRUE,
|
|
NULL);
|
|
}
|
|
|
|
void xv_center_layout (Panel panel)
|
|
{
|
|
Panel_item item, item1, item2 = XV_NULL;
|
|
Widget *widget;
|
|
int y, shift;
|
|
|
|
for (item = (Panel_item) xv_get (panel, PANEL_FIRST_ITEM); item != XV_NULL;
|
|
item = (Panel_item) xv_get (item, PANEL_NEXT_ITEM)) {
|
|
if (xv_get (item, PANEL_ITEM_OWNER))
|
|
continue;
|
|
widget = (Widget *) xv_get (item, PANEL_CLIENT_DATA);
|
|
if (widget->layout == XV_WLAY_CENTERROW) {
|
|
y = xv_get (item, XV_Y);
|
|
for (item1 = item; item1 != XV_NULL && (int) xv_get (item1, XV_Y) == y;
|
|
item1 = (Panel_item) xv_get (item1, PANEL_NEXT_ITEM)) {
|
|
item2 = item1;
|
|
}
|
|
shift = xv_get (panel, XV_WIDTH);
|
|
shift -= xv_get (item2, XV_X) + xv_get (item2, XV_WIDTH);
|
|
shift -= xv_get (item, XV_X);
|
|
shift /= 2;
|
|
for (item1 = item; item1 != XV_NULL; item1 = (Panel_item)
|
|
xv_get (item1, PANEL_NEXT_ITEM)) {
|
|
xv_set (item1,
|
|
XV_X, xv_get (item1, XV_X) + shift,
|
|
NULL);
|
|
if (item1 == item2)
|
|
break;
|
|
}
|
|
item = item2;
|
|
} else if (widget->layout == XV_WLAY_EXTENDWIDTH) {
|
|
xv_set (item,
|
|
PANEL_LIST_WIDTH, xv_get (panel, XV_WIDTH) - 2 * xv_get (item, XV_X),
|
|
NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
void xvdlg_show (Dlg_head *dialog, widget_data wdata)
|
|
{
|
|
Panel panel;
|
|
int w, h;
|
|
|
|
panel = (Panel) xv_get ((Frame) wdata, FRAME_CMD_PANEL);
|
|
window_fit (panel);
|
|
if (xv_get (panel, XV_WIDTH) < 60)
|
|
xv_set (panel, XV_WIDTH, 60);
|
|
xv_set ((Frame) wdata,
|
|
XV_WIDTH, w = xv_get (panel, XV_WIDTH),
|
|
XV_HEIGHT, h = xv_get (panel, XV_HEIGHT),
|
|
NULL);
|
|
xv_center_layout (panel);
|
|
if (dialog->initfocus != NULL) {
|
|
Panel_item item = (Panel_item) dialog->initfocus->widget->wdata;
|
|
|
|
if (xv_get (item, PANEL_ACCEPT_KEYSTROKE)) {
|
|
xv_set (panel, PANEL_CARET_ITEM, item);
|
|
}
|
|
}
|
|
xv_set ((Frame) wdata,
|
|
XV_X, (displayWidth - w) / 2,
|
|
XV_Y, (displayHeight - h) / 2,
|
|
XV_SHOW, TRUE,
|
|
NULL);
|
|
}
|
|
|
|
void xv_post_proc (Dlg_head *h, void (*callback)(void *), void *arg)
|
|
{
|
|
struct xv_dispatch_proc *proc, *proc_new;
|
|
|
|
#ifndef PARALELIZE
|
|
if (dispatch_current != NULL) {
|
|
#endif
|
|
proc_new = (struct xv_dispatch_proc *) xmalloc (
|
|
sizeof (struct xv_dispatch_proc), "XV post proc");
|
|
proc_new->callback = callback;
|
|
proc_new->arg = arg;
|
|
proc_new->next = NULL;
|
|
#ifndef PARALELIZE
|
|
if (dispatch_current->proc != NULL) {
|
|
for (proc = dispatch_current->proc;
|
|
proc->next != NULL; proc = proc->next);
|
|
proc->next = proc_new;
|
|
} else
|
|
dispatch_current->proc = proc_new;
|
|
}
|
|
#else
|
|
proc_new->h = h;
|
|
if (dispatch_current != NULL) {
|
|
for (proc = dispatch_current; proc->next != NULL;
|
|
proc = proc->next);
|
|
proc->next = proc_new;
|
|
} else
|
|
dispatch_current = proc_new;
|
|
#endif
|
|
}
|
|
|
|
widget_data x_get_parent_object (Widget *w, widget_data wdata)
|
|
{
|
|
if ((Frame) wdata == mcframe && w->wcontainer != (widget_data) NULL) {
|
|
switch (w->area) {
|
|
case AREA_TOP:
|
|
return (widget_data) xv_get ((Frame) (w->wcontainer),
|
|
XV_KEY_DATA, KEY_DATA_AREA_TOP);
|
|
case AREA_LEFT:
|
|
return (widget_data) xv_get ((Frame) (w->wcontainer),
|
|
XV_KEY_DATA, KEY_DATA_AREA_LEFT);
|
|
case AREA_RIGHT:
|
|
return (widget_data) xv_get ((Frame) (w->wcontainer),
|
|
XV_KEY_DATA, KEY_DATA_AREA_RIGHT);
|
|
case AREA_BOTTOM:
|
|
return (widget_data) xv_get ((Frame) (w->wcontainer),
|
|
XV_KEY_DATA, KEY_DATA_AREA_BOTTOM);
|
|
}
|
|
return (widget_data) NULL;
|
|
} else
|
|
return (widget_data) xv_get ((Frame) wdata, FRAME_CMD_PANEL);
|
|
}
|
|
|
|
void xv_widget_layout (Panel_item item, WLay layout)
|
|
{
|
|
Panel panel = (Panel) xv_get (item, XV_OWNER);
|
|
Panel_item lastitem = (Panel_item) xv_get (panel,
|
|
XV_KEY_DATA, KEY_DATA_PANEL_LASTITEM);
|
|
int maxx = (int) xv_get (panel, XV_KEY_DATA, KEY_DATA_PANEL_MAXX);
|
|
int maxy = (int) xv_get (panel, XV_KEY_DATA, KEY_DATA_PANEL_MAXY);
|
|
int w = (int) xv_get (item, XV_WIDTH);
|
|
int h = (int) xv_get (item, XV_HEIGHT);
|
|
int x = (int) xv_get (panel, PANEL_ITEM_X);
|
|
int y = (int) xv_get (panel, PANEL_ITEM_Y);
|
|
|
|
if (lastitem != XV_NULL && layout != XV_WLAY_DONTCARE) {
|
|
switch (layout) {
|
|
case XV_WLAY_RIGHTOF:
|
|
case XV_WLAY_RIGHTDOWN:
|
|
x = (int) xv_get (lastitem, XV_X) +
|
|
(int) xv_get (lastitem, XV_WIDTH) +
|
|
(int) xv_get (panel, PANEL_ITEM_X_GAP);
|
|
if (layout == XV_WLAY_RIGHTOF)
|
|
y = (int) xv_get (lastitem, XV_Y);
|
|
else {
|
|
y = (int) xv_get (lastitem, XV_Y) +
|
|
(int) xv_get (lastitem, XV_HEIGHT) - h;
|
|
}
|
|
break;
|
|
case XV_WLAY_BELOWOF:
|
|
x = (int) xv_get (lastitem, XV_X);
|
|
y = (int) xv_get (lastitem, XV_Y) +
|
|
(int) xv_get (lastitem, XV_HEIGHT) +
|
|
(int) xv_get (panel, PANEL_ITEM_Y_GAP);
|
|
break;
|
|
case XV_WLAY_BELOWCLOSE:
|
|
x = (int) xv_get (lastitem, XV_X);
|
|
y = (int) xv_get (lastitem, XV_Y) +
|
|
(int) xv_get (lastitem, XV_HEIGHT);
|
|
break;
|
|
case XV_WLAY_NEXTCOLUMN:
|
|
y = (int) xv_get (panel, XV_KEY_DATA, KEY_DATA_PANEL_MINY);
|
|
x = maxx + (int) xv_get (panel, PANEL_ITEM_X_GAP);
|
|
break;
|
|
case XV_WLAY_NEXTROW:
|
|
case XV_WLAY_CENTERROW:
|
|
case XV_WLAY_EXTENDWIDTH:
|
|
x = (int) xv_get (panel, XV_KEY_DATA, KEY_DATA_PANEL_MINX);
|
|
y = maxy + (int) xv_get (panel, PANEL_ITEM_Y_GAP);
|
|
break;
|
|
case XV_WLAY_DONTCARE:
|
|
break;
|
|
}
|
|
xv_set (item,
|
|
XV_X, x,
|
|
XV_Y, y,
|
|
NULL);
|
|
} else if (lastitem == XV_NULL) {
|
|
xv_set (item,
|
|
XV_X, x,
|
|
XV_Y, y,
|
|
NULL);
|
|
xv_set (panel,
|
|
XV_KEY_DATA, KEY_DATA_PANEL_MINX, x,
|
|
NULL);
|
|
xv_set (panel,
|
|
XV_KEY_DATA, KEY_DATA_PANEL_MINY, y,
|
|
NULL);
|
|
}
|
|
|
|
if (maxx < x + w)
|
|
xv_set (panel,
|
|
XV_KEY_DATA, KEY_DATA_PANEL_MAXX, x + w,
|
|
NULL);
|
|
if (maxy < y + h)
|
|
xv_set (panel,
|
|
XV_KEY_DATA, KEY_DATA_PANEL_MAXY, y + h,
|
|
NULL);
|
|
xv_set (panel,
|
|
XV_KEY_DATA, KEY_DATA_PANEL_LASTITEM, item,
|
|
NULL);
|
|
}
|
|
|
|
int move (int y, int x)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
x_init_dlg (Dlg_head *h)
|
|
{
|
|
if (h != midnight_dlg)
|
|
xvdlg_show(h, h->wdata);
|
|
else {
|
|
int i;
|
|
for (i = 0; i < containers_no; i++)
|
|
x_panel_container_show (containers [i]);
|
|
}
|
|
}
|
|
|
|
void
|
|
x_destroy_dlg_start (Dlg_head *h)
|
|
{
|
|
}
|
|
|
|
void
|
|
x_destroy_dlg (Dlg_head *h)
|
|
{
|
|
}
|
|
|
|
void
|
|
x_focus_widget (Widget_Item *p)
|
|
{
|
|
}
|
|
|
|
void
|
|
x_unfocus_widget (Widget_Item *p)
|
|
{
|
|
}
|
|
|
|
void
|
|
edition_post_exec (void)
|
|
{
|
|
}
|
|
|
|
void
|
|
edition_pre_exec (void)
|
|
{
|
|
}
|
|
|
|
/* This is only used by the editor, so we provide a dummy implementation */
|
|
void
|
|
try_alloc_color_pair (char *str, char *str2)
|
|
{
|
|
}
|