/[gxemul]/upstream/0.3.2/src/x11.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /upstream/0.3.2/src/x11.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (hide annotations)
Mon Oct 8 16:18:06 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 24070 byte(s)
0.3.2
1 dpavlin 2 /*
2     * Copyright (C) 2003-2005 Anders Gavare. All rights reserved.
3     *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28     * $Id: x11.c,v 1.56 2005/03/05 12:17:53 debug Exp $
29     *
30     * X11-related functions.
31     */
32    
33     #include <stdio.h>
34     #include <stdlib.h>
35     #include <string.h>
36    
37     #include "console.h"
38     #include "emul.h"
39     #include "machine.h"
40     #include "misc.h"
41     #include "x11.h"
42    
43    
44     #ifndef WITH_X11
45    
46    
47     /* Dummy functions: */
48     void x11_redraw_cursor(struct machine *m, int i) { }
49     void x11_redraw(struct machine *m, int x) { }
50     void x11_putpixel_fb(struct machine *m, int fb, int x, int y, int color) { }
51     void x11_init(struct machine *machine) { }
52     struct fb_window *x11_fb_init(int xsize, int ysize, char *name,
53     int scaledown, struct machine *machine)
54     { return NULL; }
55     void x11_check_event(struct emul **emuls, int n_emuls) { }
56    
57    
58     #else /* WITH_X11 */
59    
60    
61     #include <X11/Xlib.h>
62     #include <X11/Xutil.h>
63     #include <X11/cursorfont.h>
64    
65    
66     /*
67     * x11_redraw_cursor():
68     *
69     * Redraw a framebuffer's X11 cursor.
70     */
71     void x11_redraw_cursor(struct machine *m, int i)
72     {
73     int last_color_used = 0;
74     int n_colors_used = 0;
75    
76     /* Remove old cursor, if any: */
77     if (m->fb_windows[i]->x11_display != NULL &&
78     m->fb_windows[i]->OLD_cursor_on) {
79     XPutImage(m->fb_windows[i]->x11_display,
80     m->fb_windows[i]->x11_fb_window,
81     m->fb_windows[i]->x11_fb_gc, m->fb_windows[i]->fb_ximage,
82     m->fb_windows[i]->OLD_cursor_x/m->fb_windows[i]->scaledown,
83     m->fb_windows[i]->OLD_cursor_y/m->fb_windows[i]->scaledown,
84     m->fb_windows[i]->OLD_cursor_x/m->fb_windows[i]->scaledown,
85     m->fb_windows[i]->OLD_cursor_y/m->fb_windows[i]->scaledown,
86     m->fb_windows[i]->OLD_cursor_xsize/
87     m->fb_windows[i]->scaledown + 1,
88     m->fb_windows[i]->OLD_cursor_ysize/
89     m->fb_windows[i]->scaledown + 1);
90     }
91    
92     if (m->fb_windows[i]->x11_display != NULL &&
93     m->fb_windows[i]->cursor_on) {
94     int x, y, subx, suby;
95     XImage *xtmp;
96    
97     xtmp = XSubImage(m->fb_windows[i]->fb_ximage,
98     m->fb_windows[i]->cursor_x/m->fb_windows[i]->scaledown,
99     m->fb_windows[i]->cursor_y/m->fb_windows[i]->scaledown,
100     m->fb_windows[i]->cursor_xsize/
101     m->fb_windows[i]->scaledown + 1,
102     m->fb_windows[i]->cursor_ysize/
103     m->fb_windows[i]->scaledown + 1);
104     if (xtmp == NULL) {
105     fatal("out of memory in x11_redraw_cursor()\n");
106     return;
107     }
108    
109     for (y=0; y<m->fb_windows[i]->cursor_ysize;
110     y+=m->fb_windows[i]->scaledown)
111     for (x=0; x<m->fb_windows[i]->cursor_xsize;
112     x+=m->fb_windows[i]->scaledown) {
113     int px = x/m->fb_windows[i]->scaledown;
114     int py = y/m->fb_windows[i]->scaledown;
115     int p = 0, n = 0, c = 0;
116     unsigned long oldcol;
117    
118     for (suby=0; suby<m->fb_windows[i]->scaledown;
119     suby++)
120     for (subx=0; subx<m->fb_windows[i]->
121     scaledown; subx++) {
122     c = m->fb_windows[i]->
123     cursor_pixels[y+suby]
124     [x+subx];
125     if (c >= 0) {
126     p += c;
127     n++;
128     }
129     }
130     if (n > 0)
131     p /= n;
132     else
133     p = c;
134    
135     if (n_colors_used == 0) {
136     last_color_used = p;
137     n_colors_used = 1;
138     } else
139     if (p != last_color_used)
140     n_colors_used = 2;
141    
142     switch (p) {
143     case CURSOR_COLOR_TRANSPARENT:
144     break;
145     case CURSOR_COLOR_INVERT:
146     oldcol = XGetPixel(xtmp, px, py);
147     if (oldcol != m->fb_windows[i]->
148     x11_graycolor[N_GRAYCOLORS-1].pixel)
149     oldcol = m->fb_windows[i]->
150     x11_graycolor[N_GRAYCOLORS
151     -1].pixel;
152     else
153     oldcol = m->fb_windows[i]->
154     x11_graycolor[0].pixel;
155     XPutPixel(xtmp, px, py, oldcol);
156     break;
157     default: /* Normal grayscale: */
158     XPutPixel(xtmp, px, py, m->fb_windows[
159     i]->x11_graycolor[p].pixel);
160     }
161     }
162    
163     XPutImage(m->fb_windows[i]->x11_display,
164     m->fb_windows[i]->x11_fb_window,
165     m->fb_windows[i]->x11_fb_gc,
166     xtmp, 0, 0,
167     m->fb_windows[i]->cursor_x/m->fb_windows[i]->scaledown,
168     m->fb_windows[i]->cursor_y/m->fb_windows[i]->scaledown,
169     m->fb_windows[i]->cursor_xsize/m->fb_windows[i]->scaledown,
170     m->fb_windows[i]->cursor_ysize/m->fb_windows[i]->scaledown);
171    
172     XDestroyImage(xtmp);
173    
174     m->fb_windows[i]->OLD_cursor_on = m->fb_windows[i]->cursor_on;
175     m->fb_windows[i]->OLD_cursor_x = m->fb_windows[i]->cursor_x;
176     m->fb_windows[i]->OLD_cursor_y = m->fb_windows[i]->cursor_y;
177     m->fb_windows[i]->OLD_cursor_xsize =
178     m->fb_windows[i]->cursor_xsize;
179     m->fb_windows[i]->OLD_cursor_ysize =
180     m->fb_windows[i]->cursor_ysize;
181     XFlush(m->fb_windows[i]->x11_display);
182     }
183    
184     /* printf("n_colors_used = %i\n", n_colors_used); */
185    
186     if (m->fb_windows[i]->host_cursor != 0 && n_colors_used < 2) {
187     /* Remove the old X11 host cursor: */
188     XUndefineCursor(m->fb_windows[i]->x11_display,
189     m->fb_windows[i]->x11_fb_window);
190     XFlush(m->fb_windows[i]->x11_display);
191     XFreeCursor(m->fb_windows[i]->x11_display,
192     m->fb_windows[i]->host_cursor);
193     m->fb_windows[i]->host_cursor = 0;
194     }
195    
196     if (n_colors_used >= 2 && m->fb_windows[i]->host_cursor == 0) {
197     GC tmpgc;
198    
199     /* Create a new X11 host cursor: */
200     /* cursor = XCreateFontCursor(m->fb_windows[i]->x11_display,
201     XC_coffee_mug); :-) */
202     if (m->fb_windows[i]->host_cursor_pixmap != 0) {
203     XFreePixmap(m->fb_windows[i]->x11_display,
204     m->fb_windows[i]->host_cursor_pixmap);
205     m->fb_windows[i]->host_cursor_pixmap = 0;
206     }
207     m->fb_windows[i]->host_cursor_pixmap =
208     XCreatePixmap(m->fb_windows[i]->x11_display,
209     m->fb_windows[i]->x11_fb_window, 1, 1, 1);
210     XSetForeground(m->fb_windows[i]->x11_display,
211     m->fb_windows[i]->x11_fb_gc,
212     m->fb_windows[i]->x11_graycolor[0].pixel);
213    
214     tmpgc = XCreateGC(m->fb_windows[i]->x11_display,
215     m->fb_windows[i]->host_cursor_pixmap, 0,0);
216    
217     XDrawPoint(m->fb_windows[i]->x11_display,
218     m->fb_windows[i]->host_cursor_pixmap,
219     tmpgc, 0, 0);
220    
221     XFreeGC(m->fb_windows[i]->x11_display, tmpgc);
222    
223     m->fb_windows[i]->host_cursor =
224     XCreatePixmapCursor(m->fb_windows[i]->x11_display,
225     m->fb_windows[i]->host_cursor_pixmap,
226     m->fb_windows[i]->host_cursor_pixmap,
227     &m->fb_windows[i]->x11_graycolor[N_GRAYCOLORS-1],
228     &m->fb_windows[i]->x11_graycolor[N_GRAYCOLORS-1],
229     0, 0);
230     if (m->fb_windows[i]->host_cursor != 0) {
231     XDefineCursor(m->fb_windows[i]->x11_display,
232     m->fb_windows[i]->x11_fb_window,
233     m->fb_windows[i]->host_cursor);
234     XFlush(m->fb_windows[i]->x11_display);
235     }
236     }
237     }
238    
239    
240     /*
241     * x11_redraw():
242     *
243     * Redraw X11 windows.
244     */
245     void x11_redraw(struct machine *m, int i)
246     {
247     if (i < 0 || i >= m->n_fb_windows ||
248     m->fb_windows[i]->x11_fb_winxsize <= 0)
249     return;
250    
251     x11_putimage_fb(m, i);
252     x11_redraw_cursor(m, i);
253     XFlush(m->fb_windows[i]->x11_display);
254     }
255    
256    
257     /*
258     * x11_putpixel_fb():
259     *
260     * Output a framebuffer pixel. i is the framebuffer number.
261     */
262     void x11_putpixel_fb(struct machine *m, int i, int x, int y, int color)
263     {
264     if (i < 0 || i >= m->n_fb_windows ||
265     m->fb_windows[i]->x11_fb_winxsize <= 0)
266     return;
267    
268     if (color)
269     XSetForeground(m->fb_windows[i]->x11_display,
270     m->fb_windows[i]->x11_fb_gc, m->fb_windows[i]->fg_color);
271     else
272     XSetForeground(m->fb_windows[i]->x11_display,
273     m->fb_windows[i]->x11_fb_gc, m->fb_windows[i]->bg_color);
274    
275     XDrawPoint(m->fb_windows[i]->x11_display,
276     m->fb_windows[i]->x11_fb_window, m->fb_windows[i]->x11_fb_gc, x, y);
277    
278     XFlush(m->fb_windows[i]->x11_display);
279     }
280    
281    
282     /*
283     * x11_putimage_fb():
284     *
285     * Output an entire XImage to a framebuffer window. i is the
286     * framebuffer number.
287     */
288     void x11_putimage_fb(struct machine *m, int i)
289     {
290     if (i < 0 || i >= m->n_fb_windows ||
291     m->fb_windows[i]->x11_fb_winxsize <= 0)
292     return;
293    
294     XPutImage(m->fb_windows[i]->x11_display,
295     m->fb_windows[i]->x11_fb_window,
296     m->fb_windows[i]->x11_fb_gc, m->fb_windows[i]->fb_ximage, 0,0, 0,0,
297     m->fb_windows[i]->x11_fb_winxsize,
298     m->fb_windows[i]->x11_fb_winysize);
299     XFlush(m->fb_windows[i]->x11_display);
300     }
301    
302    
303     /*
304     * x11_init():
305     *
306     * Initialize X11 stuff (but doesn't create any windows).
307     *
308     * It is then up to individual drivers, for example framebuffer devices,
309     * to initialize their own windows.
310     */
311     void x11_init(struct machine *m)
312     {
313     m->n_fb_windows = 0;
314    
315     if (m->x11_n_display_names > 0) {
316     int i;
317     for (i=0; i<m->x11_n_display_names; i++)
318     fatal("Using X11 display: %s\n",
319     m->x11_display_names[i]);
320     }
321    
322     m->x11_current_display_name_nr = 0;
323     }
324    
325    
326     /*
327     * x11_fb_init():
328     *
329     * Initialize a framebuffer window.
330     */
331     struct fb_window *x11_fb_init(int xsize, int ysize, char *name,
332     int scaledown, struct machine *m)
333     {
334     Display *x11_display;
335     int x, y, fb_number = 0;
336     size_t alloclen, alloc_depth;
337     XColor tmpcolor;
338     int i;
339     char fg[80], bg[80];
340     char *display_name;
341    
342     fb_number = m->n_fb_windows;
343    
344     m->fb_windows = realloc(m->fb_windows,
345     sizeof(struct fb_window *) * (m->n_fb_windows + 1));
346     if (m->fb_windows == NULL) {
347     fprintf(stderr, "x11_fb_init(): out of memory\n");
348     exit(1);
349     }
350     m->fb_windows[fb_number] = malloc(sizeof(struct fb_window));
351     if (m->fb_windows[fb_number] == NULL) {
352     fprintf(stderr, "x11_fb_init(): out of memory\n");
353     exit(1);
354     }
355    
356     m->n_fb_windows ++;
357    
358     memset(m->fb_windows[fb_number], 0, sizeof(struct fb_window));
359    
360     m->fb_windows[fb_number]->x11_fb_winxsize = xsize;
361     m->fb_windows[fb_number]->x11_fb_winysize = ysize;
362    
363     /* Which display name? */
364     display_name = NULL;
365     if (m->x11_n_display_names > 0) {
366     display_name = m->x11_display_names[
367     m->x11_current_display_name_nr];
368     m->x11_current_display_name_nr ++;
369     m->x11_current_display_name_nr %= m->x11_n_display_names;
370     }
371    
372     if (display_name != NULL)
373     debug("[ x11_fb_init(): framebuffer window %i, %ix%i, DISPLAY"
374     "=%s ]\n", fb_number, xsize, ysize, display_name);
375    
376     x11_display = XOpenDisplay(display_name);
377    
378     if (x11_display == NULL) {
379     fatal("x11_fb_init(\"%s\"): couldn't open display\n", name);
380     if (display_name != NULL)
381     fatal("display_name = '%s'\n", display_name);
382     exit(1);
383     }
384    
385     m->fb_windows[fb_number]->x11_screen = DefaultScreen(x11_display);
386     m->fb_windows[fb_number]->x11_screen_depth = DefaultDepth(x11_display,
387     m->fb_windows[fb_number]->x11_screen);
388    
389     if (m->fb_windows[fb_number]->x11_screen_depth != 8 &&
390     m->fb_windows[fb_number]->x11_screen_depth != 15 &&
391     m->fb_windows[fb_number]->x11_screen_depth != 16 &&
392     m->fb_windows[fb_number]->x11_screen_depth != 24) {
393     fatal("\n***\n*** WARNING! Your X server is running %i-bit "
394     "color mode. This is not really\n",
395     m->fb_windows[fb_number]->x11_screen_depth);
396     fatal("*** supported yet. 8, 15, 16, and 24 bits should "
397     "work.\n*** 24-bit server gives color. Any other bit "
398     "depth gives undefined result!\n***\n\n");
399     }
400    
401     if (m->fb_windows[fb_number]->x11_screen_depth <= 8)
402     debug("WARNING! X11 screen depth is not enough for color; "
403     "using only 16 grayscales instead\n");
404    
405     strcpy(bg, "Black");
406     strcpy(fg, "White");
407    
408     XParseColor(x11_display, DefaultColormap(x11_display,
409     m->fb_windows[fb_number]->x11_screen), fg, &tmpcolor);
410     XAllocColor(x11_display, DefaultColormap(x11_display,
411     m->fb_windows[fb_number]->x11_screen), &tmpcolor);
412     m->fb_windows[fb_number]->fg_color = tmpcolor.pixel;
413     XParseColor(x11_display, DefaultColormap(x11_display,
414     m->fb_windows[fb_number]->x11_screen), bg, &tmpcolor);
415     XAllocColor(x11_display, DefaultColormap(x11_display,
416     m->fb_windows[fb_number]->x11_screen), &tmpcolor);
417     m->fb_windows[fb_number]->bg_color = tmpcolor.pixel;
418    
419     for (i=0; i<N_GRAYCOLORS; i++) {
420     char cname[8];
421     cname[0] = '#';
422     cname[1] = cname[2] = cname[3] =
423     cname[4] = cname[5] = cname[6] =
424     "0123456789ABCDEF"[i];
425     cname[7] = '\0';
426     XParseColor(x11_display, DefaultColormap(x11_display,
427     m->fb_windows[fb_number]->x11_screen), cname,
428     &m->fb_windows[fb_number]->x11_graycolor[i]);
429     XAllocColor(x11_display, DefaultColormap(x11_display,
430     m->fb_windows[fb_number]->x11_screen),
431     &m->fb_windows[fb_number]->x11_graycolor[i]);
432     }
433    
434     XFlush(x11_display);
435    
436     alloc_depth = m->fb_windows[fb_number]->x11_screen_depth;
437    
438     if (alloc_depth == 24)
439     alloc_depth = 32;
440     if (alloc_depth == 15)
441     alloc_depth = 16;
442    
443     m->fb_windows[fb_number]->x11_fb_window = XCreateWindow(
444     x11_display, DefaultRootWindow(x11_display),
445     0, 0, m->fb_windows[fb_number]->x11_fb_winxsize,
446     m->fb_windows[fb_number]->x11_fb_winysize,
447     0, CopyFromParent, InputOutput, CopyFromParent, 0,0);
448    
449     XSetStandardProperties(x11_display,
450     m->fb_windows[fb_number]->x11_fb_window, name,
451     #ifdef VERSION
452     "GXemul-" VERSION,
453     #else
454     "GXemul",
455     #endif
456     None, NULL, 0, NULL);
457     XSelectInput(x11_display, m->fb_windows[fb_number]->x11_fb_window,
458     StructureNotifyMask | ExposureMask | ButtonPressMask |
459     ButtonReleaseMask | PointerMotionMask | KeyPressMask);
460     m->fb_windows[fb_number]->x11_fb_gc = XCreateGC(x11_display,
461     m->fb_windows[fb_number]->x11_fb_window, 0,0);
462    
463     /* Make sure the window is mapped: */
464     XMapRaised(x11_display, m->fb_windows[fb_number]->x11_fb_window);
465    
466     XSetBackground(x11_display, m->fb_windows[fb_number]->x11_fb_gc,
467     m->fb_windows[fb_number]->bg_color);
468     XSetForeground(x11_display, m->fb_windows[fb_number]->x11_fb_gc,
469     m->fb_windows[fb_number]->bg_color);
470     XFillRectangle(x11_display, m->fb_windows[fb_number]->x11_fb_window,
471     m->fb_windows[fb_number]->x11_fb_gc, 0,0,
472     m->fb_windows[fb_number]->x11_fb_winxsize,
473     m->fb_windows[fb_number]->x11_fb_winysize);
474    
475     m->fb_windows[fb_number]->x11_display = x11_display;
476     m->fb_windows[fb_number]->scaledown = scaledown;
477    
478     m->fb_windows[fb_number]->fb_number = fb_number;
479    
480     alloclen = xsize * ysize * alloc_depth / 8;
481     m->fb_windows[fb_number]->ximage_data = malloc(alloclen);
482     if (m->fb_windows[fb_number]->ximage_data == NULL) {
483     fprintf(stderr, "out of memory allocating ximage_data\n");
484     exit(1);
485     }
486    
487     m->fb_windows[fb_number]->fb_ximage = XCreateImage(
488     m->fb_windows[fb_number]->x11_display, CopyFromParent,
489     m->fb_windows[fb_number]->x11_screen_depth, ZPixmap, 0,
490     (char *)m->fb_windows[fb_number]->ximage_data,
491     xsize, ysize, 8, xsize * alloc_depth / 8);
492     if (m->fb_windows[fb_number]->fb_ximage == NULL) {
493     fprintf(stderr, "out of memory allocating ximage\n");
494     exit(1);
495     }
496    
497     /* Fill the ximage with black pixels: */
498     if (m->fb_windows[fb_number]->x11_screen_depth > 8)
499     memset(m->fb_windows[fb_number]->ximage_data, 0, alloclen);
500     else {
501     debug("x11_fb_init(): clearing the XImage\n");
502     for (y=0; y<ysize; y++)
503     for (x=0; x<xsize; x++)
504     XPutPixel(m->fb_windows[fb_number]->fb_ximage,
505     x, y, m->fb_windows[fb_number]->
506     x11_graycolor[0].pixel);
507     }
508    
509     x11_putimage_fb(m, fb_number);
510    
511     /* Fill the 64x64 "hardware" cursor with white pixels: */
512     xsize = ysize = 64;
513    
514     /* Fill the cursor ximage with white pixels: */
515     for (y=0; y<ysize; y++)
516     for (x=0; x<xsize; x++)
517     m->fb_windows[fb_number]->cursor_pixels[y][x] =
518     N_GRAYCOLORS-1;
519    
520     return m->fb_windows[fb_number];
521     }
522    
523    
524     /*
525     * x11_check_events_machine():
526     *
527     * Check for X11 events on a specific machine.
528     *
529     * TODO: Yuck! This has to be rewritten. Each display should be checked,
530     * and _then_ only those windows that are actually exposed should
531     * be redrawn!
532     */
533     static void x11_check_events_machine(struct emul **emuls, int n_emuls,
534     struct machine *m)
535     {
536     int fb_nr;
537    
538     for (fb_nr=0; fb_nr<m->n_fb_windows; fb_nr++) {
539     XEvent event;
540     int need_redraw = 0, found, i, j, k;
541    
542     while (XPending(m->fb_windows[fb_nr]->x11_display)) {
543     XNextEvent(m->fb_windows[fb_nr]->x11_display, &event);
544    
545     if (event.type==ConfigureNotify) {
546     need_redraw = 1;
547     }
548    
549     if (event.type==Expose && event.xexpose.count==0) {
550     /*
551     * TODO: the xexpose struct has x,y,width,
552     * height. Those could be used to only redraw
553     * the part of the framebuffer that was
554     * exposed. Note that the (mouse) cursor must
555     * be redrawn too.
556     */
557     /* x11_winxsize = event.xexpose.width;
558     x11_winysize = event.xexpose.height; */
559     need_redraw = 1;
560     }
561    
562     if (event.type == MotionNotify) {
563     /* debug("[ X11 MotionNotify: %i,%i ]\n",
564     event.xmotion.x, event.xmotion.y); */
565    
566     /* Which window in which machine in
567     which emulation? */
568     found = -1;
569     for (k=0; k<n_emuls; k++)
570     for (j=0; j<emuls[k]->n_machines; j++) {
571     struct machine *m2 = emuls[k]->
572     machines[j];
573     for (i=0; i<m2->n_fb_windows;
574     i++)
575     if (m->fb_windows[
576     fb_nr]->
577     x11_display == m2->
578     fb_windows[i]->
579     x11_display &&
580     event.xmotion.
581     window == m2->
582     fb_windows[i]->
583     x11_fb_window)
584     found = i;
585     }
586     if (found < 0) {
587     printf("Internal error in x11.c.\n");
588     exit(1);
589     }
590     console_mouse_coordinates(event.xmotion.x *
591     m->fb_windows[found]->scaledown,
592     event.xmotion.y * m->fb_windows[found]->
593     scaledown, found);
594     }
595    
596     if (event.type == ButtonPress) {
597     debug("[ X11 ButtonPress: %i ]\n",
598     event.xbutton.button);
599     /* button = 1,2,3 = left,middle,right */
600    
601     console_mouse_button(event.xbutton.button, 1);
602     }
603    
604     if (event.type == ButtonRelease) {
605     debug("[ X11 ButtonRelease: %i ]\n",
606     event.xbutton.button);
607     /* button = 1,2,3 = left,middle,right */
608    
609     console_mouse_button(event.xbutton.button, 0);
610     }
611    
612     if (event.type==KeyPress) {
613     char text[15];
614     KeySym key;
615     XKeyPressedEvent *ke = &event.xkey;
616    
617     memset(text, sizeof(text), 0);
618    
619     if (XLookupString(&event.xkey, text,
620     sizeof(text), &key, 0) == 1) {
621     console_makeavail(
622     m->main_console_handle, text[0]);
623     } else {
624     int x = ke->keycode;
625     /*
626     * Special key codes:
627     *
628     * NOTE/TODO: I'm hardcoding these to
629     * work with my key map. Maybe they
630     * should be read from some file...
631     *
632     * Important TODO 2: It would be MUCH
633     * better if these were converted into
634     * 'native scancodes', for example for
635     * the DECstation's keyboard or the
636     * PC-style 8042 controller.
637     */
638     switch (x) {
639     case 9: /* Escape */
640     console_makeavail(m->
641     main_console_handle, 27);
642     break;
643     #if 0
644     /* TODO */
645    
646     /* The numeric keypad: */
647     90=Ins('0') 91=Del(',')
648    
649     /* Above the cursor keys: */
650     106=Ins 107=Del
651     #endif
652     /* F1..F4: */
653     case 67: /* F1 */
654     case 68: /* F2 */
655     case 69: /* F3 */
656     case 70: /* F4 */
657     console_makeavail(m->
658     main_console_handle, 27);
659     console_makeavail(m->
660     main_console_handle, '[');
661     console_makeavail(m->
662     main_console_handle, 'O');
663     console_makeavail(m->
664     main_console_handle, 'P' +
665     x - 67);
666     break;
667     case 71: /* F5 */
668     console_makeavail(m->
669     main_console_handle, 27);
670     console_makeavail(m->
671     main_console_handle, '[');
672     console_makeavail(m->
673     main_console_handle, '1');
674     console_makeavail(m->
675     main_console_handle, '5');
676     break;
677     case 72: /* F6 */
678     case 73: /* F7 */
679     case 74: /* F8 */
680     console_makeavail(m->
681     main_console_handle, 27);
682     console_makeavail(m->
683     main_console_handle, '[');
684     console_makeavail(m->
685     main_console_handle, '1');
686     console_makeavail(m->
687     main_console_handle, '7' +
688     x - 72);
689     break;
690     case 75: /* F9 */
691     case 76: /* F10 */
692     console_makeavail(m->
693     main_console_handle, 27);
694     console_makeavail(m->
695     main_console_handle, '[');
696     console_makeavail(m->
697     main_console_handle, '2');
698     console_makeavail(m->
699     main_console_handle, '1' +
700     x - 68);
701     break;
702     case 95: /* F11 */
703     case 96: /* F12 */
704     console_makeavail(m->
705     main_console_handle, 27);
706     console_makeavail(m->
707     main_console_handle, '[');
708     console_makeavail(m->
709     main_console_handle, '2');
710     console_makeavail(m->
711     main_console_handle, '3' +
712     x - 95);
713     break;
714     /* Cursor keys: */
715     case 98: /* Up */
716     case 104: /* Down */
717     case 100: /* Left */
718     case 102: /* Right */
719     console_makeavail(m->
720     main_console_handle, 27);
721     console_makeavail(m->
722     main_console_handle, '[');
723     console_makeavail(m->
724     main_console_handle,
725     x == 98? 'A' : (
726     x == 104? 'B' : (
727     x == 102? 'C' : (
728     'D'))));
729     break;
730     /* Numeric keys: */
731     case 80: /* Up */
732     case 88: /* Down */
733     case 83: /* Left */
734     case 85: /* Right */
735     console_makeavail(m->
736     main_console_handle, 27);
737     console_makeavail(m->
738     main_console_handle, '[');
739     console_makeavail(m->
740     main_console_handle,
741     x == 80? 'A' : (
742     x == 88? 'B' : (
743     x == 85? 'C' : (
744     'D'))));
745     break;
746     case 97: /* Cursor Home */
747     case 79: /* Numeric Home */
748     console_makeavail(m->
749     main_console_handle, 27);
750     console_makeavail(m->
751     main_console_handle, '[');
752     console_makeavail(m->
753     main_console_handle, 'H');
754     break;
755     case 103: /* Cursor End */
756     case 87: /* Numeric End */
757     console_makeavail(m->
758     main_console_handle, 27);
759     console_makeavail(m->
760     main_console_handle, '[');
761     console_makeavail(m->
762     main_console_handle, 'F');
763     break;
764     case 99: /* Cursor PgUp */
765     case 81: /* Numeric PgUp */
766     console_makeavail(m->
767     main_console_handle, 27);
768     console_makeavail(m->
769     main_console_handle, '[');
770     console_makeavail(m->
771     main_console_handle, '5');
772     console_makeavail(m->
773     main_console_handle, '~');
774     break;
775     case 105: /* Cursor PgUp */
776     case 89: /* Numeric PgDn */
777     console_makeavail(m->
778     main_console_handle, 27);
779     console_makeavail(m->
780     main_console_handle, '[');
781     console_makeavail(m->
782     main_console_handle, '6');
783     console_makeavail(m->
784     main_console_handle, '~');
785     break;
786     default:
787     debug("[ unimplemented X11 "
788     "keycode %i ]\n", x);
789     }
790     }
791     }
792     }
793    
794     if (need_redraw)
795     x11_redraw(m, fb_nr);
796     }
797     }
798    
799    
800     /*
801     * x11_check_event():
802     *
803     * Check for X11 events.
804     */
805     void x11_check_event(struct emul **emuls, int n_emuls)
806     {
807     int i, j;
808    
809     for (i=0; i<n_emuls; i++)
810     for (j=0; j<emuls[i]->n_machines; j++)
811     x11_check_events_machine(emuls, n_emuls,
812     emuls[i]->machines[j]);
813     }
814    
815     #endif /* WITH_X11 */

  ViewVC Help
Powered by ViewVC 1.1.26