#include "openaxiom-c-macros.h"
#include <unistd.h>
#include <sys/signal.h>
#include <setjmp.h>
#include <X11/cursorfont.h>
#include <X11/Xresource.h>
#include <X11/Xatom.h>
#include "debug.h"
#include "sockio.h"
#include "initx.h"
#ifdef SUN4OS5platform
extern int gethostname(char *, int );
#endif
#include "ht_icon"
#include "extent.h"
#include "group.h"
#include "hyper.h"
#include "scrollbar.h"
#include "titlebar.h"
#include "util.H1"
#include "cfuns.h"
#include "spadcolors.h"
#include "mouse11.bitmap"
#include "mouse11.mask"
using namespace OpenAxiom;
static void get_GCs(HDWindow * window);
static int get_border_properties();
static int get_color(const char* , const char* , int, Colormap*);
static void ingItColors_and_fonts();
static void load_font(XFontStruct * * font_info , char * fontname);
static void mergeDatabases();
static void open_form_window();
static void open_window(Window w);
static void set_name_and_icon();
static void set_size_hints(Window w);
static GContext server_font;
unsigned long *spadColors;
int scrn;
extern int received_window_request;
extern int in_next_event;
extern int gTtFontIs850;
#define MIN_WINDOW_SIZE 300
int gActiveColor,
gAxiomColor,
gBackgroundColor,
gBfColor,
gControlBackgroundColor,
gControlForegroundColor,
gEmColor,
gInputBackgroundColor,
gInputForegroundColor,
gItColor,
gRmColor,
gSlColor,
gTtColor;
XFontStruct *gAxiomFont,
*gActiveFont,
*gBfFont,
*gEmFont,
*gInputFont,
*gItFont,
*gRmFont,
*gSlFont,
*gTitleFont,
*gTtFont;
XrmDatabase rDB;
int gBorderColor;
void
initializeWindowSystem()
{
char *display_name = NULL;
XColor fg, bg;
#if 0
XColor rgbdef;
#endif
Colormap cmap;
Pixmap mousebits, mousemask;
if ((gXDisplay = XOpenDisplay(display_name)) == NULL) {
fprintf(stderr, "(HyperDoc) Cannot connect to the X11 server!\n");
exit(-1);
}
gXScreenNumber = scrn = DefaultScreen(gXDisplay);
server_font =XGContextFromGC(DefaultGC(gXDisplay, gXScreenNumber));
cmap = DefaultColormap(gXDisplay, gXScreenNumber);
fg.pixel = WhitePixel(gXDisplay,gXScreenNumber);
XQueryColor(gXDisplay, cmap, &fg );
bg.pixel = BlackPixel(gXDisplay,gXScreenNumber);
XQueryColor(gXDisplay, cmap, &bg );
#if 0
XAllocNamedColor(gXDisplay, cmap, "Black", &fg, &rgbdef);
XAllocNamedColor(gXDisplay, cmap, "White", &bg, &rgbdef);
#endif
#ifdef USE_BORING_OLD_CURSORS
gActiveCursor = XCreateFontCursor(gXDisplay, XC_circle);
gNormalCursor = XCreateFontCursor(gXDisplay, XC_dot);
#else
mousebits = XCreateBitmapFromData(gXDisplay,
RootWindow(gXDisplay, gXScreenNumber),
as_chars(mouseBitmap_bits), mouseBitmap_width,mouseBitmap_height);
mousemask = XCreateBitmapFromData(gXDisplay,
RootWindow(gXDisplay, gXScreenNumber),
as_chars(mouseMask_bits), mouseMask_width,mouseMask_height);
gActiveCursor = XCreatePixmapCursor(gXDisplay,
mousebits, mousemask, &fg, &bg,
mouseBitmap_x_hot,mouseBitmap_y_hot);
gNormalCursor = XCreateFontCursor(gXDisplay, XC_left_ptr);
#endif
gBusyCursor = XCreateFontCursor(gXDisplay, XC_watch);
ingItColors_and_fonts();
init_text();
}
int
init_top_window(const char *name)
{
HyperDocPage *page;
XSetWindowAttributes wa;
HDWindow *old_win = gWindow;
gWindow = alloc_hd_window();
if (name == NULL) {
page = alloc_page((char *) NULL);
}
else {
page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name);
if (page == NULL) {
fprintf(stderr, "(HyperDoc) Couldn\'t find page %s in page hash table \n",
name);
if (gParentWindow == NULL)
exit(-1);
else {
gWindow = old_win;
return -1;
}
}
}
gWindow->page = page;
if (old_win == NULL)
open_window(0);
else
open_window(old_win->fMainWindow);
get_GCs(gWindow);
XMapWindow(gXDisplay, gWindow->fMainWindow);
hash_insert(&gSessionHashTable, (char *)gWindow,(char *) &gWindow->fMainWindow);
change_text(gRmColor, gRmFont);
wa.background_pixel = gBackgroundColor;
XChangeWindowAttributes(gXDisplay, gWindow->fMainWindow, CWBackPixel, &wa);
XChangeWindowAttributes(gXDisplay, gWindow->fScrollWindow, CWBackPixel,&wa);
return 1;
}
static void
open_form_window()
{
int x, y, width, height;
unsigned int fwidth = 0, fheight = 0;
unsigned int xadder = 0, yadder = 0;
XrmValue value;
char *str_type[50];
XSizeHints size_hints;
int userSpecified = 0;
char userdefaults[50], progdefaults[50];
strcpy(progdefaults, "=950x450+0+0");
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.FormGeometry",
"OpenAxiom.hyperdoc.FormGeometry", str_type, &value) == True)
{
strncpy(userdefaults, value.addr, (int) value.size);
userSpecified = 1;
}
else
strcpy(userdefaults, progdefaults);
XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults,
0, fwidth, fheight, xadder, yadder,
&x, &y, &width, &height);
gWindow->border_width = get_border_properties();
gWindow->width = 1;
gWindow->height = 1;
gWindow->fMainWindow = XCreateSimpleWindow(gXDisplay, RootWindow(gXDisplay, gXScreenNumber),
x, y, width, height, gWindow->border_width,
gBorderColor,
WhitePixel(gXDisplay, gXScreenNumber));
gWindow->fScrollWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow,
1, 1, 1, 1, 0,
BlackPixel(gXDisplay, gXScreenNumber),
WhitePixel(gXDisplay, gXScreenNumber));
makeScrollBarWindows();
makeTitleBarWindows();
set_name_and_icon();
XSelectInput(gXDisplay, gWindow->fScrollWindow, PointerMotionMask);
XSelectInput(gXDisplay, gWindow->fMainWindow, StructureNotifyMask | PointerMotionMask);
XDefineCursor(gXDisplay, gWindow->fMainWindow, gNormalCursor);
size_hints.flags = 0;
size_hints.min_width = width;
size_hints.min_height = height;
size_hints.flags |= PMinSize;
size_hints.width = width;
size_hints.height = height;
size_hints.flags |= (userSpecified ? USSize : PSize);
size_hints.x = x;
size_hints.y = y;
size_hints.flags |= (userSpecified ? USPosition : PPosition);
XSetNormalHints(gXDisplay, gWindow->fMainWindow, &size_hints);
XFlush(gXDisplay);
}
int
init_form_window(char *name, int cols)
{
XSetWindowAttributes wa;
gWindow = alloc_hd_window();
open_form_window();
gWindow->width = window_width(cols);
if (name == NULL) {
gWindow->page = alloc_page((char *) NULL);
}
else {
gWindow->page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name);
if (gWindow->page == NULL) {
fprintf(stderr, "Couldn't find page %s\n", name);
return (-1);
}
}
get_GCs(gWindow);
hash_insert(&gSessionHashTable, (char *)gWindow,(char *) &gWindow->fMainWindow);
wa.background_pixel = gBackgroundColor;
XChangeWindowAttributes(gXDisplay, gWindow->fMainWindow, CWBackPixel, &wa);
XChangeWindowAttributes(gXDisplay, gWindow->fScrollWindow, CWBackPixel,&wa);
return 1;
}
static void
set_name_and_icon()
{
const char *icon_name = "HyperDoc";
char *s;
Pixmap icon_pixmap;
XWMHints wmhints;
XClassHint ch;
ch.res_name = "HyperDoc";
ch.res_class = gArgv[0];
for (s = gArgv[0] + strlen(gArgv[0]) - 1; s != gArgv[0]; s--) {
if (*s == '/') {
ch.res_class = s + 1;
break;
}
}
XSetClassHint(gXDisplay, gWindow->fMainWindow, &ch);
XStoreName(gXDisplay, gWindow->fMainWindow, "HyperDoc");
icon_pixmap = XCreateBitmapFromData(gXDisplay, gWindow->fMainWindow,
as_chars(ht_icon_bits),
ht_icon_width, ht_icon_height);
wmhints.icon_pixmap = icon_pixmap;
wmhints.flags = IconPixmapHint;
XSetWMHints(gXDisplay, gWindow->fMainWindow, &wmhints);
XSetIconName(gXDisplay, gWindow->fMainWindow, icon_name);
}
static int
get_border_properties()
{
const char *bwidth;
int bw;
Colormap cmap;
bwidth = "2";
if (bwidth == NULL)
bw = 1;
else {
bw = atoi(bwidth);
if (bw < 1) {
fprintf(stderr,
"%s: The line width value must be greater than zero\n", "OpenAxiom.hyperdoc");
bw = 1;
}
}
if (DisplayPlanes(gXDisplay, gXScreenNumber) == 1)
gBorderColor = BlackPixel(gXDisplay, gXScreenNumber);
else {
cmap = DefaultColormap(gXDisplay, gXScreenNumber);
gBorderColor = get_color("BorderColor", "Foreground",
BlackPixel(gXDisplay, gXScreenNumber), &cmap);
}
return bw;
}
static void
open_window(Window w)
{
int x = 0, y = 0;
unsigned int width = 1;
unsigned int height = 1;
unsigned int fwidth = 0, fheight = 0;
unsigned int xadder = 0, yadder = 0;
char *str_type[50];
XrmValue value;
char userdefaults[50], progdefaults[50];
strcpy(progdefaults, "=700x450+0+0");
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.Geometry",
"OpenAxiom.hyperdoc.Geometry", str_type, &value) == True)
{
strncpy(userdefaults, value.addr, (int) value.size);
}
else
strcpy(userdefaults, progdefaults);
XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults,
0, fwidth, fheight, xadder, yadder,
&x, &y, ( int *)&width,( int *) &height);
gWindow->border_width = get_border_properties();
gWindow->fMainWindow = XCreateSimpleWindow(gXDisplay, RootWindow(gXDisplay, gXScreenNumber),
x, y, width, height, gWindow->border_width,
gBorderColor,
WhitePixel(gXDisplay, gXScreenNumber));
gWindow->fScrollWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow,
1, 1, 1, 1, 0,
gBorderColor,
WhitePixel(gXDisplay, gXScreenNumber));
makeScrollBarWindows();
makeTitleBarWindows();
set_name_and_icon();
set_size_hints(w);
XSelectInput(gXDisplay, gWindow->fScrollWindow, PointerMotionMask);
XSelectInput(gXDisplay, gWindow->fMainWindow, StructureNotifyMask | PointerMotionMask);
XDefineCursor(gXDisplay, gWindow->fMainWindow, gNormalCursor);
}
static void
set_size_hints(Window w)
{
int x, y;
unsigned int width, height;
char userdefaults[50];
char progdefaults[50];
char *str_type[50];
unsigned int fwidth = 0, fheight = 0;
unsigned int xadder = 0, yadder = 0;
int geo = 0;
unsigned int depth, bw=0;
Window root;
XSizeHints size_hints;
XPoint xp;
XrmValue value;
size_hints.flags = 0;
strcpy(progdefaults, "=600x450+0+0");
if (w) {
if (XGetGeometry(gXDisplay, w, &root, &x, &y, &width, &height, &bw, &depth))
{
xp = getWindowPositionXY(gXDisplay, w);
x = xp.x + 40;
y = xp.y + 40;
if (x < 0)
x = 0;
if (y < 0)
y = 0;
size_hints.flags |= (USSize | USPosition);
}
else {
fprintf(stderr, "(HyperDoc) Error Querying window configuration: %ld.\n", w);
x = y = 0;
width = 600;
height = 450;
size_hints.flags |= (PSize | PPosition);
}
}
else {
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.Geometry", "OpenAxiom.hyperdoc.Geometry",
str_type, &value) == True)
{
strncpy(userdefaults, value.addr, (int) value.size);
geo = XParseGeometry(userdefaults, &x, &y, &width, &height);
}
else
strcpy(userdefaults, progdefaults);
size_hints.flags |= (geo & (WidthValue | HeightValue)) ? USSize : PSize;
size_hints.flags |= (geo & (XValue | YValue)) ? USPosition : PPosition;
geo = XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults,
bw, fwidth, fheight, xadder, yadder,
&x, &y, (int *)&width, (int *)&height);
}
size_hints.x = x;
size_hints.y = y;
size_hints.width = width;
size_hints.height = height;
getTitleBarMinimumSize(&(size_hints.min_width), &(size_hints.min_height));
#if 0
size_hints.min_width = MIN_WINDOW_SIZE;
size_hints.min_height = MIN_WINDOW_SIZE;
#endif
size_hints.flags |= PMinSize;
XSetNormalHints(gXDisplay, gWindow->fMainWindow, &size_hints);
XFlush(gXDisplay);
}
#define stipple_width 4
#define stipple_height 4
static unsigned char stipple_bits[] = {
0xff, 0xff, 0xff, 0xff};
Pixmap stipple;
static void
get_GCs(HDWindow *window)
{
XGCValues values;
values.background = gBackgroundColor;
window->fStandardGC = XCreateGC(gXDisplay, window->fMainWindow, GCBackground, &values);
XSetLineAttributes(gXDisplay, window->fStandardGC, window->border_width,
LineSolid, CapButt, JoinMiter);
stipple = XCreateBitmapFromData(gXDisplay,
RootWindow(gXDisplay, gXScreenNumber),
as_chars(stipple_bits), stipple_width, stipple_height);
values.background = gInputBackgroundColor;
values.foreground = gInputForegroundColor;
values.font = gInputFont->fid;
if (values.font == server_font )
window->fInputGC = XCreateGC(gXDisplay, window->fMainWindow,
GCBackground | GCForeground, &values);
else {
window->fInputGC = XCreateGC(gXDisplay, window->fMainWindow,
GCBackground | GCForeground | GCFont, &values);
}
window->fCursorGC = XCreateGC(gXDisplay, window->fMainWindow, 0, NULL);
if (values.font != server_font)
XSetFont(gXDisplay, window->fCursorGC, gInputFont->fid);
XSetBackground(gXDisplay, window->fCursorGC, gInputForegroundColor);
XSetForeground(gXDisplay, window->fCursorGC, gInputBackgroundColor);
window->fControlGC = XCreateGC(gXDisplay, window->fMainWindow, 0, NULL);
XSetBackground(gXDisplay, window->fControlGC, gControlBackgroundColor);
XSetForeground(gXDisplay, window->fControlGC, gControlForegroundColor);
}
static void
load_font(XFontStruct **font_info, char *fontname)
{
if ((*font_info = XLoadQueryFont(gXDisplay, fontname)) == NULL) {
fprintf(stderr, "(HyperDoc) Cannot load font %s ; using default.\n",
fontname);
if ((*font_info = XQueryFont(gXDisplay,
XGContextFromGC(DefaultGC(gXDisplay, gXScreenNumber)))) == NULL)
{
fprintf(stderr, "(HyperDoc) Cannot get default font ; exiting.\n");
exit(-1);
}
}
}
static void
ingItColors_and_fonts()
{
char property[256];
char *prop = &property[0];
char *str_type[50];
XrmValue value;
Colormap cmap;
int ts;
cmap = DefaultColormap(gXDisplay, gXScreenNumber);
init_group_stack();
mergeDatabases();
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.RmFont",
"OpenAxiom.hyperdoc.Font", str_type, &value) == True)
strncpy(prop, value.addr, (int) value.size);
else
strcpy(prop, RmFontDefault);
load_font(&gRmFont, prop);
load_font(&gInputFont, prop);
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.TtFont",
"OpenAxiom.hyperdoc.Font", str_type, &value) == True)
strncpy(prop, value.addr, (int) value.size);
else
strcpy(prop, TtFontDefault);
load_font(&gTtFont, prop);
gTtFontIs850=is_it_850(gTtFont);
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.ActiveFont",
"OpenAxiom.hyperdoc.Font", str_type, &value) == True)
strncpy(prop, value.addr, (int) value.size);
else
strcpy(prop, ActiveFontDefault);
load_font(&gActiveFont, prop);
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.AxiomFont",
"OpenAxiom.hyperdoc.Font", str_type, &value) == True)
strncpy(prop, value.addr, (int) value.size);
else {
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.SpadFont",
"OpenAxiom.hyperdoc.Font", str_type, &value) == True)
{
strncpy(prop, value.addr, (int) value.size);
}
else {
strcpy(prop, AxiomFontDefault);
}
}
load_font(&gAxiomFont, prop);
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.EmphasizeFont",
"OpenAxiom.hyperdoc.Font", str_type, &value) == True)
{
strncpy(prop, value.addr, (int) value.size);
}
else {
strcpy(prop, EmphasizeFontDefault);
}
load_font(&gEmFont, prop);
if (XrmGetResource(rDB, "OpenAxiom.hyperdoc.BoldFont",
"OpenAxiom.hyperdoc.Font", str_type, &value) == True)
{
strncpy(prop, value.addr, (int) value.size);
}
else {
strcpy(prop, BoldFontDefault);
}
load_font(&gBfFont, prop);
if (DisplayPlanes(gXDisplay, gXScreenNumber) == 1) {
gActiveColor = gAxiomColor
= gControlBackgroundColor
= gInputBackgroundColor
= gBfColor
= gEmColor
= gRmColor
= gSlColor
= gTtColor
= BlackPixel(gXDisplay, gXScreenNumber);
gBackgroundColor = gInputForegroundColor
= gControlForegroundColor
= WhitePixel(gXDisplay, gXScreenNumber);
}
else {
gRmColor =
get_color("RmColor", "Foreground",
BlackPixel(gXDisplay, gXScreenNumber), &cmap);
gBackgroundColor =
get_color("Background", "Background",
WhitePixel(gXDisplay, gXScreenNumber), &cmap);
gActiveColor =
get_color("ActiveColor", "Foreground",
BlackPixel(gXDisplay, gXScreenNumber), &cmap);
gControlBackgroundColor = get_color("ControlBackground",
"ControlBackground", WhitePixel(gXDisplay, gXScreenNumber), &cmap);
gControlForegroundColor = get_color("ControlForeground",
"ControlForeground", BlackPixel(gXDisplay, gXScreenNumber), &cmap);
gAxiomColor = get_color("OpenAxiomColor", "Foreground", 0, &cmap);
if (gAxiomColor == 0)
gAxiomColor = get_color("SpadColor", "Foreground",
BlackPixel(gXDisplay, gXScreenNumber), &cmap);
gInputBackgroundColor =
get_color("InputBackground", "Foreground", gRmColor, &cmap);
gInputForegroundColor =
get_color("InputForeground", "Background", gBackgroundColor, &cmap);
gEmColor =
get_color("EmphasizeColor", "Foreground", gRmColor, &cmap);
gTtColor =
get_color("TtColor", "Foreground", gRmColor, &cmap);
gSlColor =
get_color("EmphasizeColor", "Foreground", gRmColor, &cmap);
gBfColor =
get_color("BoldColor", "Foreground", gRmColor, &cmap);
}
makeColors(gXDisplay, gXScreenNumber, &cmap, &spadColors, &ts);
gTopOfGroupStack->cur_color = gRmColor;
gTopOfGroupStack->cur_font = gRmFont;
}
void
change_text(int color, XFontStruct *font)
{
if (font) {
XGCValues gcv;
gcv.foreground = color;
gcv.background = gBackgroundColor;
XChangeGC(gXDisplay, gWindow->fStandardGC, GCForeground | GCBackground , &gcv);
if (font->fid != server_font)
XSetFont(gXDisplay, gWindow->fStandardGC, font->fid);
}
}
static int
get_color(const char *name, const char *klass, int def, Colormap *map)
{
char fullname[256];
char fullclass[256];
char property[256];
char *prop = &property[0];
char *str_type[50];
XrmValue value;
int ret_val;
XColor color_def, color_db;
#ifdef DEBUG
printf("get_color: %s %s %d -> ", name, class, def);
#endif
strcpy(fullname, "OpenAxiom.hyperdoc.");
strcat(fullname, name);
strcpy(fullclass,"OpenAxiom.hyperdoc.");
strcat(fullclass, klass);
if (XrmGetResource(rDB, fullname, fullclass, str_type, &value) == True) {
strncpy(prop, value.addr, (int) value.size);
ret_val = XAllocNamedColor(gXDisplay, *map, prop, &color_def, &color_db);
if (ret_val) {
#ifdef DEBUG
printf("%d\n", color_def.pixel);
#endif
return (color_def.pixel);
}
else {
fprintf(stderr,
"(HyperDoc) Defaulting on color for %s. Unknown color is %s.\n",
name, prop);
#ifdef DEBUG
printf("%d\n", def);
#endif
return (def);
}
}
else {
#ifdef DEBUG
printf("%d\n", def);
#endif
return (def);
}
}
static void
mergeDatabases()
{
XrmDatabase homeDB, serverDB, applicationDB;
char filenamebuf[1024];
char *filename = &filenamebuf[0];
const char *classname = "OpenAxiom";
char name[255];
XrmInitialize();
strcpy(name, "/usr/lib/X11/app-defaults/");
strcat(name, classname);
applicationDB = XrmGetFileDatabase(name);
XrmMergeDatabases(applicationDB, &rDB);
if (XResourceManagerString(gXDisplay) != NULL) {
serverDB = XrmGetStringDatabase(XResourceManagerString(gXDisplay));
}
else {
strcpy(filename, oa_getenv("HOME"));
strcat(filename, "/.Xdefaults");
serverDB = XrmGetFileDatabase(filename);
}
XrmMergeDatabases(serverDB, &rDB);
if (oa_getenv("XENVIRONMENT") == NULL) {
int len;
strcpy(filename, oa_getenv("HOME"));
strcat(filename, "/.Xdefaults-");
len = strlen(filename);
gethostname(filename + len, 1024 - len);
}
else {
strcpy(filename, oa_getenv("XENVIRONMENT"));
}
homeDB = XrmGetFileDatabase(filename);
XrmMergeDatabases(homeDB, &rDB);
}
int
is_it_850(XFontStruct *fontarg)
{
char* s;
int i,val;
static struct {
const char *name;
Atom format;
Atom atom;
} proptbl = { "CHARSET_ENCODING", XA_ATOM };
proptbl.atom = XInternAtom(gXDisplay,proptbl.name,0);
for (i=0;i<fontarg->n_properties;i++)
{
if (fontarg->properties[i].name != proptbl.atom) continue;
s = XGetAtomName(gXDisplay,(Atom)fontarg->properties[i].card32);
val = !( strcmp("850",s) * strcmp("ibm-850",s));
XFree(s);
return( val );
}
return(0);
}