hopefully fix XCheckPred problem (PR 8547), and add support with -singleInstance
svn: r5701
This commit is contained in:
parent
75a0a02355
commit
efe9e73e8e
|
@ -118,6 +118,9 @@ static Scheme_Thread *user_main_thread;
|
||||||
|
|
||||||
extern void wxMediaIOCheckLSB(void);
|
extern void wxMediaIOCheckLSB(void);
|
||||||
extern void wxMouseEventHandled(void);
|
extern void wxMouseEventHandled(void);
|
||||||
|
#ifdef wx_xt
|
||||||
|
extern int wx_single_instance;
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mred.h"
|
#include "mred.h"
|
||||||
|
|
||||||
|
@ -3416,7 +3419,14 @@ void MrEdApp::RealInit(void)
|
||||||
scheme_exit = CAST_EXIT MrEdExit;
|
scheme_exit = CAST_EXIT MrEdExit;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
exit_val = mred_finish_cmd_line_run();
|
#ifdef wx_xt
|
||||||
|
if (wx_single_instance) {
|
||||||
|
exit_val = wxCheckSingleInstance(global_env);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!exit_val)
|
||||||
|
exit_val = mred_finish_cmd_line_run();
|
||||||
|
|
||||||
scheme_kill_thread(scheme_current_thread);
|
scheme_kill_thread(scheme_current_thread);
|
||||||
}
|
}
|
||||||
|
@ -3809,10 +3819,9 @@ static unsigned long get_deeper_base()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Mac AE support */
|
/* AE-like support */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
#if defined(wx_mac) || defined(wx_msw)
|
|
||||||
static void wxDo(Scheme_Object *proc, int argc, Scheme_Object **argv)
|
static void wxDo(Scheme_Object *proc, int argc, Scheme_Object **argv)
|
||||||
{
|
{
|
||||||
mz_jmp_buf * volatile save, newbuf;
|
mz_jmp_buf * volatile save, newbuf;
|
||||||
|
@ -3852,11 +3861,16 @@ void wxDrop_Runtime(char **argv, int argc)
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
Scheme_Object *p[1];
|
Scheme_Object *p[1];
|
||||||
|
#ifdef wx_xt
|
||||||
|
p[0] = scheme_char_string_to_path(scheme_make_utf8_string(argv[i]));
|
||||||
|
#else
|
||||||
p[0] = scheme_make_path(argv[i]);
|
p[0] = scheme_make_path(argv[i]);
|
||||||
|
#endif
|
||||||
wxDo(wxs_app_file_proc, 1, p);
|
wxDo(wxs_app_file_proc, 1, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(wx_mac) || defined(wx_msw)
|
||||||
void wxDrop_Quit()
|
void wxDrop_Quit()
|
||||||
{
|
{
|
||||||
#if WINDOW_STDIO
|
#if WINDOW_STDIO
|
||||||
|
|
|
@ -228,4 +228,5 @@ extern void WakeUpMrEd();
|
||||||
|
|
||||||
#if defined(wx_xt)
|
#if defined(wx_xt)
|
||||||
extern void wxUnhideAllCursors();
|
extern void wxUnhideAllCursors();
|
||||||
|
int wxCheckSingleInstance(Scheme_Env *global_env);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,6 +35,9 @@ static int grab_stack_pos = 0, grab_stack_size = 0;
|
||||||
|
|
||||||
extern Widget wx_clipWindow, wx_selWindow;
|
extern Widget wx_clipWindow, wx_selWindow;
|
||||||
|
|
||||||
|
Window wxAddClipboardWindowProperty(Atom prop);
|
||||||
|
extern Atom wx_single_instance_tag;
|
||||||
|
|
||||||
wxWindow *wxLocationToWindow(int x, int y);
|
wxWindow *wxLocationToWindow(int x, int y);
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -152,6 +155,41 @@ static Window GetEventWindow(XEvent *e)
|
||||||
static unsigned long lastUngrabTime;
|
static unsigned long lastUngrabTime;
|
||||||
static unsigned long lastUnhideTime;
|
static unsigned long lastUnhideTime;
|
||||||
|
|
||||||
|
class Check_Ungrab_Record {
|
||||||
|
public:
|
||||||
|
Window window;
|
||||||
|
int x, y, x_root, y_root;
|
||||||
|
Check_Ungrab_Record *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cur_registered = 0;
|
||||||
|
static Check_Ungrab_Record *first_cur = NULL, *last_cur = NULL;
|
||||||
|
|
||||||
|
static void CheckUngrab(Display *dpy, Check_Ungrab_Record *cur)
|
||||||
|
{
|
||||||
|
Window root;
|
||||||
|
int x, y;
|
||||||
|
unsigned w, h, b, d;
|
||||||
|
|
||||||
|
XGetGeometry(dpy, cur->window,
|
||||||
|
&root, &x, &y, &w, &h,
|
||||||
|
&b, &d);
|
||||||
|
if ((cur->x < 0) || (cur->y < 0)
|
||||||
|
|| ((unsigned int)cur->x > w) || ((unsigned int)cur->y > h)) {
|
||||||
|
/* Looks bad, but is it a click in a MrEd window
|
||||||
|
that we could care about? */
|
||||||
|
|
||||||
|
wxWindow *w;
|
||||||
|
w = wxLocationToWindow(cur->x_root, cur->y_root);
|
||||||
|
|
||||||
|
if (w) {
|
||||||
|
/* Looks like we need to ungrab */
|
||||||
|
XUngrabPointer(dpy, 0);
|
||||||
|
XUngrabKeyboard(dpy, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Bool CheckPred(Display *display, XEvent *e, char *args)
|
static Bool CheckPred(Display *display, XEvent *e, char *args)
|
||||||
{
|
{
|
||||||
Window window;
|
Window window;
|
||||||
|
@ -197,28 +235,23 @@ static Bool CheckPred(Display *display, XEvent *e, char *args)
|
||||||
/* lastUngrabTime keeps us from checking the same events
|
/* lastUngrabTime keeps us from checking the same events
|
||||||
over and over again. */
|
over and over again. */
|
||||||
if (e->xbutton.time > lastUngrabTime) {
|
if (e->xbutton.time > lastUngrabTime) {
|
||||||
Window root;
|
Check_Ungrab_Record *cur;
|
||||||
int x, y;
|
|
||||||
unsigned w, h, b, d;
|
|
||||||
|
|
||||||
XGetGeometry(XtDisplay(widget), e->xbutton.window,
|
if (!cur_registered) {
|
||||||
&root, &x, &y, &w, &h,
|
wxREGGLOB(first_cur);
|
||||||
&b, &d);
|
wxREGGLOB(last_cur);
|
||||||
if ((e->xbutton.x < 0) || (e->xbutton.y < 0)
|
|
||||||
|| ((unsigned int)e->xbutton.x > w) || ((unsigned int)e->xbutton.y > h)) {
|
|
||||||
/* Looks bad, but is it a click in a MrEd window
|
|
||||||
that we could care about? */
|
|
||||||
|
|
||||||
wxWindow *w;
|
|
||||||
w = wxLocationToWindow(e->xbutton.x_root, e->xbutton.y_root);
|
|
||||||
|
|
||||||
if (w) {
|
|
||||||
/* Looks like we need to ungrab */
|
|
||||||
XUngrabPointer(XtDisplay(widget), 0);
|
|
||||||
XUngrabKeyboard(XtDisplay(widget), 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
cur = new WXGC_PTRS Check_Ungrab_Record;
|
||||||
|
cur->window = e->xbutton.window;
|
||||||
|
cur->x = e->xbutton.x;
|
||||||
|
cur->y = e->xbutton.y;
|
||||||
|
cur->x_root = e->xbutton.x_root;
|
||||||
|
cur->y_root = e->xbutton.y_root;
|
||||||
|
if (last_cur)
|
||||||
|
last_cur->next = cur;
|
||||||
|
else
|
||||||
|
first_cur = cur;
|
||||||
|
last_cur = cur;
|
||||||
lastUngrabTime = e->xbutton.time;
|
lastUngrabTime = e->xbutton.time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,6 +372,7 @@ int MrEdGetNextEvent(int check_only, int current_only,
|
||||||
XEvent *event, MrEdContext **which)
|
XEvent *event, MrEdContext **which)
|
||||||
{
|
{
|
||||||
Display *d;
|
Display *d;
|
||||||
|
int got;
|
||||||
|
|
||||||
if (which)
|
if (which)
|
||||||
*which = NULL;
|
*which = NULL;
|
||||||
|
@ -351,7 +385,15 @@ int MrEdGetNextEvent(int check_only, int current_only,
|
||||||
else
|
else
|
||||||
d = XtDisplay(orig_top_level);
|
d = XtDisplay(orig_top_level);
|
||||||
|
|
||||||
if (XCheckIfEvent(d, event, CheckPred, (char *)which)) {
|
got = XCheckIfEvent(d, event, CheckPred, (char *)which);
|
||||||
|
|
||||||
|
while (first_cur) {
|
||||||
|
CheckUngrab(d, first_cur);
|
||||||
|
first_cur = first_cur->next;
|
||||||
|
}
|
||||||
|
last_cur = NULL;
|
||||||
|
|
||||||
|
if (got) {
|
||||||
just_check = 0;
|
just_check = 0;
|
||||||
return 1;
|
return 1;
|
||||||
} else if (short_circuit) {
|
} else if (short_circuit) {
|
||||||
|
@ -722,3 +764,179 @@ int wxUTF8StringToChar(char *str, int slen)
|
||||||
NULL, 0, '?');
|
NULL, 0, '?');
|
||||||
return (int)s[0];
|
return (int)s[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
static int has_property(Display *d, Window w, Atom atag)
|
||||||
|
{
|
||||||
|
Atom actual;
|
||||||
|
int format;
|
||||||
|
unsigned long count, remaining;
|
||||||
|
unsigned char *data = 0;
|
||||||
|
|
||||||
|
XGetWindowProperty(d, w, atag,
|
||||||
|
0, 0x8000000L, FALSE,
|
||||||
|
AnyPropertyType, &actual, &format,
|
||||||
|
&count, &remaining, &data);
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
XFree(data);
|
||||||
|
|
||||||
|
return (actual != None);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wxSendOrSetTag(char *pre_tag, char *tag, char *msg)
|
||||||
|
{
|
||||||
|
Display *d;
|
||||||
|
Window root, parent, *children;
|
||||||
|
unsigned int n, i;
|
||||||
|
Atom atag, apre_tag;
|
||||||
|
Window target = 0, me;
|
||||||
|
int try_again = 0;
|
||||||
|
|
||||||
|
/* Elect a leader, relying on the fact that the X server serializes
|
||||||
|
its interactions.
|
||||||
|
|
||||||
|
Each client sets a pre-tag, and then checks all windows. If any
|
||||||
|
window has a (non-pre) tag already, then that's the leader. If no
|
||||||
|
one else has a pre tag, then this client is elected, and it sets
|
||||||
|
the tag on itself. If someone else has a pre tag, we try again;
|
||||||
|
if the other window id is lower, this client drops it pre tag, so
|
||||||
|
that the other will be elected eventually. Note that if two
|
||||||
|
clients set a pre tag, then one must see the other (because
|
||||||
|
neither looks until its tag is set). Livelock is a possibility if
|
||||||
|
clients continuously appear with ever higher window ids, but that
|
||||||
|
possibility is exceedingly remote. */
|
||||||
|
|
||||||
|
if (!orig_top_level)
|
||||||
|
d = XtDisplay(save_top_level);
|
||||||
|
else
|
||||||
|
d = XtDisplay(orig_top_level);
|
||||||
|
|
||||||
|
apre_tag = XInternAtom(d, pre_tag, False);
|
||||||
|
atag = XInternAtom(d, tag, False);
|
||||||
|
|
||||||
|
wx_single_instance_tag = atag;
|
||||||
|
|
||||||
|
me = wxAddClipboardWindowProperty(apre_tag);
|
||||||
|
|
||||||
|
XFlush(d);
|
||||||
|
|
||||||
|
do {
|
||||||
|
XSync(d, FALSE);
|
||||||
|
if (XQueryTree(d, DefaultRootWindow(d),
|
||||||
|
&root, &parent, &children, &n)) {
|
||||||
|
for (i = n; i--; ) {
|
||||||
|
if (children[i] != me) {
|
||||||
|
if (has_property(d, children[i], atag)) {
|
||||||
|
target = children[i];
|
||||||
|
try_again = 0;
|
||||||
|
break;
|
||||||
|
} else if (has_property(d, children[i], apre_tag)) {
|
||||||
|
if ((long)me >= (long)children[i])
|
||||||
|
XDeleteProperty(d, me, apre_tag);
|
||||||
|
try_again = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children)
|
||||||
|
XFree(children);
|
||||||
|
}
|
||||||
|
} while (try_again);
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
GC_CAN_IGNORE XEvent xevent;
|
||||||
|
long mlen, offset = 0;
|
||||||
|
int sent_last = 0;
|
||||||
|
|
||||||
|
mlen = strlen(msg);
|
||||||
|
|
||||||
|
/* Send the message(s): */
|
||||||
|
while (!sent_last) {
|
||||||
|
memset(&xevent, 0, sizeof (xevent));
|
||||||
|
|
||||||
|
xevent.xany.type = ClientMessage;
|
||||||
|
xevent.xany.display = d;
|
||||||
|
xevent.xclient.window = target;
|
||||||
|
xevent.xclient.message_type = atag;
|
||||||
|
xevent.xclient.format = 8;
|
||||||
|
|
||||||
|
{
|
||||||
|
int i = sizeof(Window);
|
||||||
|
long w = (long)me;
|
||||||
|
|
||||||
|
while (i--) {
|
||||||
|
xevent.xclient.data.b[i] = (char)(w & 0xFF);
|
||||||
|
w = w >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < mlen) {
|
||||||
|
long amt;
|
||||||
|
amt = mlen - offset;
|
||||||
|
if (amt > (int)(20 - sizeof(Window)))
|
||||||
|
amt = 20 - sizeof(Window);
|
||||||
|
memcpy(xevent.xclient.data.b + sizeof(Window), msg + offset, amt);
|
||||||
|
offset += amt;
|
||||||
|
sent_last = (amt < (int)(20 - sizeof(Window)));
|
||||||
|
} else
|
||||||
|
sent_last = 1;
|
||||||
|
|
||||||
|
XSendEvent(d, target, 0, 0, &xevent);
|
||||||
|
}
|
||||||
|
|
||||||
|
XFlush(d);
|
||||||
|
XSync(d, FALSE);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
/* Set the property on the clipboard window */
|
||||||
|
wxAddClipboardWindowProperty(atag);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# define SINGLE_INSTANCE_HANDLER_CODE \
|
||||||
|
"(lambda (f)" \
|
||||||
|
" (let ([path (simplify-path" \
|
||||||
|
" (path->complete-path" \
|
||||||
|
" (or (find-executable-path (find-system-path 'run-file) #f)" \
|
||||||
|
" (find-system-path 'run-file))" \
|
||||||
|
" (current-directory)))])" \
|
||||||
|
" (let ([tag (string->bytes/utf-8" \
|
||||||
|
" (format \"~a_~a\" path (version)))])" \
|
||||||
|
" (f tag " \
|
||||||
|
" (bytes-append #\"pre\" tag)" \
|
||||||
|
" (apply" \
|
||||||
|
" bytes-append" \
|
||||||
|
" (map (lambda (s)" \
|
||||||
|
" (let ([s (path->string" \
|
||||||
|
" (path->complete-path s (current-directory)))])" \
|
||||||
|
" (string->bytes/utf-8" \
|
||||||
|
" (format \"~a:~a\"" \
|
||||||
|
" (string-length s)" \
|
||||||
|
" s))))" \
|
||||||
|
" (vector->list" \
|
||||||
|
" (current-command-line-arguments))))))))"
|
||||||
|
|
||||||
|
static Scheme_Object *prep_single_instance(int argc, Scheme_Object **argv)
|
||||||
|
{
|
||||||
|
return (wxSendOrSetTag(SCHEME_BYTE_STR_VAL(argv[0]),
|
||||||
|
SCHEME_BYTE_STR_VAL(argv[1]),
|
||||||
|
SCHEME_BYTE_STR_VAL(argv[2]))
|
||||||
|
? scheme_true
|
||||||
|
: scheme_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxCheckSingleInstance(Scheme_Env *global_env)
|
||||||
|
{
|
||||||
|
Scheme_Object *a[1], *v;
|
||||||
|
a[0] = scheme_make_prim(prep_single_instance);
|
||||||
|
v = scheme_apply(scheme_eval_string(SINGLE_INSTANCE_HANDLER_CODE,
|
||||||
|
global_env),
|
||||||
|
1,
|
||||||
|
a);
|
||||||
|
return SCHEME_TRUEP(v);
|
||||||
|
}
|
||||||
|
|
|
@ -2359,10 +2359,7 @@ static char *win_find_home()
|
||||||
static char *x_display_str;
|
static char *x_display_str;
|
||||||
extern void wxsRememberDisplay(char *str)
|
extern void wxsRememberDisplay(char *str)
|
||||||
{
|
{
|
||||||
if (str)
|
x_display_str = str;
|
||||||
x_display_str = str;
|
|
||||||
else
|
|
||||||
x_display_str = getenv("DISPLAY");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,8 @@ int wx_visual_depth;
|
||||||
Colormap wx_default_colormap;
|
Colormap wx_default_colormap;
|
||||||
unsigned long wx_white_pixel, wx_black_pixel;
|
unsigned long wx_white_pixel, wx_black_pixel;
|
||||||
|
|
||||||
|
int wx_single_instance = 0;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// wxApp implementation
|
// wxApp implementation
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -115,6 +117,8 @@ typedef struct {
|
||||||
int arg_count;
|
int arg_count;
|
||||||
} X_flag_entry;
|
} X_flag_entry;
|
||||||
|
|
||||||
|
#define SINGLE_INSTANCE "-singleInstance"
|
||||||
|
|
||||||
X_flag_entry X_flags[] = {
|
X_flag_entry X_flags[] = {
|
||||||
{ "-display", 1 },
|
{ "-display", 1 },
|
||||||
{ "-geometry", 1 },
|
{ "-geometry", 1 },
|
||||||
|
@ -134,6 +138,7 @@ X_flag_entry X_flags[] = {
|
||||||
{ "-title", 1 },
|
{ "-title", 1 },
|
||||||
{ "-xnllanguage", 1 },
|
{ "-xnllanguage", 1 },
|
||||||
{ "-xrm", 1 },
|
{ "-xrm", 1 },
|
||||||
|
{ SINGLE_INSTANCE, 0},
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -189,6 +194,9 @@ int wxEntry(int argc, char *argv[])
|
||||||
xargc = filter_x_readable(argv, argc, &x_display_str);
|
xargc = filter_x_readable(argv, argc, &x_display_str);
|
||||||
ate = xargc - 1;
|
ate = xargc - 1;
|
||||||
|
|
||||||
|
if (!x_display_str)
|
||||||
|
x_display_str = getenv("DISPLAY");
|
||||||
|
|
||||||
/* Remember -display or DISPLAY, in case someone needs it: */
|
/* Remember -display or DISPLAY, in case someone needs it: */
|
||||||
wxsRememberDisplay(x_display_str);
|
wxsRememberDisplay(x_display_str);
|
||||||
|
|
||||||
|
@ -199,8 +207,6 @@ int wxEntry(int argc, char *argv[])
|
||||||
&xargc, argv); // command line arguments
|
&xargc, argv); // command line arguments
|
||||||
|
|
||||||
if (!wxAPP_DISPLAY) {
|
if (!wxAPP_DISPLAY) {
|
||||||
if (!x_display_str)
|
|
||||||
x_display_str = getenv("DISPLAY");
|
|
||||||
if (!x_display_str) {
|
if (!x_display_str) {
|
||||||
printf("DISPLAY environment variable not set and no -display argument\n");
|
printf("DISPLAY environment variable not set and no -display argument\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,6 +215,15 @@ int wxEntry(int argc, char *argv[])
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((xargc > 1) && !strcmp("-singleInstance", argv[1])) {
|
||||||
|
wx_single_instance = 1;
|
||||||
|
--xargc;
|
||||||
|
if (xargc > 1) {
|
||||||
|
argv[1] = argv[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (xargc != 1) {
|
if (xargc != 1) {
|
||||||
printf("%s: standard X Window System flag \"%s\" was rejected\n",
|
printf("%s: standard X Window System flag \"%s\" was rejected\n",
|
||||||
argv[0], argv[1]);
|
argv[0], argv[1]);
|
||||||
|
@ -236,7 +251,8 @@ int wxEntry(int argc, char *argv[])
|
||||||
wxAPP_VISUAL = vi2.visual;
|
wxAPP_VISUAL = vi2.visual;
|
||||||
wx_visual_depth = 24;
|
wx_visual_depth = 24;
|
||||||
wx_default_colormap = XCreateColormap(wxAPP_DISPLAY,
|
wx_default_colormap = XCreateColormap(wxAPP_DISPLAY,
|
||||||
RootWindow(wxAPP_DISPLAY, DefaultScreen(wxAPP_DISPLAY)),
|
RootWindow(wxAPP_DISPLAY,
|
||||||
|
DefaultScreen(wxAPP_DISPLAY)),
|
||||||
wxAPP_VISUAL,
|
wxAPP_VISUAL,
|
||||||
AllocNone);
|
AllocNone);
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,14 @@ void wxInitClipboard(void)
|
||||||
xa_clipboard = ATOM("CLIPBOARD");
|
xa_clipboard = ATOM("CLIPBOARD");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window wxAddClipboardWindowProperty(Atom prop)
|
||||||
|
{
|
||||||
|
unsigned char data[1] = { 'm' };
|
||||||
|
XChangeProperty(XtDisplay(wx_clipWindow), XtWindow(wx_clipWindow),
|
||||||
|
prop, prop, 8, PropModeReplace, data, 1);
|
||||||
|
return XtWindow(wx_clipWindow);
|
||||||
|
}
|
||||||
|
|
||||||
static void AddClipboardFrame(wxClipboard *cb, int on)
|
static void AddClipboardFrame(wxClipboard *cb, int on)
|
||||||
{
|
{
|
||||||
if (!on)
|
if (!on)
|
||||||
|
|
|
@ -74,10 +74,24 @@ static Bool grabbing_panel_regsitered;
|
||||||
static int dnd_inited = 0;
|
static int dnd_inited = 0;
|
||||||
static DndClass dnd;
|
static DndClass dnd;
|
||||||
|
|
||||||
|
Atom wx_single_instance_tag = 0;
|
||||||
|
|
||||||
#ifndef NO_XMB_LOOKUP_STRING
|
#ifndef NO_XMB_LOOKUP_STRING
|
||||||
static XIM the_im;
|
static XIM the_im;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class Accum_Single_Instance_Message {
|
||||||
|
public:
|
||||||
|
long src;
|
||||||
|
char *accum;
|
||||||
|
int len, size;
|
||||||
|
Accum_Single_Instance_Message *next;
|
||||||
|
};
|
||||||
|
static int si_registered;
|
||||||
|
static Accum_Single_Instance_Message *si_msgs;
|
||||||
|
static void parse_and_drop_runtime(int len, char *s);
|
||||||
|
extern void wxDrop_Runtime(char **argv, int argc);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// wxWindow constructor
|
// wxWindow constructor
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1408,6 +1422,75 @@ void wxWindow::FrameEventHandler(Widget w,
|
||||||
if (win->OnClose())
|
if (win->OnClose())
|
||||||
win->Show(FALSE);
|
win->Show(FALSE);
|
||||||
}
|
}
|
||||||
|
if (wx_single_instance_tag) {
|
||||||
|
if (xev->xclient.message_type == wx_single_instance_tag) {
|
||||||
|
/* Accumulate msg data */
|
||||||
|
long src = 0;
|
||||||
|
int i;
|
||||||
|
Accum_Single_Instance_Message *msg, *prev = NULL;
|
||||||
|
|
||||||
|
if (!si_registered) {
|
||||||
|
wxREGGLOB(si_msgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = sizeof(Window); i--; ) {
|
||||||
|
src = (src << 8) | ((int)xev->xclient.data.b[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (msg = si_msgs; msg; msg = msg->next) {
|
||||||
|
if (msg->src == src)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!msg) {
|
||||||
|
char *s;
|
||||||
|
s = new WXGC_ATOMIC char[128];
|
||||||
|
msg = new WXGC_PTRS Accum_Single_Instance_Message;
|
||||||
|
msg->next = si_msgs;
|
||||||
|
si_msgs = msg;
|
||||||
|
msg->src = src;
|
||||||
|
msg->accum = s;
|
||||||
|
msg->len = 0;
|
||||||
|
msg->size = 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int len = sizeof(Window);
|
||||||
|
while (len < 20 && xev->xclient.data.b[len]) {
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
len -= sizeof(Window);
|
||||||
|
|
||||||
|
if (len) {
|
||||||
|
/* accumulate data */
|
||||||
|
if (msg->size < msg->len + 1 + len) {
|
||||||
|
char *naya;
|
||||||
|
int new_size = msg->size * 2;
|
||||||
|
naya = new WXGC_ATOMIC char[new_size];
|
||||||
|
memcpy(naya, msg->accum, msg->len);
|
||||||
|
msg->accum = naya;
|
||||||
|
msg->size = new_size;
|
||||||
|
}
|
||||||
|
memcpy(msg->accum + msg->len,
|
||||||
|
xev->xclient.data.b + sizeof(Window),
|
||||||
|
len);
|
||||||
|
msg->len += len;
|
||||||
|
if (len < (int)(20 - sizeof(Window)))
|
||||||
|
len = 0; /* inidicate that we're done */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!len) {
|
||||||
|
/* done */
|
||||||
|
if (prev)
|
||||||
|
prev->next = msg->next;
|
||||||
|
else
|
||||||
|
si_msgs = msg->next;
|
||||||
|
msg->accum[msg->len] = 0;
|
||||||
|
|
||||||
|
parse_and_drop_runtime(msg->len, msg->accum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (dnd_inited) {
|
if (dnd_inited) {
|
||||||
if (xev->xclient.message_type == dnd.XdndEnter) {
|
if (xev->xclient.message_type == dnd.XdndEnter) {
|
||||||
/* Ok... */
|
/* Ok... */
|
||||||
|
@ -2413,3 +2496,49 @@ wxWindow *wxWindow::FindChildByWidget(Widget w)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parse_and_drop_runtime(int len, char *s)
|
||||||
|
{
|
||||||
|
char **argv, *a;
|
||||||
|
int cnt = 0, pos = 0;
|
||||||
|
int sz;
|
||||||
|
|
||||||
|
while (pos < len) {
|
||||||
|
sz = 0;
|
||||||
|
while ((pos < len) && (s[pos] != ':')) {
|
||||||
|
sz = (sz * 10) + (s[pos] - '0');
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
if (sz > 0)
|
||||||
|
pos += sz;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
argv = new WXGC_PTRS char*[cnt];
|
||||||
|
|
||||||
|
pos = cnt = 0;
|
||||||
|
while (pos < len) {
|
||||||
|
sz = 0;
|
||||||
|
while ((pos < len) && (s[pos] != ':')) {
|
||||||
|
sz = (sz * 10) + (s[pos] - '0');
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
if (sz > len - pos)
|
||||||
|
sz = len - pos;
|
||||||
|
if (sz < 0)
|
||||||
|
sz = 0;
|
||||||
|
a = new WXGC_ATOMIC char[sz + 1];
|
||||||
|
memcpy(a, s + pos, sz);
|
||||||
|
a[sz] = 0;
|
||||||
|
argv[cnt] = a;
|
||||||
|
|
||||||
|
if (sz > 0)
|
||||||
|
pos += sz;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDrop_Runtime(argv, cnt);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user