491 lines
8.5 KiB
C
491 lines
8.5 KiB
C
/*
|
|
* gui.c
|
|
*
|
|
* Copyright (c) 1995-1997, John Kilburg <john@cs.unlv.edu>
|
|
*
|
|
* 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 "port_before.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#ifdef HAVE_STDLIB_H
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_STRING_H
|
|
#include <string.h>
|
|
#endif
|
|
|
|
#include <X11/IntrinsicP.h>
|
|
#include <X11/StringDefs.h>
|
|
|
|
#include "port_after.h"
|
|
|
|
#include "ChimeraP.h"
|
|
|
|
#include "WWWP.h"
|
|
|
|
struct ChimeraGUIP
|
|
{
|
|
Widget www; /* Xt widget */
|
|
MemPool mp; /* memory pool */
|
|
ChimeraContext wc;
|
|
ChimeraRender wn;
|
|
|
|
/* state flags */
|
|
bool position_set;
|
|
|
|
bool size_set;
|
|
unsigned int width, height;
|
|
|
|
GUISizeCallback size_callback;
|
|
void *size_closure;
|
|
|
|
ChimeraTask resize_task;
|
|
};
|
|
|
|
static void ResizeTask _ArgProto((void *));
|
|
|
|
void GUIToplevelResize _ArgProto((Widget, void *, void *));
|
|
static void GUIExpose _ArgProto((Widget, void *, int, int,
|
|
unsigned int, unsigned int));
|
|
static void GUIMotion _ArgProto((Widget, void *, int, int, int));
|
|
static void GUISelect _ArgProto((Widget, void *, int, int, int));
|
|
|
|
/*
|
|
* GUIAddRender
|
|
*/
|
|
void
|
|
GUIAddRender(wd, wn)
|
|
ChimeraGUI wd;
|
|
ChimeraRender wn;
|
|
{
|
|
wd->wn = wn;
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUICreate
|
|
*/
|
|
ChimeraGUI
|
|
GUICreate(wc, parent, size_callback, size_closure)
|
|
ChimeraContext wc;
|
|
ChimeraGUI parent;
|
|
GUISizeCallback size_callback;
|
|
void *size_closure;
|
|
{
|
|
ChimeraGUI wd;
|
|
MemPool mp;
|
|
|
|
myassert(parent != NULL, "NULL parent not allowed");
|
|
|
|
mp = MPCreate();
|
|
wd = (ChimeraGUI)MPCGet(mp, sizeof(struct ChimeraGUIP));
|
|
wd->mp = mp;
|
|
wd->wc = wc;
|
|
wd->size_set = false;
|
|
wd->position_set = false;
|
|
wd->size_callback = size_callback;
|
|
wd->size_closure = size_closure;
|
|
|
|
wd->www = XtVaCreateManagedWidget("www_child",
|
|
wwwWidgetClass,
|
|
WWWGetDrawWidget(parent->www),
|
|
XtNmappedWhenManaged, False,
|
|
NULL);
|
|
|
|
WWWSetSelectCallback(wd->www, GUISelect, wd);
|
|
WWWSetMotionCallback(wd->www, GUIMotion, wd);
|
|
WWWSetExposeCallback(wd->www, GUIExpose, wd);
|
|
|
|
return(wd);
|
|
}
|
|
|
|
/*
|
|
* GUIDestroy
|
|
*/
|
|
void
|
|
GUIDestroy(wd)
|
|
ChimeraGUI wd;
|
|
{
|
|
MemPool mp = wd->mp;
|
|
|
|
if (wd->www != NULL) XtDestroyWidget(wd->www);
|
|
if (wd->resize_task != NULL) TaskRemove(wd->wc->cres, wd->resize_task);
|
|
memset(wd, 0, sizeof(struct ChimeraGUIP));
|
|
MPDestroy(mp);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIToWindow
|
|
*/
|
|
Window
|
|
GUIToWindow(wd)
|
|
ChimeraGUI wd;
|
|
{
|
|
return(XtWindow(WWWGetDrawWidget(wd->www)));
|
|
}
|
|
|
|
/*
|
|
* GUIToDisplay
|
|
*/
|
|
Display *
|
|
GUIToDisplay(wd)
|
|
ChimeraGUI wd;
|
|
{
|
|
return(XtDisplay(wd->www));
|
|
}
|
|
|
|
/*
|
|
* GUICreateToplevel
|
|
*/
|
|
ChimeraGUI
|
|
GUICreateToplevel(wc, parent, size_callback, size_closure)
|
|
ChimeraContext wc;
|
|
Widget parent;
|
|
GUISizeCallback size_callback;
|
|
void *size_closure;
|
|
{
|
|
ChimeraGUI wd;
|
|
MemPool mp;
|
|
|
|
mp = MPCreate();
|
|
wd = (ChimeraGUI)MPCGet(mp, sizeof(struct ChimeraGUIP));
|
|
wd->mp = mp;
|
|
wd->wc = wc;
|
|
wd->size_set = true;
|
|
wd->position_set = true;
|
|
wd->size_callback = size_callback;
|
|
wd->size_closure = size_closure;
|
|
|
|
wd->www = XtVaCreateManagedWidget("www_toplevel",
|
|
wwwWidgetClass, parent,
|
|
NULL);
|
|
|
|
WWWSetResizeCallback(wd->www, GUIToplevelResize, wd);
|
|
WWWSetSelectCallback(wd->www, GUISelect, wd);
|
|
WWWSetMotionCallback(wd->www, GUIMotion, wd);
|
|
WWWSetExposeCallback(wd->www, GUIExpose, wd);
|
|
|
|
return(wd);
|
|
}
|
|
|
|
/*
|
|
* GUISetScrollBar
|
|
*/
|
|
void
|
|
GUISetScrollBar(wd, use_scroll)
|
|
ChimeraGUI wd;
|
|
bool use_scroll;
|
|
{
|
|
WWWSetScrollBar(wd->www, use_scroll);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIGetDimenions
|
|
*/
|
|
int
|
|
GUIGetDimensions(wd, width, height)
|
|
ChimeraGUI wd;
|
|
unsigned int *width, *height;
|
|
{
|
|
if (!wd->size_set) return(-1);
|
|
WWWGetDrawSize(wd->www, width, height);
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* GUISetDimensions
|
|
*/
|
|
void
|
|
GUISetDimensions(wd, width, height)
|
|
ChimeraGUI wd;
|
|
unsigned int width, height;
|
|
{
|
|
WWWSetDrawSize(wd->www, width, height);
|
|
return;
|
|
}
|
|
|
|
int
|
|
GUIGetNamedColor(wd, name, pixel)
|
|
ChimeraGUI wd;
|
|
char *name;
|
|
Pixel *pixel;
|
|
{
|
|
XColor sxc, exc;
|
|
Display *dpy = XtDisplay(wd->www);
|
|
|
|
XAllocNamedColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)),
|
|
name, &sxc, &exc);
|
|
|
|
*pixel = sxc.pixel;
|
|
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* GUIGetOnScreenDimensions
|
|
*/
|
|
void
|
|
GUIGetOnScreenDimensions(wd, x, y, width, height)
|
|
ChimeraGUI wd;
|
|
int *x, *y;
|
|
unsigned int *width, *height;
|
|
{
|
|
WWWWidget rw = (WWWWidget)wd->www;
|
|
|
|
*x = -(int)rw->www.child->core.x;
|
|
*y = -(int)rw->www.child->core.y;
|
|
*width = (unsigned int)rw->www.child->core.width;
|
|
*height = (unsigned int)rw->www.clip->core.height;
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIReset
|
|
*/
|
|
void
|
|
GUIReset(wd)
|
|
ChimeraGUI wd;
|
|
{
|
|
WWWWidget rw = (WWWWidget)wd->www;
|
|
|
|
wd->wn = NULL;
|
|
XClearWindow(XtDisplay(rw->www.child), XtWindow(rw->www.child));
|
|
WWWMoveChild(wd->www, 0, 0);
|
|
WWWSetDrawSize(wd->www, 0, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIExpose
|
|
*/
|
|
static void
|
|
GUIExpose(w, closure, x, y, width, height)
|
|
Widget w;
|
|
void *closure;
|
|
int x, y;
|
|
unsigned int width, height;
|
|
{
|
|
ChimeraGUI wd = (ChimeraGUI)closure;
|
|
|
|
if (wd->wn != NULL) RenderExpose(wd->wn, x, y, width, height);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUISelect
|
|
*/
|
|
static void
|
|
GUISelect(w, closure, x, y, button)
|
|
Widget w;
|
|
void *closure;
|
|
int x, y;
|
|
int button;
|
|
{
|
|
ChimeraGUI wd = (ChimeraGUI)closure;
|
|
char *action;
|
|
|
|
if (wd->wn != NULL)
|
|
{
|
|
if (button == 1) action = "open";
|
|
else if (button == 2) action = "download";
|
|
else if (button == 3) action = "external";
|
|
else action = "open";
|
|
|
|
RenderSelect(wd->wn, x, y, action);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIMotion
|
|
*/
|
|
static void
|
|
GUIMotion(w, closure, x, y, button)
|
|
Widget w;
|
|
void *closure;
|
|
int x, y;
|
|
int button;
|
|
{
|
|
ChimeraGUI wd = (ChimeraGUI)closure;
|
|
|
|
if (wd->wn != NULL) RenderMotion(wd->wn, x, y);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIToplevelResize
|
|
*/
|
|
void
|
|
GUIToplevelResize(w, closure, junk)
|
|
Widget w;
|
|
void *closure;
|
|
void *junk;
|
|
{
|
|
ChimeraGUI wd = (ChimeraGUI)closure;
|
|
|
|
if (wd->size_callback != NULL)
|
|
{
|
|
Dimension width, height;
|
|
|
|
XtVaGetValues(wd->www, XtNwidth, &width, XtNheight, &height, NULL);
|
|
wd->width = width;
|
|
wd->height = height;
|
|
CMethod(wd->size_callback)(wd, wd->size_closure, wd->width, wd->height);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIMap
|
|
*/
|
|
void
|
|
GUIMap(wd, x, y)
|
|
ChimeraGUI wd;
|
|
int x, y;
|
|
{
|
|
if (!wd->size_set)
|
|
{
|
|
fprintf (stderr, "GUIMap: GUI dimensions not set yet.\n");
|
|
return;
|
|
}
|
|
if (wd->position_set)
|
|
{
|
|
fprintf (stderr, "GUIMap: already mapped.\n");
|
|
return;
|
|
}
|
|
|
|
XtConfigureWidget(wd->www, (Position)x, (Position)y,
|
|
(Dimension)wd->width, (Dimension)wd->height, 0);
|
|
|
|
XtSetMappedWhenManaged(wd->www, True);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIUnmap
|
|
*/
|
|
void
|
|
GUIUnmap(wd)
|
|
ChimeraGUI wd;
|
|
{
|
|
XtSetMappedWhenManaged(wd->www, False);
|
|
wd->size_set = false;
|
|
wd->position_set = false;
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* ResizeTask
|
|
*/
|
|
static void
|
|
ResizeTask(closure)
|
|
void *closure;
|
|
{
|
|
ChimeraGUI wd = (ChimeraGUI)closure;
|
|
|
|
if (wd->size_callback != NULL)
|
|
{
|
|
wd->resize_task = NULL;
|
|
CMethod(wd->size_callback)(wd, wd->size_closure, wd->width, wd->height);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUISetInitialDimensions
|
|
*/
|
|
void
|
|
GUISetInitialDimensions(wd, width, height)
|
|
ChimeraGUI wd;
|
|
unsigned int width, height;
|
|
{
|
|
myassert(!wd->size_set, "GUISetInitialDimensions: dimensions already set");
|
|
|
|
if (wd->resize_task != NULL) TaskRemove(wd->wc->cres, wd->resize_task);
|
|
|
|
wd->width = width;
|
|
wd->height = height;
|
|
wd->size_set = true;
|
|
|
|
XtResizeWidget(wd->www, (Dimension)width, (Dimension)height, 0);
|
|
WWWSetDrawSize(wd->www, width, height);
|
|
|
|
wd->resize_task = TaskSchedule(wd->wc->cres, ResizeTask, wd);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUISetScrollPosition
|
|
*/
|
|
void
|
|
GUISetScrollPosition(wd, x, y)
|
|
ChimeraGUI wd;
|
|
int x, y;
|
|
{
|
|
WWWMoveChild(wd->www, x, y);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIGetScrollPosition
|
|
*/
|
|
void
|
|
GUIGetScrollPosition(wd, x, y)
|
|
ChimeraGUI wd;
|
|
int *x, *y;
|
|
{
|
|
WWWGetScrollPosition(wd->www, x, y);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GUIBackgroundPixel
|
|
*/
|
|
Pixel
|
|
GUIBackgroundPixel(wd)
|
|
ChimeraGUI wd;
|
|
{
|
|
Pixel bg;
|
|
XtVaGetValues(wd->www, XtNbackground, &bg, NULL);
|
|
return(bg);
|
|
}
|
|
|
|
/*
|
|
* GUIToWidget
|
|
*/
|
|
Widget
|
|
GUIToWidget(wd)
|
|
ChimeraGUI wd;
|
|
{
|
|
return(WWWGetDrawWidget(wd->www));
|
|
}
|
|
|