From 08c70b8e3e6a164a969c79b8e2e86eae930fad7c Mon Sep 17 00:00:00 2001 From: oldosfan Date: Sun, 16 Oct 2022 03:29:55 +0000 Subject: [PATCH] Check in new file for improved time handling * time.c: New file. --- time.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 time.c diff --git a/time.c b/time.c new file mode 100644 index 0000000..3d797f1 --- /dev/null +++ b/time.c @@ -0,0 +1,94 @@ +/* Wayland compositor running on top of an X server. + +Copyright (C) 2022 to various contributors. + +This file is part of 12to11. + +12to11 is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +12to11 is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with 12to11. If not, see . */ + +#include "compositor.h" + +/* The latest known time. */ +static Timestamp current_time; + +/* Half a month; used as a threshold in various places. */ +#define HalfMonth (1U << 31) + +/* The protocol translator can run for more than 48 days. That makes + normal X timestamp handling unsafe, as the X server wraps around + timestamps after that much time. This function creates a Timestamp + from the server time while handling overflow. */ + +Timestamp +TimestampFromServerTime (Time time) +{ + if (time >= current_time.milliseconds) + { + /* No overflow happened. */ + current_time.milliseconds = time; + return current_time; + } + + /* The server time wrapped around. */ + current_time.months++; + current_time.milliseconds = time; + + return current_time; +} + +Timestamp +TimestampFromClientTime (Time time) +{ + Timestamp timestamp; + + timestamp.months = current_time.months; + timestamp.milliseconds = time; + + /* Create a timestamp from a Time that may lie in the past. + Compensate for wraparound if the difference between the + timestamps is more than half a month. */ + + if (time < current_time.milliseconds + && (current_time.milliseconds - time) >= HalfMonth) + timestamp.months += 1; + else if (time > current_time.milliseconds + && (time - current_time.milliseconds) >= HalfMonth) + timestamp.months -= 1; + + return timestamp; +} + +TimestampDifference +CompareTimestamps (Timestamp a, Timestamp b) +{ + if (a.months < b.months) + return Earlier; + + if (a.months > b.months) + return Later; + + if (a.milliseconds < b.milliseconds) + return Earlier; + + if (a.milliseconds > b.milliseconds) + return Later; + + return Same; +} + +TimestampDifference +CompareTimeWith (Time a, Timestamp b) +{ + return CompareTimestamps (TimestampFromClientTime (a), b); +}