home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xcoral16.zip
/
GET_STRI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-15
|
13KB
|
463 lines
/*
** Copyright 1989, 1992 by Lionel Fournigault
**
** Permission to use, copy, and distribute for non-commercial purposes,
** is hereby granted without fee, providing that the above copyright
** notice appear in all copies and that both the copyright notice and this
** permission notice appear in supporting documentation.
** The software may be modified for your own purposes, but modified versions
** may not be distributed.
** This software is provided "as is" without any expressed or implied warranty.
**
**
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pwd.h>
#include "options.h"
#include "flist.h"
#define D_WIDTH 10
#define D_HEIGHT 10
#define D_SHADOW 6
#define D_WARNING 0
#define D_DIALOG 1
#define D_MESSAGE 2
#define DS_OK " Ok... "
#define DS_DIALOG "Dialog Box"
#define DS_CANCEL "Cancel"
typedef struct {
Window frame, shadow, title, main, ok, cancel;
unsigned long fg, bg, ts, bs;
GC gc;
XFontStruct *font;
int t_height, b_width;
} Dialog;
Dialog dial;
extern Display *dpy;
extern char *getenv ();
char *GetStringFromWindow ();
char *ExpandTildeName ();
/*
** Function name : InitDialogWindow
**
** Description : Initialisation de la fenetre de dialog,
** la fonte, les couleurs etc...
** Input :
** Ouput :
*/
void InitDialogWindow ()
{
XSetWindowAttributes att_f;
Window root;
int screen;
unsigned long black, white;
XGCValues gcv;
black = BlackPixel ( dpy, DefaultScreen ( dpy ));
white = WhitePixel ( dpy, DefaultScreen ( dpy ));
dial.fg = (DefaultDepth ( dpy, DefaultScreen ( dpy )) == 1) ?
black : GetOpColor ( OP_MENU_FG );
dial.bg = (DefaultDepth ( dpy, DefaultScreen ( dpy )) == 1) ?
white : GetOpColor ( OP_MENU_BG );
dial.ts = GetOpColor ( OP_MENU_TS );
dial.bs = GetOpColor ( OP_MENU_BS );
dial.font = GetOpFont ( OP_TEXT_FONT );
dial.gc = XCreateGC ( dpy, DefaultRootWindow ( dpy ), 0, &gcv );
XCopyGC ( dpy, DefaultGC (dpy, DefaultScreen ( dpy )), (~0), dial.gc );
XSetFont ( dpy, dial.gc, dial.font -> fid );
XSetForeground ( dpy, dial.gc, dial.fg );
XSetBackground ( dpy, dial.gc, dial.bg );
att_f.win_gravity = NorthWestGravity;
att_f.event_mask = 0;
att_f.override_redirect = False;
att_f.do_not_propagate_mask = NoEventMask;
att_f.cursor = None;
att_f.win_gravity = NorthWestGravity;
screen = DefaultScreen ( dpy );
root = RootWindow ( dpy, screen );
dial.frame = XCreateWindow ( dpy, root, 0, 0, D_WIDTH, D_HEIGHT, 0, 0,
InputOutput, CopyFromParent,
CWWinGravity | CWEventMask | CWOverrideRedirect |
CWDontPropagate | CWCursor, &att_f );
dial.shadow = XCreateSimpleWindow ( dpy, dial.frame, D_SHADOW, D_SHADOW,
D_WIDTH, D_HEIGHT, 0, black, black);
dial.t_height = dial.font -> ascent + dial.font -> descent + 10;
dial.title = XCreateSimpleWindow ( dpy, dial.frame, 0, 0,
D_WIDTH, dial.t_height, 0, dial.fg, dial.bg);
dial.main = XCreateSimpleWindow ( dpy, dial.frame, 0, dial.t_height,
D_WIDTH, D_HEIGHT, 0, dial.fg, dial.bg);
dial.b_width = XTextWidth ( dial.font, DS_OK, strlen (DS_OK)) + 10;
dial.ok = XCreateSimpleWindow ( dpy, dial.main, 0, 0,
dial.b_width, dial.t_height, 0, dial.fg, dial.bg );
dial.cancel = XCreateSimpleWindow ( dpy, dial.main, 0, 0,
dial.b_width, dial.t_height, 0, dial.fg, dial.bg );
XSelectInput ( dpy, dial.main, ExposureMask | KeyPressMask );
XSelectInput ( dpy, dial.title, ExposureMask );
XSelectInput ( dpy, dial.cancel, ButtonPressMask |
ButtonReleaseMask | ExposureMask);
XSelectInput ( dpy, dial.ok, ButtonPressMask |
ButtonReleaseMask | ExposureMask );
}
/*
** Function name : GetStringFromDialogBox
**
** Description : Ouvre une fenetre de dialog (grabbee),
** et manage les differentes actions possibles
** pour l'utilisaterur. Clavier et bouttons.
**
** Input : La fenetre parent, le prompt.
** Ouput : La chaine.
*/
char *GetStringFromDialogBox ( w, s )
Window w;
char *s;
{
XWindowAttributes att;
register int width, height, x, y;
XEvent event;
register char *str;
register int type;
XGetWindowAttributes ( dpy, w, &att );
width = (att.width / 4) * 3;
height = (att.height / 3);
x = att.width / 8;
y = att.height / 3;
if ( strncmp ( s, "Warning", 7 ) == 0 )
type = D_WARNING;
else if ( strncmp ( s, "Message", 7 ) == 0 )
type = D_MESSAGE;
else
type = D_DIALOG;
XReparentWindow ( dpy, dial.frame, w, x, y );
XResizeWindow ( dpy, dial.frame, width, height );
XResizeWindow ( dpy, dial.shadow, width - D_SHADOW , height - D_SHADOW );
XResizeWindow ( dpy, dial.main, width - D_SHADOW,
height - dial.t_height - D_SHADOW );
XResizeWindow ( dpy, dial.title, width -D_SHADOW , dial.t_height );
y = height - ( 2 * dial.t_height ) - D_SHADOW - ( 2 * D_HEIGHT ) ;
if ( (type != D_WARNING) && (type != D_MESSAGE)) {
XMoveWindow ( dpy, dial.ok,
( width/3 ) - ( dial.b_width/2 ), y );
XMoveWindow ( dpy, dial.cancel,
( width*2 / 3 ) - ( dial.b_width/2 ), y );
}
else
XMoveWindow ( dpy, dial.ok,
( width/2 ) - ( dial.b_width/2 ), y );
XMapSubwindows (dpy, dial.main );
XMapWindow ( dpy, dial.main );
XMapSubwindows ( dpy, dial.frame);
XMapRaised ( dpy, dial.frame);
XWindowEvent ( dpy, dial.main, ExposureMask, &event );
XWindowEvent ( dpy, dial.title, ExposureMask, &event );
XWindowEvent ( dpy, dial.ok, ExposureMask, &event );
if ( (type != D_WARNING) && (type != D_MESSAGE) )
XWindowEvent ( dpy, dial.cancel, ExposureMask, &event );
else
XUnmapWindow ( dpy, dial.cancel );
Display3D ( dpy, dial.title, dial.ts, dial.bs, 1, 0 );
Display3D ( dpy, dial.main, dial.ts, dial.bs, 1, 0 );
Display3D ( dpy, dial.ok, dial.ts, dial.bs, 1, 0 );
if ( (type != D_WARNING) && (type != D_MESSAGE) )
Display3D ( dpy, dial.cancel, dial.ts, dial.bs, 1, 0 );
x = XTextWidth ( dial.font, DS_DIALOG, strlen (DS_DIALOG));
XDrawString ( dpy, dial.title, dial.gc, (width - x)/2,
dial.font -> ascent + 5, DS_DIALOG, strlen (DS_DIALOG) );
x = XTextWidth ( dial.font, DS_OK, strlen(DS_OK));
XDrawString ( dpy, dial.ok, dial.gc, (dial.b_width - x)/2,
dial.font -> ascent + 5, DS_OK, strlen(DS_OK));
x = XTextWidth ( dial.font, DS_CANCEL, strlen (DS_CANCEL));
if ( (type != D_WARNING) && (type != D_MESSAGE) )
XDrawString ( dpy, dial.cancel, dial.gc,
(dial.b_width - x)/2, dial.font -> ascent + 5,
DS_CANCEL, strlen (DS_CANCEL));
str = GetStringFromWindow ( dial.main, dial.gc, dial.font,
s, 20, dial.font -> ascent + 20 , (char *) 0, 1 );
XUnmapSubwindows ( dpy, dial.main );
XUnmapWindow ( dpy, dial.main );
XUnmapSubwindows ( dpy, dial.frame );
XUnmapWindow ( dpy, dial.frame );
XReparentWindow ( dpy, dial.frame,
DefaultRootWindow ( dpy), 0, 0 );
return str;
}
/*
** Function name : GetStrinFromWindow
**
** Description : Assure toute la gestion concernant
** l'entree d'une chaine de caracteres.
** Input : La fenetre, le contexte graphique, la fonte,
** le prompt, la position de depart, le type de
** reponse ( chaine complete, ou un seul caractere )
** et un flag pour savoir si on doit tenir compte
** des 'ButtonPress'.
**
** Ouput : La chaine.
*/
char *GetStringFromWindow ( w, gc, font, s, x, y, reply, flag )
Window w;
GC gc;
XFontStruct *font;
register char *s;
register int x, y;
register char *reply;
register int flag;
{
XEvent event;
register int length, cur_x, cur_x_old;
XComposeStatus compose;
KeySym keysym;
register int start_x, max, font_h;
XWindowAttributes att;
register int type;
Window root, parent, **child;
unsigned int nchild;
#define MAXLENGTH 256
#define VOLUME 10
static char string [MAXLENGTH];
static char buffer [MAXLENGTH];
if ( strncmp ( s, "Warning", 7 ) == 0 )
type = D_WARNING;
else if ( strncmp ( s, "Message", 7 ) == 0 )
type = D_MESSAGE;
else
type = D_DIALOG;
XGetWindowAttributes ( dpy, w, &att );
XQueryTree ( dpy, w, &root, &parent, (Window **) &child, &nchild );
if ( nchild == 0 )
XGrabPointer ( dpy, w, True, ButtonPress, GrabModeAsync,
GrabModeAsync, None, None, CurrentTime );
else
/* On est dans le cas d'une dialog-box avec bouttons*/
XGrabPointer ( dpy, w, True, ButtonPress, GrabModeAsync,
GrabModeAsync, w, None, CurrentTime );
if ( child != 0 )
XFree ( (char *) child );
XFlush (dpy );
max = att.width - 40;
font_h = font -> ascent + font -> descent;
if ( type == D_MESSAGE ) s += strlen ( "Message : " );
XDrawImageString ( dpy, w, gc, x, y, s, strlen (s) );
if ( type == D_DIALOG ) {
start_x = x + XTextWidth ( font, s, strlen (s) );
XFillRectangle ( dpy, w, gc, start_x, y - font -> ascent, font_h/2, font_h );
}
cur_x = start_x;
string [0] = buffer [0] = buffer [1] = '\0';
for (;;) {
XNextEvent ( dpy, &event );
switch ( event.type ) {
case ButtonPress :
if ( flag == 0 ) continue;
if ( event.xbutton.window == dial.ok ) {
Display3D ( dpy, dial.ok, dial.ts, dial.bs, 1, 1 );
WaitButtonRelease ( event.xbutton.button );
if ( strlen(string) )
if ( string [0] != '~' )
return string;
else
return ( (char *) ExpandTildeName ( string ));
else
return 0;
}
if ( event.xbutton.window == dial.cancel ) {
Display3D ( dpy, dial.cancel, dial.ts, dial.bs, 1, 1 );
WaitButtonRelease ( event.xbutton.button );
string [0] = '\007';
string [1] = '\0';
return string;
}
break;
case KeyPress:
if ( (type == D_WARNING) || (type == D_MESSAGE) )
continue;
XLookupString ( (XKeyEvent *) &event.xkey, buffer,MAXLENGTH,
&keysym, &compose );
/* Cas return, linefeed ou enter */
if ( (keysym == XK_Return) || (keysym == XK_KP_Enter)
|| (keysym == XK_Linefeed) ) {
XClearArea( dpy, w, x,
y - font -> ascent,
XTextWidth ( font, string,
strlen ( string )) +
XTextWidth ( font, s, strlen (s)) + font_h/2, font_h, False );
XUngrabPointer ( dpy, CurrentTime );
if ( reply != 0 ) {
(void) strncat ( string, "\n", 1 );
return string;
}
if ( strlen ( string ))
if ( string [0] != '~' )
return string;
else
return ( (char *) ExpandTildeName ( string ));
else
return 0;
}
/* Cas du Controle G */
else if ( (keysym == XK_Control_L) ||
(keysym == XK_Control_R)) {
continue;
/* on ne fait rien */
}
else if ( keysym == XK_g && event.xkey.state == ControlMask ) {
XUngrabPointer ( dpy, CurrentTime );
string [0] = '\007';
string [1] = '\0';
return string;
}
/* Cas des caracteres imprimables */
else if ( ( (keysym >= XK_KP_Space)
&& (keysym <= XK_KP_9) )
|| ( (keysym >= XK_space)
&& (keysym <= XK_asciitilde) ) ) {
if ( reply != 0 ) {
XUngrabPointer ( dpy, CurrentTime );
(void) strncat ( string, buffer, 1 );
string [1] = '\0';
return string;
}
if ( (strlen(string) + strlen(buffer))
>= MAXLENGTH
|| XTextWidth ( font, s, strlen (s))
+ XTextWidth ( font, string,
strlen (string)) > max ) {
XBell ( dpy, VOLUME );
continue;
}
else {
(void) strncat ( string, buffer, 1 );
}
}
/* Cas shift */
else if ( (keysym >= XK_Shift_L )
&& (keysym <= XK_Shift_R) ) {
/* On fait rien */
continue;
}
/* Cas des fonctions speciales */
else if ( (keysym >= XK_F1) && (keysym <= XK_F35) ) {
if ( buffer == NULL )
(void) fprintf ( stderr, "Umapped function key\n" );
/* on ne fait rien */
else if ( (strlen(string) + strlen(buffer)) >= MAXLENGTH )
XBell ( dpy, VOLUME );
else {
XBell ( dpy, VOLUME );
continue;
}
}
/* Cas delete et backspace. */
else if ( (keysym == XK_BackSpace) || (keysym ==XK_Delete) ) {
if ( (length = strlen(string)) > 0 ) {
string [ length - 1 ] = 0;
cur_x_old = cur_x;
cur_x = start_x +
XTextWidth ( font, string, strlen (string));
XClearArea( dpy, w, cur_x, y - font -> ascent,
(font_h / 2) + (cur_x_old - cur_x),
font_h, False );
XFillRectangle ( dpy, w, gc, cur_x, y - font -> ascent,
font_h/2, font_h );
}
else
XBell ( dpy, VOLUME );
continue;
}
else {
XBell ( dpy, VOLUME );
continue;
}
XDrawImageString ( dpy, w, gc, cur_x, y, buffer, 1 );
cur_x_old = cur_x;
cur_x += XTextWidth ( font, buffer, 1 );
XFillRectangle ( dpy, w, gc, cur_x, y - font -> ascent, font_h/2, font_h );
break;
}
}
}
/*
** Function name : ExpandTildeName
**
** Description : Recherche le path de l'expression ~[name]
** Input : ~/, ~name
** Ouput : Le path
*/
char *ExpandTildeName ( name )
register char *name;
{
register struct passwd *pwd;
register char *home;
register char *p = name + 1;
static char buf [256];
bzero ( buf, 128 );
if ( name [1] == '/' ) { /* c'est moi */
if ( (home = (char *) getenv ( "HOME" )) == 0 )
return name;
(void) strcpy ( buf, home );
(void) strcat ( buf, name + 1 );
}
else { /* c'est un autre */
while ( *p && *p != '/' ) p++;
*p = 0;
pwd = getpwnam ( name + 1 );
if ( pwd ) {
(void) strcpy ( buf, pwd -> pw_dir);
*p = '/';
(void) strcat ( buf, p );
}
else
return name;
}
return buf;
}