/* Test external widget code in Motif.
Copyright (C) 1989 O'Reilly and Associates, Inc.
Copyright (C) 1993 Ben Wing.
This file is part of XEmacs.
XEmacs 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 3 of the License, or (at your
option) any later version.
XEmacs 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 XEmacs. If not, see . */
#include
#include
#include
#include
#include
#define BITMAPDEPTH 1
#define TOO_SMALL 0
#define BIG_ENOUGH 1
/* These are used as arguments to nearly every Xlib routine, so it saves
* routine arguments to declare them global. If there were
* additional source files, they would be declared extern there. */
Display *display;
int screen_num;
static char *progname; /* name this program was invoked by */
void main(argc, argv)
int argc;
char **argv;
{
Window topwin, win, win2;
unsigned int width, height; /* window size */
int x, y; /* window position */
unsigned int border_width = 4; /* four pixels */
unsigned int display_width, display_height;
char *window_name = "Basic Window Program";
char *icon_name = "basicwin";
XSizeHints size_hints;
int count;
XEvent report;
GC gc;
XFontStruct *font_info;
char *display_name = NULL;
int window_size = BIG_ENOUGH; /* or TOO_SMALL to display contents */
progname = argv[0];
/* connect to X server */
if ( (display=XOpenDisplay(display_name)) == NULL )
{
(void) fprintf( stderr, "%s: cannot connect to X server %s\n",
progname, XDisplayName(display_name));
exit( -1 );
}
/* get screen size from display structure macro */
screen_num = DefaultScreen(display);
display_width = DisplayWidth(display, screen_num);
display_height = DisplayHeight(display, screen_num);
/* Note that in a real application, x and y would default to 0
* but would be settable from the command line or resource database.
*/
x = y = 0;
/* size window with enough room for text */
width = display_width/2, height = display_height/3;
/* ------------------------------------------------------------ */
/* create top-level window */
topwin = XCreateSimpleWindow(display, RootWindow(display,screen_num),
x, y, width, 2*height, border_width,
BlackPixel(display, screen_num),
WhitePixel(display,screen_num));
/* Set size hints for window manager. The window manager may
* override these settings. Note that in a real
* application if size or position were set by the user
* the flags would be UPosition and USize, and these would
* override the window manager's preferences for this window. */
/* x, y, width, and height hints are now taken from
* the actual settings of the window when mapped. Note
* that PPosition and PSize must be specified anyway. */
size_hints.flags = PPosition | PSize | PMinSize;
size_hints.min_width = 300;
size_hints.min_height = 200;
{
XWMHints wm_hints;
XClassHint class_hints;
/* format of the window name and icon name
* arguments has changed in R4 */
XTextProperty windowName, iconName;
/* These calls store window_name and icon_name into
* XTextProperty structures and set their other
* fields properly. */
if (XStringListToTextProperty(&window_name, 1, &windowName) == 0) {
(void) fprintf( stderr, "%s: structure allocation for windowName failed.\n",
progname);
exit(-1);
}
if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) {
(void) fprintf( stderr, "%s: structure allocation for iconName failed.\n",
progname);
exit(-1);
}
wm_hints.initial_state = NormalState;
wm_hints.input = True;
wm_hints.flags = StateHint | InputHint;
class_hints.res_name = progname;
class_hints.res_class = "Basicwin";
XSetWMProperties(display, topwin, &windowName, &iconName,
argv, argc, &size_hints, &wm_hints,
&class_hints);
}
/* ------------------------------------------------------------ */
/* create the window we're in charge of */
win = XCreateSimpleWindow(display, topwin,
x, y, width, height, border_width, BlackPixel(display,
screen_num), WhitePixel(display,screen_num));
/* Select event types wanted */
XSelectInput(display, win, ExposureMask | KeyPressMask |
ButtonPressMask | StructureNotifyMask);
load_font(&font_info);
/* create GC for text and drawing */
getGC(win, &gc, font_info);
/* ------------------------------------------------------------ */
/* create the external-client window */
win2 = XCreateSimpleWindow(display, topwin,
x, y+height, width, height, border_width,
BlackPixel(display, screen_num),
WhitePixel(display,screen_num));
printf("external window: %d\n", win2);
ExternalClientInitialize(display, win2);
/* ------------------------------------------------------------ */
/* Display windows */
XMapWindow(display, topwin);
XMapWindow(display, win);
XMapWindow(display, win2);
/* get events, use first to display text and graphics */
while (1) {
XNextEvent(display, &report);
if (report.xany.window == win2)
ExternalClientEventHandler(display, win2, &report);
else
switch (report.type) {
case Expose:
/* unless this is the last contiguous expose,
* don't draw the window */
if (report.xexpose.count != 0)
break;
/* if window too small to use */
if (window_size == TOO_SMALL)
TooSmall(win, gc, font_info);
else {
/* place text in window */
draw_text(win, gc, font_info, width, height);
/* place graphics in window, */
draw_graphics(win, gc, width, height);
}
break;
case ConfigureNotify:
/* window has been resized, change width and
* height to send to draw_text and draw_graphics
* in next Expose */
width = report.xconfigure.width;
height = report.xconfigure.height;
if ((width < size_hints.min_width) ||
(height < size_hints.min_height))
window_size = TOO_SMALL;
else
window_size = BIG_ENOUGH;
break;
case ButtonPress:
/* trickle down into KeyPress (no break) */
case KeyPress:
XUnloadFont(display, font_info->fid);
XFreeGC(display, gc);
XCloseDisplay(display);
exit(1);
default:
/* all events selected by StructureNotifyMask
* except ConfigureNotify are thrown away here,
* since nothing is done with them */
break;
} /* end switch */
} /* end while */
}
getGC(win, gc, font_info)
Window win;
GC *gc;
XFontStruct *font_info;
{
unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
XGCValues values;
unsigned int line_width = 6;
int line_style = LineOnOffDash;
int cap_style = CapRound;
int join_style = JoinRound;
int dash_offset = 0;
static char dash_list[] = {12, 24};
int list_length = 2;
/* Create default Graphics Context */
*gc = XCreateGC(display, win, valuemask, &values);
/* specify font */
XSetFont(display, *gc, font_info->fid);
/* specify black foreground since default window background is
* white and default foreground is undefined. */
XSetForeground(display, *gc, BlackPixel(display,screen_num));
/* set line attributes */
XSetLineAttributes(display, *gc, line_width, line_style,
cap_style, join_style);
/* set dashes */
XSetDashes(display, *gc, dash_offset, dash_list, list_length);
}
load_font(font_info)
XFontStruct **font_info;
{
char *fontname = "9x15";
/* Load font and get font information structure. */
if ((*font_info = XLoadQueryFont(display,fontname)) == NULL)
{
(void) fprintf( stderr, "%s: Cannot open 9x15 font\n",
progname);
exit( -1 );
}
}
draw_text(win, gc, font_info, win_width, win_height)
Window win;
GC gc;
XFontStruct *font_info;
unsigned int win_width, win_height;
{
char *string1 = "Hi! I'm a window, who are you?";
char *string2 = "To terminate program; Press any key";
char *string3 = "or button while in this window.";
char *string4 = "Screen Dimensions:";
int len1, len2, len3, len4;
int width1, width2, width3;
char cd_height[50], cd_width[50], cd_depth[50];
int font_height;
int initial_y_offset, x_offset;
/* need length for both XTextWidth and XDrawString */
len1 = strlen(string1);
len2 = strlen(string2);
len3 = strlen(string3);
/* get string widths for centering */
width1 = XTextWidth(font_info, string1, len1);
width2 = XTextWidth(font_info, string2, len2);
width3 = XTextWidth(font_info, string3, len3);
font_height = font_info->ascent + font_info->descent;
/* output text, centered on each line */
XDrawString(display, win, gc, (win_width - width1)/2,
font_height,
string1, len1);
XDrawString(display, win, gc, (win_width - width2)/2,
(int)(win_height - (2 * font_height)),
string2, len2);
XDrawString(display, win, gc, (win_width - width3)/2,
(int)(win_height - font_height),
string3, len3);
/* copy numbers into string variables */
(void) sprintf(cd_height, " Height - %d pixels",
DisplayHeight(display,screen_num));
(void) sprintf(cd_width, " Width - %d pixels",
DisplayWidth(display,screen_num));
(void) sprintf(cd_depth, " Depth - %d plane(s)",
DefaultDepth(display, screen_num));
/* reuse these for same purpose */
len4 = strlen(string4);
len1 = strlen(cd_height);
len2 = strlen(cd_width);
len3 = strlen(cd_depth);
/* To center strings vertically, we place the first string
* so that the top of it is two font_heights above the center
* of the window. Since the baseline of the string is what we
* need to locate for XDrawString, and the baseline is one
* font_info->ascent below the top of the character,
* the final offset of the origin up from the center of the
* window is one font_height + one descent. */
initial_y_offset = win_height/2 - font_height - font_info->descent;
x_offset = (int) win_width/4;
XDrawString(display, win, gc, x_offset, (int) initial_y_offset,
string4,len4);
XDrawString(display, win, gc, x_offset, (int) initial_y_offset +
font_height,cd_height,len1);
XDrawString(display, win, gc, x_offset, (int) initial_y_offset +
2 * font_height,cd_width,len2);
XDrawString(display, win, gc, x_offset, (int) initial_y_offset +
3 * font_height,cd_depth,len3);
}
draw_graphics(win, gc, window_width, window_height)
Window win;
GC gc;
unsigned int window_width, window_height;
{
int x, y;
int width, height;
height = window_height/2;
width = 3 * window_width/4;
x = window_width/2 - width/2; /* center */
y = window_height/2 - height/2;
XDrawRectangle(display, win, gc, x, y, width, height);
}
TooSmall(win, gc, font_info)
Window win;
GC gc;
XFontStruct *font_info;
{
char *string1 = "Too Small";
int y_offset, x_offset;
y_offset = font_info->ascent + 2;
x_offset = 2;
/* output text, centered on each line */
XDrawString(display, win, gc, x_offset, y_offset, string1,
strlen(string1));
}