1 |
|
/* |
2 |
|
* video_x.cpp - Video/graphics emulation, X11 specific stuff |
3 |
|
* |
4 |
< |
* SheepShaver (C) 1997-2005 Marc Hellwig and Christian Bauer |
4 |
> |
* SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
37 |
|
#include <sys/shm.h> |
38 |
|
#include <errno.h> |
39 |
|
#include <pthread.h> |
40 |
+ |
#include <semaphore.h> |
41 |
|
|
42 |
|
#include <algorithm> |
43 |
|
|
88 |
|
static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread |
89 |
|
static pthread_t redraw_thread; // Redraw thread |
90 |
|
|
90 |
– |
static bool local_X11; // Flag: X server running on local machine? |
91 |
|
static volatile bool thread_stop_req = false; |
92 |
< |
static volatile bool thread_stop_ack = false; // Acknowledge for thread_stop_req |
92 |
> |
static sem_t thread_stop_ack; |
93 |
> |
static sem_t thread_resume_req; |
94 |
|
|
95 |
+ |
static bool local_X11; // Flag: X server running on local machine? |
96 |
|
static bool has_dga = false; // Flag: Video DGA capable |
97 |
|
static bool has_vidmode = false; // Flag: VidMode extension available |
98 |
|
|
170 |
|
#endif |
171 |
|
|
172 |
|
// Mutex to protect palette |
173 |
< |
#ifdef HAVE_SPINLOCKS |
172 |
< |
static spinlock_t x_palette_lock = SPIN_LOCK_UNLOCKED; |
173 |
< |
#define LOCK_PALETTE spin_lock(&x_palette_lock) |
174 |
< |
#define UNLOCK_PALETTE spin_unlock(&x_palette_lock) |
175 |
< |
#elif defined(HAVE_PTHREADS) |
173 |
> |
#if defined(HAVE_PTHREADS) |
174 |
|
static pthread_mutex_t x_palette_lock = PTHREAD_MUTEX_INITIALIZER; |
175 |
|
#define LOCK_PALETTE pthread_mutex_lock(&x_palette_lock) |
176 |
|
#define UNLOCK_PALETTE pthread_mutex_unlock(&x_palette_lock) |
177 |
+ |
#elif defined(HAVE_SPINLOCKS) |
178 |
+ |
static spinlock_t x_palette_lock = SPIN_LOCK_UNLOCKED; |
179 |
+ |
#define LOCK_PALETTE spin_lock(&x_palette_lock) |
180 |
+ |
#define UNLOCK_PALETTE spin_unlock(&x_palette_lock) |
181 |
|
#else |
182 |
|
#define LOCK_PALETTE |
183 |
|
#define UNLOCK_PALETTE |
184 |
|
#endif |
185 |
|
|
186 |
|
// Mutex to protect frame buffer |
187 |
< |
#ifdef HAVE_SPINLOCKS |
186 |
< |
static spinlock_t frame_buffer_lock = SPIN_LOCK_UNLOCKED; |
187 |
< |
#define LOCK_FRAME_BUFFER spin_lock(&frame_buffer_lock) |
188 |
< |
#define UNLOCK_FRAME_BUFFER spin_unlock(&frame_buffer_lock) |
189 |
< |
#elif defined(HAVE_PTHREADS) |
187 |
> |
#if defined(HAVE_PTHREADS) |
188 |
|
static pthread_mutex_t frame_buffer_lock = PTHREAD_MUTEX_INITIALIZER; |
189 |
|
#define LOCK_FRAME_BUFFER pthread_mutex_lock(&frame_buffer_lock); |
190 |
|
#define UNLOCK_FRAME_BUFFER pthread_mutex_unlock(&frame_buffer_lock); |
191 |
+ |
#elif defined(HAVE_SPINLOCKS) |
192 |
+ |
static spinlock_t frame_buffer_lock = SPIN_LOCK_UNLOCKED; |
193 |
+ |
#define LOCK_FRAME_BUFFER spin_lock(&frame_buffer_lock) |
194 |
+ |
#define UNLOCK_FRAME_BUFFER spin_unlock(&frame_buffer_lock) |
195 |
|
#else |
196 |
|
#define LOCK_FRAME_BUFFER |
197 |
|
#define UNLOCK_FRAME_BUFFER |
1663 |
|
|
1664 |
|
// Start periodic thread |
1665 |
|
XSync(x_display, false); |
1666 |
+ |
if (sem_init(&thread_stop_ack, 0, 0) < 0) |
1667 |
+ |
return false; |
1668 |
+ |
if (sem_init(&thread_resume_req, 0, 0) < 0) |
1669 |
+ |
return false; |
1670 |
|
Set_pthread_attr(&redraw_thread_attr, 0); |
1671 |
|
redraw_thread_cancel = false; |
1672 |
|
redraw_thread_active = (pthread_create(&redraw_thread, &redraw_thread_attr, redraw_func, NULL) == 0); |
1686 |
|
redraw_thread_cancel = true; |
1687 |
|
pthread_cancel(redraw_thread); |
1688 |
|
pthread_join(redraw_thread, NULL); |
1689 |
+ |
sem_destroy(&thread_stop_ack); |
1690 |
+ |
sem_destroy(&thread_resume_req); |
1691 |
|
redraw_thread_active = false; |
1692 |
|
} |
1693 |
|
|
2165 |
|
csSave->savePage = ReadMacInt16(ParamPtr + csPage); |
2166 |
|
|
2167 |
|
// Disable interrupts and pause redraw thread |
2160 |
– |
DisableInterrupt(); |
2161 |
– |
thread_stop_ack = false; |
2168 |
|
thread_stop_req = true; |
2169 |
< |
while (!thread_stop_ack) ; |
2169 |
> |
sem_wait(&thread_stop_ack); |
2170 |
> |
thread_stop_req = false; |
2171 |
> |
DisableInterrupt(); |
2172 |
|
|
2173 |
|
/* close old display */ |
2174 |
|
close_display(); |
2189 |
|
csSave->saveMode=VModes[cur_mode].viAppleMode; |
2190 |
|
|
2191 |
|
// Enable interrupts and resume redraw thread |
2184 |
– |
thread_stop_req = false; |
2192 |
|
EnableInterrupt(); |
2193 |
+ |
sem_post(&thread_resume_req); |
2194 |
|
return noErr; |
2195 |
|
} |
2196 |
|
} |
2442 |
|
while (!redraw_thread_cancel) { |
2443 |
|
|
2444 |
|
// Pause if requested (during video mode switches) |
2445 |
< |
while (thread_stop_req) |
2446 |
< |
thread_stop_ack = true; |
2445 |
> |
if (thread_stop_req) { |
2446 |
> |
sem_post(&thread_stop_ack); |
2447 |
> |
sem_wait(&thread_resume_req); |
2448 |
> |
} |
2449 |
|
|
2450 |
|
int64 delay = next - GetTicks_usec(); |
2451 |
|
if (delay < -VIDEO_REFRESH_DELAY) { |
2559 |
|
} |
2560 |
|
return NULL; |
2561 |
|
} |
2562 |
+ |
|
2563 |
+ |
|
2564 |
+ |
/* |
2565 |
+ |
* Record dirty area from NQD |
2566 |
+ |
*/ |
2567 |
+ |
|
2568 |
+ |
void video_set_dirty_area(int x, int y, int w, int h) |
2569 |
+ |
{ |
2570 |
+ |
VideoInfo const & mode = VModes[cur_mode]; |
2571 |
+ |
const int screen_width = VIDEO_MODE_X; |
2572 |
+ |
const int screen_height = VIDEO_MODE_Y; |
2573 |
+ |
const int bytes_per_row = VIDEO_MODE_ROW_BYTES; |
2574 |
+ |
|
2575 |
+ |
#ifdef ENABLE_VOSF |
2576 |
+ |
if (use_vosf) { |
2577 |
+ |
vosf_set_dirty_area(x, y, w, h, screen_width, screen_height, bytes_per_row); |
2578 |
+ |
return; |
2579 |
+ |
} |
2580 |
+ |
#endif |
2581 |
+ |
|
2582 |
+ |
// XXX handle dirty bounding boxes for non-VOSF modes |
2583 |
+ |
} |