1 /* $Header: /home/yav/xpx/RCS/inputstr.c,v 1.9 1995/11/25 16:06:57 yav Exp $
2  * xpx string input
3  * written by yav (UHD98984@pcvan.or.jp)
4  */
5 
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 #include <X11/keysym.h>
9 
10 #include "headers.h"
11 #include "xpx.h"
12 #define PIBLIC_INPUTSTR_C
13 #include "extern.h"
14 
15 char rcsid_inputstr[] = "$Id: inputstr.c,v 1.9 1995/11/25 16:06:57 yav Exp $";
16 
17 /*
18  * buf:           str:
19  *     abcdef         ghi
20  *        ^- pos
21  *               |
22  *               v
23  *     abcghidef
24  *           ^- pos
25  * return:
26  *     insert character count
27  */
insert_string(char * buf,int bufsz,int pos,char * str)28 int insert_string(
29 #if NeedFunctionPrototypes
30 	      char *buf, int bufsz, int pos, char *str)
31 #else
32      buf, bufsz, pos, str)
33      char *buf;
34      int bufsz;
35      int pos;
36      char *str;
37 #endif
38 {
39   int i;
40   int srclen;
41   char *p;
42 
43   srclen = strlen(str);
44   /* move tail */
45   i = strlen(buf+pos);
46   if (pos + i + srclen >= bufsz)
47     return 0;
48   if (i == 0) {
49     strcpy(buf+pos, str);
50   } else {
51     p = (char*)malloc(i+1);
52     if (p == NULL)
53       return 0;
54     strcpy(p, buf+pos);
55     strcpy(buf+pos+srclen, p);
56     free(p);
57     strncpy(buf+pos, str, srclen);
58   }
59   return srclen;
60 }
61 
62 /* return != 0 cannot to delete
63  */
delete_character(char * buf,int pos)64 int delete_character(
65 #if NeedFunctionPrototypes
66 		 char *buf, int pos)
67 #else
68      buf, pos)
69      char *buf;
70      int pos;
71 #endif
72 {
73   int i;
74   char *p;
75 
76   i = strlen(buf) - pos;
77   if (i > 0) {
78     p = (char*)malloc(i+1);
79     if (p != NULL) {
80       strcpy(p, buf+pos+1);
81       strcpy(buf+pos, p);
82       free(p);
83       return 0;
84     }
85   }
86   return 1;
87 }
88 
89 /* return redraw req. bit0:cursor bit1:string bit2:enter bit3:cancel
90  */
edit_string(XKeyEvent * ev,char * buffer,int bufferlen,int * cursor)91 int edit_string(
92 #if NeedFunctionPrototypes
93 	    XKeyEvent *ev, char *buffer, int bufferlen, int *cursor)
94 #else
95      ev, buffer, bufferlen, cursor)
96      XKeyEvent *ev;
97      char *buffer;
98      int bufferlen;
99      int *cursor;
100 #endif
101 {
102   int i;
103   KeySym key;
104   char buf[16];
105   static struct {KeySym sym; int func;} functbl[] = {
106     {XK_Right,		'F'-0x40},
107     {XK_KP_Right,	'F'-0x40},
108     {XK_Left,		'B'-0x40},
109     {XK_KP_Left,	'B'-0x40},
110     {XK_BackSpace,	'H'-0x40},
111     {XK_Delete,		'D'-0x40},
112     {XK_Up,		'P'-0x40},
113     {XK_KP_Up,		'P'-0x40},
114     {XK_Down,		'N'-0x40},
115     {XK_KP_Down,	'N'-0x40},
116     {XK_KP_Enter,	0x0d},
117     {XK_Return,		0x0d},
118     {XK_Escape,		0x1b},
119     {0, 0}
120   };
121 
122   i = XLookupString(ev, buf, sizeof(buf)-1, &key, NULL);
123   buf[i] = '\0';
124   for (i = 0; functbl[i].func; i++) {
125     if (functbl[i].sym == key) {
126       buf[0] = functbl[i].func;
127       break;
128     }
129   }
130   switch(buf[0]) {
131   case 'F'-0x40:		/* next char */
132     if (*cursor < strlen(buffer)) {
133       ++*cursor;
134       return 1;
135     }
136     break;
137   case 'B'-0x40:		/* backward char */
138     if (*cursor > 0) {
139       --*cursor;
140       return 1;
141     }
142     break;
143   case 'H'-0x40:		/* backward delete char */
144     if (*cursor > 0) {
145       --*cursor;
146       delete_character(buffer, *cursor);
147       return 3;
148     }
149     break;
150   case 'D'-0x40:		/* delete char */
151     if (*(buffer+*cursor) != '\0') {
152       delete_character(buffer, *cursor);
153       return 2;
154     }
155     break;
156   case 'A'-0x40:		/* beginning of line */
157     *cursor = 0;
158     return 1;
159   case 'E'-0x40:		/* end of file */
160     *cursor = strlen(buffer);
161     return 1;
162   case 'P'-0x40:		/* previous line (no-operation) */
163     break;
164   case 'N'-0x40:		/* next line (no-operation) */
165     break;
166   case 0x0d:			/* enter */
167     return 4|3;
168   case 0x1b:			/* escape */
169     return 8|3;
170   default:
171     if (strlen(buf) && buf[0] >= ' ') {
172       *cursor += insert_string(buffer, bufferlen, *cursor, buf);
173       return 3;
174     }
175   }
176   return 0;
177 }
178 
179 /* End of file */
180