Change 9wm to look like rio.
This commit is contained in:
parent
ba9ffa53c4
commit
038e9089b3
14 changed files with 3458 additions and 0 deletions
118
src/cmd/rio/9wm.man
Normal file
118
src/cmd/rio/9wm.man
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
.if t .ds 85 8\(12
|
||||||
|
.if n .ds 85 8-1/2
|
||||||
|
.TH 9wm 1
|
||||||
|
.SH NAME
|
||||||
|
9wm \- \*(85-like Window Manager for X
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B 9wm
|
||||||
|
[
|
||||||
|
.B \-grey
|
||||||
|
] [
|
||||||
|
.B \-version
|
||||||
|
] [
|
||||||
|
.B \-font
|
||||||
|
.I fname
|
||||||
|
] [
|
||||||
|
.B \-term
|
||||||
|
.I termprog
|
||||||
|
] [
|
||||||
|
.BR exit | restart
|
||||||
|
]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.I 9wm
|
||||||
|
is a window manager for X which attempts to emulate the window management
|
||||||
|
policies of Plan 9's
|
||||||
|
.I \*(85
|
||||||
|
window manager.
|
||||||
|
.PP
|
||||||
|
The
|
||||||
|
.B \-grey
|
||||||
|
option makes the background light grey, as does \*(85.
|
||||||
|
Use this option for maximum authenticity.
|
||||||
|
.B \-font
|
||||||
|
.I fname
|
||||||
|
sets the font in
|
||||||
|
.IR 9wm 's
|
||||||
|
menu to
|
||||||
|
.IR fname ,
|
||||||
|
overriding the default.
|
||||||
|
.B \-term
|
||||||
|
.I termprog
|
||||||
|
specifies an alternative program to run when the
|
||||||
|
.I New
|
||||||
|
menu item is selected.
|
||||||
|
.B \-version
|
||||||
|
prints the current version on standard error, then exits.
|
||||||
|
.PP
|
||||||
|
To make
|
||||||
|
.I 9wm
|
||||||
|
exit, you have to run
|
||||||
|
.B "9wm exit"
|
||||||
|
on the command line. There is no ``exit'' menu item.
|
||||||
|
.PP
|
||||||
|
.I 9wm
|
||||||
|
is click-to-type: it has a notion of the current window,
|
||||||
|
which is usually on top, and always has its border darkened.
|
||||||
|
Characters typed at the keyboard go to the current window,
|
||||||
|
and mouse clicks outside the current window are swallowed up
|
||||||
|
by
|
||||||
|
.IR 9wm .
|
||||||
|
To make another window the current one, click on it with button 1.
|
||||||
|
Unlike other X window managers, 9wm implements `mouse focus': mouse events
|
||||||
|
are sent only to the current window.
|
||||||
|
.PP
|
||||||
|
A menu of window operations is available by pressing button 3
|
||||||
|
outside the current window.
|
||||||
|
The first of these,
|
||||||
|
.IR New ,
|
||||||
|
attempts to spawn a
|
||||||
|
.I 9term
|
||||||
|
process (or
|
||||||
|
.I xterm
|
||||||
|
if
|
||||||
|
.I 9term
|
||||||
|
is not available).
|
||||||
|
The new
|
||||||
|
.I 9term
|
||||||
|
will request that its outline be swept using button 3
|
||||||
|
of the mouse, by changing the cursor.
|
||||||
|
.RI ( xterm
|
||||||
|
defaults to a fixed size, and thus wants to be dragged; pressing
|
||||||
|
button 3 places it.)
|
||||||
|
.PP
|
||||||
|
The next four menu items are
|
||||||
|
.IR Reshape ,
|
||||||
|
.IR Move ,
|
||||||
|
.IR Delete ,
|
||||||
|
and
|
||||||
|
.IR Hide .
|
||||||
|
All of the operations change the cursor into a target, prompting the user
|
||||||
|
to click button 3 on one of the windows to select it for the operation.
|
||||||
|
At this stage, clicking button 1 or 2 will abort the operation.
|
||||||
|
Otherwise, if the operation was
|
||||||
|
.IR Resize ,
|
||||||
|
the user is prompted to sweep out the new outline with button 3.
|
||||||
|
If it was
|
||||||
|
.IR Move ,
|
||||||
|
the user should keep the button held down after the initial click that selected
|
||||||
|
the window, and drag the window to the right place before releasing.
|
||||||
|
In either case, button 1 or 2 will abort the operation.
|
||||||
|
.PP
|
||||||
|
If the
|
||||||
|
.I Delete
|
||||||
|
operation is selected, the window will be deleted when the button is released.
|
||||||
|
This typically kills the client that owns the window.
|
||||||
|
The
|
||||||
|
.I Hide
|
||||||
|
operation just makes the window invisible. While hidden, the window's
|
||||||
|
name appears on the bottom of the button 3 menu. Selecting that item
|
||||||
|
brings the window back (unhides it).
|
||||||
|
This operation replaces the iconification feature provided by other
|
||||||
|
window managers.
|
||||||
|
.SH BUGS
|
||||||
|
Is not completely compatible with \*(85.
|
||||||
|
.PP
|
||||||
|
There is a currently a compiled-in limit of 32 hidden windows.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.IR 9term (1),
|
||||||
|
.IR xterm (1).
|
||||||
203
src/cmd/rio/README
Normal file
203
src/cmd/rio/README
Normal file
|
|
@ -0,0 +1,203 @@
|
||||||
|
This is David Hogan's 9wm updated to behave more like
|
||||||
|
Plan 9's rio. Since I cannot get approval for the changes
|
||||||
|
and I'd prefer not to resort to patches, I have renamed it "rio".
|
||||||
|
|
||||||
|
Current incompatibilities that would be nice to fix:
|
||||||
|
|
||||||
|
- Rio uses X11 fonts for the menu, and there aren't any good ones!
|
||||||
|
I'm tempted to hard-code the Plan 9 default font bitmap.
|
||||||
|
|
||||||
|
- The command-line options should be made more like Plan 9.
|
||||||
|
|
||||||
|
- Should work out a protocol between 9term and rio so that:
|
||||||
|
* 9term can tell rio to blue its border during hold mode
|
||||||
|
* rio can tell 9term to fade its text when it loses focus
|
||||||
|
* rio can tell 9term to unfade its text when it regains focus
|
||||||
|
|
||||||
|
- Should change window focus on b2/b3 clicks and then
|
||||||
|
pass along the click event to the now-focused window.
|
||||||
|
|
||||||
|
- Should change 9term to redirect b3 clicks to rio so that rio
|
||||||
|
can put up the usual b3 menu.
|
||||||
|
|
||||||
|
The original README is below.
|
||||||
|
|
||||||
|
- russ cox
|
||||||
|
rsc@swtch.com
|
||||||
|
20 march 2004
|
||||||
|
|
||||||
|
|
||||||
|
9wm Version 1.2
|
||||||
|
Copyright 1994-1996 David Hogan.
|
||||||
|
|
||||||
|
What is 9wm?
|
||||||
|
============
|
||||||
|
|
||||||
|
9wm is an X window manager which attempts to emulate the Plan 9 window
|
||||||
|
manager 8-1/2 as far as possible within the constraints imposed by X.
|
||||||
|
It provides a simple yet comfortable user interface, without garish
|
||||||
|
decorations or title-bars. Or icons. And it's click-to-type. This
|
||||||
|
will not appeal to everybody, but if you're not put off yet then read
|
||||||
|
on. (And don't knock it until you've tried it.)
|
||||||
|
|
||||||
|
One major difference between 9wm and 8-1/2 is that the latter provides
|
||||||
|
windows of text with a typescript interface, and doesn't need to run a
|
||||||
|
separate program to emulate a terminal. 9wm, as an X window manager,
|
||||||
|
does require a separate program. For better 8-1/2 emulation, you should
|
||||||
|
obtain Matthew Farrow's "9term" program (ftp://ftp.cs.su.oz.au/matty/unicode),
|
||||||
|
version 1.6 or later (earlier versions don't cooperate with 9wm in
|
||||||
|
implementing "hold mode"). Of course, you can run xterm under 9wm as well.
|
||||||
|
|
||||||
|
What is 9wm not?
|
||||||
|
================
|
||||||
|
|
||||||
|
9wm is not a virtual window manager. It is not customisable to any
|
||||||
|
great extent. It is not large and unwieldy, and doesn't use the X
|
||||||
|
toolkit. Requests to make it any of these things will be silently
|
||||||
|
ignored (or flamed if I have had a bad day :-) If you want tvtwm
|
||||||
|
or mwm, you know where to get them...
|
||||||
|
|
||||||
|
Where do I get it?
|
||||||
|
==================
|
||||||
|
|
||||||
|
The latest version of 9wm is held at ftp://ftp.cs.su.oz.au/dhog/9wm
|
||||||
|
|
||||||
|
Author
|
||||||
|
======
|
||||||
|
|
||||||
|
9wm was written by David Hogan (dhog@cs.su.oz.au), a postgraduate
|
||||||
|
student at the Basser Department of Computer Science, University
|
||||||
|
of Sydney (http://www.cs.su.oz.au/~dhog/).
|
||||||
|
|
||||||
|
Licence
|
||||||
|
=======
|
||||||
|
|
||||||
|
9wm is free software, and is Copyright (c) 1994-1996 by David Hogan.
|
||||||
|
Permission is granted to all sentient beings to use this software,
|
||||||
|
to make copies of it, and to distribute those copies, provided
|
||||||
|
that:
|
||||||
|
|
||||||
|
(1) the copyright and licence notices are left intact
|
||||||
|
(2) the recipients are aware that it is free software
|
||||||
|
(3) any unapproved changes in functionality are either
|
||||||
|
(i) only distributed as patches
|
||||||
|
or (ii) distributed as a new program which is not called 9wm
|
||||||
|
and whose documentation gives credit where it is due
|
||||||
|
(4) the author is not held responsible for any defects
|
||||||
|
or shortcomings in the software, or damages caused by it.
|
||||||
|
|
||||||
|
There is no warranty for this software. Have a nice day.
|
||||||
|
|
||||||
|
How do I compile/install it?
|
||||||
|
============================
|
||||||
|
|
||||||
|
Assuming your system is correctly configured, you should only need to
|
||||||
|
run xmkmf to generate the Makefile, and then run make or make install.
|
||||||
|
make install.man should copy the manpage (9wm.man) to the appropriate
|
||||||
|
directory.
|
||||||
|
|
||||||
|
If the make fails, complaining that the function _XShapeQueryExtension
|
||||||
|
does not exist, try removing the "-DSHAPE" from the Imakefile, and
|
||||||
|
run xmkmf and make again.
|
||||||
|
|
||||||
|
If you don't have imake, or it is misconfigured, or you would prefer
|
||||||
|
not to use it, try copying the file "Makefile.no-imake" to "Makefile",
|
||||||
|
then edit the definitions in this Makefile to suit your system. This
|
||||||
|
may require defining suitable compilation flags for your system
|
||||||
|
(normally imake does this for you). For instance, on AIX you must
|
||||||
|
include "-DBSD_INCLUDES" in CFLAGS.
|
||||||
|
|
||||||
|
How do I use it?
|
||||||
|
================
|
||||||
|
|
||||||
|
See the manual page for details. You should probably read the
|
||||||
|
man page for 9term as well.
|
||||||
|
|
||||||
|
What if I find a bug?
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Please mail all bug reports to 9wm-bugs@plan9.cs.su.oz.au, so
|
||||||
|
that I can incorporate fixes into the next release. If you can
|
||||||
|
tell me how to fix it, all the better.
|
||||||
|
|
||||||
|
Known Problems/Bugs
|
||||||
|
===================
|
||||||
|
|
||||||
|
9wm tries hard to emulate 8-1/2, but isn't 100% compatible. If
|
||||||
|
you are an experienced 8-1/2 user, please be patient with it.
|
||||||
|
|
||||||
|
One intentional difference between 9wm and 8-1/2 is in the behaviour
|
||||||
|
of the menu when the last hidden item is unhidden. Under 8-1/2, when
|
||||||
|
the menu is next used, it pops up with "New" selected. Under 9wm,
|
||||||
|
the (new) last menu item will be selected. This is a feature. It
|
||||||
|
may be confusing if you frequently switch between 9wm and 8-1/2.
|
||||||
|
If you don't like this feature, email me for the one line fix.
|
||||||
|
|
||||||
|
There have been some problems encountered when resizing 9term on
|
||||||
|
some platforms. This turns out to be a problem in 9term (actually
|
||||||
|
in libXg, to be precise). Newer versions of 9term should be
|
||||||
|
immune to this, see matty@cs.su.oz.au if your 9term needs fixing.
|
||||||
|
|
||||||
|
Some client programs do weird things. One of these is Frame Maker.
|
||||||
|
It appears that if it has a modal dialog on the screen, then if any
|
||||||
|
of its windows are current, all keypresses are redirected to the
|
||||||
|
modal dialog. This is not 9wm's fault -- Frame Maker is doing this.
|
||||||
|
|
||||||
|
Programs like Netscape Navigator like to put riddiculously long
|
||||||
|
icon name properties on their windows, of the form "Netscape: blah blah".
|
||||||
|
There is no way that I know of to stop netscape from doing this. For this
|
||||||
|
reason, 9wm truncates labels at the first colon it finds. This keeps the
|
||||||
|
button 3 menu from becoming excessively wide. Note that with same
|
||||||
|
applications, you can use an iconName resource to set the label; this
|
||||||
|
works well for "xman", whose default icon name of "Manual Browser"
|
||||||
|
is a tad too long.
|
||||||
|
|
||||||
|
See Also
|
||||||
|
========
|
||||||
|
|
||||||
|
http://www.cs.su.oz.au/~dhog/
|
||||||
|
The 9wm Home Page
|
||||||
|
|
||||||
|
ftp://ftp.cs.su.oz.au/matty/unicode/
|
||||||
|
for source to 9term (get README first)
|
||||||
|
|
||||||
|
ftp://plan9.att.com/plan9/unixsrc/sam/
|
||||||
|
for source && info on Rob Pike's editor "sam"
|
||||||
|
|
||||||
|
ftp://rtfm.mit.edu/pub/usenet/news.answers/unix-faq/shell/rc
|
||||||
|
for information on a publically available implementation
|
||||||
|
of the Plan 9 shell "rc" for unix (or look in comp.unix.shell).
|
||||||
|
|
||||||
|
ftp://viz.tamu.edu/pub/rc
|
||||||
|
for source to the abovementioned implementation of rc.
|
||||||
|
|
||||||
|
http://plan9.att.com/plan9/
|
||||||
|
http://plan9.att.com/magic/man2html/1/8%c2%bd
|
||||||
|
for information on Plan 9 (including the 8-1/2 manual entry)
|
||||||
|
|
||||||
|
Acknowledgements
|
||||||
|
================
|
||||||
|
|
||||||
|
Thanks to Rob Pike for writing the original 8-1/2 program (and
|
||||||
|
before that, mux) which inspired the writing of 9wm.
|
||||||
|
|
||||||
|
Thanks to John Mackin, whose gwm "wool code" for emulating mux
|
||||||
|
was also an inspiration: I used it (and hacked it) until I got
|
||||||
|
too frustrated with gwm's large memory requirements and lack of
|
||||||
|
speed (sorry Colas!), and decided to write a dedicated program.
|
||||||
|
|
||||||
|
Thanks to Matthew Farrow for writing 9term.
|
||||||
|
|
||||||
|
A big thanks to Dave Edmondson for adding support for
|
||||||
|
multi-screen displays.
|
||||||
|
|
||||||
|
The following people helped beta test 9wm:
|
||||||
|
|
||||||
|
John Mackin
|
||||||
|
Noel Hunt
|
||||||
|
Fred Curtis
|
||||||
|
James Matthew Farrow
|
||||||
|
Danny Yee
|
||||||
|
Arnold Robbins
|
||||||
|
Byron Rakitzis
|
||||||
|
micro@cooper.edu
|
||||||
242
src/cmd/rio/client.c
Normal file
242
src/cmd/rio/client.c
Normal file
|
|
@ -0,0 +1,242 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
Client *clients;
|
||||||
|
Client *current;
|
||||||
|
|
||||||
|
void
|
||||||
|
setactive(Client *c, int on)
|
||||||
|
{
|
||||||
|
if (c->parent == c->screen->root) {
|
||||||
|
fprintf(stderr, "9wm: bad parent in setactive; dumping core\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (on) {
|
||||||
|
XUngrabButton(dpy, AnyButton, AnyModifier, c->parent);
|
||||||
|
XSetInputFocus(dpy, c->window, RevertToPointerRoot, timestamp());
|
||||||
|
if (c->proto & Ptakefocus)
|
||||||
|
sendcmessage(c->window, wm_protocols, wm_take_focus, 0);
|
||||||
|
cmapfocus(c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
XGrabButton(dpy, AnyButton, AnyModifier, c->parent, False,
|
||||||
|
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||||
|
draw_border(c, on);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_border(Client *c, int active)
|
||||||
|
{
|
||||||
|
unsigned long pixel;
|
||||||
|
|
||||||
|
if(active){
|
||||||
|
if(c->hold)
|
||||||
|
pixel = c->screen->activeholdborder;
|
||||||
|
else
|
||||||
|
pixel = c->screen->activeborder;
|
||||||
|
}else{
|
||||||
|
if(c->hold)
|
||||||
|
pixel = c->screen->inactiveholdborder;
|
||||||
|
else
|
||||||
|
pixel = c->screen->inactiveborder;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSetWindowBackground(dpy, c->parent, pixel);
|
||||||
|
XClearWindow(dpy, c->parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
active(Client *c)
|
||||||
|
{
|
||||||
|
Client *cc;
|
||||||
|
|
||||||
|
if (c == 0) {
|
||||||
|
fprintf(stderr, "9wm: active(c==0)\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (c == current)
|
||||||
|
return;
|
||||||
|
if (current) {
|
||||||
|
setactive(current, 0);
|
||||||
|
if (current->screen != c->screen)
|
||||||
|
cmapnofocus(current->screen);
|
||||||
|
}
|
||||||
|
setactive(c, 1);
|
||||||
|
for (cc = clients; cc; cc = cc->next)
|
||||||
|
if (cc->revert == c)
|
||||||
|
cc->revert = c->revert;
|
||||||
|
c->revert = current;
|
||||||
|
while (c->revert && !normal(c->revert))
|
||||||
|
c->revert = c->revert->revert;
|
||||||
|
current = c;
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (debug)
|
||||||
|
dump_revert();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nofocus(void)
|
||||||
|
{
|
||||||
|
static Window w = 0;
|
||||||
|
int mask;
|
||||||
|
XSetWindowAttributes attr;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
if (current) {
|
||||||
|
setactive(current, 0);
|
||||||
|
for (c = current->revert; c; c = c->revert)
|
||||||
|
if (normal(c)) {
|
||||||
|
active(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cmapnofocus(current->screen);
|
||||||
|
/* if no candidates to revert to, fall through */
|
||||||
|
}
|
||||||
|
current = 0;
|
||||||
|
if (w == 0) {
|
||||||
|
mask = CWOverrideRedirect;
|
||||||
|
attr.override_redirect = 1;
|
||||||
|
w = XCreateWindow(dpy, screens[0].root, 0, 0, 1, 1, 0,
|
||||||
|
CopyFromParent, InputOnly, CopyFromParent, mask, &attr);
|
||||||
|
XMapWindow(dpy, w);
|
||||||
|
}
|
||||||
|
XSetInputFocus(dpy, w, RevertToPointerRoot, timestamp());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
top(Client *c)
|
||||||
|
{
|
||||||
|
Client **l, *cc;
|
||||||
|
|
||||||
|
l = &clients;
|
||||||
|
for (cc = *l; cc; cc = *l) {
|
||||||
|
if (cc == c) {
|
||||||
|
*l = c->next;
|
||||||
|
c->next = clients;
|
||||||
|
clients = c;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
l = &cc->next;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "9wm: %x not on client list in top()\n", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
Client *
|
||||||
|
getclient(Window w, int create)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
if (w == 0 || getscreen(w))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (c = clients; c; c = c->next)
|
||||||
|
if (c->window == w || c->parent == w)
|
||||||
|
return c;
|
||||||
|
|
||||||
|
if (!create)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
c = (Client *)malloc(sizeof(Client));
|
||||||
|
memset(c, 0, sizeof(Client));
|
||||||
|
c->window = w;
|
||||||
|
/* c->parent will be set by the caller */
|
||||||
|
c->parent = None;
|
||||||
|
c->reparenting = 0;
|
||||||
|
c->state = WithdrawnState;
|
||||||
|
c->init = 0;
|
||||||
|
c->cmap = None;
|
||||||
|
c->label = c->class = 0;
|
||||||
|
c->revert = 0;
|
||||||
|
c->is9term = 0;
|
||||||
|
c->hold = 0;
|
||||||
|
c->ncmapwins = 0;
|
||||||
|
c->cmapwins = 0;
|
||||||
|
c->wmcmaps = 0;
|
||||||
|
c->next = clients;
|
||||||
|
clients = c;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rmclient(Client *c)
|
||||||
|
{
|
||||||
|
Client *cc;
|
||||||
|
|
||||||
|
for (cc = current; cc && cc->revert; cc = cc->revert)
|
||||||
|
if (cc->revert == c)
|
||||||
|
cc->revert = cc->revert->revert;
|
||||||
|
|
||||||
|
if (c == clients)
|
||||||
|
clients = c->next;
|
||||||
|
for (cc = clients; cc && cc->next; cc = cc->next)
|
||||||
|
if (cc->next == c)
|
||||||
|
cc->next = cc->next->next;
|
||||||
|
|
||||||
|
if (hidden(c))
|
||||||
|
unhidec(c, 0);
|
||||||
|
|
||||||
|
if (c->parent != c->screen->root)
|
||||||
|
XDestroyWindow(dpy, c->parent);
|
||||||
|
|
||||||
|
c->parent = c->window = None; /* paranoia */
|
||||||
|
if (current == c) {
|
||||||
|
current = c->revert;
|
||||||
|
if (current == 0)
|
||||||
|
nofocus();
|
||||||
|
else {
|
||||||
|
if (current->screen != c->screen)
|
||||||
|
cmapnofocus(c->screen);
|
||||||
|
setactive(current, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c->ncmapwins != 0) {
|
||||||
|
XFree((char *)c->cmapwins);
|
||||||
|
free((char *)c->wmcmaps);
|
||||||
|
}
|
||||||
|
if (c->iconname != 0)
|
||||||
|
XFree((char*) c->iconname);
|
||||||
|
if (c->name != 0)
|
||||||
|
XFree((char*) c->name);
|
||||||
|
if (c->instance != 0)
|
||||||
|
XFree((char*) c->instance);
|
||||||
|
if (c->class != 0)
|
||||||
|
XFree((char*) c->class);
|
||||||
|
memset(c, 0, sizeof(Client)); /* paranoia */
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
void
|
||||||
|
dump_revert(void)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (c = current; c; c = c->revert) {
|
||||||
|
fprintf(stderr, "%s(%x:%d)", c->label ? c->label : "?", c->window, c->state);
|
||||||
|
if (i++ > 100)
|
||||||
|
break;
|
||||||
|
if (c->revert)
|
||||||
|
fprintf(stderr, " -> ");
|
||||||
|
}
|
||||||
|
if (current == 0)
|
||||||
|
fprintf(stderr, "empty");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dump_clients(void)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
for (c = clients; c; c = c->next)
|
||||||
|
fprintf(stderr, "w 0x%x parent 0x%x @ (%d, %d)\n", c->window, c->parent, c->x, c->y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
44
src/cmd/rio/color.c
Normal file
44
src/cmd/rio/color.c
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* Copyright (c) 2004 Russ Cox, see README for licence details */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
unsigned long
|
||||||
|
colorpixel(Display *dpy, int depth, ulong rgb)
|
||||||
|
{
|
||||||
|
int r, g, b;
|
||||||
|
|
||||||
|
r = rgb>>16;
|
||||||
|
g = (rgb>>8)&0xFF;
|
||||||
|
b = rgb&0xFF;
|
||||||
|
|
||||||
|
switch(depth){
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 8:
|
||||||
|
default:
|
||||||
|
/* not going to waste color map entries */
|
||||||
|
if(rgb == 0xFFFFFF)
|
||||||
|
return WhitePixel(dpy, DefaultScreen(dpy));
|
||||||
|
return BlackPixel(dpy, DefaultScreen(dpy));
|
||||||
|
case 15:
|
||||||
|
r >>= 3;
|
||||||
|
g >>= 3;
|
||||||
|
b >>= 3;
|
||||||
|
return (r<<10) | (g<<5) | b;
|
||||||
|
case 16:
|
||||||
|
r >>= 3;
|
||||||
|
g >>= 2;
|
||||||
|
b >>= 3;
|
||||||
|
return (r<<11) | (g<<5) | b;
|
||||||
|
case 24:
|
||||||
|
case 32:
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
368
src/cmd/rio/cursor.c
Normal file
368
src/cmd/rio/cursor.c
Normal file
|
|
@ -0,0 +1,368 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int width;
|
||||||
|
int hot[2];
|
||||||
|
unsigned char mask[64];
|
||||||
|
unsigned char fore[64];
|
||||||
|
} Cursordata;
|
||||||
|
|
||||||
|
Cursordata bigarrow = {
|
||||||
|
16,
|
||||||
|
{0, 0},
|
||||||
|
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x3F,
|
||||||
|
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x1F, 0xFF, 0x3F,
|
||||||
|
0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x3F,
|
||||||
|
0xCF, 0x1F, 0x8F, 0x0F, 0x07, 0x07, 0x03, 0x02,
|
||||||
|
},
|
||||||
|
{ 0x00, 0x00, 0xFE, 0x7F, 0xFE, 0x3F, 0xFE, 0x0F,
|
||||||
|
0xFE, 0x07, 0xFE, 0x07, 0xFE, 0x0F, 0xFE, 0x1F,
|
||||||
|
0xFE, 0x3F, 0xFE, 0x7F, 0xFE, 0x3F, 0xCE, 0x1F,
|
||||||
|
0x86, 0x0F, 0x06, 0x07, 0x02, 0x02, 0x00, 0x00,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursordata sweep0data = {
|
||||||
|
16,
|
||||||
|
{7, 7},
|
||||||
|
{0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03,
|
||||||
|
0xC0, 0x03, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xC0, 0x03,
|
||||||
|
0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03},
|
||||||
|
{0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||||
|
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xFE, 0x7F,
|
||||||
|
0xFE, 0x7F, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||||
|
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00}
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursordata boxcursdata = {
|
||||||
|
16,
|
||||||
|
{7, 7},
|
||||||
|
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8,
|
||||||
|
0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||||
|
{0x00, 0x00, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F,
|
||||||
|
0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70,
|
||||||
|
0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70,
|
||||||
|
0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0x00, 0x00}
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursordata sightdata = {
|
||||||
|
16,
|
||||||
|
{7, 7},
|
||||||
|
{0xF8, 0x1F, 0xFC, 0x3F, 0xFE, 0x7F, 0xDF, 0xFB,
|
||||||
|
0xCF, 0xF3, 0xC7, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xE3, 0xCF, 0xF3,
|
||||||
|
0xDF, 0x7B, 0xFE, 0x7F, 0xFC, 0x3F, 0xF8, 0x1F,},
|
||||||
|
{0x00, 0x00, 0xF0, 0x0F, 0x8C, 0x31, 0x84, 0x21,
|
||||||
|
0x82, 0x41, 0x82, 0x41, 0x82, 0x41, 0xFE, 0x7F,
|
||||||
|
0xFE, 0x7F, 0x82, 0x41, 0x82, 0x41, 0x82, 0x41,
|
||||||
|
0x84, 0x21, 0x8C, 0x31, 0xF0, 0x0F, 0x00, 0x00,}
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursordata arrowdata = {
|
||||||
|
16,
|
||||||
|
{1, 1},
|
||||||
|
{0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x03, 0xFF, 0x00,
|
||||||
|
0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x03, 0xFF, 0x07,
|
||||||
|
0xE7, 0x0F, 0xC7, 0x1F, 0x83, 0x3F, 0x00, 0x7F,
|
||||||
|
0x00, 0xFE, 0x00, 0x7C, 0x00, 0x38, 0x00, 0x10,},
|
||||||
|
{0x00, 0x00, 0xFE, 0x03, 0xFE, 0x00, 0x3E, 0x00,
|
||||||
|
0x7E, 0x00, 0xFE, 0x00, 0xF6, 0x01, 0xE6, 0x03,
|
||||||
|
0xC2, 0x07, 0x82, 0x0F, 0x00, 0x1F, 0x00, 0x3E,
|
||||||
|
0x00, 0x7C, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00,}
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursordata whitearrow = {
|
||||||
|
16,
|
||||||
|
{0, 0},
|
||||||
|
{0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x03, 0xFF, 0x00,
|
||||||
|
0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x03, 0xFF, 0x07,
|
||||||
|
0xE7, 0x0F, 0xC7, 0x1F, 0x83, 0x3F, 0x00, 0x7F,
|
||||||
|
0x00, 0xFE, 0x00, 0x7C, 0x00, 0x38, 0x00, 0x10,},
|
||||||
|
{0xFF, 0x07, 0xFF, 0x07, 0x83, 0x03, 0xC3, 0x00,
|
||||||
|
0xC3, 0x00, 0x83, 0x01, 0x1B, 0x03, 0x3F, 0x06,
|
||||||
|
0x67, 0x0C, 0xC7, 0x18, 0x83, 0x31, 0x00, 0x63,
|
||||||
|
0x00, 0xC6, 0x00, 0x6C, 0x00, 0x38, 0x00, 0x10,}
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursordata blittarget = {
|
||||||
|
18,
|
||||||
|
{8, 8},
|
||||||
|
{0xe0, 0x1f, 0x00, 0xf0, 0x3f, 0x00, 0xf8, 0x7f, 0x00,
|
||||||
|
0xfc, 0xff, 0x00, 0xfe, 0xff, 0x01, 0xff, 0xff, 0x03,
|
||||||
|
0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03,
|
||||||
|
0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03,
|
||||||
|
0xff, 0xff, 0x03, 0xfe, 0xff, 0x01, 0xfc, 0xff, 0x00,
|
||||||
|
0xf8, 0x7f, 0x00, 0xf0, 0x3f, 0x00, 0xe0, 0x1f, 0x00},
|
||||||
|
{0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0xf0, 0x3f, 0x00,
|
||||||
|
0x38, 0x73, 0x00, 0x8c, 0xc7, 0x00, 0xec, 0xdf, 0x00,
|
||||||
|
0x66, 0x9b, 0x01, 0x36, 0xb3, 0x01, 0xfe, 0xff, 0x01,
|
||||||
|
0xfe, 0xff, 0x01, 0x36, 0xb3, 0x01, 0x66, 0x9b, 0x01,
|
||||||
|
0xec, 0xdf, 0x00, 0x8c, 0xc7, 0x00, 0x38, 0x73, 0x00,
|
||||||
|
0xf0, 0x3f, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00}
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursordata blitarrow = {
|
||||||
|
18,
|
||||||
|
{1, 1},
|
||||||
|
{0xff, 0x0f, 0x00, 0xff, 0x07, 0x00, 0xff, 0x03, 0x00,
|
||||||
|
0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x01, 0x00,
|
||||||
|
0xff, 0x03, 0x00, 0xff, 0x07, 0x00, 0xe7, 0x0f, 0x00,
|
||||||
|
0xc7, 0x1f, 0x00, 0x87, 0x3f, 0x00, 0x03, 0x7f, 0x00,
|
||||||
|
0x01, 0xfe, 0x00, 0x00, 0xfc, 0x01, 0x00, 0xf8, 0x03,
|
||||||
|
0x00, 0xf0, 0x01, 0x00, 0xe0, 0x00, 0x00, 0x40, 0x00},
|
||||||
|
{0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0xfe, 0x00, 0x00,
|
||||||
|
0x3e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfe, 0x00, 0x00,
|
||||||
|
0xf6, 0x01, 0x00, 0xe6, 0x03, 0x00, 0xc2, 0x07, 0x00,
|
||||||
|
0x82, 0x0f, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x3e, 0x00,
|
||||||
|
0x00, 0x7c, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf0, 0x01,
|
||||||
|
0x00, 0xe0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00}
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursordata blitsweep = {
|
||||||
|
18,
|
||||||
|
{8, 8},
|
||||||
|
{0xc4, 0xff, 0x03, 0xce, 0xff, 0x03, 0xdf, 0xff, 0x03,
|
||||||
|
0x3e, 0x80, 0x03, 0x7c, 0x83, 0x03, 0xf8, 0x83, 0x03,
|
||||||
|
0xf7, 0x83, 0x03, 0xe7, 0x83, 0x03, 0xf7, 0x83, 0x03,
|
||||||
|
0xf7, 0x83, 0x03, 0x07, 0x80, 0x03, 0x07, 0x80, 0x03,
|
||||||
|
0x07, 0x80, 0x03, 0x07, 0x80, 0x03, 0x07, 0x80, 0x03,
|
||||||
|
0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03},
|
||||||
|
{0x00, 0x00, 0x00, 0x84, 0xff, 0x01, 0x0e, 0x00, 0x01,
|
||||||
|
0x1c, 0x00, 0x01, 0x38, 0x00, 0x01, 0x70, 0x01, 0x01,
|
||||||
|
0xe0, 0x01, 0x01, 0xc2, 0x01, 0x01, 0xe2, 0x01, 0x01,
|
||||||
|
0x02, 0x00, 0x01, 0x02, 0x00, 0x01, 0x02, 0x00, 0x01,
|
||||||
|
0x02, 0x00, 0x01, 0x02, 0x00, 0x01, 0x02, 0x00, 0x01,
|
||||||
|
0x02, 0x00, 0x01, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Grey tile pattern for root background
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define grey_width 4
|
||||||
|
#define grey_height 2
|
||||||
|
static char grey_bits[] = {
|
||||||
|
0x01, 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
static XColor bl, wh;
|
||||||
|
|
||||||
|
Cursor
|
||||||
|
getcursor(c, s)
|
||||||
|
Cursordata *c;
|
||||||
|
ScreenInfo *s;
|
||||||
|
{
|
||||||
|
Pixmap f, m;
|
||||||
|
|
||||||
|
f = XCreatePixmapFromBitmapData(dpy, s->root, (char *)c->fore,
|
||||||
|
c->width, c->width, 1, 0, 1);
|
||||||
|
m = XCreatePixmapFromBitmapData(dpy, s->root, (char *)c->mask,
|
||||||
|
c->width, c->width, 1, 0, 1);
|
||||||
|
return XCreatePixmapCursor(dpy, f, m, &bl, &wh,
|
||||||
|
c->hot[0], c->hot[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initcurs(s)
|
||||||
|
ScreenInfo *s;
|
||||||
|
{
|
||||||
|
XColor dummy;
|
||||||
|
|
||||||
|
XAllocNamedColor(dpy, DefaultColormap(dpy, s->num),
|
||||||
|
"black", &bl, &dummy);
|
||||||
|
XAllocNamedColor(dpy, DefaultColormap(dpy, s->num),
|
||||||
|
"white", &wh, &dummy);
|
||||||
|
|
||||||
|
if (nostalgia) {
|
||||||
|
s->arrow = getcursor(&blitarrow, s);
|
||||||
|
s->target = getcursor(&blittarget, s);
|
||||||
|
s->sweep0 = getcursor(&blitsweep, s);
|
||||||
|
s->boxcurs = getcursor(&blitsweep, s);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s->arrow = getcursor(&bigarrow, s);
|
||||||
|
s->target = getcursor(&sightdata, s);
|
||||||
|
s->sweep0 = getcursor(&sweep0data, s);
|
||||||
|
s->boxcurs = getcursor(&boxcursdata, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
s->root_pixmap = XCreatePixmapFromBitmapData(dpy,
|
||||||
|
s->root, grey_bits, grey_width, grey_height,
|
||||||
|
s->black, s->white, DefaultDepth(dpy, s->num));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* RIO
|
||||||
|
|
||||||
|
Cursor crosscursor = {
|
||||||
|
{-7, -7},
|
||||||
|
{0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
|
||||||
|
0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0,
|
||||||
|
0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, },
|
||||||
|
{0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
|
||||||
|
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x7F, 0xFE,
|
||||||
|
0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
|
||||||
|
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor boxcursor = {
|
||||||
|
{-7, -7},
|
||||||
|
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,
|
||||||
|
0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
|
||||||
|
{0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,
|
||||||
|
0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
|
||||||
|
0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
|
||||||
|
0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor sightcursor = {
|
||||||
|
{-7, -7},
|
||||||
|
{0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,
|
||||||
|
0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,
|
||||||
|
0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8, },
|
||||||
|
{0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,
|
||||||
|
0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,
|
||||||
|
0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
|
||||||
|
0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor whitearrow = {
|
||||||
|
{0, 0},
|
||||||
|
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC,
|
||||||
|
0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8, 0xFF, 0xFC,
|
||||||
|
0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC,
|
||||||
|
0xF3, 0xF8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, },
|
||||||
|
{0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0xC0, 0x1C,
|
||||||
|
0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x38, 0xC0, 0x1C,
|
||||||
|
0xC0, 0x0E, 0xC0, 0x07, 0xCE, 0x0E, 0xDF, 0x1C,
|
||||||
|
0xD3, 0xB8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor query = {
|
||||||
|
{-7,-7},
|
||||||
|
{0x0f, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe,
|
||||||
|
0x7c, 0x7e, 0x78, 0x7e, 0x00, 0xfc, 0x01, 0xf8,
|
||||||
|
0x03, 0xf0, 0x07, 0xe0, 0x07, 0xc0, 0x07, 0xc0,
|
||||||
|
0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, },
|
||||||
|
{0x00, 0x00, 0x0f, 0xf0, 0x1f, 0xf8, 0x3c, 0x3c,
|
||||||
|
0x38, 0x1c, 0x00, 0x3c, 0x00, 0x78, 0x00, 0xf0,
|
||||||
|
0x01, 0xe0, 0x03, 0xc0, 0x03, 0x80, 0x03, 0x80,
|
||||||
|
0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor tl = {
|
||||||
|
{-4, -4},
|
||||||
|
{0xfe, 0x00, 0x82, 0x00, 0x8c, 0x00, 0x87, 0xff,
|
||||||
|
0xa0, 0x01, 0xb0, 0x01, 0xd0, 0x01, 0x11, 0xff,
|
||||||
|
0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00,
|
||||||
|
0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x1f, 0x00, },
|
||||||
|
{0x00, 0x00, 0x7c, 0x00, 0x70, 0x00, 0x78, 0x00,
|
||||||
|
0x5f, 0xfe, 0x4f, 0xfe, 0x0f, 0xfe, 0x0e, 0x00,
|
||||||
|
0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00,
|
||||||
|
0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor t = {
|
||||||
|
{-7, -8},
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x06, 0xc0,
|
||||||
|
0x1c, 0x70, 0x10, 0x10, 0x0c, 0x60, 0xfc, 0x7f,
|
||||||
|
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80, 0x03, 0x80,
|
||||||
|
0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor tr = {
|
||||||
|
{-11, -4},
|
||||||
|
{0x00, 0x7f, 0x00, 0x41, 0x00, 0x31, 0xff, 0xe1,
|
||||||
|
0x80, 0x05, 0x80, 0x0d, 0x80, 0x0b, 0xff, 0x88,
|
||||||
|
0x00, 0x88, 0x0, 0x88, 0x00, 0x88, 0x00, 0x88,
|
||||||
|
0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xf8, },
|
||||||
|
{0x00, 0x00, 0x00, 0x3e, 0x00, 0x0e, 0x00, 0x1e,
|
||||||
|
0x7f, 0xfa, 0x7f, 0xf2, 0x7f, 0xf0, 0x00, 0x70,
|
||||||
|
0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70,
|
||||||
|
0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor r = {
|
||||||
|
{-8, -7},
|
||||||
|
{0x07, 0xc0, 0x04, 0x40, 0x04, 0x40, 0x04, 0x58,
|
||||||
|
0x04, 0x68, 0x04, 0x6c, 0x04, 0x06, 0x04, 0x02,
|
||||||
|
0x04, 0x06, 0x04, 0x6c, 0x04, 0x68, 0x04, 0x58,
|
||||||
|
0x04, 0x40, 0x04, 0x40, 0x04, 0x40, 0x07, 0xc0, },
|
||||||
|
{0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80,
|
||||||
|
0x03, 0x90, 0x03, 0x90, 0x03, 0xf8, 0x03, 0xfc,
|
||||||
|
0x03, 0xf8, 0x03, 0x90, 0x03, 0x90, 0x03, 0x80,
|
||||||
|
0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor br = {
|
||||||
|
{-11, -11},
|
||||||
|
{0x00, 0xf8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88,
|
||||||
|
0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88,
|
||||||
|
0xff, 0x88, 0x80, 0x0b, 0x80, 0x0d, 0x80, 0x05,
|
||||||
|
0xff, 0xe1, 0x00, 0x31, 0x00, 0x41, 0x00, 0x7f, },
|
||||||
|
{0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70,
|
||||||
|
0x0, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70,
|
||||||
|
0x00, 0x70, 0x7f, 0xf0, 0x7f, 0xf2, 0x7f, 0xfa,
|
||||||
|
0x00, 0x1e, 0x00, 0x0e, 0x00, 0x3e, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor b = {
|
||||||
|
{-7, -7},
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||||
|
0xfc, 0x7f, 0x0c, 0x60, 0x10, 0x10, 0x1c, 0x70,
|
||||||
|
0x06, 0xc0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, },
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe,
|
||||||
|
0x03, 0x80, 0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor bl = {
|
||||||
|
{-4, -11},
|
||||||
|
{0x1f, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00,
|
||||||
|
0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00,
|
||||||
|
0x11, 0xff, 0xd0, 0x01, 0xb0, 0x01, 0xa0, 0x01,
|
||||||
|
0x87, 0xff, 0x8c, 0x00, 0x82, 0x00, 0xfe, 0x00, },
|
||||||
|
{0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00,
|
||||||
|
0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00,
|
||||||
|
0x0e, 0x00, 0x0f, 0xfe, 0x4f, 0xfe, 0x5f, 0xfe,
|
||||||
|
0x78, 0x00, 0x70, 0x00, 0x7c, 0x00, 0x00, 0x0, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor l = {
|
||||||
|
{-7, -7},
|
||||||
|
{0x03, 0xe0, 0x02, 0x20, 0x02, 0x20, 0x1a, 0x20,
|
||||||
|
0x16, 0x20, 0x36, 0x20, 0x60, 0x20, 0x40, 0x20,
|
||||||
|
0x60, 0x20, 0x36, 0x20, 0x16, 0x20, 0x1a, 0x20,
|
||||||
|
0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x03, 0xe0, },
|
||||||
|
{0x00, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0,
|
||||||
|
0x09, 0xc0, 0x09, 0xc0, 0x1f, 0xc0, 0x3f, 0xc0,
|
||||||
|
0x1f, 0xc0, 0x09, 0xc0, 0x09, 0xc0, 0x01, 0xc0,
|
||||||
|
0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor *corners[9] = {
|
||||||
|
&tl, &t, &tr,
|
||||||
|
&l, nil, &r,
|
||||||
|
&bl, &b, &br,
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
148
src/cmd/rio/dat.h
Normal file
148
src/cmd/rio/dat.h
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
|
||||||
|
#define BORDER _border
|
||||||
|
#define INSET _inset
|
||||||
|
#define MAXHIDDEN 32
|
||||||
|
#define B3FIXED 5
|
||||||
|
|
||||||
|
#define AllButtonMask (Button1Mask|Button2Mask|Button3Mask \
|
||||||
|
|Button4Mask|Button5Mask)
|
||||||
|
#define ButtonMask (ButtonPressMask|ButtonReleaseMask)
|
||||||
|
#define MenuMask (ButtonMask|ButtonMotionMask|ExposureMask)
|
||||||
|
#define MenuGrabMask (ButtonMask|ButtonMotionMask|StructureNotifyMask)
|
||||||
|
|
||||||
|
#ifdef Plan9
|
||||||
|
#define DEFSHELL "/bin/rc"
|
||||||
|
#else
|
||||||
|
#define DEFSHELL "/bin/sh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct Client Client;
|
||||||
|
typedef struct Menu Menu;
|
||||||
|
typedef struct ScreenInfo ScreenInfo;
|
||||||
|
|
||||||
|
struct Client {
|
||||||
|
Window window;
|
||||||
|
Window parent;
|
||||||
|
Window trans;
|
||||||
|
Client *next;
|
||||||
|
Client *revert;
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int dx;
|
||||||
|
int dy;
|
||||||
|
int border;
|
||||||
|
|
||||||
|
XSizeHints size;
|
||||||
|
int min_dx;
|
||||||
|
int min_dy;
|
||||||
|
|
||||||
|
int state;
|
||||||
|
int init;
|
||||||
|
int reparenting;
|
||||||
|
int is9term;
|
||||||
|
int hold;
|
||||||
|
int proto;
|
||||||
|
|
||||||
|
char *label;
|
||||||
|
char *instance;
|
||||||
|
char *class;
|
||||||
|
char *name;
|
||||||
|
char *iconname;
|
||||||
|
|
||||||
|
Colormap cmap;
|
||||||
|
int ncmapwins;
|
||||||
|
Window *cmapwins;
|
||||||
|
Colormap *wmcmaps;
|
||||||
|
ScreenInfo *screen;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define hidden(c) ((c)->state == IconicState)
|
||||||
|
#define withdrawn(c) ((c)->state == WithdrawnState)
|
||||||
|
#define normal(c) ((c)->state == NormalState)
|
||||||
|
|
||||||
|
/* c->proto */
|
||||||
|
#define Pdelete 1
|
||||||
|
#define Ptakefocus 2
|
||||||
|
|
||||||
|
struct Menu {
|
||||||
|
char **item;
|
||||||
|
char *(*gen)();
|
||||||
|
int lasthit;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScreenInfo {
|
||||||
|
int num;
|
||||||
|
int depth;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
Window root;
|
||||||
|
Window menuwin;
|
||||||
|
Window sweepwin;
|
||||||
|
Colormap def_cmap;
|
||||||
|
GC gc;
|
||||||
|
GC gccopy;
|
||||||
|
GC gcred;
|
||||||
|
GC gcsweep;
|
||||||
|
GC gcmenubg;
|
||||||
|
GC gcmenubgs;
|
||||||
|
GC gcmenufg;
|
||||||
|
GC gcmenufgs;
|
||||||
|
unsigned long black;
|
||||||
|
unsigned long white;
|
||||||
|
unsigned long activeholdborder;
|
||||||
|
unsigned long inactiveholdborder;
|
||||||
|
unsigned long activeborder;
|
||||||
|
unsigned long inactiveborder;
|
||||||
|
unsigned long red;
|
||||||
|
Pixmap bkup[2];
|
||||||
|
int min_cmaps;
|
||||||
|
Cursor target;
|
||||||
|
Cursor sweep0;
|
||||||
|
Cursor boxcurs;
|
||||||
|
Cursor arrow;
|
||||||
|
Pixmap root_pixmap;
|
||||||
|
char display[256]; /* arbitrary limit */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* main.c */
|
||||||
|
extern Display *dpy;
|
||||||
|
extern ScreenInfo *screens;
|
||||||
|
extern int num_screens;
|
||||||
|
extern int initting;
|
||||||
|
extern XFontStruct *font;
|
||||||
|
extern int nostalgia;
|
||||||
|
extern char **myargv;
|
||||||
|
extern Bool shape;
|
||||||
|
extern char *termprog;
|
||||||
|
extern char *shell;
|
||||||
|
extern char *version[];
|
||||||
|
extern int _border;
|
||||||
|
extern int _inset;
|
||||||
|
extern int curtime;
|
||||||
|
extern int debug;
|
||||||
|
extern int solidsweep;
|
||||||
|
|
||||||
|
extern Atom exit_9wm;
|
||||||
|
extern Atom restart_9wm;
|
||||||
|
extern Atom wm_state;
|
||||||
|
extern Atom wm_change_state;
|
||||||
|
extern Atom _9wm_hold_mode;
|
||||||
|
extern Atom wm_protocols;
|
||||||
|
extern Atom wm_delete;
|
||||||
|
extern Atom wm_take_focus;
|
||||||
|
extern Atom wm_colormaps;
|
||||||
|
|
||||||
|
/* client.c */
|
||||||
|
extern Client *clients;
|
||||||
|
extern Client *current;
|
||||||
|
|
||||||
|
/* menu.c */
|
||||||
|
extern Client *hiddenc[];
|
||||||
|
extern int numhidden;
|
||||||
|
extern char *b3items[];
|
||||||
|
extern Menu b3menu;
|
||||||
|
|
||||||
|
/* error.c */
|
||||||
|
extern int ignore_badwindow;
|
||||||
98
src/cmd/rio/error.c
Normal file
98
src/cmd/rio/error.c
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xproto.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
int ignore_badwindow;
|
||||||
|
|
||||||
|
void
|
||||||
|
fatal(char *s)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "9wm: ");
|
||||||
|
perror(s);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
handler(Display *d, XErrorEvent *e)
|
||||||
|
{
|
||||||
|
char msg[80], req[80], number[80];
|
||||||
|
|
||||||
|
if (initting && (e->request_code == X_ChangeWindowAttributes) && (e->error_code == BadAccess)) {
|
||||||
|
fprintf(stderr, "9wm: it looks like there's already a window manager running; 9wm not started\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignore_badwindow && (e->error_code == BadWindow || e->error_code == BadColor))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
XGetErrorText(d, e->error_code, msg, sizeof(msg));
|
||||||
|
sprintf(number, "%d", e->request_code);
|
||||||
|
XGetErrorDatabaseText(d, "XRequest", number, "", req, sizeof(req));
|
||||||
|
if (req[0] == '\0')
|
||||||
|
sprintf(req, "<request-code-%d>", e->request_code);
|
||||||
|
|
||||||
|
fprintf(stderr, "9wm: %s(0x%x): %s\n", req, e->resourceid, msg);
|
||||||
|
|
||||||
|
if (initting) {
|
||||||
|
fprintf(stderr, "9wm: failure during initialisation; aborting\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
graberror(char *f, int err)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG /* sick of "bug" reports; grab errors "just happen" */
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case GrabNotViewable:
|
||||||
|
s = "not viewable";
|
||||||
|
break;
|
||||||
|
case AlreadyGrabbed:
|
||||||
|
s = "already grabbed";
|
||||||
|
break;
|
||||||
|
case GrabFrozen:
|
||||||
|
s = "grab frozen";
|
||||||
|
break;
|
||||||
|
case GrabInvalidTime:
|
||||||
|
s = "invalid time";
|
||||||
|
break;
|
||||||
|
case GrabSuccess:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "9wm: %s: grab error: %d\n", f, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "9wm: %s: grab error: %s\n", f, s);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_EV
|
||||||
|
#include "showevent/ShowEvent.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
void
|
||||||
|
dotrace(char *s, Client *c, XEvent *e)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "9wm: %s: c=0x%x", s, c);
|
||||||
|
if (c)
|
||||||
|
fprintf(stderr, " x %d y %d dx %d dy %d w 0x%x parent 0x%x", c->x, c->y, c->dx, c->dy, c->window, c->parent);
|
||||||
|
#ifdef DEBUG_EV
|
||||||
|
if (e) {
|
||||||
|
fprintf(stderr, "\n\t");
|
||||||
|
ShowEvent(e);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
465
src/cmd/rio/event.c
Normal file
465
src/cmd/rio/event.c
Normal file
|
|
@ -0,0 +1,465 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xos.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "patchlevel.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
mainloop(int shape_event)
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
getevent(&ev);
|
||||||
|
|
||||||
|
#ifdef DEBUG_EV
|
||||||
|
if (debug) {
|
||||||
|
ShowEvent(&ev);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
switch (ev.type) {
|
||||||
|
default:
|
||||||
|
#ifdef SHAPE
|
||||||
|
if (shape && ev.type == shape_event)
|
||||||
|
shapenotify((XShapeEvent *)&ev);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "9wm: unknown ev.type %d\n", ev.type);
|
||||||
|
break;
|
||||||
|
case ButtonPress:
|
||||||
|
button(&ev.xbutton);
|
||||||
|
break;
|
||||||
|
case ButtonRelease:
|
||||||
|
break;
|
||||||
|
case MapRequest:
|
||||||
|
mapreq(&ev.xmaprequest);
|
||||||
|
break;
|
||||||
|
case ConfigureRequest:
|
||||||
|
configurereq(&ev.xconfigurerequest);
|
||||||
|
break;
|
||||||
|
case CirculateRequest:
|
||||||
|
circulatereq(&ev.xcirculaterequest);
|
||||||
|
break;
|
||||||
|
case UnmapNotify:
|
||||||
|
unmap(&ev.xunmap);
|
||||||
|
break;
|
||||||
|
case CreateNotify:
|
||||||
|
newwindow(&ev.xcreatewindow);
|
||||||
|
break;
|
||||||
|
case DestroyNotify:
|
||||||
|
destroy(ev.xdestroywindow.window);
|
||||||
|
break;
|
||||||
|
case ClientMessage:
|
||||||
|
clientmesg(&ev.xclient);
|
||||||
|
break;
|
||||||
|
case ColormapNotify:
|
||||||
|
cmap(&ev.xcolormap);
|
||||||
|
break;
|
||||||
|
case PropertyNotify:
|
||||||
|
property(&ev.xproperty);
|
||||||
|
break;
|
||||||
|
case SelectionClear:
|
||||||
|
fprintf(stderr, "9wm: SelectionClear (this should not happen)\n");
|
||||||
|
break;
|
||||||
|
case SelectionNotify:
|
||||||
|
fprintf(stderr, "9wm: SelectionNotify (this should not happen)\n");
|
||||||
|
break;
|
||||||
|
case SelectionRequest:
|
||||||
|
fprintf(stderr, "9wm: SelectionRequest (this should not happen)\n");
|
||||||
|
break;
|
||||||
|
case EnterNotify:
|
||||||
|
enter(&ev.xcrossing);
|
||||||
|
break;
|
||||||
|
case ReparentNotify:
|
||||||
|
reparent(&ev.xreparent);
|
||||||
|
break;
|
||||||
|
case FocusIn:
|
||||||
|
focusin(&ev.xfocus);
|
||||||
|
break;
|
||||||
|
case MotionNotify:
|
||||||
|
case Expose:
|
||||||
|
case NoExpose:
|
||||||
|
case FocusOut:
|
||||||
|
case ConfigureNotify:
|
||||||
|
case MapNotify:
|
||||||
|
case MappingNotify:
|
||||||
|
/* not interested */
|
||||||
|
trace("ignore", 0, &ev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
configurereq(XConfigureRequestEvent *e)
|
||||||
|
{
|
||||||
|
XWindowChanges wc;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
/* we don't set curtime as nothing here uses it */
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
trace("configurereq", c, e);
|
||||||
|
|
||||||
|
e->value_mask &= ~CWSibling;
|
||||||
|
|
||||||
|
if (c) {
|
||||||
|
gravitate(c, 1);
|
||||||
|
if (e->value_mask & CWX)
|
||||||
|
c->x = e->x;
|
||||||
|
if (e->value_mask & CWY)
|
||||||
|
c->y = e->y;
|
||||||
|
if (e->value_mask & CWWidth)
|
||||||
|
c->dx = e->width;
|
||||||
|
if (e->value_mask & CWHeight)
|
||||||
|
c->dy = e->height;
|
||||||
|
if (e->value_mask & CWBorderWidth)
|
||||||
|
c->border = e->border_width;
|
||||||
|
gravitate(c, 0);
|
||||||
|
if (e->value_mask & CWStackMode) {
|
||||||
|
if (wc.stack_mode == Above)
|
||||||
|
top(c);
|
||||||
|
else
|
||||||
|
e->value_mask &= ~CWStackMode;
|
||||||
|
}
|
||||||
|
if (c->parent != c->screen->root && c->window == e->window) {
|
||||||
|
wc.x = c->x-BORDER;
|
||||||
|
wc.y = c->y-BORDER;
|
||||||
|
wc.width = c->dx+2*BORDER;
|
||||||
|
wc.height = c->dy+2*BORDER;
|
||||||
|
wc.border_width = 1;
|
||||||
|
wc.sibling = None;
|
||||||
|
wc.stack_mode = e->detail;
|
||||||
|
XConfigureWindow(dpy, c->parent, e->value_mask, &wc);
|
||||||
|
sendconfig(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c && c->init) {
|
||||||
|
wc.x = BORDER;
|
||||||
|
wc.y = BORDER;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wc.x = e->x;
|
||||||
|
wc.y = e->y;
|
||||||
|
}
|
||||||
|
wc.width = e->width;
|
||||||
|
wc.height = e->height;
|
||||||
|
wc.border_width = 0;
|
||||||
|
wc.sibling = None;
|
||||||
|
wc.stack_mode = Above;
|
||||||
|
e->value_mask &= ~CWStackMode;
|
||||||
|
e->value_mask |= CWBorderWidth;
|
||||||
|
|
||||||
|
XConfigureWindow(dpy, e->window, e->value_mask, &wc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mapreq(XMapRequestEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
curtime = CurrentTime;
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
trace("mapreq", c, e);
|
||||||
|
|
||||||
|
if (c == 0 || c->window != e->window) {
|
||||||
|
/* workaround for stupid NCDware */
|
||||||
|
fprintf(stderr, "9wm: bad mapreq c %x w %x, rescanning\n",
|
||||||
|
c, e->window);
|
||||||
|
for (i = 0; i < num_screens; i++)
|
||||||
|
scanwins(&screens[i]);
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (c == 0 || c->window != e->window) {
|
||||||
|
fprintf(stderr, "9wm: window not found after rescan\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (c->state) {
|
||||||
|
case WithdrawnState:
|
||||||
|
if (c->parent == c->screen->root) {
|
||||||
|
if (!manage(c, 0))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
XReparentWindow(dpy, c->window, c->parent, BORDER-1, BORDER-1);
|
||||||
|
XAddToSaveSet(dpy, c->window);
|
||||||
|
/* fall through... */
|
||||||
|
case NormalState:
|
||||||
|
XMapWindow(dpy, c->window);
|
||||||
|
XMapRaised(dpy, c->parent);
|
||||||
|
top(c);
|
||||||
|
setstate(c, NormalState);
|
||||||
|
if (c->trans != None && current && c->trans == current->window)
|
||||||
|
active(c);
|
||||||
|
break;
|
||||||
|
case IconicState:
|
||||||
|
unhidec(c, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unmap(XUnmapEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
curtime = CurrentTime;
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (c) {
|
||||||
|
switch (c->state) {
|
||||||
|
case IconicState:
|
||||||
|
if (e->send_event) {
|
||||||
|
unhidec(c, 0);
|
||||||
|
withdraw(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NormalState:
|
||||||
|
if (c == current)
|
||||||
|
nofocus();
|
||||||
|
if (!c->reparenting)
|
||||||
|
withdraw(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c->reparenting = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
circulatereq(XCirculateRequestEvent *e)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "It must be the warlock Krill!\n"); /* ☺ */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
newwindow(XCreateWindowEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
ScreenInfo *s;
|
||||||
|
|
||||||
|
/* we don't set curtime as nothing here uses it */
|
||||||
|
if (e->override_redirect)
|
||||||
|
return;
|
||||||
|
c = getclient(e->window, 1);
|
||||||
|
if (c && c->window == e->window && (s = getscreen(e->parent))) {
|
||||||
|
c->x = e->x;
|
||||||
|
c->y = e->y;
|
||||||
|
c->dx = e->width;
|
||||||
|
c->dy = e->height;
|
||||||
|
c->border = e->border_width;
|
||||||
|
c->screen = s;
|
||||||
|
if (c->parent == None)
|
||||||
|
c->parent = c->screen->root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
destroy(Window w)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
curtime = CurrentTime;
|
||||||
|
c = getclient(w, 0);
|
||||||
|
if (c == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rmclient(c);
|
||||||
|
|
||||||
|
/* flush any errors generated by the window's sudden demise */
|
||||||
|
ignore_badwindow = 1;
|
||||||
|
XSync(dpy, False);
|
||||||
|
ignore_badwindow = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clientmesg(XClientMessageEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
curtime = CurrentTime;
|
||||||
|
if (e->message_type == exit_9wm) {
|
||||||
|
cleanup();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
if (e->message_type == restart_9wm) {
|
||||||
|
fprintf(stderr, "*** 9wm restarting ***\n");
|
||||||
|
cleanup();
|
||||||
|
execvp(myargv[0], myargv);
|
||||||
|
perror("9wm: exec failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (e->message_type == wm_change_state) {
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (e->format == 32 && e->data.l[0] == IconicState && c != 0) {
|
||||||
|
if (normal(c))
|
||||||
|
hide(c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf(stderr, "9wm: WM_CHANGE_STATE: format %d data %d w 0x%x\n",
|
||||||
|
e->format, e->data.l[0], e->window);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "9wm: strange ClientMessage, type 0x%x window 0x%x\n",
|
||||||
|
e->message_type, e->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmap(XColormapEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* we don't set curtime as nothing here uses it */
|
||||||
|
if (e->new) {
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (c) {
|
||||||
|
c->cmap = e->colormap;
|
||||||
|
if (c == current)
|
||||||
|
cmapfocus(c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (c = clients; c; c = c->next) {
|
||||||
|
for (i = 0; i < c->ncmapwins; i++)
|
||||||
|
if (c->cmapwins[i] == e->window) {
|
||||||
|
c->wmcmaps[i] = e->colormap;
|
||||||
|
if (c == current)
|
||||||
|
cmapfocus(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
property(XPropertyEvent *e)
|
||||||
|
{
|
||||||
|
Atom a;
|
||||||
|
int delete;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
/* we don't set curtime as nothing here uses it */
|
||||||
|
a = e->atom;
|
||||||
|
delete = (e->state == PropertyDelete);
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (c == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (a) {
|
||||||
|
case XA_WM_ICON_NAME:
|
||||||
|
if (c->iconname != 0)
|
||||||
|
XFree((char*) c->iconname);
|
||||||
|
c->iconname = delete ? 0 : getprop(c->window, a);
|
||||||
|
setlabel(c);
|
||||||
|
renamec(c, c->label);
|
||||||
|
return;
|
||||||
|
case XA_WM_NAME:
|
||||||
|
if (c->name != 0)
|
||||||
|
XFree((char*) c->name);
|
||||||
|
c->name = delete ? 0 : getprop(c->window, a);
|
||||||
|
setlabel(c);
|
||||||
|
renamec(c, c->label);
|
||||||
|
return;
|
||||||
|
case XA_WM_TRANSIENT_FOR:
|
||||||
|
gettrans(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (a == _9wm_hold_mode) {
|
||||||
|
c->hold = getiprop(c->window, _9wm_hold_mode);
|
||||||
|
if (c == current)
|
||||||
|
draw_border(c, 1);
|
||||||
|
}
|
||||||
|
else if (a == wm_colormaps) {
|
||||||
|
getcmaps(c);
|
||||||
|
if (c == current)
|
||||||
|
cmapfocus(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
reparent(XReparentEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
XWindowAttributes attr;
|
||||||
|
ScreenInfo *s;
|
||||||
|
|
||||||
|
/* we don't set curtime as nothing here uses it */
|
||||||
|
if (!getscreen(e->event) || e->override_redirect)
|
||||||
|
return;
|
||||||
|
if ((s = getscreen(e->parent)) != 0) {
|
||||||
|
c = getclient(e->window, 1);
|
||||||
|
if (c != 0 && (c->dx == 0 || c->dy == 0)) {
|
||||||
|
XGetWindowAttributes(dpy, c->window, &attr);
|
||||||
|
c->x = attr.x;
|
||||||
|
c->y = attr.y;
|
||||||
|
c->dx = attr.width;
|
||||||
|
c->dy = attr.height;
|
||||||
|
c->border = attr.border_width;
|
||||||
|
c->screen = s;
|
||||||
|
if (c->parent == None)
|
||||||
|
c->parent = c->screen->root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (c != 0 && (c->parent == c->screen->root || withdrawn(c)))
|
||||||
|
rmclient(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SHAPE
|
||||||
|
void
|
||||||
|
shapenotify(XShapeEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
/* we don't set curtime as nothing here uses it */
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (c == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setshape(c);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
enter(XCrossingEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
curtime = e->time;
|
||||||
|
if (e->mode != NotifyGrab || e->detail != NotifyNonlinearVirtual)
|
||||||
|
return;
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (c != 0 && c != current) {
|
||||||
|
/* someone grabbed the pointer; make them current */
|
||||||
|
XMapRaised(dpy, c->parent);
|
||||||
|
top(c);
|
||||||
|
active(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
focusin(XFocusChangeEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
curtime = CurrentTime;
|
||||||
|
if (e->detail != NotifyNonlinearVirtual)
|
||||||
|
return;
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (c != 0 && c->window == e->window && c != current) {
|
||||||
|
/* someone grabbed keyboard or seized focus; make them current */
|
||||||
|
XMapRaised(dpy, c->parent);
|
||||||
|
top(c);
|
||||||
|
active(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
96
src/cmd/rio/fns.h
Normal file
96
src/cmd/rio/fns.h
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define trace(s, c, e) dotrace((s), (c), (e))
|
||||||
|
#else
|
||||||
|
#define trace(s, c, e)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* color.c */
|
||||||
|
unsigned long colorpixel(Display*, int, unsigned long);
|
||||||
|
|
||||||
|
/* main.c */
|
||||||
|
void usage();
|
||||||
|
void initscreen();
|
||||||
|
ScreenInfo *getscreen();
|
||||||
|
Time timestamp();
|
||||||
|
void sendcmessage();
|
||||||
|
void sendconfig();
|
||||||
|
void sighandler();
|
||||||
|
void getevent();
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
/* event.c */
|
||||||
|
void mainloop();
|
||||||
|
void configurereq();
|
||||||
|
void mapreq();
|
||||||
|
void circulatereq();
|
||||||
|
void unmap();
|
||||||
|
void newwindow();
|
||||||
|
void destroy();
|
||||||
|
void clientmesg();
|
||||||
|
void cmap();
|
||||||
|
void property();
|
||||||
|
void shapenotify();
|
||||||
|
void enter();
|
||||||
|
void focusin();
|
||||||
|
void reparent();
|
||||||
|
|
||||||
|
/* manage.c */
|
||||||
|
int manage();
|
||||||
|
void scanwins();
|
||||||
|
void setshape();
|
||||||
|
void withdraw();
|
||||||
|
void gravitate();
|
||||||
|
void cmapfocus();
|
||||||
|
void cmapnofocus();
|
||||||
|
void getcmaps();
|
||||||
|
int _getprop();
|
||||||
|
char *getprop();
|
||||||
|
Window getwprop();
|
||||||
|
int getiprop();
|
||||||
|
int getstate();
|
||||||
|
void setstate();
|
||||||
|
void setlabel();
|
||||||
|
void getproto();
|
||||||
|
void gettrans();
|
||||||
|
|
||||||
|
/* menu.c */
|
||||||
|
void button();
|
||||||
|
void spawn();
|
||||||
|
void reshape();
|
||||||
|
void move();
|
||||||
|
void delete();
|
||||||
|
void hide();
|
||||||
|
void unhide();
|
||||||
|
void unhidec();
|
||||||
|
void renamec();
|
||||||
|
|
||||||
|
/* client.c */
|
||||||
|
void setactive();
|
||||||
|
void draw_border();
|
||||||
|
void active();
|
||||||
|
void nofocus();
|
||||||
|
void top();
|
||||||
|
Client *getclient();
|
||||||
|
void rmclient();
|
||||||
|
void dump_revert();
|
||||||
|
void dump_clients();
|
||||||
|
|
||||||
|
/* grab.c */
|
||||||
|
int menuhit();
|
||||||
|
Client *selectwin();
|
||||||
|
int sweep();
|
||||||
|
int drag();
|
||||||
|
void getmouse();
|
||||||
|
void setmouse();
|
||||||
|
|
||||||
|
/* error.c */
|
||||||
|
int handler();
|
||||||
|
void fatal();
|
||||||
|
void graberror();
|
||||||
|
void showhints();
|
||||||
|
void dotrace();
|
||||||
|
|
||||||
|
/* cursor.c */
|
||||||
|
void initcurs();
|
||||||
498
src/cmd/rio/grab.c
Normal file
498
src/cmd/rio/grab.c
Normal file
|
|
@ -0,0 +1,498 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xos.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
nobuttons(XButtonEvent *e) /* Einstuerzende */
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
|
||||||
|
state = (e->state & AllButtonMask);
|
||||||
|
return (e->type == ButtonRelease) && (state & (state - 1)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
grab(Window w, Window constrain, int mask, Cursor curs, int t)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (t == 0)
|
||||||
|
t = timestamp();
|
||||||
|
status = XGrabPointer(dpy, w, False, mask,
|
||||||
|
GrabModeAsync, GrabModeAsync, constrain, curs, t);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ungrab(XButtonEvent *e)
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
if (!nobuttons(e))
|
||||||
|
for (;;) {
|
||||||
|
XMaskEvent(dpy, ButtonMask | ButtonMotionMask, &ev);
|
||||||
|
if (ev.type == MotionNotify)
|
||||||
|
continue;
|
||||||
|
e = &ev.xbutton;
|
||||||
|
if (nobuttons(e))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
XUngrabPointer(dpy, e->time);
|
||||||
|
curtime = e->time;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drawstring(Display *dpy, ScreenInfo *s, Menu *m, int wide, int high, int i, int selected)
|
||||||
|
{
|
||||||
|
int tx, ty;
|
||||||
|
|
||||||
|
tx = (wide - XTextWidth(font, m->item[i], strlen(m->item[i])))/2;
|
||||||
|
ty = i*high + font->ascent + 1;
|
||||||
|
XFillRectangle(dpy, s->menuwin, selected ? s->gcmenubgs : s->gcmenubg, 0, i*high, wide, high);
|
||||||
|
XDrawString(dpy, s->menuwin, selected ? s->gcmenufgs : s->gcmenufg, tx, ty, m->item[i], strlen(m->item[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
menuhit(XButtonEvent *e, Menu *m)
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
int i, n, cur, old, wide, high, status, drawn, warp;
|
||||||
|
int x, y, dx, dy, xmax, ymax;
|
||||||
|
int tx, ty;
|
||||||
|
ScreenInfo *s;
|
||||||
|
|
||||||
|
if (font == 0)
|
||||||
|
return -1;
|
||||||
|
s = getscreen(e->root);
|
||||||
|
if (s == 0 || e->window == s->menuwin) /* ugly event mangling */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
dx = 0;
|
||||||
|
for (n = 0; m->item[n]; n++) {
|
||||||
|
wide = XTextWidth(font, m->item[n], strlen(m->item[n])) + 4;
|
||||||
|
if (wide > dx)
|
||||||
|
dx = wide;
|
||||||
|
}
|
||||||
|
wide = dx;
|
||||||
|
cur = m->lasthit;
|
||||||
|
if (cur >= n)
|
||||||
|
cur = n - 1;
|
||||||
|
|
||||||
|
high = font->ascent + font->descent + 1;
|
||||||
|
dy = n*high;
|
||||||
|
x = e->x - wide/2;
|
||||||
|
y = e->y - cur*high - high/2;
|
||||||
|
warp = 0;
|
||||||
|
xmax = DisplayWidth(dpy, s->num);
|
||||||
|
ymax = DisplayHeight(dpy, s->num);
|
||||||
|
if (x < 0) {
|
||||||
|
e->x -= x;
|
||||||
|
x = 0;
|
||||||
|
warp++;
|
||||||
|
}
|
||||||
|
if (x+wide >= xmax) {
|
||||||
|
e->x -= x+wide-xmax;
|
||||||
|
x = xmax-wide;
|
||||||
|
warp++;
|
||||||
|
}
|
||||||
|
if (y < 0) {
|
||||||
|
e->y -= y;
|
||||||
|
y = 0;
|
||||||
|
warp++;
|
||||||
|
}
|
||||||
|
if (y+dy >= ymax) {
|
||||||
|
e->y -= y+dy-ymax;
|
||||||
|
y = ymax-dy;
|
||||||
|
warp++;
|
||||||
|
}
|
||||||
|
if (warp)
|
||||||
|
setmouse(e->x, e->y, s);
|
||||||
|
XMoveResizeWindow(dpy, s->menuwin, x, y, dx, dy);
|
||||||
|
XSelectInput(dpy, s->menuwin, MenuMask);
|
||||||
|
XMapRaised(dpy, s->menuwin);
|
||||||
|
status = grab(s->menuwin, None, MenuGrabMask, None, e->time);
|
||||||
|
if (status != GrabSuccess) {
|
||||||
|
/* graberror("menuhit", status); */
|
||||||
|
XUnmapWindow(dpy, s->menuwin);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
drawn = 0;
|
||||||
|
for (;;) {
|
||||||
|
XMaskEvent(dpy, MenuMask, &ev);
|
||||||
|
switch (ev.type) {
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "9wm: menuhit: unknown ev.type %d\n", ev.type);
|
||||||
|
break;
|
||||||
|
case ButtonPress:
|
||||||
|
break;
|
||||||
|
case ButtonRelease:
|
||||||
|
if (ev.xbutton.button != e->button)
|
||||||
|
break;
|
||||||
|
x = ev.xbutton.x;
|
||||||
|
y = ev.xbutton.y;
|
||||||
|
i = y/high;
|
||||||
|
if (cur >= 0 && y >= cur*high-3 && y < (cur+1)*high+3)
|
||||||
|
i = cur;
|
||||||
|
if (x < 0 || x > wide || y < -3)
|
||||||
|
i = -1;
|
||||||
|
else if (i < 0 || i >= n)
|
||||||
|
i = -1;
|
||||||
|
else
|
||||||
|
m->lasthit = i;
|
||||||
|
if (!nobuttons(&ev.xbutton))
|
||||||
|
i = -1;
|
||||||
|
ungrab(&ev.xbutton);
|
||||||
|
XUnmapWindow(dpy, s->menuwin);
|
||||||
|
return i;
|
||||||
|
case MotionNotify:
|
||||||
|
if (!drawn)
|
||||||
|
break;
|
||||||
|
x = ev.xbutton.x;
|
||||||
|
y = ev.xbutton.y;
|
||||||
|
old = cur;
|
||||||
|
cur = y/high;
|
||||||
|
if (old >= 0 && y >= old*high-3 && y < (old+1)*high+3)
|
||||||
|
cur = old;
|
||||||
|
if (x < 0 || x > wide || y < -3)
|
||||||
|
cur = -1;
|
||||||
|
else if (cur < 0 || cur >= n)
|
||||||
|
cur = -1;
|
||||||
|
if (cur == old)
|
||||||
|
break;
|
||||||
|
if (old >= 0 && old < n)
|
||||||
|
drawstring(dpy, s, m, wide, high, old, 0);
|
||||||
|
if (cur >= 0 && cur < n)
|
||||||
|
drawstring(dpy, s, m, wide, high, cur, 1);
|
||||||
|
break;
|
||||||
|
case Expose:
|
||||||
|
XClearWindow(dpy, s->menuwin);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
drawstring(dpy, s, m, wide, high, i, cur==i);
|
||||||
|
drawn = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Client *
|
||||||
|
selectwin(int release, int *shift, ScreenInfo *s)
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
XButtonEvent *e;
|
||||||
|
int status;
|
||||||
|
Window w;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
status = grab(s->root, s->root, ButtonMask, s->target, 0);
|
||||||
|
if (status != GrabSuccess) {
|
||||||
|
graberror("selectwin", status); /* */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
w = None;
|
||||||
|
for (;;) {
|
||||||
|
XMaskEvent(dpy, ButtonMask, &ev);
|
||||||
|
e = &ev.xbutton;
|
||||||
|
switch (ev.type) {
|
||||||
|
case ButtonPress:
|
||||||
|
if (e->button != Button3) {
|
||||||
|
ungrab(e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
w = e->subwindow;
|
||||||
|
if (!release) {
|
||||||
|
c = getclient(w, 0);
|
||||||
|
if (c == 0)
|
||||||
|
ungrab(e);
|
||||||
|
if (shift != 0)
|
||||||
|
*shift = (e->state&ShiftMask) != 0;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ButtonRelease:
|
||||||
|
ungrab(e);
|
||||||
|
if (e->button != Button3 || e->subwindow != w)
|
||||||
|
return 0;
|
||||||
|
if (shift != 0)
|
||||||
|
*shift = (e->state&ShiftMask) != 0;
|
||||||
|
return getclient(w, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sweepcalc(Client *c, int x, int y)
|
||||||
|
{
|
||||||
|
int dx, dy, sx, sy;
|
||||||
|
|
||||||
|
dx = x - c->x;
|
||||||
|
dy = y - c->y;
|
||||||
|
sx = sy = 1;
|
||||||
|
if (dx < 0) {
|
||||||
|
dx = -dx;
|
||||||
|
sx = -1;
|
||||||
|
}
|
||||||
|
if (dy < 0) {
|
||||||
|
dy = -dy;
|
||||||
|
sy = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dx -= 2*BORDER;
|
||||||
|
dy -= 2*BORDER;
|
||||||
|
|
||||||
|
if (!c->is9term) {
|
||||||
|
if (dx < c->min_dx)
|
||||||
|
dx = c->min_dx;
|
||||||
|
if (dy < c->min_dy)
|
||||||
|
dy = c->min_dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->size.flags & PResizeInc) {
|
||||||
|
dx = c->min_dx + (dx-c->min_dx)/c->size.width_inc*c->size.width_inc;
|
||||||
|
dy = c->min_dy + (dy-c->min_dy)/c->size.height_inc*c->size.height_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->size.flags & PMaxSize) {
|
||||||
|
if (dx > c->size.max_width)
|
||||||
|
dx = c->size.max_width;
|
||||||
|
if (dy > c->size.max_height)
|
||||||
|
dy = c->size.max_height;
|
||||||
|
}
|
||||||
|
c->dx = sx*(dx + 2*BORDER);
|
||||||
|
c->dy = sy*(dy + 2*BORDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dragcalc(Client *c, int x, int y)
|
||||||
|
{
|
||||||
|
c->x = x;
|
||||||
|
c->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xcopy(int fwd, Display *dpy, Drawable src, Drawable dst, GC gc, int x, int y, int dx, int dy, int x1, int y1)
|
||||||
|
{
|
||||||
|
if(fwd)
|
||||||
|
XCopyArea(dpy, src, dst, gc, x, y, dx, dy, x1, y1);
|
||||||
|
else
|
||||||
|
XCopyArea(dpy, dst, src, gc, x1, y1, dx, dy, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drawbound(Client *c, int drawing)
|
||||||
|
{
|
||||||
|
int x, y, dx, dy;
|
||||||
|
ScreenInfo *s;
|
||||||
|
|
||||||
|
s = c->screen;
|
||||||
|
x = c->x;
|
||||||
|
y = c->y;
|
||||||
|
dx = c->dx;
|
||||||
|
dy = c->dy;
|
||||||
|
if (dx < 0) {
|
||||||
|
x += dx;
|
||||||
|
dx = -dx;
|
||||||
|
}
|
||||||
|
if (dy < 0) {
|
||||||
|
y += dy;
|
||||||
|
dy = -dy;
|
||||||
|
}
|
||||||
|
if (dx <= 2 || dy <= 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(solidsweep){
|
||||||
|
if(drawing == -1){
|
||||||
|
XUnmapWindow(dpy, s->sweepwin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
x += BORDER;
|
||||||
|
y += BORDER;
|
||||||
|
dx -= 2*BORDER;
|
||||||
|
dy -= 2*BORDER;
|
||||||
|
|
||||||
|
if(drawing){
|
||||||
|
XMoveResizeWindow(dpy, s->sweepwin, x, y, dx, dy);
|
||||||
|
XSelectInput(dpy, s->sweepwin, MenuMask);
|
||||||
|
XMapRaised(dpy, s->sweepwin);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(drawing == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xcopy(drawing, dpy, s->root, s->bkup[0], s->gccopy, x, y, dx, BORDER, 0, 0);
|
||||||
|
xcopy(drawing, dpy, s->root, s->bkup[0], s->gccopy, x, y+dy-BORDER, dx, BORDER, dx, 0);
|
||||||
|
xcopy(drawing, dpy, s->root, s->bkup[1], s->gccopy, x, y, BORDER, dy, 0, 0);
|
||||||
|
xcopy(drawing, dpy, s->root, s->bkup[1], s->gccopy, x+dx-BORDER, y, BORDER, dy, 0, dy);
|
||||||
|
|
||||||
|
if(drawing){
|
||||||
|
XFillRectangle(dpy, s->root, s->gcred, x, y, dx, BORDER);
|
||||||
|
XFillRectangle(dpy, s->root, s->gcred, x, y+dy-BORDER, dx, BORDER);
|
||||||
|
XFillRectangle(dpy, s->root, s->gcred, x, y, BORDER, dy);
|
||||||
|
XFillRectangle(dpy, s->root, s->gcred, x+dx-BORDER, y, BORDER, dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
misleep(int msec)
|
||||||
|
{
|
||||||
|
struct timeval t;
|
||||||
|
|
||||||
|
t.tv_sec = msec/1000;
|
||||||
|
t.tv_usec = (msec%1000)*1000;
|
||||||
|
select(0, 0, 0, 0, &t);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sweepdrag(Client *c, XButtonEvent *e0, void (*recalc)(Client*, int, int))
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
int idle;
|
||||||
|
int cx, cy, rx, ry;
|
||||||
|
int ox, oy, odx, ody;
|
||||||
|
XButtonEvent *e;
|
||||||
|
|
||||||
|
ox = c->x;
|
||||||
|
oy = c->y;
|
||||||
|
odx = c->dx;
|
||||||
|
ody = c->dy;
|
||||||
|
c->x -= BORDER;
|
||||||
|
c->y -= BORDER;
|
||||||
|
c->dx += 2*BORDER;
|
||||||
|
c->dy += 2*BORDER;
|
||||||
|
if (e0) {
|
||||||
|
c->x = cx = e0->x;
|
||||||
|
c->y = cy = e0->y;
|
||||||
|
recalc(c, e0->x, e0->y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
getmouse(&cx, &cy, c->screen);
|
||||||
|
XGrabServer(dpy);
|
||||||
|
drawbound(c, 1);
|
||||||
|
idle = 0;
|
||||||
|
for (;;) {
|
||||||
|
if (XCheckMaskEvent(dpy, ButtonMask, &ev) == 0) {
|
||||||
|
getmouse(&rx, &ry, c->screen);
|
||||||
|
if (rx != cx || ry != cy || ++idle > 300) {
|
||||||
|
drawbound(c, 0);
|
||||||
|
if (rx == cx && ry == cy) {
|
||||||
|
XUngrabServer(dpy);
|
||||||
|
XFlush(dpy);
|
||||||
|
misleep(500);
|
||||||
|
XGrabServer(dpy);
|
||||||
|
idle = 0;
|
||||||
|
}
|
||||||
|
recalc(c, rx, ry);
|
||||||
|
cx = rx;
|
||||||
|
cy = ry;
|
||||||
|
drawbound(c, 1);
|
||||||
|
XFlush(dpy);
|
||||||
|
}
|
||||||
|
misleep(50);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
e = &ev.xbutton;
|
||||||
|
switch (ev.type) {
|
||||||
|
case ButtonPress:
|
||||||
|
case ButtonRelease:
|
||||||
|
drawbound(c, 0);
|
||||||
|
ungrab(e);
|
||||||
|
XUngrabServer(dpy);
|
||||||
|
if (e->button != Button3 && c->init)
|
||||||
|
goto bad;
|
||||||
|
recalc(c, ev.xbutton.x, ev.xbutton.y);
|
||||||
|
if (c->dx < 0) {
|
||||||
|
c->x += c->dx;
|
||||||
|
c->dx = -c->dx;
|
||||||
|
}
|
||||||
|
if (c->dy < 0) {
|
||||||
|
c->y += c->dy;
|
||||||
|
c->dy = -c->dy;
|
||||||
|
}
|
||||||
|
c->x += BORDER;
|
||||||
|
c->y += BORDER;
|
||||||
|
c->dx -= 2*BORDER;
|
||||||
|
c->dy -= 2*BORDER;
|
||||||
|
if (c->dx < 4 || c->dy < 4 || c->dx < c->min_dx || c->dy < c->min_dy)
|
||||||
|
goto bad;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bad:
|
||||||
|
c->x = ox;
|
||||||
|
c->y = oy;
|
||||||
|
c->dx = odx;
|
||||||
|
c->dy = ody;
|
||||||
|
drawbound(c, -1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sweep(Client *c)
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
int status;
|
||||||
|
XButtonEvent *e;
|
||||||
|
ScreenInfo *s;
|
||||||
|
|
||||||
|
s = c->screen;
|
||||||
|
status = grab(s->root, s->root, ButtonMask, s->sweep0, 0);
|
||||||
|
if (status != GrabSuccess) {
|
||||||
|
graberror("sweep", status); /* */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMaskEvent(dpy, ButtonMask, &ev);
|
||||||
|
e = &ev.xbutton;
|
||||||
|
if (e->button != Button3) {
|
||||||
|
ungrab(e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (c->size.flags & (PMinSize|PBaseSize))
|
||||||
|
setmouse(e->x+c->min_dx, e->y+c->min_dy, s);
|
||||||
|
XChangeActivePointerGrab(dpy, ButtonMask, s->boxcurs, e->time);
|
||||||
|
return sweepdrag(c, e, sweepcalc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
drag(Client *c)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
ScreenInfo *s;
|
||||||
|
|
||||||
|
s = c->screen;
|
||||||
|
if (c->init)
|
||||||
|
setmouse(c->x-BORDER, c->y-BORDER, s);
|
||||||
|
else {
|
||||||
|
getmouse(&c->x, &c->y, s); /* start at current mouse pos */
|
||||||
|
c->x += BORDER;
|
||||||
|
c->y += BORDER;
|
||||||
|
}
|
||||||
|
status = grab(s->root, s->root, ButtonMask, s->boxcurs, 0);
|
||||||
|
if (status != GrabSuccess) {
|
||||||
|
graberror("drag", status); /* */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sweepdrag(c, 0, dragcalc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getmouse(int *x, int *y, ScreenInfo *s)
|
||||||
|
{
|
||||||
|
Window dw1, dw2;
|
||||||
|
int t1, t2;
|
||||||
|
unsigned int t3;
|
||||||
|
|
||||||
|
XQueryPointer(dpy, s->root, &dw1, &dw2, x, y, &t1, &t2, &t3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setmouse(int x, int y, ScreenInfo *s)
|
||||||
|
{
|
||||||
|
XWarpPointer(dpy, None, s->root, None, None, None, None, x, y);
|
||||||
|
}
|
||||||
437
src/cmd/rio/main.c
Normal file
437
src/cmd/rio/main.c
Normal file
|
|
@ -0,0 +1,437 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xos.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
#include "patchlevel.h"
|
||||||
|
|
||||||
|
char *version[] =
|
||||||
|
{
|
||||||
|
"rio version 1.0, Copyright (c) 1994-1996 David Hogan, (c) 2004 Russ Cox", 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
Display *dpy;
|
||||||
|
ScreenInfo *screens;
|
||||||
|
int initting;
|
||||||
|
XFontStruct *font;
|
||||||
|
int nostalgia;
|
||||||
|
char **myargv;
|
||||||
|
char *termprog;
|
||||||
|
char *shell;
|
||||||
|
Bool shape;
|
||||||
|
int _border = 4;
|
||||||
|
int _inset = 1;
|
||||||
|
int curtime;
|
||||||
|
int debug;
|
||||||
|
int signalled;
|
||||||
|
int num_screens;
|
||||||
|
int solidsweep = 0;
|
||||||
|
|
||||||
|
Atom exit_9wm;
|
||||||
|
Atom restart_9wm;
|
||||||
|
Atom wm_state;
|
||||||
|
Atom wm_change_state;
|
||||||
|
Atom wm_protocols;
|
||||||
|
Atom wm_delete;
|
||||||
|
Atom wm_take_focus;
|
||||||
|
Atom wm_colormaps;
|
||||||
|
Atom _9wm_running;
|
||||||
|
Atom _9wm_hold_mode;
|
||||||
|
|
||||||
|
char *fontlist[] = {
|
||||||
|
"lucm.latin1.9",
|
||||||
|
"blit",
|
||||||
|
"lucidasanstypewriter-bold-10",
|
||||||
|
"9x15bold",
|
||||||
|
"fixed",
|
||||||
|
"*",
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: rio [-grey] [-version] [-font fname] [-term prog] [exit|restart]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i, background, do_exit, do_restart;
|
||||||
|
char *fname;
|
||||||
|
int shape_event, dummy;
|
||||||
|
|
||||||
|
myargv = argv; /* for restart */
|
||||||
|
|
||||||
|
do_exit = do_restart = 0;
|
||||||
|
background = 1;
|
||||||
|
font = 0;
|
||||||
|
fname = 0;
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
if (strcmp(argv[i], "-nostalgia") == 0)
|
||||||
|
nostalgia++;
|
||||||
|
else if (strcmp(argv[i], "-grey") == 0)
|
||||||
|
background = 1;
|
||||||
|
else if (strcmp(argv[i], "-debug") == 0)
|
||||||
|
debug++;
|
||||||
|
else if (strcmp(argv[i], "-font") == 0 && i+1<argc) {
|
||||||
|
i++;
|
||||||
|
fname = argv[i];
|
||||||
|
}
|
||||||
|
else if (strcmp(argv[i], "-term") == 0 && i+1<argc)
|
||||||
|
termprog = argv[++i];
|
||||||
|
else if (strcmp(argv[i], "-version") == 0) {
|
||||||
|
fprintf(stderr, "%s", version[0]);
|
||||||
|
if (PATCHLEVEL > 0)
|
||||||
|
fprintf(stderr, "; patch level %d", PATCHLEVEL);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else if (argv[i][0] == '-')
|
||||||
|
usage();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
for (; i < argc; i++)
|
||||||
|
if (strcmp(argv[i], "exit") == 0)
|
||||||
|
do_exit++;
|
||||||
|
else if (strcmp(argv[i], "restart") == 0)
|
||||||
|
do_restart++;
|
||||||
|
else
|
||||||
|
usage();
|
||||||
|
|
||||||
|
if (do_exit && do_restart)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
shell = (char *)getenv("SHELL");
|
||||||
|
if (shell == NULL)
|
||||||
|
shell = DEFSHELL;
|
||||||
|
|
||||||
|
dpy = XOpenDisplay("");
|
||||||
|
if (dpy == 0)
|
||||||
|
fatal("can't open display");
|
||||||
|
|
||||||
|
initting = 1;
|
||||||
|
XSetErrorHandler(handler);
|
||||||
|
if (signal(SIGTERM, sighandler) == SIG_IGN)
|
||||||
|
signal(SIGTERM, SIG_IGN);
|
||||||
|
if (signal(SIGINT, sighandler) == SIG_IGN)
|
||||||
|
signal(SIGINT, SIG_IGN);
|
||||||
|
if (signal(SIGHUP, sighandler) == SIG_IGN)
|
||||||
|
signal(SIGHUP, SIG_IGN);
|
||||||
|
|
||||||
|
exit_9wm = XInternAtom(dpy, "9WM_EXIT", False);
|
||||||
|
restart_9wm = XInternAtom(dpy, "9WM_RESTART", False);
|
||||||
|
|
||||||
|
curtime = -1; /* don't care */
|
||||||
|
if (do_exit) {
|
||||||
|
sendcmessage(DefaultRootWindow(dpy), exit_9wm, 0L, 1);
|
||||||
|
XSync(dpy, False);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
if (do_restart) {
|
||||||
|
sendcmessage(DefaultRootWindow(dpy), restart_9wm, 0L, 1);
|
||||||
|
XSync(dpy, False);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
wm_state = XInternAtom(dpy, "WM_STATE", False);
|
||||||
|
wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False);
|
||||||
|
wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
|
||||||
|
wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
||||||
|
wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
|
||||||
|
wm_colormaps = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False);
|
||||||
|
_9wm_running = XInternAtom(dpy, "_9WM_RUNNING", False);
|
||||||
|
_9wm_hold_mode = XInternAtom(dpy, "_9WM_HOLD_MODE", False);
|
||||||
|
|
||||||
|
if (fname != 0)
|
||||||
|
if ((font = XLoadQueryFont(dpy, fname)) == 0)
|
||||||
|
fprintf(stderr, "9wm: warning: can't load font %s\n", fname);
|
||||||
|
|
||||||
|
if (font == 0) {
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
fname = fontlist[i++];
|
||||||
|
if (fname == 0) {
|
||||||
|
fprintf(stderr, "9wm: warning: can't find a font\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
font = XLoadQueryFont(dpy, fname);
|
||||||
|
if (font != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nostalgia) {
|
||||||
|
_border--;
|
||||||
|
_inset--;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SHAPE
|
||||||
|
shape = XShapeQueryExtension(dpy, &shape_event, &dummy);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
num_screens = ScreenCount(dpy);
|
||||||
|
screens = (ScreenInfo *)malloc(sizeof(ScreenInfo) * num_screens);
|
||||||
|
|
||||||
|
for (i = 0; i < num_screens; i++)
|
||||||
|
initscreen(&screens[i], i, background);
|
||||||
|
|
||||||
|
/* set selection so that 9term knows we're running */
|
||||||
|
curtime = CurrentTime;
|
||||||
|
XSetSelectionOwner(dpy, _9wm_running, screens[0].menuwin, timestamp());
|
||||||
|
|
||||||
|
XSync(dpy, False);
|
||||||
|
initting = 0;
|
||||||
|
|
||||||
|
nofocus();
|
||||||
|
|
||||||
|
for (i = 0; i < num_screens; i++)
|
||||||
|
scanwins(&screens[i]);
|
||||||
|
|
||||||
|
mainloop(shape_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initscreen(ScreenInfo *s, int i, int background)
|
||||||
|
{
|
||||||
|
char *ds, *colon, *dot1;
|
||||||
|
unsigned long mask;
|
||||||
|
XGCValues gv;
|
||||||
|
XSetWindowAttributes attr;
|
||||||
|
|
||||||
|
s->num = i;
|
||||||
|
s->root = RootWindow(dpy, i);
|
||||||
|
s->def_cmap = DefaultColormap(dpy, i);
|
||||||
|
s->min_cmaps = MinCmapsOfScreen(ScreenOfDisplay(dpy, i));
|
||||||
|
s->depth = DefaultDepth(dpy, i);
|
||||||
|
|
||||||
|
ds = DisplayString(dpy);
|
||||||
|
colon = rindex(ds, ':');
|
||||||
|
if (colon && num_screens > 1) {
|
||||||
|
strcpy(s->display, "DISPLAY=");
|
||||||
|
strcat(s->display, ds);
|
||||||
|
colon = s->display + 8 + (colon - ds); /* use version in buf */
|
||||||
|
dot1 = index(colon, '.'); /* first period after colon */
|
||||||
|
if (!dot1)
|
||||||
|
dot1 = colon + strlen(colon); /* if not there, append */
|
||||||
|
sprintf(dot1, ".%d", i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s->display[0] = '\0';
|
||||||
|
|
||||||
|
s->activeholdborder = colorpixel(dpy, s->depth, 0x000099);
|
||||||
|
s->inactiveholdborder = colorpixel(dpy, s->depth, 0x005DBB);
|
||||||
|
s->activeborder = colorpixel(dpy, s->depth ,0x55AAAA);
|
||||||
|
s->inactiveborder = colorpixel(dpy, s->depth, 0x9EEEEE);
|
||||||
|
s->red = colorpixel(dpy, s->depth, 0xDD0000);
|
||||||
|
s->black = BlackPixel(dpy, i);
|
||||||
|
s->white = WhitePixel(dpy, i);
|
||||||
|
s->width = WidthOfScreen(ScreenOfDisplay(dpy, i));
|
||||||
|
s->height = HeightOfScreen(ScreenOfDisplay(dpy, i));
|
||||||
|
s->bkup[0] = XCreatePixmap(dpy, s->root, 2*s->width, BORDER, DefaultDepth(dpy, i));
|
||||||
|
s->bkup[1] = XCreatePixmap(dpy, s->root, BORDER, 2*s->height, DefaultDepth(dpy, i));
|
||||||
|
|
||||||
|
gv.foreground = s->black^s->white;
|
||||||
|
gv.background = s->white;
|
||||||
|
gv.function = GXxor;
|
||||||
|
gv.line_width = 0;
|
||||||
|
gv.subwindow_mode = IncludeInferiors;
|
||||||
|
mask = GCForeground | GCBackground | GCFunction | GCLineWidth
|
||||||
|
| GCSubwindowMode;
|
||||||
|
if (font != 0) {
|
||||||
|
gv.font = font->fid;
|
||||||
|
mask |= GCFont;
|
||||||
|
}
|
||||||
|
s->gc = XCreateGC(dpy, s->root, mask, &gv);
|
||||||
|
|
||||||
|
gv.function = GXcopy;
|
||||||
|
s->gccopy = XCreateGC(dpy, s->root, mask, &gv);
|
||||||
|
|
||||||
|
gv.foreground = s->red;
|
||||||
|
s->gcred = XCreateGC(dpy, s->root, mask, &gv);
|
||||||
|
|
||||||
|
gv.foreground = colorpixel(dpy, s->depth, 0xEEEEEE);
|
||||||
|
s->gcsweep = XCreateGC(dpy, s->root, mask, &gv);
|
||||||
|
|
||||||
|
gv.foreground = colorpixel(dpy, s->depth, 0xE9FFE9);
|
||||||
|
s->gcmenubg = XCreateGC(dpy, s->root, mask, &gv);
|
||||||
|
|
||||||
|
gv.foreground = colorpixel(dpy, s->depth, 0x448844);
|
||||||
|
s->gcmenubgs = XCreateGC(dpy, s->root, mask, &gv);
|
||||||
|
|
||||||
|
gv.foreground = s->black;
|
||||||
|
gv.background = colorpixel(dpy, s->depth, 0xE9FFE9);
|
||||||
|
s->gcmenufg = XCreateGC(dpy, s->root, mask, &gv);
|
||||||
|
|
||||||
|
gv.foreground = colorpixel(dpy, s->depth, 0xE9FFE9);
|
||||||
|
gv.background = colorpixel(dpy, s->depth, 0x448844);
|
||||||
|
s->gcmenufgs = XCreateGC(dpy, s->root, mask, &gv);
|
||||||
|
|
||||||
|
initcurs(s);
|
||||||
|
|
||||||
|
attr.cursor = s->arrow;
|
||||||
|
attr.event_mask = SubstructureRedirectMask
|
||||||
|
| SubstructureNotifyMask | ColormapChangeMask
|
||||||
|
| ButtonPressMask | ButtonReleaseMask | PropertyChangeMask;
|
||||||
|
mask = CWCursor|CWEventMask;
|
||||||
|
XChangeWindowAttributes(dpy, s->root, mask, &attr);
|
||||||
|
XSync(dpy, False);
|
||||||
|
|
||||||
|
if (background) {
|
||||||
|
/*
|
||||||
|
XSetWindowBackgroundPixmap(dpy, s->root, s->root_pixmap);
|
||||||
|
XClearWindow(dpy, s->root);
|
||||||
|
*/
|
||||||
|
system("xsetroot -solid grey30");
|
||||||
|
}
|
||||||
|
s->menuwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 2, colorpixel(dpy, s->depth, 0xAAFFAA), colorpixel(dpy, s->depth, 0xE9FFE9));
|
||||||
|
s->sweepwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 4, s->red, colorpixel(dpy, s->depth, 0xEEEEEE));
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenInfo*
|
||||||
|
getscreen(Window w)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_screens; i++)
|
||||||
|
if (screens[i].root == w)
|
||||||
|
return &screens[i];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Time
|
||||||
|
timestamp(void)
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
if (curtime == CurrentTime) {
|
||||||
|
XChangeProperty(dpy, screens[0].root, _9wm_running, _9wm_running, 8,
|
||||||
|
PropModeAppend, (unsigned char *)"", 0);
|
||||||
|
XMaskEvent(dpy, PropertyChangeMask, &ev);
|
||||||
|
curtime = ev.xproperty.time;
|
||||||
|
}
|
||||||
|
return curtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sendcmessage(Window w, Atom a, long x, int isroot)
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
int status;
|
||||||
|
long mask;
|
||||||
|
|
||||||
|
memset(&ev, 0, sizeof(ev));
|
||||||
|
ev.xclient.type = ClientMessage;
|
||||||
|
ev.xclient.window = w;
|
||||||
|
ev.xclient.message_type = a;
|
||||||
|
ev.xclient.format = 32;
|
||||||
|
ev.xclient.data.l[0] = x;
|
||||||
|
ev.xclient.data.l[1] = timestamp();
|
||||||
|
mask = 0L;
|
||||||
|
if (isroot)
|
||||||
|
mask = SubstructureRedirectMask; /* magic! */
|
||||||
|
status = XSendEvent(dpy, w, False, mask, &ev);
|
||||||
|
if (status == 0)
|
||||||
|
fprintf(stderr, "9wm: sendcmessage failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sendconfig(Client *c)
|
||||||
|
{
|
||||||
|
XConfigureEvent ce;
|
||||||
|
|
||||||
|
ce.type = ConfigureNotify;
|
||||||
|
ce.event = c->window;
|
||||||
|
ce.window = c->window;
|
||||||
|
ce.x = c->x;
|
||||||
|
ce.y = c->y;
|
||||||
|
ce.width = c->dx;
|
||||||
|
ce.height = c->dy;
|
||||||
|
ce.border_width = c->border;
|
||||||
|
ce.above = None;
|
||||||
|
ce.override_redirect = 0;
|
||||||
|
XSendEvent(dpy, c->window, False, StructureNotifyMask, (XEvent*)&ce);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sighandler(void)
|
||||||
|
{
|
||||||
|
signalled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getevent(XEvent *e)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval t;
|
||||||
|
|
||||||
|
if (!signalled) {
|
||||||
|
if (QLength(dpy) > 0) {
|
||||||
|
XNextEvent(dpy, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fd = ConnectionNumber(dpy);
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(fd, &rfds);
|
||||||
|
t.tv_sec = t.tv_usec = 0;
|
||||||
|
if (select(fd+1, &rfds, NULL, NULL, &t) == 1) {
|
||||||
|
XNextEvent(dpy, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XFlush(dpy);
|
||||||
|
FD_SET(fd, &rfds);
|
||||||
|
if (select(fd+1, &rfds, NULL, NULL, NULL) == 1) {
|
||||||
|
XNextEvent(dpy, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (errno != EINTR || !signalled) {
|
||||||
|
perror("9wm: select failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr, "9wm: exiting on signal\n");
|
||||||
|
cleanup();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanup(void)
|
||||||
|
{
|
||||||
|
Client *c, *cc[2], *next;
|
||||||
|
XWindowChanges wc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* order of un-reparenting determines final stacking order... */
|
||||||
|
cc[0] = cc[1] = 0;
|
||||||
|
for (c = clients; c; c = next) {
|
||||||
|
next = c->next;
|
||||||
|
i = normal(c);
|
||||||
|
c->next = cc[i];
|
||||||
|
cc[i] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
for (c = cc[i]; c; c = c->next) {
|
||||||
|
if (!withdrawn(c)) {
|
||||||
|
gravitate(c, 1);
|
||||||
|
XReparentWindow(dpy, c->window, c->screen->root,
|
||||||
|
c->x, c->y);
|
||||||
|
}
|
||||||
|
wc.border_width = c->border;
|
||||||
|
XConfigureWindow(dpy, c->window, CWBorderWidth, &wc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, timestamp());
|
||||||
|
for (i = 0; i < num_screens; i++)
|
||||||
|
cmapnofocus(&screens[i]);
|
||||||
|
XCloseDisplay(dpy);
|
||||||
|
}
|
||||||
482
src/cmd/rio/manage.c
Normal file
482
src/cmd/rio/manage.c
Normal file
|
|
@ -0,0 +1,482 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xos.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
manage(Client *c, int mapped)
|
||||||
|
{
|
||||||
|
int fixsize, dohide, doreshape, state;
|
||||||
|
long msize;
|
||||||
|
XClassHint class;
|
||||||
|
XWMHints *hints;
|
||||||
|
|
||||||
|
trace("manage", c, 0);
|
||||||
|
XSelectInput(dpy, c->window, ColormapChangeMask | EnterWindowMask | PropertyChangeMask | FocusChangeMask);
|
||||||
|
|
||||||
|
/* Get loads of hints */
|
||||||
|
|
||||||
|
if (XGetClassHint(dpy, c->window, &class) != 0) { /* ``Success'' */
|
||||||
|
c->instance = class.res_name;
|
||||||
|
c->class = class.res_class;
|
||||||
|
c->is9term = (strcmp(c->class, "9term") == 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c->instance = 0;
|
||||||
|
c->class = 0;
|
||||||
|
c->is9term = 0;
|
||||||
|
}
|
||||||
|
c->iconname = getprop(c->window, XA_WM_ICON_NAME);
|
||||||
|
c->name = getprop(c->window, XA_WM_NAME);
|
||||||
|
setlabel(c);
|
||||||
|
|
||||||
|
hints = XGetWMHints(dpy, c->window);
|
||||||
|
if (XGetWMNormalHints(dpy, c->window, &c->size, &msize) == 0 || c->size.flags == 0)
|
||||||
|
c->size.flags = PSize; /* not specified - punt */
|
||||||
|
|
||||||
|
getcmaps(c);
|
||||||
|
getproto(c);
|
||||||
|
gettrans(c);
|
||||||
|
if (c->is9term)
|
||||||
|
c->hold = getiprop(c->window, _9wm_hold_mode);
|
||||||
|
|
||||||
|
/* Figure out what to do with the window from hints */
|
||||||
|
|
||||||
|
if (!getstate(c->window, &state))
|
||||||
|
state = hints ? hints->initial_state : NormalState;
|
||||||
|
dohide = (state == IconicState);
|
||||||
|
|
||||||
|
fixsize = 0;
|
||||||
|
if ((c->size.flags & (USSize|PSize)))
|
||||||
|
fixsize = 1;
|
||||||
|
if ((c->size.flags & (PMinSize|PMaxSize)) == (PMinSize|PMaxSize) && c->size.min_width == c->size.max_width && c->size.min_height == c->size.max_height)
|
||||||
|
fixsize = 1;
|
||||||
|
doreshape = !mapped;
|
||||||
|
if (fixsize) {
|
||||||
|
if (c->size.flags & USPosition)
|
||||||
|
doreshape = 0;
|
||||||
|
if (dohide && (c->size.flags & PPosition))
|
||||||
|
doreshape = 0;
|
||||||
|
if (c->trans != None)
|
||||||
|
doreshape = 0;
|
||||||
|
}
|
||||||
|
if (c->is9term)
|
||||||
|
fixsize = 0;
|
||||||
|
if (c->size.flags & PBaseSize) {
|
||||||
|
c->min_dx = c->size.base_width;
|
||||||
|
c->min_dy = c->size.base_height;
|
||||||
|
}
|
||||||
|
else if (c->size.flags & PMinSize) {
|
||||||
|
c->min_dx = c->size.min_width;
|
||||||
|
c->min_dy = c->size.min_height;
|
||||||
|
}
|
||||||
|
else if (c->is9term) {
|
||||||
|
c->min_dx = 100;
|
||||||
|
c->min_dy = 50;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
c->min_dx = c->min_dy = 0;
|
||||||
|
|
||||||
|
if (hints)
|
||||||
|
XFree(hints);
|
||||||
|
|
||||||
|
/* Now do it!!! */
|
||||||
|
|
||||||
|
if (doreshape) {
|
||||||
|
if (current && current->screen == c->screen)
|
||||||
|
cmapnofocus(c->screen);
|
||||||
|
if (!c->is9term && c->x==0 && c->y==0) {
|
||||||
|
static int nwin;
|
||||||
|
|
||||||
|
c->x = 20*nwin+BORDER;
|
||||||
|
c->y = 20*nwin+BORDER;
|
||||||
|
nwin++;
|
||||||
|
nwin %= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->is9term && !(fixsize ? drag(c) : sweep(c))) {
|
||||||
|
XKillClient(dpy, c->window);
|
||||||
|
rmclient(c);
|
||||||
|
if (current && current->screen == c->screen)
|
||||||
|
cmapfocus(current);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gravitate(c, 0);
|
||||||
|
|
||||||
|
c->parent = XCreateSimpleWindow(dpy, c->screen->root,
|
||||||
|
c->x - BORDER, c->y - BORDER,
|
||||||
|
c->dx + 2*BORDER, c->dy + 2*BORDER,
|
||||||
|
0, c->screen->black, c->screen->white);
|
||||||
|
XSelectInput(dpy, c->parent, SubstructureRedirectMask | SubstructureNotifyMask);
|
||||||
|
if (mapped)
|
||||||
|
c->reparenting = 1;
|
||||||
|
if (doreshape && !fixsize)
|
||||||
|
XResizeWindow(dpy, c->window, c->dx, c->dy);
|
||||||
|
XSetWindowBorderWidth(dpy, c->window, 0);
|
||||||
|
XReparentWindow(dpy, c->window, c->parent, BORDER, BORDER);
|
||||||
|
#ifdef SHAPE
|
||||||
|
if (shape) {
|
||||||
|
XShapeSelectInput(dpy, c->window, ShapeNotifyMask);
|
||||||
|
ignore_badwindow = 1; /* magic */
|
||||||
|
setshape(c);
|
||||||
|
ignore_badwindow = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
XAddToSaveSet(dpy, c->window);
|
||||||
|
if (dohide)
|
||||||
|
hide(c);
|
||||||
|
else {
|
||||||
|
XMapWindow(dpy, c->window);
|
||||||
|
XMapWindow(dpy, c->parent);
|
||||||
|
XUnmapWindow(dpy, c->screen->sweepwin);
|
||||||
|
if (nostalgia || doreshape)
|
||||||
|
active(c);
|
||||||
|
else if (c->trans != None && current && current->window == c->trans)
|
||||||
|
active(c);
|
||||||
|
else
|
||||||
|
setactive(c, 0);
|
||||||
|
setstate(c, NormalState);
|
||||||
|
}
|
||||||
|
if (current && (current != c))
|
||||||
|
cmapfocus(current);
|
||||||
|
c->init = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
scanwins(ScreenInfo *s)
|
||||||
|
{
|
||||||
|
unsigned int i, nwins;
|
||||||
|
Client *c;
|
||||||
|
Window dw1, dw2, *wins;
|
||||||
|
XWindowAttributes attr;
|
||||||
|
|
||||||
|
XQueryTree(dpy, s->root, &dw1, &dw2, &wins, &nwins);
|
||||||
|
for (i = 0; i < nwins; i++) {
|
||||||
|
XGetWindowAttributes(dpy, wins[i], &attr);
|
||||||
|
if (attr.override_redirect || wins[i] == s->menuwin)
|
||||||
|
continue;
|
||||||
|
c = getclient(wins[i], 1);
|
||||||
|
if (c != 0 && c->window == wins[i] && !c->init) {
|
||||||
|
c->x = attr.x;
|
||||||
|
c->y = attr.y;
|
||||||
|
c->dx = attr.width;
|
||||||
|
c->dy = attr.height;
|
||||||
|
c->border = attr.border_width;
|
||||||
|
c->screen = s;
|
||||||
|
c->parent = s->root;
|
||||||
|
if (attr.map_state == IsViewable)
|
||||||
|
manage(c, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree((void *) wins); /* cast is to shut stoopid compiler up */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gettrans(Client *c)
|
||||||
|
{
|
||||||
|
Window trans;
|
||||||
|
|
||||||
|
trans = None;
|
||||||
|
if (XGetTransientForHint(dpy, c->window, &trans) != 0)
|
||||||
|
c->trans = trans;
|
||||||
|
else
|
||||||
|
c->trans = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
withdraw(Client *c)
|
||||||
|
{
|
||||||
|
XUnmapWindow(dpy, c->parent);
|
||||||
|
gravitate(c, 1);
|
||||||
|
XReparentWindow(dpy, c->window, c->screen->root, c->x, c->y);
|
||||||
|
gravitate(c, 0);
|
||||||
|
XRemoveFromSaveSet(dpy, c->window);
|
||||||
|
setstate(c, WithdrawnState);
|
||||||
|
|
||||||
|
/* flush any errors */
|
||||||
|
ignore_badwindow = 1;
|
||||||
|
XSync(dpy, False);
|
||||||
|
ignore_badwindow = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gravitate(Client *c, int invert)
|
||||||
|
{
|
||||||
|
int gravity, dx, dy, delta;
|
||||||
|
|
||||||
|
gravity = NorthWestGravity;
|
||||||
|
if (c->size.flags & PWinGravity)
|
||||||
|
gravity = c->size.win_gravity;
|
||||||
|
|
||||||
|
delta = c->border-BORDER;
|
||||||
|
switch (gravity) {
|
||||||
|
case NorthWestGravity:
|
||||||
|
dx = 0;
|
||||||
|
dy = 0;
|
||||||
|
break;
|
||||||
|
case NorthGravity:
|
||||||
|
dx = delta;
|
||||||
|
dy = 0;
|
||||||
|
break;
|
||||||
|
case NorthEastGravity:
|
||||||
|
dx = 2*delta;
|
||||||
|
dy = 0;
|
||||||
|
break;
|
||||||
|
case WestGravity:
|
||||||
|
dx = 0;
|
||||||
|
dy = delta;
|
||||||
|
break;
|
||||||
|
case CenterGravity:
|
||||||
|
case StaticGravity:
|
||||||
|
dx = delta;
|
||||||
|
dy = delta;
|
||||||
|
break;
|
||||||
|
case EastGravity:
|
||||||
|
dx = 2*delta;
|
||||||
|
dy = delta;
|
||||||
|
break;
|
||||||
|
case SouthWestGravity:
|
||||||
|
dx = 0;
|
||||||
|
dy = 2*delta;
|
||||||
|
break;
|
||||||
|
case SouthGravity:
|
||||||
|
dx = delta;
|
||||||
|
dy = 2*delta;
|
||||||
|
break;
|
||||||
|
case SouthEastGravity:
|
||||||
|
dx = 2*delta;
|
||||||
|
dy = 2*delta;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "9wm: bad window gravity %d for 0x%x\n", gravity, c->window);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dx += BORDER;
|
||||||
|
dy += BORDER;
|
||||||
|
if (invert) {
|
||||||
|
dx = -dx;
|
||||||
|
dy = -dy;
|
||||||
|
}
|
||||||
|
c->x += dx;
|
||||||
|
c->y += dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
installcmap(ScreenInfo *s, Colormap cmap)
|
||||||
|
{
|
||||||
|
if (cmap == None)
|
||||||
|
XInstallColormap(dpy, s->def_cmap);
|
||||||
|
else
|
||||||
|
XInstallColormap(dpy, cmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmapfocus(Client *c)
|
||||||
|
{
|
||||||
|
int i, found;
|
||||||
|
Client *cc;
|
||||||
|
|
||||||
|
if (c == 0)
|
||||||
|
return;
|
||||||
|
else if (c->ncmapwins != 0) {
|
||||||
|
found = 0;
|
||||||
|
for (i = c->ncmapwins-1; i >= 0; i--) {
|
||||||
|
installcmap(c->screen, c->wmcmaps[i]);
|
||||||
|
if (c->cmapwins[i] == c->window)
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
installcmap(c->screen, c->cmap);
|
||||||
|
}
|
||||||
|
else if (c->trans != None && (cc = getclient(c->trans, 0)) != 0 && cc->ncmapwins != 0)
|
||||||
|
cmapfocus(cc);
|
||||||
|
else
|
||||||
|
installcmap(c->screen, c->cmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmapnofocus(ScreenInfo *s)
|
||||||
|
{
|
||||||
|
installcmap(s, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getcmaps(Client *c)
|
||||||
|
{
|
||||||
|
int n, i;
|
||||||
|
Window *cw;
|
||||||
|
XWindowAttributes attr;
|
||||||
|
|
||||||
|
if (!c->init) {
|
||||||
|
XGetWindowAttributes(dpy, c->window, &attr);
|
||||||
|
c->cmap = attr.colormap;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = _getprop(c->window, wm_colormaps, XA_WINDOW, 100L, (unsigned char **)&cw);
|
||||||
|
if (c->ncmapwins != 0) {
|
||||||
|
XFree((char *)c->cmapwins);
|
||||||
|
free((char *)c->wmcmaps);
|
||||||
|
}
|
||||||
|
if (n <= 0) {
|
||||||
|
c->ncmapwins = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->ncmapwins = n;
|
||||||
|
c->cmapwins = cw;
|
||||||
|
|
||||||
|
c->wmcmaps = (Colormap*)malloc(n*sizeof(Colormap));
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
if (cw[i] == c->window)
|
||||||
|
c->wmcmaps[i] = c->cmap;
|
||||||
|
else {
|
||||||
|
XSelectInput(dpy, cw[i], ColormapChangeMask);
|
||||||
|
XGetWindowAttributes(dpy, cw[i], &attr);
|
||||||
|
c->wmcmaps[i] = attr.colormap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setlabel(Client *c)
|
||||||
|
{
|
||||||
|
char *label, *p;
|
||||||
|
|
||||||
|
if (c->iconname != 0)
|
||||||
|
label = c->iconname;
|
||||||
|
else if (c->name != 0)
|
||||||
|
label = c->name;
|
||||||
|
else if (c->instance != 0)
|
||||||
|
label = c->instance;
|
||||||
|
else if (c->class != 0)
|
||||||
|
label = c->class;
|
||||||
|
else
|
||||||
|
label = "no label";
|
||||||
|
if ((p = index(label, ':')) != 0)
|
||||||
|
*p = '\0';
|
||||||
|
c->label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SHAPE
|
||||||
|
void
|
||||||
|
setshape(Client *c)
|
||||||
|
{
|
||||||
|
int n, order;
|
||||||
|
XRectangle *rect;
|
||||||
|
|
||||||
|
/* don't try to add a border if the window is non-rectangular */
|
||||||
|
rect = XShapeGetRectangles(dpy, c->window, ShapeBounding, &n, &order);
|
||||||
|
if (n > 1)
|
||||||
|
XShapeCombineShape(dpy, c->parent, ShapeBounding, BORDER, BORDER,
|
||||||
|
c->window, ShapeBounding, ShapeSet);
|
||||||
|
XFree((void*)rect);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
_getprop(Window w, Atom a, Atom type, long len, unsigned char **p)
|
||||||
|
{
|
||||||
|
Atom real_type;
|
||||||
|
int format;
|
||||||
|
unsigned long n, extra;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = XGetWindowProperty(dpy, w, a, 0L, len, False, type, &real_type, &format, &n, &extra, p);
|
||||||
|
if (status != Success || *p == 0)
|
||||||
|
return -1;
|
||||||
|
if (n == 0)
|
||||||
|
XFree((void*) *p);
|
||||||
|
/* could check real_type, format, extra here... */
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
getprop(Window w, Atom a)
|
||||||
|
{
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
if (_getprop(w, a, XA_STRING, 100L, &p) <= 0)
|
||||||
|
return 0;
|
||||||
|
return (char *)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get1prop(Window w, Atom a, Atom type)
|
||||||
|
{
|
||||||
|
char **p, *x;
|
||||||
|
|
||||||
|
if (_getprop(w, a, type, 1L, (unsigned char**)&p) <= 0)
|
||||||
|
return 0;
|
||||||
|
x = *p;
|
||||||
|
XFree((void*) p);
|
||||||
|
return (int)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window
|
||||||
|
getwprop(Window w, Atom a)
|
||||||
|
{
|
||||||
|
return get1prop(w, a, XA_WINDOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getiprop(Window w, Atom a)
|
||||||
|
{
|
||||||
|
return get1prop(w, a, XA_INTEGER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setstate(Client *c, int state)
|
||||||
|
{
|
||||||
|
long data[2];
|
||||||
|
|
||||||
|
data[0] = (long) state;
|
||||||
|
data[1] = (long) None;
|
||||||
|
|
||||||
|
c->state = state;
|
||||||
|
XChangeProperty(dpy, c->window, wm_state, wm_state, 32,
|
||||||
|
PropModeReplace, (unsigned char *)data, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getstate(Window w, int *state)
|
||||||
|
{
|
||||||
|
long *p = 0;
|
||||||
|
|
||||||
|
if (_getprop(w, wm_state, wm_state, 2L, (unsigned char**)&p) <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*state = (int) *p;
|
||||||
|
XFree((char *) p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getproto(Client *c)
|
||||||
|
{
|
||||||
|
Atom *p;
|
||||||
|
int i;
|
||||||
|
long n;
|
||||||
|
Window w;
|
||||||
|
|
||||||
|
w = c->window;
|
||||||
|
c->proto = 0;
|
||||||
|
if ((n = _getprop(w, wm_protocols, XA_ATOM, 20L, (unsigned char**)&p)) <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
if (p[i] == wm_delete)
|
||||||
|
c->proto |= Pdelete;
|
||||||
|
else if (p[i] == wm_take_focus)
|
||||||
|
c->proto |= Ptakefocus;
|
||||||
|
|
||||||
|
XFree((char *) p);
|
||||||
|
}
|
||||||
258
src/cmd/rio/menu.c
Normal file
258
src/cmd/rio/menu.c
Normal file
|
|
@ -0,0 +1,258 @@
|
||||||
|
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
Client *hiddenc[MAXHIDDEN];
|
||||||
|
|
||||||
|
int numhidden;
|
||||||
|
|
||||||
|
char *b3items[B3FIXED+MAXHIDDEN+1] =
|
||||||
|
{
|
||||||
|
"New",
|
||||||
|
"Reshape",
|
||||||
|
"Move",
|
||||||
|
"Delete",
|
||||||
|
"Hide",
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
Menu b3menu =
|
||||||
|
{
|
||||||
|
b3items,
|
||||||
|
};
|
||||||
|
|
||||||
|
Menu egg =
|
||||||
|
{
|
||||||
|
version,
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
button(XButtonEvent *e)
|
||||||
|
{
|
||||||
|
int n, shift;
|
||||||
|
Client *c;
|
||||||
|
Window dw;
|
||||||
|
ScreenInfo *s;
|
||||||
|
|
||||||
|
curtime = e->time;
|
||||||
|
s = getscreen(e->root);
|
||||||
|
if (s == 0)
|
||||||
|
return;
|
||||||
|
c = getclient(e->window, 0);
|
||||||
|
if (c) {
|
||||||
|
e->x += c->x - BORDER;
|
||||||
|
e->y += c->y - BORDER;
|
||||||
|
}
|
||||||
|
else if (e->window != e->root)
|
||||||
|
XTranslateCoordinates(dpy, e->window, s->root, e->x, e->y,
|
||||||
|
&e->x, &e->y, &dw);
|
||||||
|
switch (e->button) {
|
||||||
|
case Button1:
|
||||||
|
if (c) {
|
||||||
|
XMapRaised(dpy, c->parent);
|
||||||
|
top(c);
|
||||||
|
active(c);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case Button2:
|
||||||
|
if ((e->state&(ShiftMask|ControlMask))==(ShiftMask|ControlMask))
|
||||||
|
menuhit(e, &egg);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
case Button3:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current && current->screen == s)
|
||||||
|
cmapnofocus(s);
|
||||||
|
switch (n = menuhit(e, &b3menu)) {
|
||||||
|
case 0: /* New */
|
||||||
|
spawn(s);
|
||||||
|
break;
|
||||||
|
case 1: /* Reshape */
|
||||||
|
reshape(selectwin(1, 0, s));
|
||||||
|
break;
|
||||||
|
case 2: /* Move */
|
||||||
|
move(selectwin(0, 0, s));
|
||||||
|
break;
|
||||||
|
case 3: /* Delete */
|
||||||
|
shift = 0;
|
||||||
|
c = selectwin(1, &shift, s);
|
||||||
|
delete(c, shift);
|
||||||
|
break;
|
||||||
|
case 4: /* Hide */
|
||||||
|
hide(selectwin(1, 0, s));
|
||||||
|
break;
|
||||||
|
default: /* unhide window */
|
||||||
|
unhide(n - B3FIXED, 1);
|
||||||
|
break;
|
||||||
|
case -1: /* nothing */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (current && current->screen == s)
|
||||||
|
cmapfocus(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spawn(ScreenInfo *s)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* ugly dance to avoid leaving zombies. Could use SIGCHLD,
|
||||||
|
* but it's not very portable.
|
||||||
|
*/
|
||||||
|
if (fork() == 0) {
|
||||||
|
if (fork() == 0) {
|
||||||
|
close(ConnectionNumber(dpy));
|
||||||
|
if (s->display[0] != '\0')
|
||||||
|
putenv(s->display);
|
||||||
|
if (termprog != NULL) {
|
||||||
|
execl(shell, shell, "-c", termprog, 0);
|
||||||
|
fprintf(stderr, "9wm: exec %s", shell);
|
||||||
|
perror(" failed");
|
||||||
|
}
|
||||||
|
execlp("9term", "9term", "-w", 0);
|
||||||
|
execlp("xterm", "xterm", "-ut", 0);
|
||||||
|
perror("9wm: exec 9term/xterm failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
wait((int *) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
reshape(Client *c)
|
||||||
|
{
|
||||||
|
int odx, ody;
|
||||||
|
|
||||||
|
if (c == 0)
|
||||||
|
return;
|
||||||
|
odx = c->dx;
|
||||||
|
ody = c->dy;
|
||||||
|
if (sweep(c) == 0)
|
||||||
|
return;
|
||||||
|
active(c);
|
||||||
|
top(c);
|
||||||
|
XRaiseWindow(dpy, c->parent);
|
||||||
|
XMoveResizeWindow(dpy, c->parent, c->x-BORDER, c->y-BORDER,
|
||||||
|
c->dx+2*BORDER, c->dy+2*BORDER);
|
||||||
|
if (c->dx == odx && c->dy == ody)
|
||||||
|
sendconfig(c);
|
||||||
|
else
|
||||||
|
XMoveResizeWindow(dpy, c->window, BORDER, BORDER, c->dx, c->dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
move(Client *c)
|
||||||
|
{
|
||||||
|
if (c == 0)
|
||||||
|
return;
|
||||||
|
if (drag(c) == 0)
|
||||||
|
return;
|
||||||
|
active(c);
|
||||||
|
top(c);
|
||||||
|
XRaiseWindow(dpy, c->parent);
|
||||||
|
XMoveWindow(dpy, c->parent, c->x-BORDER, c->y-BORDER);
|
||||||
|
sendconfig(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
delete(Client *c, int shift)
|
||||||
|
{
|
||||||
|
if (c == 0)
|
||||||
|
return;
|
||||||
|
if ((c->proto & Pdelete) && !shift)
|
||||||
|
sendcmessage(c->window, wm_protocols, wm_delete, 0);
|
||||||
|
else
|
||||||
|
XKillClient(dpy, c->window); /* let event clean up */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hide(Client *c)
|
||||||
|
{
|
||||||
|
if (c == 0 || numhidden == MAXHIDDEN)
|
||||||
|
return;
|
||||||
|
if (hidden(c)) {
|
||||||
|
fprintf(stderr, "9wm: already hidden: %s\n", c->label);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XUnmapWindow(dpy, c->parent);
|
||||||
|
XUnmapWindow(dpy, c->window);
|
||||||
|
setstate(c, IconicState);
|
||||||
|
if (c == current)
|
||||||
|
nofocus();
|
||||||
|
hiddenc[numhidden] = c;
|
||||||
|
b3items[B3FIXED+numhidden] = c->label;
|
||||||
|
numhidden++;
|
||||||
|
b3items[B3FIXED+numhidden] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unhide(int n, int map)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (n >= numhidden) {
|
||||||
|
fprintf(stderr, "9wm: unhide: n %d numhidden %d\n", n, numhidden);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
c = hiddenc[n];
|
||||||
|
if (!hidden(c)) {
|
||||||
|
fprintf(stderr, "9wm: unhide: not hidden: %s(0x%x)\n",
|
||||||
|
c->label, c->window);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map) {
|
||||||
|
XMapWindow(dpy, c->window);
|
||||||
|
XMapRaised(dpy, c->parent);
|
||||||
|
setstate(c, NormalState);
|
||||||
|
active(c);
|
||||||
|
top(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
numhidden--;
|
||||||
|
for (i = n; i < numhidden; i ++) {
|
||||||
|
hiddenc[i] = hiddenc[i+1];
|
||||||
|
b3items[B3FIXED+i] = b3items[B3FIXED+i+1];
|
||||||
|
}
|
||||||
|
b3items[B3FIXED+numhidden] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unhidec(Client *c, int map)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < numhidden; i++)
|
||||||
|
if (c == hiddenc[i]) {
|
||||||
|
unhide(i, map);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "9wm: unhidec: not hidden: %s(0x%x)\n",
|
||||||
|
c->label, c->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
renamec(Client *c, char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (name == 0)
|
||||||
|
name = "???";
|
||||||
|
c->label = name;
|
||||||
|
if (!hidden(c))
|
||||||
|
return;
|
||||||
|
for (i = 0; i < numhidden; i++)
|
||||||
|
if (c == hiddenc[i]) {
|
||||||
|
b3items[B3FIXED+i] = name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/cmd/rio/patchlevel.h
Normal file
1
src/cmd/rio/patchlevel.h
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
#define PATCHLEVEL 0
|
||||||
Loading…
Add table
Add a link
Reference in a new issue