mirror of
https://github.com/digarok/gsplus.git
synced 2024-11-24 22:30:55 +00:00
149 lines
7.4 KiB
Plaintext
149 lines
7.4 KiB
Plaintext
|
|
||
|
xdriver.c contains the routines for interfacing to X windows. The rest
|
||
|
of KEGS interacts with X windows only through xdriver.c routines.
|
||
|
|
||
|
Externally called routines are:
|
||
|
show_xcolor_array(): Debug routine, it does not need to do anything.
|
||
|
dev_video_init(): Called at startup, it should open up the
|
||
|
window and do other initialization.
|
||
|
update_physical_colormap(): Updates the X windows palette with the colors
|
||
|
from xcolor_a2vid_array[], which is maintained by
|
||
|
other xdriver routines.
|
||
|
update_status_line(): Call to update the internal array of chars
|
||
|
representing the status lines at the bottom of
|
||
|
the window. Does not draw the chars to the screen.
|
||
|
xdriver_end(): Shutdown routine
|
||
|
check_input_events(): Called up to 60 times a second (see video_update() in
|
||
|
video.c) to handle any X window events and get
|
||
|
keypresses.
|
||
|
On a mouse press, call update_mouse() with the
|
||
|
new x, y coordinates, and the status of the mouse
|
||
|
button.
|
||
|
If g_warp_pointer is set, constrain mouse within
|
||
|
the window.
|
||
|
On keypress, calls handle_keysym().
|
||
|
handle_keysym(): Takes X keysym, and converts to the appropriate
|
||
|
a2code using the a2_key_to_xsym[] lookup table.
|
||
|
The a2codes are the Apple // ADB keycodes.
|
||
|
Special work is done to handle shift and control
|
||
|
properly since Apple only has one keycode for both
|
||
|
shift and control keys. Then call
|
||
|
adb_physical_key_update() with the a2 keycode and
|
||
|
is_up = 1 if keyup, 0 = if key down.
|
||
|
In addition, this routine handles all the Function
|
||
|
keys doing special actions, which should be easy to
|
||
|
port.
|
||
|
x_refresh_ximage(): Redraws the window using the a2_line_* arrays.
|
||
|
Described in more detail below.
|
||
|
update_color_array(): Interface to the color map. Sets color[col_num]
|
||
|
of the internal colormap array to a2_color.
|
||
|
a2_color is the 12 bit apple color of the form:
|
||
|
(red << 8) + (green << 4) + (blue).
|
||
|
There are 16 palettes of 16 colors each, managed as
|
||
|
one 256-color colormap. See discussion of
|
||
|
g_a2vid_palette below.
|
||
|
x_auto_repeat_on(): The X routines turn off key repeat when the cursor
|
||
|
enters the graphics window automatically, and turn
|
||
|
it back on when the cursor leaves. But if the
|
||
|
debugger gets control due to a breakpoint, keyrepeat
|
||
|
would be left off. So the debugger calls this
|
||
|
routine to make sure key repeat is back on.
|
||
|
redraw_status_lines(): Draw the status lines from the g_status_buf[][] array
|
||
|
to the graphics window.
|
||
|
|
||
|
Externally referenced data:
|
||
|
|
||
|
g_use_shmem: Set by main() to enable/disable MIT-SHM for X.
|
||
|
Also used by sound routines to auto-turn-off sound
|
||
|
if not using MIT-SHM.
|
||
|
|
||
|
Bytes representing screen data:
|
||
|
byte *data_text[2]: Array of bytes for the lores and text pages 1 and 2.
|
||
|
Just 400*640 bytes.
|
||
|
byte *data_hires[2]: Array of bytes for the hires pages 1 and 2.
|
||
|
byte *data_superhires: Array of bytes for superhires screen.
|
||
|
byte *data_border_sides: Array of bytes representing the border sides.
|
||
|
Basically just A2_WINDOW_HEIGHT*EFF_BORDER_WIDTH bytes.
|
||
|
byte *data_border_special: Top and bottom border bytes.
|
||
|
(X_A2_WINDOW_HEIGHT - A2_WINDOW_HEIGHT + 2*8) *
|
||
|
(X_A2_WINDOW_WIDTH) bytes.
|
||
|
|
||
|
Handles used for X windows drawing:
|
||
|
XImage *ximage_hires[2]: Opaque handle to XImage object for hires page 1 and
|
||
|
page 2.
|
||
|
XImage *ximage_text[2]: Text pages 1 and 2.
|
||
|
XImage *ximage_superhires: Superhires graphics XImage
|
||
|
XImage *ximage_border_special: Top and bottom border XImage.
|
||
|
XImage *ximage_border_sides: Left and right sides (only one copy, it is
|
||
|
drawn at two different locations to be both sides).
|
||
|
|
||
|
Basic operation of xdriver:
|
||
|
--------------------------
|
||
|
|
||
|
X windows can push arrays of bytes to the screen through structures
|
||
|
called XImages. An XImage is a structure describing an offscreen bitmap.
|
||
|
For efficiency of page flipping, KEGS maintains separate bitmaps for the
|
||
|
two lores/text screens, the two hires screens, and the superhires screen.
|
||
|
It also maintains bitmaps for the border. For MIT-SHM to work, X
|
||
|
requires a unique XImage for each bitmap, and the bitmap must be allocated
|
||
|
within xdriver.c since it must be obtained through an shmat() call.
|
||
|
The X code also has non-MIT-SHM code which allocates the data_* buffers
|
||
|
just through malloc().
|
||
|
|
||
|
All bitmaps are 8-bits of Pseudo-color. The color arrays are managed
|
||
|
through the update_color_array() and update_physical_colormap() routines.
|
||
|
KEGS manages all 256 colors in the colormap as 16 palettes of 16 colors.
|
||
|
One of the palettes is reserved for the 16 lores colors, and is
|
||
|
indicated by the variable g_a2vid_palette. It defaults to 0xe.
|
||
|
Update_color_array() is called to update superhires colormap entries.
|
||
|
Update_color_array must not update colors corresponding to g_a2vid_palette.
|
||
|
Update_physical_colormap() pushes the color array managed by
|
||
|
update_color_array() to the screen, but first forces the lores colors into
|
||
|
the g_a2vid_palette palette. g_installed_full_superhires_colormap is
|
||
|
always false in KEGS for now. video.c calls update_color_array and changes
|
||
|
g_a2vid_palette. No xdriver routines gets notified when g_a2vid_palette
|
||
|
changes, so update_physical_colormap must handle the case where
|
||
|
g_a2vid_palette might have changed since it was last called.
|
||
|
|
||
|
x_redraw_ximage():
|
||
|
Routines in video.c are free to draw into the corresponding data_*
|
||
|
arrays to change any byte at any time. video.c manages remembering
|
||
|
which lines need to be redrawn and which parts of the screen are in
|
||
|
which video mode via the a2_line_* arrays.
|
||
|
|
||
|
KEGS divides the video screen up into 25 groups, corresponding to each
|
||
|
text line. Each of these groups consists of 16 sublines. 25*8 = 400 lines.
|
||
|
(video.c has already doubled the vertical resolution in all video modes).
|
||
|
KEGS can allow any group to be from any of the five screens it manages:
|
||
|
The two text/lores pages, the two hires pages, and the superhires screen.
|
||
|
For each group, KEGS keeps track of what part of it needs to be redrawn.
|
||
|
g_a2_screen_buffer_changed has a bit set for each group which has changed
|
||
|
since the last call to x_redraw_ximage(). The rightmost bit (bit 0)
|
||
|
corresponds to group 0. If g_a2_screen_buffer_changed == 0, no groups
|
||
|
need to be redrawn. x_redraw_ximage clears out g_a2_screen_buffer_changed
|
||
|
after drawing the screen.
|
||
|
|
||
|
For each group, a2_line_left_edge[] and a2_line_right_edge give the pixel
|
||
|
offsets of what should be redrawn. a2_line_xim[] gives the ximage handle
|
||
|
of what needs to be redrawn. KEGS always redraws 8 verticals of a group.
|
||
|
g_full_refresh_needed also has one bit set in it for each group, which
|
||
|
indicates overriding the a2_line_*_edge functions and redraw from 0 to
|
||
|
640 pixels of each group that needs to be redrawn. x_redraw_ximage()
|
||
|
interprets this information now using a simple algorithm: Skip over
|
||
|
groups which have not changed (using g_a2_screen_buffer_changed).
|
||
|
Save the ximage of this group, the left pixel and the right pixel.
|
||
|
Continue with the next group if it has changed. Widen the pixel region
|
||
|
and keep sucking up new groups to the same ximage. At group 25, or
|
||
|
when the ximage changes, call x_refresh_lines to redraw this large
|
||
|
rectangle from this ximage. x_refresh_lines() knows the ximage
|
||
|
corresponding to the border for the last group has to be handled
|
||
|
specially since the border group is not 640*400 pixels like the others.
|
||
|
|
||
|
Other porting info:
|
||
|
a2_key_to_xsym[][3] contains the mapping function from X keysyms to
|
||
|
a2 keycodes. The first element is the a2 keycode, the second element
|
||
|
is the unshifted X keysym, and the third element is the shifted keysym.
|
||
|
A port must make the conversion to a2 keycodes, and provide up and
|
||
|
down events.
|
||
|
|