#include <X11/Intrinsic.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Shell.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xaw/Dialog.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xmu/Error.h>
#include "editresP.h"
static WNode * FindWidgetFromWindowGivenNode ( WNode * node, Window win );
static WidgetResources * ParseResources ( GetResourcesInfo * info,
char **error );
static int CompareResourceEntries ( const void *e1,
const void *e2 );
static void AddResource ( ResourceInfo * res_info,
WidgetResourceInfo * resource );
static void FreeResources ( WidgetResources * resources );
void
SetMessage(w, str)
Widget w;
char * str;
{
Arg args[1];
XtSetArg(args[0], XtNlabel, str);
XtSetValues(w, args, ONE);
}
void
GetAllStrings(char *in, char sep, char ***out, int *num)
{
int size, i;
char * ptr;
if (*in == sep)
in++;
for (*num = 1, ptr = in; (ptr = strchr(ptr, sep)) != NULL; (*num)++)
ptr++;
size = (sizeof(char *) * *num) + (sizeof(char) * (strlen(in) + 1));
*out = (char **) XtMalloc( (Cardinal) size);
ptr = (char *) (*out + *num);
strcpy(ptr, in);
i = 1;
(*out)[0] = ptr;
while (TRUE) {
if ((ptr = strchr(ptr, sep)) == NULL)
break;
*ptr++ = '\0';
(*out)[i++] = ptr;
}
if ( *((*out)[i - 1]) == '\0' )
(*num)--;
}
void
AddString(str, add)
char ** str, *add;
{
int len_str, len_add;
char * ptr;
len_str = ((*str) ? strlen(*str) : 0);
len_add = strlen(add);
*str = XtRealloc(*str, sizeof(char) * (len_str + len_add + 1));
ptr = *str + len_str;
strcpy(ptr, add);
}
WNode *
FindNode(top_node, ids, number)
WNode *top_node;
unsigned long * ids;
Cardinal number;
{
int i, j;
WNode *node;
if (top_node == NULL)
return(NULL);
if (ids[0] != top_node->id)
return(NULL);
for (node = top_node, i = 1 ; i < number; i++) {
Boolean found_it = FALSE;
for (j = 0; j < node->num_children; j++) {
if (node->children[j]->id == ids[i]) {
node = node->children[j];
found_it = TRUE;
break;
}
}
if (!found_it)
return(NULL);
}
return(node);
}
WNode *
FindWidgetFromWindow(tree_info, win)
TreeInfo * tree_info;
Window win;
{
if (tree_info == NULL)
return(NULL);
return(FindWidgetFromWindowGivenNode(tree_info->top_node, win));
}
static WNode *
FindWidgetFromWindowGivenNode(node, win)
WNode * node;
Window win;
{
int i;
WNode * ret_node;
if (node->window == win)
return(node);
for (i = 0; i < node->num_children; i++) {
ret_node = FindWidgetFromWindowGivenNode(node->children[i], win);
if (ret_node != NULL)
return(ret_node);
}
return(NULL);
}
int
HandleXErrors(display, error)
Display * display;
XErrorEvent * error;
{
if (error->serial != global_serial_num) {
(*global_old_error_handler) (display, error);
return(0);
}
if (error->error_code == BadWindow)
global_error_code = NO_WINDOW;
else {
if (XmuPrintDefaultErrorMessage(display, error, stderr) != 0)
exit(1);
}
return(0);
}
void
_DumpTreeToFile(w, tree_ptr, filename)
Widget w;
XtPointer tree_ptr;
XtPointer filename;
{
TreeInfo * tree_info = (TreeInfo *) tree_ptr;
FILE * fp;
if (tree_info == NULL) {
SetMessage(global_screen_data.info_label,
res_labels[17]);
return;
}
if ( (fp = fopen((char *)filename, "w")) == NULL ) {
char buf[BUFSIZ];
sprintf(buf, res_labels[24], (char *)filename);
SetMessage(global_screen_data.info_label, buf);
return;
}
PerformTreeToFileDump(tree_info->top_node, 0, fp);
fclose(fp);
}
static XContext file_dialog_context = None;
typedef struct _FileDialogInfo {
XtCallbackProc func;
XtPointer data;
} FileDialogInfo;
void
_PopupFileDialog(w, str, default_value, func, data)
Widget w;
String str, default_value;
XtCallbackProc func;
XtPointer data;
{
FileDialogInfo * file_info;
Widget shell, dialog;
Arg args[2];
Cardinal num_args;
if (file_dialog_context == None)
file_dialog_context = XUniqueContext();
shell = XtCreatePopupShell("fileDialog", transientShellWidgetClass, w,
NULL, ZERO);
num_args = 0;
XtSetArg(args[num_args], XtNlabel, str); num_args++;
XtSetArg(args[num_args], XtNvalue, default_value); num_args++;
dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
shell, args, num_args);
file_info = XtNew(FileDialogInfo);
file_info->func = func;
file_info->data = data;
if (XSaveContext(XtDisplay(dialog), (Window) dialog, file_dialog_context,
(XPointer) file_info) != 0) {
SetMessage(global_screen_data.info_label,
"Error while trying to save Context\nAborting file dialog popup.");
XtDestroyWidget(shell);
return;
}
XawDialogAddButton(dialog, "okay", _PopdownFileDialog, (XtPointer) TRUE);
XawDialogAddButton(dialog, "cancel", _PopdownFileDialog,(XtPointer) FALSE);
PopupCentered(NULL, shell, XtGrabNone);
}
void
PopupCentered(event, w, mode)
XEvent * event;
Widget w;
XtGrabKind mode;
{
Boolean get_from_cursor = FALSE;
Arg args[3];
Cardinal num_args;
Dimension width, height, b_width;
int x, y, max_x, max_y;
XtRealizeWidget(w);
if (event == NULL)
get_from_cursor = TRUE;
else {
switch (event->type) {
case ButtonPress:
case ButtonRelease:
x = event->xbutton.x_root;
y = event->xbutton.y_root;
break;
case KeyPress:
case KeyRelease:
x = event->xkey.x_root;
y = event->xkey.y_root;
break;
default:
get_from_cursor = TRUE;
break;
}
}
if (get_from_cursor) {
Window root, child;
int win_x, win_y;
unsigned int mask;
XQueryPointer(XtDisplay(w), XtWindow(w),
&root, &child, &x, &y, &win_x, &win_y, &mask);
}
num_args = 0;
XtSetArg(args[num_args], XtNwidth, &width); num_args++;
XtSetArg(args[num_args], XtNheight, &height); num_args++;
XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
XtGetValues(w, args, num_args);
width += 2 * b_width;
height += 2 * b_width;
x -= ((int) width/2);
if (x < 0)
x = 0;
if ( x > (max_x = (int) (XtScreen(w)->width - width)) )
x = max_x;
y -= ( (Position) height/2 );
if (y < 0)
y = 0;
if ( y > (max_y = (int) (XtScreen(w)->height - height)) )
y = max_y;
num_args = 0;
XtSetArg(args[num_args], XtNx, x); num_args++;
XtSetArg(args[num_args], XtNy, y); num_args++;
XtSetValues(w, args, num_args);
XtPopup(w, mode);
}
void
_PopdownFileDialog(w, client_data, junk)
Widget w;
XtPointer client_data, junk;
{
Widget dialog = XtParent(w);
XPointer file_info_ptr;
FileDialogInfo * file_info;
if (XFindContext(XtDisplay(dialog), (Window) dialog, file_dialog_context,
&file_info_ptr) == XCNOENT) {
SetMessage(global_screen_data.info_label,
"Error while trying to find Context\nAborting...");
}
(void) XDeleteContext(XtDisplay(dialog), (Window)dialog,
file_dialog_context);
file_info = (FileDialogInfo *) file_info_ptr;
if ( ((Boolean)(long) client_data) == TRUE ) {
String filename = XawDialogGetValueString(dialog);
(*file_info->func)(w, file_info->data, filename);
}
XtFree( (XtPointer) file_info);
XtPopdown(XtParent(dialog));
XtDestroyWidget(XtParent(dialog));
}
void
GetNamesAndClasses(node, names, classes)
WNode * node;
char *** names, ***classes;
{
int i, total_widgets;
WNode * temp = node;
for (total_widgets = 1 ; temp->parent != NULL ;
total_widgets++, temp = temp->parent) {}
*names = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
*classes = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
(*names)[total_widgets] = (*classes)[total_widgets] = NULL;
for ( i = (total_widgets - 1); i >= 0 ; node = node->parent, i--) {
(*names)[i] = node->name;
(*classes)[i] = node->class;
}
}
char *
HandleGetResources(event)
Event * event;
{
GetResourcesEvent * get_event = (GetResourcesEvent *) event;
char buf[BUFSIZ], * errors = NULL;
int i;
WNode * node;
for (i = 0; i < (int)get_event->num_entries; i++) {
node = FindNode(global_tree_info->top_node,
get_event->info[i].widgets.ids,
get_event->info[i].widgets.num_widgets);
if (node == NULL) {
sprintf(buf, res_labels[16]);
AddString(&errors, buf);
continue;
}
if (node->resources != NULL)
FreeResources(node->resources);
if (!get_event->info[i].error) {
node->resources = ParseResources(get_event->info + i, &errors);
CreateResourceBox(node, &errors);
}
else {
AddString(&errors, get_event->info[i].message);
AddString(&errors, "\n");
}
}
return(errors);
}
void
CreateResourceBox(node, errors)
WNode * node;
char ** errors;
{
WidgetResources * resources = node->resources;
char ** names, ** cons_names;
int i;
if (global_resource_box_up) {
AddString(errors, res_labels[34]);
return;
}
else
global_resource_box_up = TRUE;
if (resources->num_normal > 0) {
names = (char **) XtMalloc(sizeof(char *) *
(resources->num_normal + 1));
for (i = 0 ; i < resources->num_normal ; i++)
names[i] = resources->normal[i].name;
names[i] = NULL;
}
else
names = NULL;
if (resources->num_constraint > 0) {
cons_names = (char **) XtMalloc(sizeof(char *) *
(resources->num_constraint + 1));
for (i = 0 ; i < resources->num_constraint ; i++)
cons_names[i] = resources->constraint[i].name;
cons_names[i] = NULL;
}
else
cons_names = NULL;
CreateResourceBoxWidgets(node, names, cons_names);
}
static WidgetResources *
ParseResources(info, error)
GetResourcesInfo * info;
char **error;
{
WidgetResources * resources;
WidgetResourceInfo * normal;
int i;
resources = (WidgetResources *) XtMalloc(sizeof(WidgetResources));
resources->normal = (WidgetResourceInfo *)
XtMalloc(sizeof(WidgetResourceInfo) * info->num_resources);
normal = resources->normal;
resources->constraint = resources->normal + info->num_resources - 1;
resources->num_constraint = resources->num_normal = 0;
for (i = 0; i < (int)info->num_resources; i++) {
switch((int) info->res_info[i].res_type) {
case NormalResource:
resources->num_normal++;
AddResource(info->res_info + i, normal++);
break;
case ConstraintResource:
resources->num_constraint++;
AddResource(info->res_info + i, resources->constraint--);
break;
default:
{
char buf[BUFSIZ];
sprintf(buf, "Unknown resource type %d\n",
info->res_info[i].res_type);
AddString(error, buf);
}
break;
}
}
qsort(resources->normal, resources->num_normal,
sizeof(WidgetResourceInfo), CompareResourceEntries);
if (resources->num_constraint > 0) {
resources->constraint++;
qsort(resources->constraint, resources->num_constraint,
sizeof(WidgetResourceInfo), CompareResourceEntries);
}
else
resources->constraint = NULL;
return(resources);
}
static int
CompareResourceEntries(e1, e2)
const void *e1, *e2;
{
return (strcmp(((WidgetResourceInfo *)e1)->name,
((WidgetResourceInfo *)e2)->name));
}
static void
AddResource(res_info, resource)
ResourceInfo * res_info;
WidgetResourceInfo * resource;
{
resource->name = res_info->name;
res_info->name = NULL;
resource->class = res_info->class;
res_info->class = NULL;
resource->type = res_info->type;
res_info->type = NULL;
}
static void
FreeResources(resources)
WidgetResources * resources;
{
int i;
if (resources->num_normal > 0) {
for (i = 0; i < resources->num_normal; i++) {
XtFree(resources->normal[i].name);
XtFree(resources->normal[i].class);
XtFree(resources->normal[i].type);
}
XFree((char *)resources->normal);
}
if (resources->num_constraint > 0) {
for (i = 0; i < resources->num_constraint; i++) {
XtFree(resources->constraint[i].name);
XtFree(resources->constraint[i].class);
XtFree(resources->constraint[i].type);
}
XFree((char *)resources->constraint);
}
XFree((char *)resources);
}
Boolean
CheckDatabase(db, names, classes)
XrmDatabase db;
XrmQuarkList names, classes;
{
XrmRepresentation junk;
XrmValue garbage;
return(XrmQGetResource(db, names, classes, &junk, &garbage));
}
XrmQuarkList
Quarkify(list, ptr)
char ** list;
char * ptr;
{
int i;
char ** tlist;
XrmQuarkList quarks, tquarks;
for (i = 0, tlist = list; *tlist != NULL; tlist++, i++) {}
if (ptr != NULL)
i++;
i++;
quarks = (XrmQuarkList) XtMalloc(sizeof(XrmQuark) * i);
for (tlist = list, tquarks = quarks; *tlist != NULL; tlist++, tquarks++)
*tquarks = XrmStringToQuark(*tlist);
if (ptr != NULL)
*tquarks++ = XrmStringToQuark(ptr);
*tquarks = NULLQUARK;
return(quarks);
}
void
ExecuteOverAllNodes(top_node, func, data)
WNode * top_node;
void (*func)(WNode *, XtPointer);
XtPointer data;
{
int i;
(*func)(top_node, data);
for (i = 0; i < top_node->num_children; i++)
ExecuteOverAllNodes(top_node->children[i], func, data);
}
void
InsertWidgetFromNode(stream, node)
ProtocolStream * stream;
WNode * node;
{
WNode *temp;
unsigned long * widget_list;
register int i, num_widgets;
for (temp = node, i = 0; temp != 0; temp = temp->parent, i++) {}
num_widgets = i;
widget_list = (unsigned long *)
XtMalloc(sizeof(unsigned long) * num_widgets);
for (i--, temp = node; temp != 0; temp = temp->parent, i--)
widget_list[i] = temp->id;
_XEditResPut16(stream, num_widgets);
for (i = 0; i < num_widgets; i++)
_XEditResPut32(stream, widget_list[i]);
XtFree((char *)widget_list);
}
char *
GetFailureMessage(stream)
ProtocolStream * stream;
{
char * return_str;
if (_XEditResGetString8(stream, &return_str))
return(return_str);
return(XtNewString(res_labels[35]));
}
char *
ProtocolFailure(stream)
ProtocolStream * stream;
{
char buf[BUFSIZ];
unsigned char version;
char* old_version_string;
if (!_XEditResGet8(stream, &version))
return(XtNewString(res_labels[35]));
switch ((int)version) {
case PROTOCOL_VERSION_ONE_POINT_ZERO: old_version_string = "1.0"; break;
default: old_version_string = "1.0";
}
sprintf(buf, res_labels[36],
CURRENT_PROTOCOL_VERSION_STRING, old_version_string);
return(XtNewString(buf));
}