mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-11 14:30:08 +00:00
Support for dynamically changing window size
* Beginning of support for fullscreen mode * Fullscreen depends on "fuzzing" the graphics
This commit is contained in:
parent
b5023f88f4
commit
12f6c9704e
@ -735,6 +735,7 @@ typedef enum interface_enum_t {
|
|||||||
OPT_PATH,
|
OPT_PATH,
|
||||||
//OPT_MODE,
|
//OPT_MODE,
|
||||||
OPT_COLOR,
|
OPT_COLOR,
|
||||||
|
OPT_VIDEO,
|
||||||
OPT_VOLUME,
|
OPT_VOLUME,
|
||||||
OPT_JOYSTICK,
|
OPT_JOYSTICK,
|
||||||
OPT_CALIBRATE,
|
OPT_CALIBRATE,
|
||||||
@ -750,6 +751,7 @@ static const char *options[] =
|
|||||||
" Path : ",
|
" Path : ",
|
||||||
//" Mode : ",
|
//" Mode : ",
|
||||||
" Color : ",
|
" Color : ",
|
||||||
|
" Video : ",
|
||||||
" Volume : ",
|
" Volume : ",
|
||||||
" Joystick : ",
|
" Joystick : ",
|
||||||
" Calibrate Joystick...",
|
" Calibrate Joystick...",
|
||||||
@ -864,6 +866,10 @@ void c_interface_parameters()
|
|||||||
(color_mode == COLOR_INTERP) ? "Interpolated" : "Black/White ");
|
(color_mode == COLOR_INTERP) ? "Interpolated" : "Black/White ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_VIDEO:
|
||||||
|
sprintf(temp, "%s", (a2_video_mode == VIDEO_1X) ? "1X " : (a2_video_mode == VIDEO_2X) ? "2X " : "Fullscreen");
|
||||||
|
break;
|
||||||
|
|
||||||
case OPT_VOLUME:
|
case OPT_VOLUME:
|
||||||
if (sound_volume == 0)
|
if (sound_volume == 0)
|
||||||
{
|
{
|
||||||
@ -1031,6 +1037,18 @@ void c_interface_parameters()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_VIDEO:
|
||||||
|
if (a2_video_mode == 1)
|
||||||
|
{
|
||||||
|
a2_video_mode = NUM_VIDOPTS-1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--a2_video_mode;
|
||||||
|
}
|
||||||
|
video_set_mode(a2_video_mode);
|
||||||
|
break;
|
||||||
|
|
||||||
case OPT_VOLUME:
|
case OPT_VOLUME:
|
||||||
if (sound_volume > 0)
|
if (sound_volume > 0)
|
||||||
{
|
{
|
||||||
@ -1124,6 +1142,18 @@ void c_interface_parameters()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_VIDEO:
|
||||||
|
if (a2_video_mode == NUM_VIDOPTS-1)
|
||||||
|
{
|
||||||
|
a2_video_mode = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++a2_video_mode;
|
||||||
|
}
|
||||||
|
video_set_mode(a2_video_mode);
|
||||||
|
break;
|
||||||
|
|
||||||
case OPT_VOLUME:
|
case OPT_VOLUME:
|
||||||
sound_volume++;
|
sound_volume++;
|
||||||
if (sound_volume > 10)
|
if (sound_volume > 10)
|
||||||
|
17
src/prefs.c
17
src/prefs.c
@ -37,6 +37,7 @@
|
|||||||
#define PRM_HIRES_COLOR 4
|
#define PRM_HIRES_COLOR 4
|
||||||
#define PRM_VOLUME 5
|
#define PRM_VOLUME 5
|
||||||
#define PRM_JOY_INPUT 6
|
#define PRM_JOY_INPUT 6
|
||||||
|
#define PRM_VIDEO_MODE 7
|
||||||
#define PRM_JOY_PC_CALIBRATE 10
|
#define PRM_JOY_PC_CALIBRATE 10
|
||||||
#define PRM_JOY_KPAD_CALIBRATE 11
|
#define PRM_JOY_KPAD_CALIBRATE 11
|
||||||
#define PRM_ROM_PATH 12
|
#define PRM_ROM_PATH 12
|
||||||
@ -48,6 +49,7 @@ char disk_path[DISKSIZE];
|
|||||||
int apple_mode;
|
int apple_mode;
|
||||||
int sound_volume;
|
int sound_volume;
|
||||||
color_mode_t color_mode;
|
color_mode_t color_mode;
|
||||||
|
a2_video_mode_t a2_video_mode;
|
||||||
joystick_mode_t joy_mode;
|
joystick_mode_t joy_mode;
|
||||||
|
|
||||||
static char *config_filename = NULL;
|
static char *config_filename = NULL;
|
||||||
@ -68,6 +70,7 @@ static const struct match_table prefs_table[] =
|
|||||||
{ "disk_path", PRM_DISK_PATH },
|
{ "disk_path", PRM_DISK_PATH },
|
||||||
{ "path", PRM_DISK_PATH },
|
{ "path", PRM_DISK_PATH },
|
||||||
{ "color", PRM_HIRES_COLOR },
|
{ "color", PRM_HIRES_COLOR },
|
||||||
|
{ "video", PRM_VIDEO_MODE },
|
||||||
{ "volume", PRM_VOLUME },
|
{ "volume", PRM_VOLUME },
|
||||||
{ "joystick", PRM_JOY_INPUT },
|
{ "joystick", PRM_JOY_INPUT },
|
||||||
{ "pc joystick parms", PRM_JOY_PC_CALIBRATE },
|
{ "pc joystick parms", PRM_JOY_PC_CALIBRATE },
|
||||||
@ -99,6 +102,14 @@ static const struct match_table color_table[] =
|
|||||||
{ 0, COLOR }
|
{ 0, COLOR }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct match_table video_table[] =
|
||||||
|
{
|
||||||
|
{ "1X", VIDEO_1X },
|
||||||
|
{ "2X", VIDEO_2X },
|
||||||
|
{ "Fullscreen", VIDEO_FULLSCREEN },
|
||||||
|
{ 0, VIDEO_1X }
|
||||||
|
};
|
||||||
|
|
||||||
static const struct match_table volume_table[] =
|
static const struct match_table volume_table[] =
|
||||||
{
|
{
|
||||||
{ "0", 0 },
|
{ "0", 0 },
|
||||||
@ -274,6 +285,10 @@ void load_settings(void)
|
|||||||
color_mode = match(color_table, argument);
|
color_mode = match(color_table, argument);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PRM_VIDEO_MODE:
|
||||||
|
a2_video_mode = match(video_table, argument);
|
||||||
|
break;
|
||||||
|
|
||||||
case PRM_VOLUME:
|
case PRM_VOLUME:
|
||||||
sound_volume = match(volume_table, argument);
|
sound_volume = match(volume_table, argument);
|
||||||
break;
|
break;
|
||||||
@ -388,6 +403,7 @@ bool save_settings(void)
|
|||||||
"mode = %s\n"
|
"mode = %s\n"
|
||||||
"disk path = %s\n"
|
"disk path = %s\n"
|
||||||
"color = %s\n"
|
"color = %s\n"
|
||||||
|
"video = %s\n"
|
||||||
"volume = %s\n"
|
"volume = %s\n"
|
||||||
"joystick = %s\n"
|
"joystick = %s\n"
|
||||||
"system path = %s\n",
|
"system path = %s\n",
|
||||||
@ -396,6 +412,7 @@ bool save_settings(void)
|
|||||||
reverse_match(modes_table, apple_mode),
|
reverse_match(modes_table, apple_mode),
|
||||||
disk_path,
|
disk_path,
|
||||||
reverse_match(color_table, color_mode),
|
reverse_match(color_table, color_mode),
|
||||||
|
reverse_match(video_table, a2_video_mode),
|
||||||
reverse_match(volume_table, sound_volume),
|
reverse_match(volume_table, sound_volume),
|
||||||
reverse_match(joy_input_table, joy_mode),
|
reverse_match(joy_input_table, joy_mode),
|
||||||
system_path);
|
system_path);
|
||||||
|
@ -41,6 +41,13 @@ typedef enum color_mode_t {
|
|||||||
NUM_COLOROPTS
|
NUM_COLOROPTS
|
||||||
} color_mode_t;
|
} color_mode_t;
|
||||||
|
|
||||||
|
typedef enum a2_video_mode_t {
|
||||||
|
VIDEO_FULLSCREEN = 0,
|
||||||
|
VIDEO_1X,
|
||||||
|
VIDEO_2X,
|
||||||
|
NUM_VIDOPTS
|
||||||
|
} a2_video_mode_t;
|
||||||
|
|
||||||
#define SYSSIZE 4096
|
#define SYSSIZE 4096
|
||||||
extern char system_path[SYSSIZE];
|
extern char system_path[SYSSIZE];
|
||||||
#define DISKSIZE 4096
|
#define DISKSIZE 4096
|
||||||
@ -49,6 +56,7 @@ extern char disk_path[DISKSIZE];
|
|||||||
extern int apple_mode; /* undocumented instructions or //e mode */
|
extern int apple_mode; /* undocumented instructions or //e mode */
|
||||||
extern int sound_volume;
|
extern int sound_volume;
|
||||||
extern color_mode_t color_mode;
|
extern color_mode_t color_mode;
|
||||||
|
extern a2_video_mode_t a2_video_mode;
|
||||||
|
|
||||||
/* generic joystick settings */
|
/* generic joystick settings */
|
||||||
extern joystick_mode_t joy_mode;
|
extern joystick_mode_t joy_mode;
|
||||||
|
10
src/video.h
10
src/video.h
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
#include "prefs.h"
|
||||||
|
|
||||||
/* Prepare the video system, converting console to graphics mode, or
|
/* Prepare the video system, converting console to graphics mode, or
|
||||||
* opening X window, or whatever. This is called only once when the
|
* opening X window, or whatever. This is called only once when the
|
||||||
* emulator is run
|
* emulator is run
|
||||||
@ -104,13 +106,7 @@ void video_plotchar(int row, int col, int color, unsigned char code);
|
|||||||
*/
|
*/
|
||||||
void video_sync(int block);
|
void video_sync(int block);
|
||||||
|
|
||||||
typedef enum A2_VIDSCALE {
|
void video_set_mode(a2_video_mode_t mode);
|
||||||
VIDEO_FULL_SCREEN = 0,
|
|
||||||
VIDEO_SCALE_1,
|
|
||||||
VIDEO_SCALE_2
|
|
||||||
} A2_VIDSCALE;
|
|
||||||
|
|
||||||
void video_setscale();
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLER__ */
|
#endif /* !__ASSEMBLER__ */
|
||||||
|
|
||||||
|
249
src/xvideo.c
249
src/xvideo.c
@ -42,24 +42,39 @@ static Display *display;
|
|||||||
static Window win;
|
static Window win;
|
||||||
static GC gc;
|
static GC gc;
|
||||||
static unsigned int width, height; /* window size */
|
static unsigned int width, height; /* window size */
|
||||||
static A2_VIDSCALE scale = VIDEO_SCALE_1;
|
static unsigned int scale = 1;
|
||||||
|
|
||||||
static int screen_num;
|
static int screen_num;
|
||||||
static XVisualInfo visualinfo;
|
static XVisualInfo visualinfo;
|
||||||
static XColor colors[256];
|
static XColor colors[256];
|
||||||
XImage *image;
|
static XImage *image=NULL;
|
||||||
static Colormap cmap;
|
static Colormap cmap;
|
||||||
XEvent xevent;
|
static XEvent xevent;
|
||||||
|
|
||||||
|
static XSizeHints *size_hints=NULL;
|
||||||
|
static XWMHints *wm_hints=NULL;
|
||||||
|
static XClassHint *class_hints=NULL;
|
||||||
|
static XTextProperty windowName, iconName;
|
||||||
|
|
||||||
static uint32_t red_shift;
|
static uint32_t red_shift;
|
||||||
static uint32_t green_shift;
|
static uint32_t green_shift;
|
||||||
static uint32_t blue_shift;
|
static uint32_t blue_shift;
|
||||||
static uint32_t alpha_shift;
|
static uint32_t alpha_shift;
|
||||||
|
|
||||||
int doShm = 1; /* assume true */
|
static int doShm = 1; /* assume true */
|
||||||
XShmSegmentInfo xshminfo;
|
static XShmSegmentInfo xshminfo;
|
||||||
int xshmeventtype;
|
static int xshmeventtype;
|
||||||
|
|
||||||
|
// pad pixels to uint32_t boundaries
|
||||||
|
static int bitmap_pad = sizeof(uint32_t);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long functions;
|
||||||
|
unsigned long decorations;
|
||||||
|
long inputMode;
|
||||||
|
unsigned long status;
|
||||||
|
} FullScreenHints;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
video_setpage(p): Switch to screen page p
|
video_setpage(p): Switch to screen page p
|
||||||
@ -462,7 +477,7 @@ static void post_image() {
|
|||||||
((uint32_t)(colors[index].blue) << blue_shift) |
|
((uint32_t)(colors[index].blue) << blue_shift) |
|
||||||
((uint32_t)0xff /* alpha */ << alpha_shift)
|
((uint32_t)0xff /* alpha */ << alpha_shift)
|
||||||
);
|
);
|
||||||
if (scale == VIDEO_SCALE_2)
|
if (scale > 1)
|
||||||
{
|
{
|
||||||
j+=4;
|
j+=4;
|
||||||
|
|
||||||
@ -637,13 +652,137 @@ static void parseArgs() {
|
|||||||
{
|
{
|
||||||
doShm=0;
|
doShm=0;
|
||||||
}
|
}
|
||||||
else if (strstr(argv[i], "-2"))
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _destroy_image() {
|
||||||
|
if (doShm)
|
||||||
|
{
|
||||||
|
// Detach from X server
|
||||||
|
if (!XShmDetach(display, &xshminfo))
|
||||||
{
|
{
|
||||||
scale=VIDEO_SCALE_2;
|
fprintf(stderr,"XShmDetach() failed in video_shutdown()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
XDestroyImage(image);
|
||||||
|
|
||||||
|
// Release shared memory.
|
||||||
|
shmdt(xshminfo.shmaddr);
|
||||||
|
shmctl(xshminfo.shmid, IPC_RMID, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XDestroyImage(image);
|
||||||
|
//free(image->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _create_image() {
|
||||||
|
int pixel_buffer_size = width*height*bitmap_pad;
|
||||||
|
|
||||||
|
if (doShm) {
|
||||||
|
image = XShmCreateImage(display, visualinfo.visual, visualinfo.depth, ZPixmap, NULL, &xshminfo, width, height);
|
||||||
|
|
||||||
|
if (!image) {
|
||||||
|
ERRQUIT("XShmCreateImage failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG("Allocating shared memory: bytes_per_line:%ds height:x%d (depth:%d) bitmap_pad:%d",
|
||||||
|
image->bytes_per_line, image->height, visualinfo.depth, bitmap_pad);
|
||||||
|
|
||||||
|
getshm(pixel_buffer_size);
|
||||||
|
|
||||||
|
/* get the X server to attach to it */
|
||||||
|
if (!XShmAttach(display, &xshminfo)) {
|
||||||
|
ERRQUIT("XShmAttach() failed");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
void *data = malloc(pixel_buffer_size);
|
||||||
|
if (!data) {
|
||||||
|
ERRQUIT("no memory for image data!");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG("Creating regular XImage");
|
||||||
|
image = XCreateImage(display, visualinfo.visual, visualinfo.depth, ZPixmap, 0 /*offset*/, data, width, height, 8, width*bitmap_pad /*bytes_per_line*/);
|
||||||
|
|
||||||
|
if (!image) {
|
||||||
|
ERRQUIT("XCreateImage failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _size_hints_set_fixed() {
|
||||||
|
size_hints->flags = PPosition | PSize | PMinSize | PMaxSize;
|
||||||
|
size_hints->min_width = width;
|
||||||
|
size_hints->min_height = height;
|
||||||
|
size_hints->max_width = XDisplayWidth(display, 0);
|
||||||
|
size_hints->max_height = XDisplayHeight(display, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _size_hints_set_resize() {
|
||||||
|
size_hints->flags = USPosition | USSize | PMinSize | PMaxSize;
|
||||||
|
size_hints->min_width = width;
|
||||||
|
size_hints->min_height = height;
|
||||||
|
size_hints->max_width = XDisplayWidth(display, 0);
|
||||||
|
size_hints->max_height = XDisplayHeight(display, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void video_set_mode(a2_video_mode_t mode) {
|
||||||
|
_destroy_image();
|
||||||
|
|
||||||
|
scale = mode;
|
||||||
|
if (mode == VIDEO_FULLSCREEN) {
|
||||||
|
scale = 1; // HACK FIXME for now ................
|
||||||
|
}
|
||||||
|
|
||||||
|
width = SCANWIDTH*scale;
|
||||||
|
height = SCANHEIGHT*scale;
|
||||||
|
|
||||||
|
_size_hints_set_resize();
|
||||||
|
|
||||||
|
//XResizeWindow(display, win, width, height);
|
||||||
|
XSetWMProperties(display, win, &windowName, &iconName,
|
||||||
|
argv, argc, size_hints, wm_hints,
|
||||||
|
class_hints);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// TODO ...
|
||||||
|
// Fullscreen mode really should "fuzz" the graphics like AppleWin does when emulating NTSC.
|
||||||
|
// Also will need to verify the canonical way to switch to fullscreen in X11
|
||||||
|
// http://www.tonyobryan.com/index.php?article=9
|
||||||
|
if (mode == VIDEO_FULLSCREEN) {
|
||||||
|
FullScreenHints hints = { .flags=2, .decorations=0 };
|
||||||
|
Atom property = XInternAtom(display, "_MOTIF_WM_HINTS", True);
|
||||||
|
|
||||||
|
XChangeProperty(display, win, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
|
||||||
|
|
||||||
|
/*
|
||||||
|
int modecount_return = 0;
|
||||||
|
XF86VidModeModeInfo *modesinfo = NULL;
|
||||||
|
XF86VidModeGetAllModeLines(display, DefaultScreen(display), &modecount_return, &modesinfo);
|
||||||
|
XF86VidModeSwitchToMode(display, DefaultScreen(display), video_mode);
|
||||||
|
XF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
int display_w = XDisplayWidth(display, 0);
|
||||||
|
int display_h = XDisplayHeight(display, 0);
|
||||||
|
LOG("Fullscreen : %d x %d", display_w, display_h);
|
||||||
|
|
||||||
|
XMoveResizeWindow(display, win, 0, 0, display_w, display_h);
|
||||||
|
XMapRaised(display, win);
|
||||||
|
XGrabPointer(display, win, True, 0, GrabModeAsync, GrabModeAsync, win, 0L, CurrentTime);
|
||||||
|
XGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
XWindowChanges changes = { .width=width, .height=height };
|
||||||
|
XConfigureWindow(display, win, CWWidth|CWHeight, &changes);
|
||||||
|
|
||||||
|
_create_image();
|
||||||
|
|
||||||
|
_size_hints_set_fixed();
|
||||||
|
}
|
||||||
|
|
||||||
void video_init() {
|
void video_init() {
|
||||||
XSetWindowAttributes attribs;
|
XSetWindowAttributes attribs;
|
||||||
unsigned long attribmask;
|
unsigned long attribmask;
|
||||||
@ -652,12 +791,8 @@ void video_init() {
|
|||||||
//unsigned int display_width, display_height;
|
//unsigned int display_width, display_height;
|
||||||
XGCValues xgcvalues;
|
XGCValues xgcvalues;
|
||||||
int valuemask;
|
int valuemask;
|
||||||
char *window_name = "Apple ][";
|
char *window_name = "Apple //ix";
|
||||||
char *icon_name = window_name;
|
char *icon_name = window_name;
|
||||||
XSizeHints *size_hints;
|
|
||||||
XWMHints *wm_hints;
|
|
||||||
XClassHint *class_hints;
|
|
||||||
XTextProperty windowName, iconName;
|
|
||||||
//GC gc;
|
//GC gc;
|
||||||
char *progname; /* name this program was invoked by */
|
char *progname; /* name this program was invoked by */
|
||||||
char *displayname = NULL;
|
char *displayname = NULL;
|
||||||
@ -728,7 +863,7 @@ void video_init() {
|
|||||||
unsigned int shift = 0;
|
unsigned int shift = 0;
|
||||||
for (unsigned int i=0; i<4; i++)
|
for (unsigned int i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
if ((((uint32_t)visualinfo.red_mask >>shift) & 0xff) == (uint32_t)0xff)
|
if ((((uint32_t)visualinfo.red_mask >>shift) & 0xff) == (uint32_t)0xff)
|
||||||
{
|
{
|
||||||
red_shift = shift;
|
red_shift = shift;
|
||||||
}
|
}
|
||||||
@ -757,6 +892,11 @@ void video_init() {
|
|||||||
fprintf(stderr, "red mask:%08x green mask:%08x blue mask:%08x\n", (uint32_t)visualinfo.red_mask, (uint32_t)visualinfo.blue_mask, (uint32_t)visualinfo.green_mask);
|
fprintf(stderr, "red mask:%08x green mask:%08x blue mask:%08x\n", (uint32_t)visualinfo.red_mask, (uint32_t)visualinfo.blue_mask, (uint32_t)visualinfo.green_mask);
|
||||||
fprintf(stderr, "redshift:%08d greenshift:%08d blueshift:%08d alphashift:%08d\n", red_shift, blue_shift, green_shift, alpha_shift);
|
fprintf(stderr, "redshift:%08d greenshift:%08d blueshift:%08d alphashift:%08d\n", red_shift, blue_shift, green_shift, alpha_shift);
|
||||||
|
|
||||||
|
scale = a2_video_mode;
|
||||||
|
if (a2_video_mode == VIDEO_FULLSCREEN) {
|
||||||
|
scale = 1; // HACK FIXME FOR NOW ...
|
||||||
|
}
|
||||||
|
|
||||||
/* Note that in a real Xlib application, x and y would default to 0
|
/* Note that in a real Xlib application, x and y would default to 0
|
||||||
* but would be settable from the command line or resource database.
|
* but would be settable from the command line or resource database.
|
||||||
*/
|
*/
|
||||||
@ -811,16 +951,6 @@ void video_init() {
|
|||||||
attribmask,
|
attribmask,
|
||||||
&attribs);
|
&attribs);
|
||||||
|
|
||||||
/* set size hints for window manager. We don't want the user to
|
|
||||||
* dynamically allocate window size since we won't do the right
|
|
||||||
* scaling in response. Whaddya want, performance or a snazzy gui?
|
|
||||||
*/
|
|
||||||
size_hints->flags = PPosition | PSize | PMinSize | PMaxSize;
|
|
||||||
size_hints->min_width = width;
|
|
||||||
size_hints->min_height = height;
|
|
||||||
size_hints->max_width = width;
|
|
||||||
size_hints->max_height = height;
|
|
||||||
|
|
||||||
/* store window_name and icon_name for niceity. */
|
/* store window_name and icon_name for niceity. */
|
||||||
if (XStringListToTextProperty(&window_name, 1, &windowName) == 0)
|
if (XStringListToTextProperty(&window_name, 1, &windowName) == 0)
|
||||||
{
|
{
|
||||||
@ -842,6 +972,7 @@ void video_init() {
|
|||||||
class_hints->res_name = progname;
|
class_hints->res_name = progname;
|
||||||
class_hints->res_class = "Apple2";
|
class_hints->res_class = "Apple2";
|
||||||
|
|
||||||
|
_size_hints_set_fixed();
|
||||||
XSetWMProperties(display, win, &windowName, &iconName,
|
XSetWMProperties(display, win, &windowName, &iconName,
|
||||||
argv, argc, size_hints, wm_hints,
|
argv, argc, size_hints, wm_hints,
|
||||||
class_hints);
|
class_hints);
|
||||||
@ -868,53 +999,9 @@ void video_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pad pixels to uint32_t boundaries
|
|
||||||
int bitmap_pad = sizeof(uint32_t);
|
|
||||||
int pixel_buffer_size = width*height*bitmap_pad;
|
|
||||||
|
|
||||||
xshmeventtype = XShmGetEventBase(display) + ShmCompletion;
|
xshmeventtype = XShmGetEventBase(display) + ShmCompletion;
|
||||||
|
|
||||||
/* create the image */
|
_create_image();
|
||||||
if (doShm)
|
|
||||||
{
|
|
||||||
image = XShmCreateImage(display, visualinfo.visual, visualinfo.depth, ZPixmap, NULL, &xshminfo, width, height);
|
|
||||||
|
|
||||||
if (!image)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "XShmCreateImage failed\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Allocating shared memory: bytes_per_line:%ds height:x%d (depth:%d) bitmap_pad:%d\n",
|
|
||||||
image->bytes_per_line, image->height, visualinfo.depth, bitmap_pad);
|
|
||||||
|
|
||||||
getshm(pixel_buffer_size);
|
|
||||||
|
|
||||||
/* get the X server to attach to it */
|
|
||||||
if (!XShmAttach(display, &xshminfo))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "XShmAttach() failed in InitGraphics()\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
void *data = malloc(pixel_buffer_size); // pad to uint32_t
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "no memory for image data!\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Creating regular XImage\n");
|
|
||||||
image = XCreateImage(display, visualinfo.visual, visualinfo.depth, ZPixmap, 0 /*offset*/, data, width, height, 8, width*bitmap_pad /*bytes_per_line*/);
|
|
||||||
|
|
||||||
if (!image)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "XCreateImage failed\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
video__fb1 = vga_mem_page_0;
|
video__fb1 = vga_mem_page_0;
|
||||||
video__fb2 = vga_mem_page_1;
|
video__fb2 = vga_mem_page_1;
|
||||||
@ -936,25 +1023,7 @@ void video_init() {
|
|||||||
|
|
||||||
void video_shutdown(void)
|
void video_shutdown(void)
|
||||||
{
|
{
|
||||||
if (doShm)
|
_destroy_image();
|
||||||
{
|
|
||||||
// Detach from X server
|
|
||||||
if (!XShmDetach(display, &xshminfo))
|
|
||||||
{
|
|
||||||
fprintf(stderr,"XShmDetach() failed in video_shutdown()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release shared memory.
|
|
||||||
shmdt(xshminfo.shmaddr);
|
|
||||||
shmctl(xshminfo.shmid, IPC_RMID, 0);
|
|
||||||
|
|
||||||
// Paranoia.
|
|
||||||
image->data = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
free(image->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user