home *** CD-ROM | disk | FTP | other *** search
- /* x11_windows.c -- Window handling for X11
- Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
-
- This file is part of Jade.
-
- Jade 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, or (at your option)
- any later version.
-
- Jade 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 Jade; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "jade.h"
- #include "jade_protos.h"
- #include "revision.h"
-
- #include <string.h>
- #include <X11/Xutil.h>
-
- _PR int sleepwin(VW *);
- _PR int unsleep(VW *);
- _PR void os_newvw(VW *);
- _PR void os_killvw(VW *);
- _PR void updatedimensions(VW *);
- _PR void _updatedimensions(VW *, int, int);
- _PR Window newwindow(VW *, VW *, bool);
- _PR void killwindow(VW *);
- _PR void activatewin(VW *);
- _PR void setvwtitle(VW *);
- _PR void setvwpos(VW *, long, long, long, long);
- _PR VW *findwindowvw(Window);
- _PR int ezreq(u_char *, u_char *, int, ...);
- _PR int setfont(VW *);
- _PR void unsetfont(VW *);
- _PR void resetslptxtitles(TX *);
- _PR bool makemousepos(POS *, VW *);
- _PR void sys_windows_init(void);
-
- #define INPUT_EVENTS ButtonPressMask | ButtonReleaseMask | KeyPressMask \
- | ExposureMask | StructureNotifyMask | FocusChangeMask
-
- static XSizeHints SizeHints;
- static XClassHint ClassHints = { "jade", "Editor" };
- static XWMHints WMHints;
-
- /*
- * Let the window-manager handle all iconifying...
- */
- int
- sleepwin(VW *vw)
- {
- XIconifyWindow(XDisplay, vw->vw_Window, XScreen);
- return(TRUE);
- }
- int
- unsleep(VW *vw)
- {
- return(TRUE);
- }
-
- void
- os_newvw(VW *vw)
- {
- ;
- }
- void
- os_killvw(VW *vw)
- {
- ;
- }
-
- void
- updatedimensions(VW *vw)
- {
- XWindowAttributes xwa;
- XGetWindowAttributes(XDisplay, vw->vw_Window, &xwa);
- _updatedimensions(vw, xwa.width, xwa.height);
- }
-
- void
- _updatedimensions(VW *vw, int width, int height)
- {
- if(vw->vw_Window && !vw->vw_Sleeping)
- {
- vw->vw_WindowSys.ws_MessageLineY = height - vw->vw_FontY - 2;
- vw->vw_WindowSys.ws_MessageFontY = vw->vw_WindowSys.ws_MessageLineY + 2 + vw->vw_Font->ascent;
- vw->vw_XStartPix = 0;
- vw->vw_YStartPix = 0;
- /*
- * only measure *text* area, not where messages go
- */
- vw->vw_XEndPix = width;
- vw->vw_YEndPix = (vw->vw_WindowSys.ws_MessageLineY - 1) - vw->vw_YStartPix;
- vw->vw_XWidthPix = vw->vw_XEndPix - vw->vw_XStartPix;
- vw->vw_YHeightPix = vw->vw_YEndPix - vw->vw_YStartPix;
-
- vw->vw_FontStart = vw->vw_YStartPix + vw->vw_Font->ascent;
-
- vw->vw_MaxX = (vw->vw_XWidthPix / vw->vw_FontX);
- vw->vw_MaxY = (vw->vw_YHeightPix / vw->vw_FontY);
- if((vw->vw_XStepRatio <= 0)
- || ((vw->vw_XStep = vw->vw_MaxX / vw->vw_XStepRatio) <= 0))
- vw->vw_XStep = 1;
- if((vw->vw_YStepRatio <= 0)
- || ((vw->vw_YStep = vw->vw_MaxY / vw->vw_YStepRatio) <= 0))
- vw->vw_YStep = 1;
- }
- }
-
- /*
- * The only thing necessary in `vw' is the font stuff (I think)
- */
- Window
- newwindow(VW *oldVW, VW *vw, bool useDefDims)
- {
- unsigned int x, y, width, height;
- Window win;
- SizeHints.flags = 0;
- if(!useDefDims && oldVW)
- {
- x = y = 0;
- width = vw->vw_FontX * oldVW->vw_MaxX;
- height = (vw->vw_FontY * (oldVW->vw_MaxY + 1)) + 3;
- SizeHints.flags |= PPosition | PSize;
- }
- else
- {
- if(DefDims[0] != -1)
- {
- x = DefDims[0];
- SizeHints.flags |= USPosition;
- }
- else
- x = 0;
- if(DefDims[1] != -1)
- {
- y = DefDims[1];
- SizeHints.flags |= USPosition;
- }
- else
- y = 0;
- if(DefDims[2] != -1)
- {
- width = DefDims[2];
- SizeHints.flags |= USSize;
- }
- else
- width = 80;
- if(DefDims[3] != -1)
- {
- height = DefDims[3];
- SizeHints.flags |= USSize;
- }
- else
- height = 24;
- width = vw->vw_FontX * width;
- height = (vw->vw_FontY * (height + 1)) + 3;
- }
- win = XCreateSimpleWindow(XDisplay, DefaultRootWindow(XDisplay),
- x, y, width, height,
- WINDOW_BORDER_WIDTH, XForePixel, XBackPixel);
- if(win)
- {
- XGCValues xgcv;
- vw->vw_Window = win;
- /*
- * xgcv.plane_mask = XForePixel | XBackPixel;
- */
- xgcv.foreground = XForePixel;
- xgcv.background = XBackPixel;
- xgcv.line_width = 1;
- xgcv.font = vw->vw_Font->fid;
- vw->vw_WindowSys.ws_TextFontGC = XCreateGC(XDisplay, vw->vw_Window,
- GCForeground | GCBackground
- | GCLineWidth | GCFont,
- &xgcv);
- xgcv.foreground = XBackPixel;
- xgcv.background = XForePixel;
- vw->vw_WindowSys.ws_BlkFontGC = XCreateGC(XDisplay, vw->vw_Window,
- GCForeground | GCBackground
- | GCLineWidth | GCFont,
- &xgcv);
- SizeHints.x = x,
- SizeHints.y = y,
- SizeHints.width = width,
- SizeHints.height = height,
- SizeHints.base_width = 0;
- SizeHints.base_height = vw->vw_FontY + 3;
- SizeHints.width_inc = vw->vw_FontX;
- SizeHints.height_inc = vw->vw_FontY;
- SizeHints.min_width = SizeHints.base_width + SizeHints.width_inc;
- SizeHints.min_height = SizeHints.base_height + SizeHints.height_inc;
- SizeHints.flags |= PMinSize | PResizeInc | PBaseSize;
- WMHints.flags = InputHint;
- WMHints.input = True;
- XSetWMProperties(XDisplay, win, NULL, NULL, Argv, Argc, &SizeHints, &WMHints, &ClassHints);
- XStoreName(XDisplay, win, /* "jade" */ VERSSTRING);
- XSetWMProtocols(XDisplay, win, &Wm_Del_Win, 1);
- XSelectInput(XDisplay, win, INPUT_EVENTS);
- XMapWindow(XDisplay, win);
- return(win);
- }
- return(FALSE);
- }
- void
- killwindow(VW *vw)
- {
- XFreeGC(XDisplay, vw->vw_WindowSys.ws_BlkFontGC);
- XFreeGC(XDisplay, vw->vw_WindowSys.ws_TextFontGC);
- XDestroyWindow(XDisplay, vw->vw_Window);
- }
-
- void
- activatewin(VW *vw)
- {
- /* Not sure about all this?? */
- XRaiseWindow(XDisplay, vw->vw_Window);
- XWarpPointer(XDisplay, None, vw->vw_Window, 0, 0, 0, 0, 1, 1);
- }
-
- void
- setvwtitle(VW *vw)
- {
- if(vw->vw_LastTitle)
- {
- int len = strlen(vw->vw_LastTitle);
- if(len > vw->vw_MaxX)
- drawmsg(vw, vw->vw_LastTitle + (len - vw->vw_MaxX), vw->vw_MaxX);
- else
- drawmsg(vw, vw->vw_LastTitle, strlen(vw->vw_LastTitle));
- }
- else
- drawmsg(vw, "", 0);
- }
-
- void
- setvwpos(VW *vw, long x, long y, long w, long h)
- {
- XMoveResizeWindow(XDisplay, vw->vw_Window,
- (unsigned int)x, (unsigned int)y,
- (unsigned int)w, (unsigned int)h);
- }
-
- VW *
- findwindowvw(Window win)
- {
- VW *vw = ViewChain;
- while(vw)
- {
- if(vw->vw_Window == win)
- break;
- vw = vw->vw_Next;
- }
- return(vw);
- }
-
- int
- ezreq(u_char *bodyfmt, u_char *gadfmt, int arg1, ...)
- {
- return(0);
- }
-
- int
- setfont(VW *vw)
- {
- XFontStruct *font;
- if((font = XLoadQueryFont(XDisplay, VSTR(vw->vw_FontName)))
- || (font = XLoadQueryFont(XDisplay, DEFAULT_FONT)))
- {
- if(vw->vw_Font)
- XFreeFont(XDisplay, vw->vw_Font);
- vw->vw_Font = font;
- vw->vw_FontX = XTextWidth(font, "M", 1);
- vw->vw_FontY = vw->vw_Font->ascent + vw->vw_Font->descent;
- if(vw->vw_Window)
- {
- int w, h;
- w = vw->vw_MaxX * vw->vw_FontX;
- h = ((vw->vw_MaxY + 1) * vw->vw_FontY) + 3;
- XSetFont(XDisplay, vw->vw_WindowSys.ws_TextFontGC, font->fid);
- XSetFont(XDisplay, vw->vw_WindowSys.ws_BlkFontGC, font->fid);
- updatedimensions(vw);
- SizeHints.width = w;
- SizeHints.height = h;
- SizeHints.base_width = 0;
- SizeHints.base_height = vw->vw_FontY + 3;
- SizeHints.width_inc = vw->vw_FontX;
- SizeHints.height_inc = vw->vw_FontY;
- SizeHints.min_width = SizeHints.base_width + SizeHints.width_inc;
- SizeHints.min_height = SizeHints.base_height + SizeHints.height_inc;
- SizeHints.flags = PResizeInc | PMinSize | PBaseSize;
- XSetWMNormalHints(XDisplay, vw->vw_Window, &SizeHints);
- XResizeWindow(XDisplay, vw->vw_Window, w, h);
- #if 0
- vw->vw_DeferRefresh++;
- #endif
- }
- return(TRUE);
- }
- return(FALSE);
- }
- void
- unsetfont(VW *vw)
- {
- if(vw->vw_Font)
- {
- XFreeFont(XDisplay, vw->vw_Font);
- vw->vw_Font = NULL;
- }
- }
-
- _PR VALUE cmd_set_font(VALUE fontname, VALUE vw);
- DEFUN("set-font", cmd_set_font, subr_set_font, (VALUE fontname, VALUE vw), V_Subr2, DOC_set_font) /*
- ::doc:set_font::
- (set-font FONT-NAME [WINDOW])
- FONT-NAME specifies the font to use in WINDOW (or the active one).
- Under X11 FONT-NAME is a standard font description, under AmigaDOS it is the
- name of the font followed by a dash and then the point size to use (for
- example "topaz.font-8" to get an 8-point topaz font).
- ::end:: */
- {
- VALUE oldfont;
- DECLARE1(fontname, STRINGP);
- if(!WINDOWP(vw))
- vw = CurrVW;
- oldfont = VWIN(vw)->vw_FontName;
- VWIN(vw)->vw_FontName = fontname;
- if(setfont(VWIN(vw)))
- {
- VWIN(vw)->vw_Flags |= VWFF_FORCE_REFRESH;
- #if 0
- VWIN(vw)->vw_DeferRefresh++;
- #endif
- return(sym_t);
- }
- else
- {
- cmd_signal(sym_error, list_2(MKSTR("Can't open font"), fontname));
- VWIN(vw)->vw_FontName = oldfont;
- return(NULL);
- }
- }
-
- void
- resetslptxtitles(TX *tx)
- {
- ;
- }
-
- _PR VALUE cmd_screen_width(void);
- DEFUN("screen-width", cmd_screen_width, subr_screen_width, (void), V_Subr0, DOC_screen_width) /*
- ::doc:screen_width::
- (screen-width)
- Returns the width of the root window or screen in pixels.
- ::end:: */
- {
- Window root;
- int dummy1;
- unsigned int dummy2;
- int val;
- if(XGetGeometry(XDisplay, DefaultRootWindow(XDisplay),
- &root, &dummy1, &dummy1,
- (unsigned int *)&val, &dummy2,
- &dummy2, &dummy2))
- return(newnumber(val));
- return(NULL);
- }
-
- _PR VALUE cmd_screen_height(void);
- DEFUN("screen-height", cmd_screen_height, subr_screen_height, (void), V_Subr0, DOC_screen_height) /*
- ::doc:screen_height::
- (screen-height)
- Returns the height of the root window or screen in pixels.
- ::end:: */
- {
- Window root;
- int dummy1;
- unsigned int dummy2;
- int val;
- if(XGetGeometry(XDisplay, DefaultRootWindow(XDisplay),
- &root, &dummy1, &dummy1,
- &dummy2, (unsigned int *)&val,
- &dummy2, &dummy2))
- return(newnumber(val));
- return(NULL);
- }
-
- _PR VALUE cmd_window_left_edge(void);
- DEFUN("window-left-edge", cmd_window_left_edge, subr_window_left_edge, (void), V_Subr0, DOC_window_left_edge) /*
- ::doc:window_left_edge::
- (window-left-edge)
- Returns the x position of the current window relative to the origin of the
- root window or screen.
- ::end:: */
- {
- Window root;
- int dummy1;
- unsigned int dummy2;
- int val;
- if(XGetGeometry(XDisplay, CurrVW->vw_Window,
- &root, &val, &dummy1,
- &dummy2, &dummy2,
- &dummy2, &dummy2))
- return(newnumber(val));
- return(NULL);
- }
-
- _PR VALUE cmd_window_top_edge(void);
- DEFUN("window-top-edge", cmd_window_top_edge, subr_window_top_edge, (void), V_Subr0, DOC_window_top_edge) /*
- ::doc:window_top_edge::
- (window-top-edge)
- Returns the y position of the current window relative to the origin of the
- root window or screen.
- ::end:: */
- {
- Window root;
- int dummy1;
- unsigned int dummy2;
- int val;
- if(XGetGeometry(XDisplay, CurrVW->vw_Window,
- &root, &dummy1, &val,
- &dummy2, &dummy2,
- &dummy2, &dummy2))
- return(newnumber(val));
- return(NULL);
- }
-
- _PR VALUE cmd_window_width(void);
- DEFUN("window-width", cmd_window_width, subr_window_width, (void), V_Subr0, DOC_window_width) /*
- ::doc:window_width::
- (window-width)
- Returns the width, in pixels, of the current window.
- ::end:: */
- {
- Window root;
- int dummy1;
- unsigned int dummy2;
- int val;
- if(XGetGeometry(XDisplay, CurrVW->vw_Window,
- &root, &dummy1, &dummy1,
- (unsigned int *)&val, &dummy2,
- &dummy2, &dummy2))
- return(newnumber(val));
- return(NULL);
- }
-
- _PR VALUE cmd_window_height(void);
- DEFUN("window-height", cmd_window_height, subr_window_height, (void), V_Subr0, DOC_window_height) /*
- ::doc:window_height::
- (window-height)
- Returns the height, in pixels, of the current window.
- ::end:: */
- {
- Window root;
- int dummy1;
- unsigned int dummy2;
- int val;
- if(XGetGeometry(XDisplay, CurrVW->vw_Window,
- &root, &dummy1, &dummy1,
- &dummy2, (unsigned int *)&val,
- &dummy2, &dummy2))
- return(newnumber(val));
- return(NULL);
- }
-
- _PR VALUE cmd_window_bar_height(void);
- DEFUN("window-bar-height", cmd_window_bar_height, subr_window_bar_height, (void), V_Subr0, DOC_window_bar_height) /*
- ::doc:window_bar_height::
- (window-bar-height)
- On an Amiga returns the number of pixels high the title bar of the window
- is. This is 0 in X11.
- ::end:: */
- {
- return(newnumber(0));
- }
-
- bool
- makemousepos(POS *pos, VW *vw)
- {
- Window tmpw;
- int tmp;
- int x, y;
- if(XQueryPointer(XDisplay, vw->vw_Window, &tmpw, &tmpw, &tmp, &tmp, &x, &y, &tmp))
- {
- x = (x - vw->vw_XStartPix) / vw->vw_FontX;
- y = (y - vw->vw_YStartPix) / vw->vw_FontY;
- if((x < 0) || (y < 0) || (x >= vw->vw_MaxX) || (y >= vw->vw_MaxY))
- return(FALSE);
- pos->pos_Col = x + vw->vw_StartCol;
- pos->pos_Line = y + vw->vw_StartLine;
- return(TRUE);
- }
- return(FALSE);
- }
-
- _PR VALUE cmd_flush_output(void);
- DEFUN("flush-output", cmd_flush_output, subr_flush_output, (void), V_Subr0, DOC_flush_output) /*
- ::doc:flush_output::
- (flush-output)
- Forces any cached window output to be drawn. This is usually unnecessary.
- ::end:: */
- {
- XFlush(XDisplay);
- return(sym_t);
- }
-
- void
- sys_windows_init(void)
- {
- ADD_SUBR(subr_set_font);
- ADD_SUBR(subr_screen_width);
- ADD_SUBR(subr_screen_height);
- ADD_SUBR(subr_window_left_edge);
- ADD_SUBR(subr_window_top_edge);
- ADD_SUBR(subr_window_width);
- ADD_SUBR(subr_window_height);
- ADD_SUBR(subr_window_bar_height);
- ADD_SUBR(subr_flush_output);
- }
-