1 /*****************************************************************************
2 * This file is part of gfxprim library. *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
19 * Copyright (C) 2009-2013 Cyril Hrubis <metan@ucw.cz> *
21 *****************************************************************************/
26 #include "core/GP_Common.h"
27 #include "core/GP_Transform.h"
28 #include "core/GP_Debug.h"
30 #include "input/GP_EventQueue.h"
31 #include "input/GP_TimeStamp.h"
33 #include "backends/GP_Backend.h"
35 void GP_BackendFlip(GP_Backend
*backend
)
37 if (backend
->Flip
!= NULL
)
38 backend
->Flip(backend
);
41 void GP_BackendUpdateRectXYXY(GP_Backend
*backend
,
42 GP_Coord x0
, GP_Coord y0
,
43 GP_Coord x1
, GP_Coord y1
)
45 if (backend
->UpdateRect
== NULL
)
48 GP_TRANSFORM_POINT(backend
->context
, x0
, y0
);
49 GP_TRANSFORM_POINT(backend
->context
, x1
, y1
);
58 GP_WARN("Negative x coordinate %i, clipping to 0", x0
);
63 GP_WARN("Negative y coordinate %i, clipping to 0", y0
);
67 GP_Coord w
= backend
->context
->w
;
70 GP_WARN("Too large x coordinate %i, clipping to %u", x1
, w
- 1);
74 GP_Coord h
= backend
->context
->h
;
77 GP_WARN("Too large y coordinate %i, clipping to %u", y1
, h
- 1);
81 backend
->UpdateRect(backend
, x0
, y0
, x1
, y1
);
85 int GP_BackendResize(GP_Backend
*backend
, uint32_t w
, uint32_t h
)
87 if (backend
->SetAttributes
== NULL
)
91 w
= backend
->context
->w
;
94 h
= backend
->context
->h
;
96 if (backend
->context
->w
== w
&& backend
->context
->h
== h
)
99 return backend
->SetAttributes(backend
, w
, h
, NULL
);
102 int GP_BackendResizeAck(GP_Backend
*self
)
104 GP_DEBUG(2, "Calling backend %s ResizeAck()", self
->name
);
107 return self
->ResizeAck(self
);
112 static uint32_t pushevent_callback(GP_Timer
*self
)
117 gettimeofday(&ev
.time
, NULL
);
120 GP_EventQueuePut(self
->priv
, &ev
);
125 void GP_BackendAddTimer(GP_Backend
*self
, GP_Timer
*timer
)
127 if (timer
->Callback
== NULL
) {
128 timer
->Callback
= pushevent_callback
;
129 timer
->priv
= &self
->event_queue
;
132 GP_TimerQueueInsert(&self
->timers
, GP_GetTimeStamp(), timer
);
135 void GP_BackendRemTimer(GP_Backend
*self
, GP_Timer
*timer
)
137 GP_TimerQueueRemove(&self
->timers
, timer
);
140 void GP_BackendPoll(GP_Backend
*self
)
145 GP_TimerQueueProcess(&self
->timers
, GP_GetTimeStamp());
148 static void wait_timers_fd(GP_Backend
*self
, uint64_t now
)
152 timeout
= self
->timers
->expires
- now
;
154 struct pollfd fd
= {.fd
= self
->fd
, .events
= POLLIN
, fd
.revents
= 0};
156 if (poll(&fd
, 1, timeout
))
159 now
= GP_GetTimeStamp();
161 GP_TimerQueueProcess(&self
->timers
, now
);
165 * Polling for backends that does not expose FD to wait on (namely SDL).
167 static void wait_timers_poll(GP_Backend
*self
)
170 uint64_t now
= GP_GetTimeStamp();
172 if (GP_TimerQueueProcess(&self
->timers
, now
))
177 if (GP_BackendEventsQueued(self
))
184 void GP_BackendWait(GP_Backend
*self
)
187 uint64_t now
= GP_GetTimeStamp();
189 /* Get rid of possibly expired timers */
190 if (GP_TimerQueueProcess(&self
->timers
, now
))
193 /* Wait for events or timer expiration */
195 wait_timers_fd(self
, now
);
197 wait_timers_poll(self
);
205 int GP_BackendWaitEvent(GP_Backend
*self
, GP_Event
*ev
)
210 if ((ret
= GP_BackendGetEvent(self
, ev
)))
213 GP_BackendWait(self
);
217 int GP_BackendPollEvent(GP_Backend
*self
, GP_Event
*ev
)
221 if ((ret
= GP_BackendGetEvent(self
, ev
)))
224 GP_BackendPoll(self
);
226 if ((ret
= GP_BackendGetEvent(self
, ev
)))