Merge branch 'genete_master'
[synfig.git] / synfig-osx / launcher / quartz-server.c
1 //
2 //  quartzServer.c
3 //
4 //  This class handles the interaction between CG and the X server thread
5 //
6 /*
7  * Copyright (c) 2001 Andreas Monitzer. All Rights Reserved.
8  * Copyright (c) 2002 Torrey T. Lyons. All Rights Reserved.
9  * Copyright (c) 2002 Apple Software, Inc. All Rights Reserved.
10  * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the
14  * "Software"), to deal in the Software without restriction, including
15  * without limitation the rights to use, copy, modify, merge, publish,
16  * distribute, sublicense, and/or sell copies of the Software, and to
17  * permit persons to whom the Software is furnished to do so, subject to
18  * the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included
21  * in all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30  *
31  * Except as contained in this notice, the name(s) of the above copyright
32  * holders shall not be used in advertising or otherwise to promote the
33  * sale, use or other dealings in this Software without prior written
34  * authorization.
35  */
36 /* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XServer.m,v 1.3 2002/07/15 18:57:44 torrey Exp $ */
37
38 #include "quartz.h"
39 #include "Xplugin.h"
40 #include "X11Controller.h"
41 #define _APPLEDRI_SERVER_
42 #include "appledri.h"
43 #include "dri-surface.h"
44 #include "opaque.h"
45 #include "globals.h"
46 #include <fcntl.h>
47 #include <stdarg.h>
48 #include <unistd.h>
49
50 char **envpGlobal;      // argcGlobal and argvGlobal
51                         // are from dix/globals.c
52
53 void
54 QuartzMessageMainThread (int type, int argc, ...)
55 {
56     xEvent xe;
57     INT32 *argv;
58     int i, max_args;
59     va_list args;
60
61     memset (&xe, 0, sizeof (xe));
62     xe.u.u.type = ClientMessage;
63     xe.u.clientMessage.u.l.type = type;
64
65     argv = &xe.u.clientMessage.u.l.longs0;
66     max_args = 4;
67
68     if (argc > 0 && argc <= max_args)
69     {
70         va_start (args, argc);
71         for (i = 0; i < argc; i++)
72             argv[i] = (int) va_arg (args, int);
73         va_end (args);
74     }
75
76     DarwinEnqueueEvent (&xe);
77 }
78
79 static void
80 event_handler (unsigned int type, const void *arg,
81                unsigned int arg_size, void *data)
82 {
83     switch (type)
84     {
85     case XP_EVENT_DISPLAY_CHANGED:
86         QuartzMessageMainThread (kXquartzDisplayChanged, 0);
87         break;
88
89     case XP_EVENT_WINDOW_STATE_CHANGED:
90         if (arg_size >= sizeof (xp_window_state_event))
91         {
92             const xp_window_state_event *ws_arg = arg;
93             QuartzMessageMainThread (kXquartzWindowState, 2,
94                                      ws_arg->id, ws_arg->state);
95         }
96         break;
97
98     case XP_EVENT_WINDOW_MOVED:
99         if (arg_size == sizeof (xp_window_id))
100         {
101             xp_window_id id = * (xp_window_id *) arg;
102
103             QuartzMessageMainThread (kXquartzWindowMoved, 1, id);
104         }
105         break;
106
107     case XP_EVENT_SURFACE_DESTROYED:
108     case XP_EVENT_SURFACE_CHANGED:
109         if (arg_size == sizeof (xp_surface_id))
110         {
111             int kind;
112
113             if (type == XP_EVENT_SURFACE_DESTROYED)
114                 kind = AppleDRISurfaceNotifyDestroyed;
115             else
116                 kind = AppleDRISurfaceNotifyChanged;
117
118             DRISurfaceNotify (*(xp_surface_id *) arg, kind);
119         }
120         break;
121     }
122 }
123
124 static void
125 server_thread (void *arg)
126 {
127     extern int main (int argc, char **argv, char **envp);
128
129     /* Xinerama defaults to enabled */
130     noPanoramiXExtension = FALSE;
131
132     if (xp_init (XP_BACKGROUND_EVENTS | quartzXpluginOptions) != Success)
133     {
134         fprintf (stderr, "can't initialize window system\n");
135         exit (1);
136     }
137
138     xp_select_events (XP_EVENT_DISPLAY_CHANGED
139                       | XP_EVENT_WINDOW_STATE_CHANGED
140                       | XP_EVENT_WINDOW_MOVED
141                       | XP_EVENT_SURFACE_CHANGED
142                       | XP_EVENT_SURFACE_DESTROYED,
143                       event_handler, NULL);
144
145     exit (main (argcGlobal, argvGlobal, envpGlobal));
146 }
147
148 /*
149  * DarwinHandleGUI
150  *  This function is called first from main(). We use it to connect to
151  *  the cg window server and spawn the the thread that will listen for
152  *  cg events
153  */
154 void DarwinHandleGUI(
155     int         argc,
156     char        *argv[],
157     char        *envp[] )
158 {
159     static Bool here_before;
160
161     extern void _InitHLTB (void);
162
163     if (here_before)
164         return;
165
166     here_before = TRUE;
167
168     DarwinInputPreInit ();
169
170     // Store command line arguments to pass back to main()
171     argcGlobal = argc;
172     argvGlobal = argv;
173     envpGlobal = envp;
174
175     /* Initially I ran the X server on the main thread, and received
176        events on the second thread. But now we may be using Carbon,
177        that needs to run on the main thread. (Otherwise, when it's
178        prebound, it will initialize itself on the wrong thread)
179
180        grr.. but doing that means that if the X thread gets scheduled
181        before the main thread when we're _not_ prebound, things fail,
182        so initialize by hand. */
183
184     _InitHLTB ();
185
186     X11ControllerMain (argc, argv, server_thread, NULL);
187
188     /* not reached */
189     exit (1);
190 }