]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - sys_sdl.c
SDL2: add clipboard support for all platforms.
[xonotic/darkplaces.git] / sys_sdl.c
1
2 #ifdef WIN32
3 #include <io.h>
4 #include "conio.h"
5 #else
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <sys/time.h>
9 #endif
10
11 #ifdef __ANDROID__
12 #include <android/log.h>
13
14 #ifndef FNDELAY
15 #define FNDELAY         O_NDELAY
16 #endif
17 #endif
18
19 #include <signal.h>
20
21 #include <SDL.h>
22
23 #ifdef WIN32
24 #ifdef _MSC_VER
25 #if SDL_MAJOR_VERSION == 1
26 #pragma comment(lib, "sdl.lib")
27 #pragma comment(lib, "sdlmain.lib")
28 #else
29 #pragma comment(lib, "sdl2.lib")
30 #pragma comment(lib, "sdl2main.lib")
31 #endif
32 #endif
33 #endif
34
35 #include "quakedef.h"
36
37 // =======================================================================
38 // General routines
39 // =======================================================================
40
41 void Sys_Shutdown (void)
42 {
43 #ifdef __ANDROID__
44         Sys_AllowProfiling(false);
45 #endif
46 #ifndef WIN32
47         fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
48 #endif
49         fflush(stdout);
50         SDL_Quit();
51 }
52
53
54 void Sys_Error (const char *error, ...)
55 {
56         va_list argptr;
57         char string[MAX_INPUTLINE];
58
59 // change stdin to non blocking
60 #ifndef WIN32
61         fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
62 #endif
63
64         va_start (argptr,error);
65         dpvsnprintf (string, sizeof (string), error, argptr);
66         va_end (argptr);
67
68         Con_Printf ("Quake Error: %s\n", string);
69
70         Host_Shutdown ();
71         exit (1);
72 }
73
74 static int outfd = 1;
75 void Sys_PrintToTerminal(const char *text)
76 {
77 #ifdef __ANDROID__
78         if (developer.integer > 0)
79         {
80                 __android_log_write(ANDROID_LOG_DEBUG, com_argv[0], text);
81         }
82 #else
83         if(outfd < 0)
84                 return;
85 #ifdef FNDELAY
86         // BUG: for some reason, NDELAY also affects stdout (1) when used on stdin (0).
87         // this is because both go to /dev/tty by default!
88         {
89                 int origflags = fcntl (outfd, F_GETFL, 0);
90                 fcntl (outfd, F_SETFL, origflags & ~FNDELAY);
91 #endif
92 #ifdef WIN32
93 #define write _write
94 #endif
95                 while(*text)
96                 {
97                         fs_offset_t written = (fs_offset_t)write(outfd, text, (int)strlen(text));
98                         if(written <= 0)
99                                 break; // sorry, I cannot do anything about this error - without an output
100                         text += written;
101                 }
102 #ifdef FNDELAY
103                 fcntl (outfd, F_SETFL, origflags);
104         }
105 #endif
106         //fprintf(stdout, "%s", text);
107 #endif
108 }
109
110 char *Sys_ConsoleInput(void)
111 {
112 //      if (cls.state == ca_dedicated)
113         {
114                 static char text[MAX_INPUTLINE];
115                 int len = 0;
116 #ifdef WIN32
117                 int c;
118
119                 // read a line out
120                 while (_kbhit ())
121                 {
122                         c = _getch ();
123                         _putch (c);
124                         if (c == '\r')
125                         {
126                                 text[len] = 0;
127                                 _putch ('\n');
128                                 len = 0;
129                                 return text;
130                         }
131                         if (c == 8)
132                         {
133                                 if (len)
134                                 {
135                                         _putch (' ');
136                                         _putch (c);
137                                         len--;
138                                         text[len] = 0;
139                                 }
140                                 continue;
141                         }
142                         text[len] = c;
143                         len++;
144                         text[len] = 0;
145                         if (len == sizeof (text))
146                                 len = 0;
147                 }
148 #else
149                 fd_set fdset;
150                 struct timeval timeout;
151                 FD_ZERO(&fdset);
152                 FD_SET(0, &fdset); // stdin
153                 timeout.tv_sec = 0;
154                 timeout.tv_usec = 0;
155                 if (select (1, &fdset, NULL, NULL, &timeout) != -1 && FD_ISSET(0, &fdset))
156                 {
157                         len = read (0, text, sizeof(text));
158                         if (len >= 1)
159                         {
160                                 // rip off the \n and terminate
161                                 text[len-1] = 0;
162                                 return text;
163                         }
164                 }
165 #endif
166         }
167         return NULL;
168 }
169
170 char *Sys_GetClipboardData (void)
171 {
172 #if SDL_MAJOR_VERSION != 1
173         char *data = NULL;
174         char *cliptext;
175
176         cliptext = SDL_GetClipboardText();
177         if (cliptext != NULL) {
178                 size_t allocsize;
179                 allocsize = strlen(cliptext) + 1;
180                 data = (char *)Z_Malloc (allocsize);
181                 strlcpy (data, cliptext, allocsize);
182                 SDL_free(cliptext);
183         }
184
185         return data;
186 #elif defined(WIN32)
187         char *data = NULL;
188         char *cliptext;
189
190         if (OpenClipboard (NULL) != 0)
191         {
192                 HANDLE hClipboardData;
193
194                 if ((hClipboardData = GetClipboardData (CF_TEXT)) != 0)
195                 {
196                         if ((cliptext = (char *)GlobalLock (hClipboardData)) != 0)
197                         {
198                                 size_t allocsize;
199                                 allocsize = GlobalSize (hClipboardData) + 1;
200                                 data = (char *)Z_Malloc (allocsize);
201                                 strlcpy (data, cliptext, allocsize);
202                                 GlobalUnlock (hClipboardData);
203                         }
204                 }
205                 CloseClipboard ();
206         }
207         return data;
208 #else
209         return NULL;
210 #endif
211 }
212
213 void Sys_InitConsole (void)
214 {
215 }
216
217 int main (int argc, char *argv[])
218 {
219         signal(SIGFPE, SIG_IGN);
220
221 #ifdef __ANDROID__
222         Sys_AllowProfiling(true);
223 #endif
224
225         com_argc = argc;
226         com_argv = (const char **)argv;
227         Sys_ProvideSelfFD();
228
229         // COMMANDLINEOPTION: sdl: -noterminal disables console output on stdout
230         if(COM_CheckParm("-noterminal"))
231                 outfd = -1;
232         // COMMANDLINEOPTION: sdl: -stderr moves console output to stderr
233         else if(COM_CheckParm("-stderr"))
234                 outfd = 2;
235         else
236                 outfd = 1;
237
238 #ifndef WIN32
239         fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
240 #endif
241
242         // we don't know which systems we'll want to init, yet...
243         SDL_Init(0);
244
245         Host_Main();
246
247         return 0;
248 }
249
250 qboolean sys_supportsdlgetticks = true;
251 unsigned int Sys_SDL_GetTicks (void)
252 {
253         return SDL_GetTicks();
254 }
255 void Sys_SDL_Delay (unsigned int milliseconds)
256 {
257         SDL_Delay(milliseconds);
258 }