diff options
| author | Mattias Andrée <maandree@kth.se> | 2019-10-22 15:04:45 +0200 | 
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2019-10-22 15:04:45 +0200 | 
| commit | b13efce73e506b0feb4bb7c275c273a54ae6e716 (patch) | |
| tree | 79f93e69b01d236e96037aa60332d214696e048b /src/servers | |
| parent | Fix NULL-pointer bug in get_pathname when running with -mdrm (diff) | |
| download | coopgammad-b13efce73e506b0feb4bb7c275c273a54ae6e716.tar.gz coopgammad-b13efce73e506b0feb4bb7c275c273a54ae6e716.tar.bz2 coopgammad-b13efce73e506b0feb4bb7c275c273a54ae6e716.tar.xz  | |
Change license and style, reorganise file, make makefile portable, and fix bugs1.3
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/servers')
| -rw-r--r-- | src/servers/coopgamma.c | 558 | ||||
| -rw-r--r-- | src/servers/coopgamma.h | 101 | ||||
| -rw-r--r-- | src/servers/crtc.c | 325 | ||||
| -rw-r--r-- | src/servers/crtc.h | 100 | ||||
| -rw-r--r-- | src/servers/gamma.c | 398 | ||||
| -rw-r--r-- | src/servers/gamma.h | 85 | ||||
| -rw-r--r-- | src/servers/kernel.c | 384 | ||||
| -rw-r--r-- | src/servers/kernel.h | 85 | ||||
| -rw-r--r-- | src/servers/master.c | 394 | ||||
| -rw-r--r-- | src/servers/master.h | 36 | 
10 files changed, 0 insertions, 2466 deletions
diff --git a/src/servers/coopgamma.c b/src/servers/coopgamma.c deleted file mode 100644 index 6e544be..0000000 --- a/src/servers/coopgamma.c +++ /dev/null @@ -1,558 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#include "coopgamma.h" -#include "gamma.h" -#include "../state.h" -#include "../communication.h" -#include "../util.h" -#include "../types/output.h" - -#include <libclut.h> - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - - - -/** - * Apply a filter on top of another filter - *  - * @param  dest         The output for the resulting ramp-trio, must be initialised - * @param  application  The red, green and blue ramps, as one single raw array, - *                      of the filter that should be applied - * @param  depth        -1: `float` stops - *                      -2: `double` stops - *                      Other: the number of bits of each (integral) stop - * @param  base         The CLUT on top of which the new filter should be applied, - *                      this can be the same pointer as `dest` - */ -static void apply_filter(union gamma_ramps* restrict dest, void* restrict application, -			 int depth, union gamma_ramps* restrict base) -{ -  union gamma_ramps app; -  size_t bytedepth; -  size_t red_width, green_width, blue_width; -   -  if (depth == -1) -    bytedepth = sizeof(float); -  else if (depth == -2) -    bytedepth = sizeof(double); -  else -    bytedepth = (size_t)depth / 8; -   -  red_width   = (app.u8.red_size   = base->u8.red_size)   * bytedepth; -  green_width = (app.u8.green_size = base->u8.green_size) * bytedepth; -  blue_width  = (app.u8.blue_size  = base->u8.blue_size)  * bytedepth; -   -  app.u8.red   = application; -  app.u8.green = app.u8.red   + red_width; -  app.u8.blue  = app.u8.green + green_width; -   -  if (dest != base) -    { -      memcpy(dest->u8.red,   base->u8.red,   red_width); -      memcpy(dest->u8.green, base->u8.green, green_width); -      memcpy(dest->u8.blue,  base->u8.blue,  blue_width); -    } -   -  switch (depth) -    { -    case 8: -      libclut_apply(&(dest->u8), UINT8_MAX, uint8_t, &(app.u8), UINT8_MAX, uint8_t, 1, 1, 1); -      break; -    case 16: -      libclut_apply(&(dest->u16), UINT16_MAX, uint16_t, &(app.u16), UINT16_MAX, uint16_t, 1, 1, 1); -      break; -    case 32: -      libclut_apply(&(dest->u32), UINT32_MAX, uint32_t, &(app.u32), UINT32_MAX, uint32_t, 1, 1, 1); -      break; -    case 64: -      libclut_apply(&(dest->u64), UINT64_MAX, uint64_t, &(app.u64), UINT64_MAX, uint64_t, 1, 1, 1); -      break; -    case -1: -      libclut_apply(&(dest->f), 1.0f, float, &(app.d), 1.0f, float, 1, 1, 1); -      break; -    case -2: -      libclut_apply(&(dest->d), (double)1, double, &(app.f), (double)1, double, 1, 1, 1); -      break; -    default: -      abort(); -    } -} - - - -/** - * Remove a filter from an output - *  - * @param   out     The output - * @param   filter  The filter - * @return          The index of the filter, `out->table_size` if not found - */ -static ssize_t remove_filter(struct output* restrict out, struct filter* restrict filter) -{ -  size_t i, n = out->table_size; -   -  for (i = 0; i < n; i++) -    if (!strcmp(filter->class, out->table_filters[i].class)) -      break; -   -  if (i == out->table_size) -    { -      fprintf(stderr, "%s: ignoring attempt to removing non-existing filter on CRTC %s: %s\n", -	      argv0, out->name, filter->class); -      return (ssize_t)(out->table_size); -    } -   -  filter_destroy(out->table_filters + i); -  libgamma_gamma_ramps8_destroy(&(out->table_sums[i].u8)); -   -  n = n - i - 1; -  memmove(out->table_filters + i, out->table_filters + i + 1, n * sizeof(*(out->table_filters))); -  memmove(out->table_sums    + i, out->table_sums    + i + 1, n * sizeof(*(out->table_sums))); -  out->table_size--; -   -  return (ssize_t)i; -} - - -/** - * Add a filter to an output - *  - * @param   out     The output - * @param   filter  The filter - * @return          The index given to the filter, -1 on error - */ -static ssize_t add_filter(struct output* restrict out, struct filter* restrict filter) -{ -  size_t i, n = out->table_size; -  int r = -1; -   -  /* Remove? */ -  if (filter->lifespan == LIFESPAN_REMOVE) -    return remove_filter(out, filter); -   -  /* Update? */ -  for (i = 0; i < n; i++) -    if (!strcmp(filter->class, out->table_filters[i].class)) -      break; -  if (i != n) -    { -      filter_destroy(out->table_filters + i); -      out->table_filters[i] = *filter; -      filter->class = NULL; -      filter->ramps = NULL; -      return (ssize_t)i; -    } -   -  /* Add! */ -  for (i = 0; i < n; i++) -    if (filter->priority > out->table_filters[i].priority) -      break; -   -  if (n == out->table_alloc) -    { -      void* new; -       -      new = realloc(out->table_filters, (n + 10) * sizeof(*(out->table_filters))); -      if (new == NULL) -	return -1; -      out->table_filters = new; -       -      new = realloc(out->table_sums, (n + 10) * sizeof(*(out->table_sums))); -      if (new == NULL) -	return -1; -      out->table_sums = new; -       -      out->table_alloc += 10; -    } -   -  memmove(out->table_filters + i + 1, out->table_filters + i, (n - i) * sizeof(*(out->table_filters))); -  memmove(out->table_sums    + i + 1, out->table_sums    + i, (n - i) * sizeof(*(out->table_sums))); -  out->table_size++; -   -  out->table_filters[i] = *filter; -  filter->class = NULL; -  filter->ramps = NULL; -   -  COPY_RAMP_SIZES(&(out->table_sums[i].u8), out); -  switch (out->depth) -    { -    case  8:  r = libgamma_gamma_ramps8_initialise(&(out->table_sums[i].u8));    break; -    case 16:  r = libgamma_gamma_ramps16_initialise(&(out->table_sums[i].u16));  break; -    case 32:  r = libgamma_gamma_ramps32_initialise(&(out->table_sums[i].u32));  break; -    case 64:  r = libgamma_gamma_ramps64_initialise(&(out->table_sums[i].u64));  break; -    case -1:  r = libgamma_gamma_rampsf_initialise(&(out->table_sums[i].f));     break; -    case -2:  r = libgamma_gamma_rampsd_initialise(&(out->table_sums[i].d));     break; -    default: -      abort(); -    } -  if (r < 0) -    return -1; -   -  return (ssize_t)i; -} - - -/** - * Handle a closed connection - *  - * @param   client  The file descriptor for the client - * @return          Zero on success, -1 on error - */ -int connection_closed(int client) -{ -  size_t i, j, k; -  int remove; -   -  for (i = 0; i < outputs_n; i++) -    { -      struct output* output = outputs + i; -      ssize_t updated = -1; -      for (j = k = 0; j < output->table_size; j += !remove, k++) -	{ -	  if (j != k) -	    { -	      output->table_filters[j] = output->table_filters[k]; -	      output->table_sums[j]    = output->table_sums[k]; -	    } -	  remove = output->table_filters[j].client == client; -	  remove = remove && (output->table_filters[j].lifespan == LIFESPAN_UNTIL_DEATH); -	  if (remove) -	    { -	      filter_destroy(output->table_filters + j); -	      libgamma_gamma_ramps8_destroy(&(output->table_sums[j].u8)); -	      output->table_size -= 1; -	      if (updated == -1) -		updated = (ssize_t)j; -	    } -	} -      if (updated >= 0) -	if (flush_filters(output, (size_t)updated) < 0) -	  return -1; -    } -   -  return 0; -} - - -/** - * Handle a ‘Command: get-gamma’ message - *  - * @param   conn           The index of the connection - * @param   message_id     The value of the ‘Message ID’ header - * @param   crtc           The value of the ‘CRTC’ header - * @param   coalesce       The value of the ‘Coalesce’ header - * @param   high_priority  The value of the ‘High priority’ header - * @param   low_priority   The value of the ‘Low priority’ header - * @return                 Zero on success (even if ignored), -1 on error, - *                         1 if connection closed - */ -int handle_get_gamma(size_t conn, const char* restrict message_id, const char* restrict crtc, -		     const char* restrict coalesce, const char* restrict high_priority, -		     const char* restrict low_priority) -{ -  struct output* restrict output; -  int64_t high, low; -  int coal; -  char* restrict buf; -  size_t start, end, len, n, i; -  char depth[3]; -  char tables[sizeof("Tables: \n") + 3 * sizeof(size_t)]; -   -  if (crtc          == NULL)  return send_error("protocol error: 'CRTC' header omitted"); -  if (coalesce      == NULL)  return send_error("protocol error: 'Coalesce' header omitted"); -  if (high_priority == NULL)  return send_error("protocol error: 'High priority' header omitted"); -  if (low_priority  == NULL)  return send_error("protocol error: 'Low priority' header omitted"); -   -  high = (int64_t)atoll(high_priority); -  low  = (int64_t)atoll(low_priority); -   -  if (!strcmp(coalesce, "yes")) -    coal = 1; -  else if (!strcmp(coalesce, "no")) -    coal = 0; -  else -    return send_error("protocol error: recognised value for 'Coalesce' header"); -   -  output = output_find_by_name(crtc, outputs, outputs_n); -  if (output == NULL) -    return send_error("selected CRTC does not exist"); -  else if (output->supported == LIBGAMMA_NO) -    return send_error("selected CRTC does not support gamma adjustments"); -   -  for (start = 0; start < output->table_size; start++) -    if (output->table_filters[start].priority <= high) -      break; -   -  for (end = output->table_size; end > 0; end--) -    if (output->table_filters[end - 1].priority >= low) -      break; -   -  switch (output->depth) -    { -    case -2:  strcpy(depth, "d");  break; -    case -1:  strcpy(depth, "f");  break; -    default: -      sprintf(depth, "%i", output->depth); -      break; -    } -   -  if (coal) -    { -      *tables = '\0'; -      n = output->ramps_size; -    } -  else -    { -      sprintf(tables, "Tables: %zu\n", end - start); -      n = (sizeof(int64_t) + output->ramps_size) * (end - start); -      for (i = start; i < end; i++) -	n += strlen(output->table_filters[i].class) + 1; -    } -   -  MAKE_MESSAGE(&buf, &n, n, -	       "In response to: %s\n" -	       "Depth: %s\n" -	       "Red size: %zu\n" -	       "Green size: %zu\n" -	       "Blue size: %zu\n" -	       "%s" -	       "Length: %zu\n" -	       "\n", -	       message_id, depth, output->red_size, output->green_size, -	       output->blue_size, tables, n); -   -  if (coal) -    { -      if ((start == 0) && (start < end)) -	memcpy(buf + n, output->table_sums[end - 1].u8.red, output->ramps_size); -      else -	{ -	  union gamma_ramps ramps; -	  if (make_plain_ramps(&ramps, output)) -	    { -	      int saved_errno = errno; -	      free(buf); -	      errno = saved_errno; -	      return -1; -	    } -	  for (i = start; i < end; i++) -	    apply_filter(&ramps, output->table_filters[i].ramps, output->depth, &ramps); -	  memcpy(buf + n, ramps.u8.red, output->ramps_size); -	  libgamma_gamma_ramps8_destroy(&(ramps.u8)); -	} -      n += output->ramps_size; -    } -  else -    for (i = start; i < end; i++) -      { -#if defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wcast-align" -#endif -	*(int64_t*)(buf + n) = output->table_filters[i].priority; -#if defined(__clang__) -# pragma GCC diagnostic pop -#endif -	n += sizeof(int64_t); -	len = strlen(output->table_filters[i].class) + 1; -	memcpy(buf + n, output->table_filters[i].class, len); -	n += len; -	memcpy(buf + n, output->table_filters[i].ramps, output->ramps_size); -	n += output->ramps_size; -      } -   -  return send_message(conn, buf, n); -} - - -/** - * Handle a ‘Command: set-gamma’ message - *  - * @param   conn        The index of the connection - * @param   message_id  The value of the ‘Message ID’ header - * @param   crtc        The value of the ‘CRTC’ header - * @param   priority    The value of the ‘Priority’ header - * @param   class       The value of the ‘Class’ header - * @param   lifespan    The value of the ‘Lifespan’ header - * @return              Zero on success (even if ignored), -1 on error, - *                      1 if connection closed - */ -int handle_set_gamma(size_t conn, const char* restrict message_id, const char* restrict crtc, -		     const char* restrict priority, const char* restrict class, const char* restrict lifespan) -{ -  struct message* restrict msg = inbound + conn; -  struct output* restrict output = NULL; -  struct filter filter; -  char* restrict p; -  char* restrict q; -  int saved_errno; -  ssize_t r; -   -  if (crtc     == NULL)  return send_error("protocol error: 'CRTC' header omitted"); -  if (class    == NULL)  return send_error("protocol error: 'Class' header omitted"); -  if (lifespan == NULL)  return send_error("protocol error: 'Lifespan' header omitted"); -   -  filter.client   = connections[conn]; -  filter.priority = priority == NULL ? 0 : (int64_t)atoll(priority); -  filter.ramps    = NULL; -   -  output = output_find_by_name(crtc, outputs, outputs_n); -  if (output == NULL) -    return send_error("CRTC does not exists"); -   -  p = strstr(class, "::"); -  if ((p == NULL) || (p == class)) -    return send_error("protocol error: malformatted value for 'Class' header"); -  q = strstr(p + 2, "::"); -  if ((q == NULL) || (q == p)) -    return send_error("protocol error: malformatted value for 'Class' header"); -   -  if (!strcmp(lifespan, "until-removal")) -    filter.lifespan = LIFESPAN_UNTIL_REMOVAL; -  else if (!strcmp(lifespan, "until-death")) -    filter.lifespan = LIFESPAN_UNTIL_DEATH; -  else if (!strcmp(lifespan, "remove")) -    filter.lifespan = LIFESPAN_REMOVE; -  else -    return send_error("protocol error: recognised value for 'Lifespan' header"); -   -  if (filter.lifespan == LIFESPAN_REMOVE) -    { -      if (msg->payload_size) -	fprintf(stderr, "%s: ignoring superfluous payload on Command: set-gamma message with " -			"Lifespan: remove\n", argv0); -      if (priority != NULL) -	fprintf(stderr, "%s: ignoring superfluous Priority header on Command: set-gamma message with " -			"Lifespan: remove\n", argv0); -    } -  else if (msg->payload_size != output->ramps_size) -    return send_error("invalid payload: size of message payload does matched the expectancy"); -  else if (priority == NULL) -    return send_error("protocol error: 'Priority' header omitted"); -   -  filter.class = memdup(class, strlen(class) + 1); -  if (filter.class == NULL) -    goto fail; -   -  if (filter.lifespan != LIFESPAN_REMOVE) -    { -      filter.ramps = memdup(msg->payload, msg->payload_size); -      if (filter.ramps == NULL) -	goto fail; -    } -   -  if ((r = add_filter(output, &filter)) < 0) -    goto fail; -  if (flush_filters(output, (size_t)r)) -    goto fail; -   -  free(filter.class); -  free(filter.ramps); -  return send_errno(0); -   - fail: -  saved_errno = errno; -  send_errno(saved_errno); -  free(filter.class); -  free(filter.ramps); -  errno = saved_errno; -  return -1; -} - - - -/** - * Recalculate the resulting gamma and - * update push the new gamma ramps to the CRTC - *  - * @param   output         The output - * @param   first_updated  The index of the first added or removed filter - * @return                 Zero on success, -1 on error - */ -int flush_filters(struct output* restrict output, size_t first_updated) -{ -  union gamma_ramps plain; -  union gamma_ramps* last; -  size_t i; -   -  if (first_updated == 0) -    { -      if (make_plain_ramps(&plain, output) < 0) -	return -1; -      last = &plain; -    } -  else -    last = output->table_sums + (first_updated - 1); -   -  for (i = first_updated; i < output->table_size; i++) -    { -      apply_filter(output->table_sums + i, output->table_filters[i].ramps, output->depth, last); -      last = output->table_sums + i; -    } -   -  set_gamma(output, last); -   -  if (first_updated == 0) -    libgamma_gamma_ramps8_destroy(&(plain.u8)); -   -  return 0; -} - - - -/** - * Preserve current gamma ramps at priority 0 for all outputs - *  - * @return  Zero on success, -1 on error - */ -int preserve_gamma(void) -{ -  size_t i; -   -  for (i = 0; i < outputs_n; i++) -    { -      struct filter filter = { -	.client   = -1, -	.priority = 0, -	.class    = NULL, -	.lifespan = LIFESPAN_UNTIL_REMOVAL, -	.ramps    = NULL -      }; -      outputs[i].table_filters = calloc(4, sizeof(*(outputs[i].table_filters))); -      outputs[i].table_sums = calloc(4, sizeof(*(outputs[i].table_sums))); -      outputs[i].table_alloc = 4; -      outputs[i].table_size = 1; -      filter.class = memdup(PKGNAME "::" COMMAND "::preserved", sizeof(PKGNAME "::" COMMAND "::preserved")); -      if (filter.class == NULL) -	return -1; -      filter.ramps = memdup(outputs[i].saved_ramps.u8.red, outputs[i].ramps_size); -      if (filter.ramps == NULL) -	return -1; -      outputs[i].table_filters[0] = filter; -      COPY_RAMP_SIZES(&(outputs[i].table_sums[0].u8), outputs + i); -      if (!gamma_ramps_unmarshal(outputs[i].table_sums, outputs[i].saved_ramps.u8.red, outputs[i].ramps_size)) -	return -1; -    } -   -  return 0; -} - diff --git a/src/servers/coopgamma.h b/src/servers/coopgamma.h deleted file mode 100644 index 5a9f7d9..0000000 --- a/src/servers/coopgamma.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef SERVERS_COOPGAMMA_H -#define SERVERS_COOPGAMMA_H - - -#include "../types/output.h" - -#include <stddef.h> - - - -#ifndef GCC_ONLY -# if defined(__GNUC__) && !defined(__clang__) -#  define GCC_ONLY(...)  __VA_ARGS__ -# else -#  define GCC_ONLY(...)  /* nothing */ -# endif -#endif - - - -/** - * Handle a closed connection - *  - * @param   client  The file descriptor for the client - * @return          Zero on success, -1 on error - */ -int connection_closed(int client); - -/** - * Handle a ‘Command: get-gamma’ message - *  - * @param   conn           The index of the connection - * @param   message_id     The value of the ‘Message ID’ header - * @param   crtc           The value of the ‘CRTC’ header - * @param   coalesce       The value of the ‘Coalesce’ header - * @param   high_priority  The value of the ‘High priority’ header - * @param   low_priority   The value of the ‘Low priority’ header - * @return                 Zero on success (even if ignored), -1 on error, - *                         1 if connection closed - */ -GCC_ONLY(__attribute__((nonnull(2)))) -int handle_get_gamma(size_t conn, const char* restrict message_id, const char* restrict crtc, -		     const char* restrict coalesce, const char* restrict high_priority, -		     const char* restrict low_priority); - -/** - * Handle a ‘Command: set-gamma’ message - *  - * @param   conn        The index of the connection - * @param   message_id  The value of the ‘Message ID’ header - * @param   crtc        The value of the ‘CRTC’ header - * @param   priority    The value of the ‘Priority’ header - * @param   class       The value of the ‘Class’ header - * @param   lifespan    The value of the ‘Lifespan’ header - * @return              Zero on success (even if ignored), -1 on error, - *                      1 if connection closed - */ -GCC_ONLY(__attribute__((nonnull(2)))) -int handle_set_gamma(size_t conn, const char* restrict message_id, const char* restrict crtc, -		     const char* restrict priority, const char* restrict class, const char* restrict lifespan); - - -/** - * Recalculate the resulting gamma and - * update push the new gamma ramps to the CRTC - *  - * @param   output         The output - * @param   first_updated  The index of the first added or removed filter - * @return                 Zero on success, -1 on error - */ -GCC_ONLY(__attribute__((nonnull))) -int flush_filters(struct output* restrict output, size_t first_updated); - - -/** - * Preserve current gamma ramps at priority 0 for all outputs - *  - * @return  Zero on success, -1 on error - */ -int preserve_gamma(void); - - -#endif - diff --git a/src/servers/crtc.c b/src/servers/crtc.c deleted file mode 100644 index ca10940..0000000 --- a/src/servers/crtc.c +++ /dev/null @@ -1,325 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#include "crtc.h" -#include "gamma.h" -#include "coopgamma.h" -#include "../state.h" -#include "../communication.h" -#include "../util.h" - -#include <errno.h> -#include <string.h> - - - -/** - * Handle a ‘Command: enumerate-crtcs’ message - *  - * @param   conn        The index of the connection - * @param   message_id  The value of the ‘Message ID’ header - * @return              Zero on success (even if ignored), -1 on error, - *                      1 if connection closed - */ -int handle_enumerate_crtcs(size_t conn, const char* restrict message_id) -{ -  size_t i, n = 0, len; -  char* restrict buf; -   -  for (i = 0; i < outputs_n; i++) -    n += strlen(outputs[i].name) + 1; -   -  MAKE_MESSAGE(&buf, &n, n, -	       "Command: crtc-enumeration\n" -	       "In response to: %s\n" -	       "Length: %zu\n" -	       "\n", -	       message_id, n); -   -  for (i = 0; i < outputs_n; i++) -    { -      len = strlen(outputs[i].name); -      memcpy(buf + n, outputs[i].name, len); -      buf[n + len] = '\n'; -      n += len + 1; -    } -   -  return send_message(conn, buf, n); -} - - -/** - * Get the name of a CRTC - *  - * @param   info  Information about the CRTC - * @param   crtc  libgamma's state for the CRTC - * @return        The name of the CRTC, `NULL` on error - */ -char* get_crtc_name(const libgamma_crtc_information_t* restrict info, -		    const libgamma_crtc_state_t* restrict crtc) -{ -  if ((info->edid_error == 0) && (info->edid != NULL)) -    return libgamma_behex_edid(info->edid, info->edid_length); -  else if ((info->connector_name_error == 0) && (info->connector_name != NULL)) -    { -      char* name = malloc(3 * sizeof(size_t) + strlen(info->connector_name) + 2); -      if (name != NULL) -	sprintf(name, "%zu.%s", crtc->partition->partition, info->connector_name); -      return name; -    } -  else -    { -      char* name = malloc(2 * 3 * sizeof(size_t) + 2); -      if (name != NULL) -	sprintf(name, "%zu.%zu", crtc->partition->partition, crtc->crtc); -      return name; -    } -} - - -/** - * Initialise the site - *  - * @return  Zero on success, -1 on error - */ -int initialise_site(void) -{ -  char* restrict sitename_dup = NULL; -  int gerror, saved_errno; -   -  if ((sitename != NULL) && !(sitename_dup = memdup(sitename, strlen(sitename) + 1))) -    goto fail; -  if ((gerror = libgamma_site_initialise(&site, method, sitename_dup))) -    goto fail_libgamma; -   -  return 0; - fail_libgamma: -  sitename_dup = NULL; -  libgamma_perror(argv0, gerror); -  errno = 0; - fail: -  saved_errno = errno; -  free(sitename_dup); -  errno = saved_errno; -  return -1; -} - - -/** - * Get partitions and CRTC:s - *  - * @return  Zero on success, -1 on error - */ -int initialise_crtcs(void) -{ -  size_t i, j, n, n0; -  int gerror; -   -  /* Get partitions */ -  outputs_n = 0; -  if (site.partitions_available) -    if (!(partitions = calloc(site.partitions_available, sizeof(*partitions)))) -      goto fail; -  for (i = 0; i < site.partitions_available; i++) -    { -      if ((gerror = libgamma_partition_initialise(partitions + i, &site, i))) -	goto fail_libgamma; -      outputs_n += partitions[i].crtcs_available; -    } -   -  /* Get CRTC:s */ -  if (outputs_n) -    if (!(crtcs = calloc(outputs_n, sizeof(*crtcs)))) -      goto fail; -  for (i = 0, j = n = 0; i < site.partitions_available; i++) -    for (n0 = n, n += partitions[i].crtcs_available; j < n; j++) -      if ((gerror = libgamma_crtc_initialise(crtcs + j, partitions + i, j - n0))) -	goto fail_libgamma; -   -  return 0; -   - fail_libgamma: -  libgamma_perror(argv0, gerror); -  errno = 0; - fail: -  return -1; -} - - -/** - * Merge the new state with an old state - *  - * @param   old_outputs    The old `outputs` - * @param   old_outputs_n  The old `outputs_n` - * @return                 Zero on success, -1 on error - */ -int merge_state(struct output* restrict old_outputs, size_t old_outputs_n) -{ -  struct output* restrict new_outputs = NULL; -  size_t new_outputs_n; -  size_t i, j; -   -  /* How many outputs does the system now have? */ -  i = j = new_outputs_n = 0; -  while ((i < old_outputs_n) && (j < outputs_n)) -    { -      int cmp = strcmp(old_outputs[i].name, outputs[j].name); -      if (cmp <= 0) -	new_outputs_n++; -      i += cmp >= 0; -      j += cmp <= 0; -    } -  new_outputs_n += outputs_n - j; -   -  /* Allocate output state array */ -  if (new_outputs_n > 0) -    { -      new_outputs = calloc(new_outputs_n, sizeof(*new_outputs)); -      if (new_outputs == NULL) -	return -1; -    } -   -  /* Merge output states */ -  i = j = new_outputs_n = 0; -  while ((i < old_outputs_n) && (j < outputs_n)) -    { -      int is_same = 0, cmp = strcmp(old_outputs[i].name, outputs[j].name); -      if (cmp == 0) -	is_same = (old_outputs[i].depth      == outputs[j].depth      && -		   old_outputs[i].red_size   == outputs[j].red_size   && -		   old_outputs[i].green_size == outputs[j].green_size && -		   old_outputs[i].blue_size  == outputs[j].blue_size); -      if (is_same) -	{ -	  new_outputs[new_outputs_n] = old_outputs[i]; -	  new_outputs[new_outputs_n].crtc = outputs[j].crtc; -	  memset(old_outputs + i, 0, sizeof(*old_outputs)); -	  outputs[j].crtc = NULL; -	  output_destroy(outputs + j); -	  new_outputs_n++; -	} -      else if (cmp <= 0) -	new_outputs[new_outputs_n++] = outputs[j]; -      i += cmp >= 0; -      j += cmp <= 0; -    } -  while (j < outputs_n) -    new_outputs[new_outputs_n++] = outputs[j++]; -   -  /* Commit merge */ -  free(outputs); -  outputs   = new_outputs; -  outputs_n = new_outputs_n; -   -  return 0; -} - - - -/** - * Disconnect from the site - *  - * @return  Zero on success, -1 on error - */ -int disconnect(void) -{ -  size_t i; -   -  if (!connected) -    return 0; -  connected = 0; -   -  for (i = 0; i < outputs_n; i++) -    { -      outputs[i].crtc = NULL; -      libgamma_crtc_destroy(crtcs + i); -    } -  free(crtcs), crtcs = NULL; -  for (i = 0; i < site.partitions_available; i++) -    libgamma_partition_destroy(partitions + i); -  free(partitions), partitions = NULL; -  libgamma_site_destroy(&site); -  memset(&site, 0, sizeof(site)); -   -  return 0; -} - - -/** - * Reconnect to the site - *  - * @return  Zero on success, -1 on error - */ -int reconnect(void) -{ -  struct output* restrict old_outputs; -  size_t i, old_outputs_n; -  int saved_errno; -   -  if (connected) -    return 0; -  connected = 1; -   -  /* Remember old state */ -  old_outputs   = outputs,   outputs   = NULL; -  old_outputs_n = outputs_n, outputs_n = 0; -   -  /* Get site */ -  if (initialise_site() < 0) -    goto fail; -   -  /* Get partitions and CRTC:s */ -  if (initialise_crtcs() < 0) -    goto fail; -   -  /* Get CRTC information */ -  if (outputs_n && !(outputs = calloc(outputs_n, sizeof(*outputs)))) -    goto fail; -  if (initialise_gamma_info() < 0) -    goto fail; -   -  /* Sort outputs */ -  qsort(outputs, outputs_n, sizeof(*outputs), output_cmp_by_name); -   -  /* Load current gamma ramps */ -  store_gamma(); -   -  /* Preserve current gamma ramps at priority=0 if -p */ -  if (preserve && (preserve_gamma() < 0)) -    goto fail; -   -  /* Merge state */ -  if (merge_state(old_outputs, old_outputs_n) < 0) -    goto fail; -  for (i = 0; i < old_outputs_n; i++) -    output_destroy(old_outputs + i); -  free(old_outputs), old_outputs = NULL, old_outputs_n = 0; -   -  /* Reapply gamma ramps */ -  reapply_gamma(); -   -  return 0; -   - fail: -  saved_errno = errno; -  for (i = 0; i < old_outputs_n; i++) -    output_destroy(old_outputs + i); -  free(old_outputs); -  errno = saved_errno; -  return -1; -} - diff --git a/src/servers/crtc.h b/src/servers/crtc.h deleted file mode 100644 index 68239d4..0000000 --- a/src/servers/crtc.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef SERVERS_CRTC_H -#define SERVERS_CRTC_H - - -#include "../types/output.h" - -#include <libgamma.h> - - - -#ifndef GCC_ONLY -# if defined(__GNUC__) && !defined(__clang__) -#  define GCC_ONLY(...)  __VA_ARGS__ -# else -#  define GCC_ONLY(...)  /* nothing */ -# endif -#endif - - - -/** - * Handle a ‘Command: enumerate-crtcs’ message - *  - * @param   conn        The index of the connection - * @param   message_id  The value of the ‘Message ID’ header - * @return              Zero on success (even if ignored), -1 on error, - *                      1 if connection closed - */ -GCC_ONLY(__attribute__((nonnull))) -int handle_enumerate_crtcs(size_t conn, const char* restrict message_id); - -/** - * Get the name of a CRTC - *  - * @param   info  Information about the CRTC - * @param   crtc  libgamma's state for the CRTC - * @return        The name of the CRTC, `NULL` on error - */ -GCC_ONLY(__attribute__((nonnull))) -char* get_crtc_name(const libgamma_crtc_information_t* restrict info, -		    const libgamma_crtc_state_t* restrict crtc); - -/** - * Initialise the site - *  - * @return   Zero on success, -1 on error - */ -int initialise_site(void); - -/** - * Get partitions and CRTC:s - *  - * @return   Zero on success, -1 on error - */ -int initialise_crtcs(void); - -/** - * Merge the new state with an old state - *  - * @param   old_outputs    The old `outputs` - * @param   old_outputs_n  The old `outputs_n` - * @return                 Zero on success, -1 on error - */ -int merge_state(struct output* restrict old_outputs, size_t old_outputs_n); - - -/** - * Disconnect from the site - *  - * @return  Zero on success, -1 on error - */ -int disconnect(void); - -/** - * Reconnect to the site - *  - * @return  Zero on success, -1 on error - */ -int reconnect(void); - - -#endif - diff --git a/src/servers/gamma.c b/src/servers/gamma.c deleted file mode 100644 index 17105d4..0000000 --- a/src/servers/gamma.c +++ /dev/null @@ -1,398 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#include "gamma.h" -#include "crtc.h" -#include "../state.h" -#include "../communication.h" -#include "../util.h" - -#include <errno.h> -#include <string.h> - - - -#if defined(__clang__) -# pragma GCC diagnostic ignored "-Wswitch-enum" -#endif - - - -/** - * Handle a ‘Command: set-gamma’ message - *  - * @param   conn        The index of the connection - * @param   message_id  The value of the ‘Message ID’ header - * @param   crtc        The value of the ‘CRTC’ header - * @return              Zero on success (even if ignored), -1 on error, - *                      1 if connection closed - */ -int handle_get_gamma_info(size_t conn, const char* restrict message_id, const char* restrict crtc) -{ -  struct output* restrict output; -  char* restrict buf; -  char depth[3]; -  const char* supported; -  const char* colourspace; -  char gamut[8 * sizeof("White x: 1023")]; -  size_t n; -   -  if (crtc == NULL)  return send_error("protocol error: 'CRTC' header omitted"); -   -  output = output_find_by_name(crtc, outputs, outputs_n); -  if (output == NULL) -    return send_error("selected CRTC does not exist"); -   -  switch (output->depth) -    { -    case -2:  strcpy(depth, "d");  break; -    case -1:  strcpy(depth, "f");  break; -    default: -      sprintf(depth, "%i", output->depth); -      break; -    } -   -  switch (output->supported) -    { -    case LIBGAMMA_YES:    supported = "yes";    break; -    case LIBGAMMA_NO:     supported = "no";     break; -    default:              supported = "maybe";  break; -    } -   -  switch (output->colourspace) -    { -    case COLOURSPACE_SRGB_SANS_GAMUT: -    case COLOURSPACE_SRGB:     colourspace = "Colour space: sRGB\n";     break; -    case COLOURSPACE_RGB_SANS_GAMUT: -    case COLOURSPACE_RGB:      colourspace = "Colour space: RGB\n";      break; -    case COLOURSPACE_NON_RGB:  colourspace = "Colour space: non-RGB\n";  break; -    case COLOURSPACE_GREY:     colourspace = "Colour space: grey\n";     break; -    default:                   colourspace = "";                         break; -    } -   -  switch (output->colourspace) -    { -    case COLOURSPACE_SRGB: -    case COLOURSPACE_RGB: -      sprintf(gamut, -	      "Red x: %u\n" -	      "Red y: %u\n" -	      "Green x: %u\n" -	      "Green y: %u\n" -	      "Blue x: %u\n" -	      "Blue y: %u\n" -	      "White x: %u\n" -	      "White y: %u\n", -	      output->red_x, output->red_y, output->green_x, output->green_y, -	      output->blue_x, output->blue_y, output->white_x, output->white_y); -      break; -    default: -      *gamut = '\0'; -      break; -    } -   -  MAKE_MESSAGE(&buf, &n, 0, -	       "In response to: %s\n" -	       "Cooperative: yes\n" /* In mds: say ‘no’, mds-coopgamma changes to ‘yes’.” */ -	       "Depth: %s\n" -	       "Red size: %zu\n" -	       "Green size: %zu\n" -	       "Blue size: %zu\n" -	       "Gamma support: %s\n" -	       "%s%s" -	       "\n", -	       message_id, depth, output->red_size, output->green_size, -	       output->blue_size, supported, gamut, colourspace); -   -  return send_message(conn, buf, n); -} - - -/** - * Set the gamma ramps on an output - *  - * @param  output  The output - * @param  ramps   The gamma ramps - */ -void set_gamma(const struct output* restrict output, const union gamma_ramps* restrict ramps) -{ -  int r = 0; -   -  if (!connected) -    return; -   -  switch (output->depth) -    { -    case  8:  r = libgamma_crtc_set_gamma_ramps8(output->crtc,  ramps->u8);   break; -    case 16:  r = libgamma_crtc_set_gamma_ramps16(output->crtc, ramps->u16);  break; -    case 32:  r = libgamma_crtc_set_gamma_ramps32(output->crtc, ramps->u32);  break; -    case 64:  r = libgamma_crtc_set_gamma_ramps64(output->crtc, ramps->u64);  break; -    case -1:  r = libgamma_crtc_set_gamma_rampsf(output->crtc,  ramps->f);    break; -    case -2:  r = libgamma_crtc_set_gamma_rampsd(output->crtc,  ramps->d);    break; -    default: -      abort(); -    } -  if (r) -    libgamma_perror(argv0, r); /* Not fatal */ -} - - -/** - * Parse the EDID of a monitor - *  - * @param  output  The output - * @param  edid    The EDID in binary format - * @param  n       The length of the EDID - */ -static void parse_edid(struct output* restrict output, const unsigned char* restrict edid, size_t n) -{ -  size_t i; -  int analogue; -  unsigned sum; -   -  output->red_x = output->green_x = output->blue_x = output->white_x = 0; -  output->red_y = output->green_y = output->blue_y = output->white_y = 0; -  output->colourspace = COLOURSPACE_UNKNOWN; -   -  if ((edid == NULL) || (n < 128)) -    return; -  for (i = 0, sum = 0; i < 128; i++) -    sum += (unsigned)edid[i]; -  if ((sum & 0xFF) != 0) -    return; -  if ((edid[0] != 0) || (edid[7] != 0)) -    return; -  for (i = 1; i < 7; i++) -    if (edid[i] != 0xFF) -      return; -   -  analogue = !(edid[20] & 0x80); -  if (!analogue) -    output->colourspace = COLOURSPACE_RGB; -  else -    switch ((edid[24] >> 3) & 3) -      { -      case 0:   output->colourspace = COLOURSPACE_GREY;     break; -      case 1:   output->colourspace = COLOURSPACE_RGB;      break; -      case 2:   output->colourspace = COLOURSPACE_NON_RGB;  break; -      default:  output->colourspace = COLOURSPACE_UNKNOWN;  break; -      } -   -  if (output->colourspace != COLOURSPACE_RGB) -    return; -   -  if (edid[24] & 4) -    output->colourspace = COLOURSPACE_SRGB; -   -  output->red_x   = (edid[25] >> 6) & 3; -  output->red_y   = (edid[25] >> 4) & 3; -  output->green_x = (edid[25] >> 2) & 3; -  output->green_y = (edid[25] >> 0) & 3; -  output->blue_x  = (edid[26] >> 6) & 3; -  output->blue_y  = (edid[26] >> 4) & 3; -  output->white_x = (edid[26] >> 2) & 3; -  output->white_y = (edid[26] >> 0) & 3; -   -  output->red_x   |= ((unsigned)(edid[27])) << 2; -  output->red_y   |= ((unsigned)(edid[28])) << 2; -  output->green_x |= ((unsigned)(edid[29])) << 2; -  output->green_y |= ((unsigned)(edid[30])) << 2; -  output->blue_x  |= ((unsigned)(edid[31])) << 2; -  output->blue_y  |= ((unsigned)(edid[32])) << 2; -  output->white_x |= ((unsigned)(edid[33])) << 2; -  output->white_y |= ((unsigned)(edid[34])) << 2; -   -  if ((output->red_x == output->red_y)   && -      (output->red_x == output->green_x) && -      (output->red_x == output->green_y) && -      (output->red_x == output->blue_x)  && -      (output->red_x == output->blue_y)  && -      (output->red_x == output->white_x) && -      (output->red_x == output->white_y)) -    { -      if (output->colourspace == COLOURSPACE_SRGB) -	output->colourspace = COLOURSPACE_SRGB_SANS_GAMUT; -      else -	output->colourspace = COLOURSPACE_RGB_SANS_GAMUT; -    } -} - - -/** - * Store all current gamma ramps - *  - * @return  Zero on success, -1 on error - */ -int initialise_gamma_info(void) -{ -  libgamma_crtc_information_t info; -  int saved_errno; -  size_t i; -   -  for (i = 0; i < outputs_n; i++) -    { -      libgamma_get_crtc_information(&info, crtcs + i, -				    LIBGAMMA_CRTC_INFO_EDID | -				    LIBGAMMA_CRTC_INFO_MACRO_RAMP | -				    LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT | -				    LIBGAMMA_CRTC_INFO_CONNECTOR_NAME); -      outputs[i].depth        = info.gamma_depth_error   ? 0 : info.gamma_depth; -      outputs[i].red_size     = info.gamma_size_error    ? 0 : info.red_gamma_size; -      outputs[i].green_size   = info.gamma_size_error    ? 0 : info.green_gamma_size; -      outputs[i].blue_size    = info.gamma_size_error    ? 0 : info.blue_gamma_size; -      outputs[i].supported    = info.gamma_support_error ? 0 : info.gamma_support; -      if (info.gamma_support_error == LIBGAMMA_CRTC_INFO_NOT_SUPPORTED) -	outputs[i].supported = LIBGAMMA_MAYBE; -      if (outputs[i].depth      == 0 || outputs[i].red_size  == 0 || -	  outputs[i].green_size == 0 || outputs[i].blue_size == 0) -	outputs[i].supported  = 0; -      parse_edid(outputs + i, info.edid_error ? NULL : info.edid, info.edid_error ? 0 : info.edid_length); -      outputs[i].name         = get_crtc_name(&info, crtcs + i); -      saved_errno = errno; -      outputs[i].name_is_edid = ((info.edid_error == 0) && (info.edid != NULL)); -      outputs[i].crtc         = crtcs + i; -      libgamma_crtc_information_destroy(&info); -      outputs[i].ramps_size = outputs[i].red_size + outputs[i].green_size + outputs[i].blue_size; -      switch (outputs[i].depth) -	{ -	default: -	  outputs[i].depth = 64; -	  /* Fall through */ -	case  8: -	case 16: -	case 32: -	case 64:  outputs[i].ramps_size *= (size_t)(outputs[i].depth / 8);  break; -	case -2:  outputs[i].ramps_size *= sizeof(double);                  break; -	case -1:  outputs[i].ramps_size *= sizeof(float);                   break; -	} -      errno = saved_errno; -      if (outputs[i].name == NULL) -	return -1; -    } -   -  return 0; -} - - -/** - * Store all current gamma ramps - */ -void store_gamma(void) -{ -  int gerror; -  size_t i; -   -#define LOAD_RAMPS(SUFFIX, MEMBER) \ -  do \ -    { \ -      libgamma_gamma_ramps##SUFFIX##_initialise(&(outputs[i].saved_ramps.MEMBER)); \ -      gerror = libgamma_crtc_get_gamma_ramps##SUFFIX(outputs[i].crtc, &(outputs[i].saved_ramps.MEMBER)); \ -      if (gerror) \ -	{ \ -	  libgamma_perror(argv0, gerror); \ -	  outputs[i].supported = LIBGAMMA_NO; \ -	  libgamma_gamma_ramps##SUFFIX##_destroy(&(outputs[i].saved_ramps.MEMBER)); \ -	  memset(&(outputs[i].saved_ramps.MEMBER), 0, sizeof(outputs[i].saved_ramps.MEMBER)); \ -	} \ -    } \ -  while (0) -   -  for (i = 0; i < outputs_n; i++) -    { -      if (outputs[i].supported == LIBGAMMA_NO) -	continue; -       -      outputs[i].saved_ramps.u8.red_size   = outputs[i].red_size; -      outputs[i].saved_ramps.u8.green_size = outputs[i].green_size; -      outputs[i].saved_ramps.u8.blue_size  = outputs[i].blue_size; -       -      switch (outputs[i].depth) -	{ -	case 64:  LOAD_RAMPS(64, u64);  break; -	case 32:  LOAD_RAMPS(32, u32);  break; -	case 16:  LOAD_RAMPS(16, u16);  break; -	case  8:  LOAD_RAMPS( 8, u8);   break; -	case -2:  LOAD_RAMPS(d, d);     break; -	case -1:  LOAD_RAMPS(f, f);     break; -	default:  /* impossible */      break; -	} -    } -} - - -/** - * Restore all gamma ramps - */ -void restore_gamma(void) -{ -  size_t i; -  int gerror; -   -#define RESTORE_RAMPS(SUFFIX, MEMBER) \ -  do \ -    if (outputs[i].saved_ramps.MEMBER.red != NULL) \ -      { \ -	gerror = libgamma_crtc_set_gamma_ramps##SUFFIX(outputs[i].crtc, outputs[i].saved_ramps.MEMBER); \ -	if (gerror) \ -	    libgamma_perror(argv0, gerror); \ -      } \ -  while (0) -   -  for (i = 0; i < outputs_n; i++) -    { -      if (outputs[i].supported == LIBGAMMA_NO) -	continue; -      if (outputs[i].saved_ramps.u8.red == NULL) -	continue; -       -      switch (outputs[i].depth) -	{ -	case 64:  RESTORE_RAMPS(64, u64);  break; -	case 32:  RESTORE_RAMPS(32, u32);  break; -	case 16:  RESTORE_RAMPS(16, u16);  break; -	case  8:  RESTORE_RAMPS( 8, u8);   break; -	case -2:  RESTORE_RAMPS(d, d);     break; -	case -1:  RESTORE_RAMPS(f, f);     break; -	default:  /* impossible */         break; -	} -    } -} - - -/** - * Reapplu all gamma ramps - */ -void reapply_gamma(void) -{ -  union gamma_ramps plain; -  size_t i; -   -  /* Reapply gamma ramps */ -  for (i = 0; i < outputs_n; i++) -    { -      struct output* output = outputs + i; -      if (output->table_size > 0) -	set_gamma(output, output->table_sums + output->table_size - 1); -      else -	{ -	  make_plain_ramps(&plain, output); -	  set_gamma(output, &plain); -	  libgamma_gamma_ramps8_destroy(&(plain.u8)); -	} -    } -} - diff --git a/src/servers/gamma.h b/src/servers/gamma.h deleted file mode 100644 index ac269e0..0000000 --- a/src/servers/gamma.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef SERVERS_GAMMA_H -#define SERVERS_GAMMA_H - - -#include "../types/output.h" - -#include <stddef.h> - - - -#ifndef GCC_ONLY -# if defined(__GNUC__) && !defined(__clang__) -#  define GCC_ONLY(...)  __VA_ARGS__ -# else -#  define GCC_ONLY(...)  /* nothing */ -# endif -#endif - - - -/** - * Handle a ‘Command: set-gamma’ message - *  - * @param   conn        The index of the connection - * @param   message_id  The value of the ‘Message ID’ header - * @param   crtc        The value of the ‘CRTC’ header - * @return              Zero on success (even if ignored), -1 on error, - *                      1 if connection closed - */ -GCC_ONLY(__attribute__((nonnull(2)))) -int handle_get_gamma_info(size_t conn, const char* restrict message_id, const char* restrict crtc); - -/** - * Set the gamma ramps on an output - *  - * @param  output  The output - * @param  ramps   The gamma ramps - */ -GCC_ONLY(__attribute__((nonnull))) -void set_gamma(const struct output* restrict output, const union gamma_ramps* restrict ramps); - - -/** - * Store all current gamma ramps - *  - * @return  Zero on success, -1 on error - */ -int initialise_gamma_info(void); - -/** - * Store all current gamma ramps - */ -void store_gamma(void); - -/** - * Restore all gamma ramps - */ -void restore_gamma(void); - - -/** - * Reapplu all gamma ramps - */ -void reapply_gamma(void); - - -#endif - diff --git a/src/servers/kernel.c b/src/servers/kernel.c deleted file mode 100644 index 1600d0a..0000000 --- a/src/servers/kernel.c +++ /dev/null @@ -1,384 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#include "kernel.h" -#include "../state.h" -#include "../util.h" - -#include <libgamma.h> - -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/un.h> -#include <errno.h> -#include <fcntl.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - - - -/** - * Get the pathname of the runtime file - *  - * @param   suffix  The suffix for the file - * @return          The pathname of the file, `NULL` on error - */ -GCC_ONLY(__attribute__((malloc, nonnull))) -static char* get_pathname(const char* restrict suffix) -{ -  const char* restrict rundir = getenv("XDG_RUNTIME_DIR"); -  const char* restrict username = ""; -  char* name = NULL; -  char* p; -  char* restrict rc; -  struct passwd* restrict pw; -  size_t n; -  int saved_errno; -   -  if (sitename) -    { -      name = memdup(sitename, strlen(sitename) + 1); -      if (name == NULL) -	goto fail; -    } -  else if ((name = libgamma_method_default_site(method))) -    { -      name = memdup(name, strlen(name) + 1); -      if (name == NULL) -	goto fail; -    } -   -  if (name != NULL) -    switch (method) -      { -      case LIBGAMMA_METHOD_X_RANDR: -      case LIBGAMMA_METHOD_X_VIDMODE: -	if ((p = strrchr(name, ':'))) -	  if ((p = strchr(p, '.'))) -	    *p = '\0'; -	break; -      default: -	break; -      } -   -  if (!rundir || !*rundir) -    rundir = "/tmp"; -   -  if ((pw = getpwuid(getuid()))) -    username = pw->pw_name ? pw->pw_name : ""; -   -  n = sizeof("/.coopgammad/~/.") + 3 * sizeof(int); -  n += strlen(rundir) + strlen(username) + ((name != NULL) ? strlen(name) : 0) + strlen(suffix); -  if (!(rc = malloc(n))) -    goto fail; -  sprintf(rc, "%s/.coopgammad/~%s/%i%s%s%s", -	  rundir, username, method, name ? "." : "", name ? name : "", suffix); -  free(name); -  return rc; -   - fail: -  saved_errno = errno; -  free(name); -  errno = saved_errno; -  return NULL; -} - - -/** - * Get the pathname of the socket - *  - * @return  The pathname of the socket, `NULL` on error - */ -char* get_socket_pathname(void) -{ -  return get_pathname(".socket"); -} - - -/** - * Get the pathname of the PID file - *  - * @return  The pathname of the PID file, `NULL` on error - */ -char* get_pidfile_pathname(void) -{ -  return get_pathname(".pid"); -} - - -/** - * Get the pathname of the state file - *  - * @return  The pathname of the state file, `NULL` on error - */ -char* get_state_pathname(void) -{ -  return get_pathname(".state"); -} - - -/** - * Check whether a PID file is outdated - *  - * @param   pidpath  The PID file - * @param   token    An environment variable (including both key and value) - *                   that must exist in the process if it is a coopgammad process - * @return           -1: An error occurred - *                    0: The service is already running - *                    1: The PID file is outdated - */ -GCC_ONLY(__attribute__((nonnull))) -static int is_pidfile_reusable(const char* restrict pidpath, const char* restrict token) -{ -  /* PORTERS: /proc/$PID/environ is Linux specific */ -   -  char temp[sizeof("/proc//environ") + 3 * sizeof(long long int)]; -  int fd = -1, saved_errno, tries = 0; -  char* content = NULL; -  char* p; -  pid_t pid = 0; -  size_t n; -#if defined(HAVE_LINUX_PROCFS) -  char* end; -#else -  (void) token; -#endif -   -  /* Get PID */ - retry: -  fd = open(pidpath, O_RDONLY); -  if (fd < 0) -    return -1; -  content = nread(fd, &n); -  if (content == NULL) -    goto fail; -  close(fd), fd = -1; -   -  if (n == 0) -    { -      if (++tries > 1) -	goto bad; -      msleep(100); /* 1 tenth of a second */ -      goto retry; -    } -   -  if (('0' > content[0]) || (content[0] > '9')) -    goto bad; -  if ((content[0] == '0') && ('0' <= content[1]) && (content[1] <= '9')) -    goto bad; -  for (p = content; *p; p++) -    if (('0' <= *p) && (*p <= '9')) -      pid = pid * 10 + (*p & 15); -    else -      break; -  if (*p++ != '\n') -    goto bad; -  if (*p) -    goto bad; -  if ((size_t)(p - content) != n) -    goto bad; -  sprintf(temp, "%llu\n", (unsigned long long)pid); -  if (strcmp(content, temp)) -    goto bad; -  free(content); -   -  /* Validate PID */ -#if defined(HAVE_LINUX_PROCFS) -  sprintf(temp, "/proc/%llu/environ", (unsigned long long)pid); -  fd = open(temp, O_RDONLY); -  if (fd < 0) -    return ((errno == ENOENT) || (errno == EACCES)) ? 1 : -1; -  content = nread(fd, &n); -  if (content == NULL) -    goto fail; -  close(fd), fd = -1; -   -  for (end = (p = content) + n; p != end; p = strchr(p, '\0') + 1) -    if (!strcmp(p, token)) -      return free(content), 0; -  free(content); -#else -  if ((kill(pid, 0) == 0) || (errno == EINVAL)) -    return 0; -#endif -   -  return 1; - bad: -  fprintf(stderr, "%s: pid file contains invalid content: %s\n", argv0, pidpath); -  errno = 0; -  return -1; - fail: -  saved_errno = errno; -  free(content); -  if (fd >= 0) -    close(fd); -  errno = saved_errno; -  return -1; -} - - -/** - * Create PID file - *  - * @param   pidpath  The pathname of the PID file - * @return           Zero on success, -1 on error, - *                   -2 if the service is already running - */ -int create_pidfile(char* pidpath) -{ -  int fd = -1, r, saved_errno; -  char* p; -  char* restrict token = NULL; -   -  /* Create token used to validate the service. */ -  token = malloc(sizeof("COOPGAMMAD_PIDFILE_TOKEN=") + strlen(pidpath)); -  if (token == NULL) -    return -1; -  sprintf(token, "COOPGAMMAD_PIDFILE_TOKEN=%s", pidpath); -#if !defined(USE_VALGRIND) -  if (putenv(token)) -    goto putenv_fail; -  /* `token` must not be free! */ -#else -  { -    static char static_token[sizeof("COOPGAMMAD_PIDFILE_TOKEN=") + PATH_MAX]; -    if (strlen(pidpath) > PATH_MAX) -      abort(); -    strcpy(static_token, token); -    if (putenv(static_token)) -      goto fail; -  } -#endif -   -  /* Create PID file's directory. */ -  for (p = pidpath; *p == '/'; p++); -  while ((p = strchr(p, '/'))) -    { -      *p = '\0'; -      if (mkdir(pidpath, 0755) < 0) -	if (errno != EEXIST) -	  { -	    *p = '/'; -	    goto fail; -	  } -      *p++ = '/'; -    } -   -  /* Create PID file. */ - retry: -  fd = open(pidpath, O_CREAT | O_EXCL | O_WRONLY, 0644); -  if (fd < 0) -    { -      if (errno == EINTR) -	goto retry; -      if (errno != EEXIST) -	return -1; -      r = is_pidfile_reusable(pidpath, token); -      if (r > 0) -	{ -	  unlink(pidpath); -	  goto retry; -	} -      else if (r < 0) -	goto fail; -      fprintf(stderr, "%s: service is already running\n", argv0); -      errno = 0; -      return -2; -    } -   -  /* Write PID to PID file. */ -  if (dprintf(fd, "%llu\n", (unsigned long long)getpid()) < 0) -    goto fail; -   -  /* Done */ -#if defined(USE_VALGRIND) -  free(token); -#endif -  if (close(fd) < 0) -    if (errno != EINTR) -      return -1; -  return 0; -#if !defined(USE_VALGRIND) - putenv_fail: -  saved_errno = errno; -  free(token); -  errno = saved_errno; -#endif - fail: -  saved_errno = errno; -#if defined(USE_VALGRIND) -  free(token); -#endif -  if (fd >= 0) -    { -      close(fd); -      unlink(pidpath); -    } -  errno = saved_errno; -  return -1; -} - - -/** - * Create socket and start listening - *  - * @param   socketpath  The pathname of the socket - * @return              Zero on success, -1 on error - */ -int create_socket(const char* socketpath) -{ -  struct sockaddr_un address; -   -  address.sun_family = AF_UNIX; -  if (strlen(socketpath) >= sizeof(address.sun_path)) -    { -      errno = ENAMETOOLONG; -      return -1; -    } -  strcpy(address.sun_path, socketpath); -  unlink(socketpath); -  if ((socketfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) -    return -1; -  if (fchmod(socketfd, S_IRWXU) < 0) -    return -1; -  if (bind(socketfd, (struct sockaddr*)(&address), (socklen_t)sizeof(address)) < 0) -    return -1; -  if (listen(socketfd, SOMAXCONN) < 0) -    return -1; -   -  return 0; -} - - -/** - * Close and unlink the socket - *  - * @param  socketpath  The pathname of the socket - */ -void close_socket(const char* socketpath) -{ -  if (socketfd >= 0) -    { -      shutdown(socketfd, SHUT_RDWR); -      close(socketfd); -      unlink(socketpath); -    } -} - diff --git a/src/servers/kernel.h b/src/servers/kernel.h deleted file mode 100644 index 494e150..0000000 --- a/src/servers/kernel.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef SERVERS_KERNEL_H -#define SERVERS_KERNEL_H - - -#ifndef GCC_ONLY -# if defined(__GNUC__) && !defined(__clang__) -#  define GCC_ONLY(...)  __VA_ARGS__ -# else -#  define GCC_ONLY(...)  /* nothing */ -# endif -#endif - - - -/** - * Get the pathname of the socket - *  - * @return  The pathname of the socket, `NULL` on error - */ -GCC_ONLY(__attribute__((malloc))) -char* get_socket_pathname(void); - -/** - * Get the pathname of the PID file - *  - * @return  The pathname of the PID file, `NULL` on error - */ -GCC_ONLY(__attribute__((malloc))) -char* get_pidfile_pathname(void); - -/** - * Get the pathname of the state file - *  - * @return  The pathname of the state file, `NULL` on error - */ -GCC_ONLY(__attribute__((malloc))) -char* get_state_pathname(void); - -/** - * Create PID file - *  - * @param   pidpath  The pathname of the PID file - * @return           Zero on success, -1 on error, - *                   -2 if the service is already running - */ -GCC_ONLY(__attribute__((nonnull))) -int create_pidfile(char* pidpath); - -/** - * Create socket and start listening - *  - * @param   socketpath  The pathname of the socket - * @return              Zero on success, -1 on error - */ -GCC_ONLY(__attribute__((nonnull))) -int create_socket(const char* socketpath); - -/** - * Close and unlink the socket - *  - * @param  socketpath  The pathname of the socket - */ -GCC_ONLY(__attribute__((nonnull))) -void close_socket(const char* socketpath); - - -#endif - diff --git a/src/servers/master.c b/src/servers/master.c deleted file mode 100644 index 01b9bb5..0000000 --- a/src/servers/master.c +++ /dev/null @@ -1,394 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#include "master.h" -#include "crtc.h" -#include "gamma.h" -#include "coopgamma.h" -#include "../util.h" -#include "../communication.h" -#include "../state.h" - -#include <sys/socket.h> -#include <errno.h> -#include <fcntl.h> -#include <poll.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - - - -/** - * All poll(3p) events that are not for writing - */ -#define NON_WR_POLL_EVENTS  (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | POLLERR | POLLHUP | POLLNVAL) - - -/** - * Extract headers from an inbound message and pass - * them on to appropriate message handling function - *  - * @param   conn  The index of the connection - * @param   msg   The inbound message - * @return        1: The connection as closed - *                0: Successful - *                -1: Failure - */ -static int dispatch_message(size_t conn, struct message* restrict msg) -{ -  size_t i; -  int r = 0; -  const char* header; -  const char* value; -  const char* command       = NULL; -  const char* crtc          = NULL; -  const char* coalesce      = NULL; -  const char* high_priority = NULL; -  const char* low_priority  = NULL; -  const char* priority      = NULL; -  const char* class         = NULL; -  const char* lifespan      = NULL; -  const char* message_id    = NULL; -   -  for (i = 0; i < msg->header_count; i++) -    { -      value = strstr((header = msg->headers[i]), ": ") + 2; -      if      (strstr(header, "Command: ")       == header)  command       = value; -      else if (strstr(header, "CRTC: ")          == header)  crtc          = value; -      else if (strstr(header, "Coalesce: ")      == header)  coalesce      = value; -      else if (strstr(header, "High priority: ") == header)  high_priority = value; -      else if (strstr(header, "Low priority: ")  == header)  low_priority  = value; -      else if (strstr(header, "Priority: ")      == header)  priority      = value; -      else if (strstr(header, "Class: ")         == header)  class         = value; -      else if (strstr(header, "Lifespan: ")      == header)  lifespan      = value; -      else if (strstr(header, "Message ID: ")    == header)  message_id    = value; -      else if (strstr(header, "Length: ")        == header)  ;/* Handled transparently */ -      else -	fprintf(stderr, "%s: ignoring unrecognised header: %s\n", argv0, header); -    } -   -  if (command == NULL) -    fprintf(stderr, "%s: ignoring message without Command header\n", argv0); -  else if (message_id == NULL) -    fprintf(stderr, "%s: ignoring message without Message ID header\n", argv0); -  else if (!strcmp(command, "enumerate-crtcs")) -    { -      if (crtc || coalesce || high_priority || low_priority || priority || class || lifespan) -	fprintf(stderr, "%s: ignoring superfluous headers in Command: enumerate-crtcs message\n", argv0); -      r = handle_enumerate_crtcs(conn, message_id); -    } -  else if (!strcmp(command, "get-gamma-info")) -    { -      if (coalesce || high_priority || low_priority || priority || class || lifespan) -	fprintf(stderr, "%s: ignoring superfluous headers in Command: get-gamma-info message\n", argv0); -      r = handle_get_gamma_info(conn, message_id, crtc); -    } -  else if (!strcmp(command, "get-gamma")) -    { -      if (priority || class || lifespan) -	fprintf(stderr, "%s: ignoring superfluous headers in Command: get-gamma message\n", argv0); -      r = handle_get_gamma(conn, message_id, crtc, coalesce, high_priority, low_priority); -    } -  else if (!strcmp(command, "set-gamma")) -    { -      if (coalesce || high_priority || low_priority) -	fprintf(stderr, "%s: ignoring superfluous headers in Command: set-gamma message\n", argv0); -      r = handle_set_gamma(conn, message_id, crtc, priority, class, lifespan); -    } -  else -    fprintf(stderr, "%s: ignoring unrecognised command: Command: %s\n", argv0, command); -   -  return r; -} - - -/** - * Sets the file descriptor set that includes - * the server socket and all connections - *  - * The file descriptor will be ordered as in - * the array `connections`, `socketfd` will - * be last. - *  - * @param   fds        Reference parameter for the array of file descriptors - * @param   fdn        Output parameter for the number of file descriptors - * @param   fds_alloc  Reference parameter for the allocation size of `fds`, in elements - * @return             Zero on success, -1 on error - */ -static int update_fdset(struct pollfd** restrict fds, nfds_t* restrict fdn, nfds_t* restrict fds_alloc) -{ -  size_t i; -  nfds_t j = 0; -   -  if (connections_used + 1 > *fds_alloc) -    { -      void* new = realloc(*fds, (connections_used + 1) * sizeof(**fds)); -      if (new == NULL) -	return -1; -      *fds = new; -      *fds_alloc = connections_used + 1; -    } -   -  for (i = 0; i < connections_used; i++) -    if (connections[i] >= 0) -      { -	(*fds)[j].fd = connections[i]; -	(*fds)[j].events = NON_WR_POLL_EVENTS; -	j++; -      } -   -  (*fds)[j].fd = socketfd; -  (*fds)[j].events = NON_WR_POLL_EVENTS; -  j++; -   -  *fdn = j; -  return 0; -} - - -/** - * Handle event on the server socket - *  - * @return  1: New connection accepted - *          0: Successful - *          -1: Failure - */ -static int handle_server(void) -{ -  int fd, flags, saved_errno; -   -  fd = accept(socketfd, NULL, NULL); -  if (fd < 0) -    switch (errno) -      { -      case EINTR: -	return 0; -      case ECONNABORTED: -      case EINVAL: -	terminate = 1; -	return 0; -      default: -	return -1; -      } -   -  flags = fcntl(fd, F_GETFL); -  if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) -    goto fail; -  -  if (connections_ptr == connections_alloc) -    { -      void* new; -       -      new = realloc(connections, (connections_alloc + 10) * sizeof(*connections)); -      if (new == NULL) -	goto fail; -      connections = new; -      connections[connections_ptr] = fd; -       -      new = realloc(outbound, (connections_alloc + 10) * sizeof(*outbound)); -      if (new == NULL) -	goto fail; -      outbound = new; -      ring_initialise(outbound + connections_ptr); -       -      new = realloc(inbound, (connections_alloc + 10) * sizeof(*inbound)); -      if (new == NULL) -	goto fail; -      inbound = new; -      connections_alloc += 10; -      if (message_initialise(inbound + connections_ptr)) -	goto fail; -    } -  else -    { -      connections[connections_ptr] = fd; -      ring_initialise(outbound + connections_ptr); -      if (message_initialise(inbound + connections_ptr)) -	goto fail; -    } -   -  connections_ptr++; -  while ((connections_ptr < connections_used) && (connections[connections_ptr] >= 0)) -    connections_ptr++; -  if (connections_used < connections_ptr) -    connections_used = connections_ptr; -   -  return 1; - fail: -  saved_errno = errno; -  shutdown(fd, SHUT_RDWR); -  close(fd); -  errno = saved_errno; -  return -1; -} - - -/** - * Handle event on a connection to a client - *  - * @param   conn  The index of the connection - * @return        1: The connection as closed - *                0: Successful - *                -1: Failure - */ -static int handle_connection(size_t conn) -{ -  struct message* restrict msg = inbound + conn; -  int r, fd = connections[conn]; -   - again: -  switch (message_read(msg, fd)) -    { -    default: -      break; -    case -1: -      switch (errno) -	{ -	case EINTR: -	case EAGAIN: -#if EAGAIN != EWOULDBLOCK -	case EWOULDBLOCK: -#endif -	  return 0; -	default: -	  return -1; -	case ECONNRESET:; -	  /* Fall throught to `case -2` in outer switch */ -	} -    case -2: -      shutdown(fd, SHUT_RDWR); -      close(fd); -      connections[conn] = -1; -      if (conn < connections_ptr) -	connections_ptr = conn; -      while ((connections_used > 0) && (connections[connections_used - 1] < 0)) -	connections_used -= 1; -      message_destroy(msg); -      ring_destroy(outbound + conn); -      if (connection_closed(fd) < 0) -	return -1; -      return 1; -    } -   -  if ((r = dispatch_message(conn, msg))) -    return r; -   -  goto again; -} - - - -/** - * Disconnect all clients - */ -void disconnect_all(void) -{ -  size_t i; -  for (i = 0; i < connections_used; i++) -    if (connections[i] >= 0) -      { -	shutdown(connections[i], SHUT_RDWR); -	close(connections[i]); -      } -} - - -/** - * The program's main loop - *  - * @return  Zero on success, -1 on error - */ -int main_loop(void) -{ -  struct pollfd* fds = NULL; -  nfds_t i, fdn = 0, fds_alloc = 0; -  int r, update, saved_errno; -  size_t j; -   -  if (update_fdset(&fds, &fdn, &fds_alloc) < 0) -    goto fail; -   -  while (!reexec && !terminate) -    { -      if (connection) -	{ -	  if ((connection == 1 ? disconnect() : reconnect()) < 0) -	    { -	      connection = 0; -	      goto fail; -	    } -	  connection = 0; -	} -       -      for (j = 0, i = 0; j < connections_used; j++) -	if (connections[j] >= 0) -	  { -	    fds[i].revents = 0; -	    if (ring_have_more(outbound + j)) -	      fds[(size_t)i++ + j].events |= POLLOUT; -	    else -	      fds[(size_t)i++ + j].events &= ~POLLOUT; -	  } -      fds[i].revents = 0; -       -      if (poll(fds, fdn, -1) < 0) -	{ -	  if (errno == EAGAIN) -	    perror(argv0); -	  else if (errno != EINTR) -	    goto fail; -	} -       -      update = 0; -      for (i = 0; i < fdn; i++) -	{ -	  int do_read  = fds[i].revents & NON_WR_POLL_EVENTS; -	  int do_write = fds[i].revents & POLLOUT; -	  int fd = fds[i].fd; -	  if (!do_read && !do_write) -	    continue; -	   -	  if (fd == socketfd) -	    r = handle_server(); -	  else -	    { -	      for (j = 0; connections[j] != fd; j++); -	      r = do_read ? handle_connection(j) : 0; -	    } -	   -	  if ((r >= 0) && do_write) -	    r |= continue_send(j); -	  if (r < 0) -	    goto fail; -	  update |= (r > 0); -	} -      if (update) -	if (update_fdset(&fds, &fdn, &fds_alloc) < 0) -	  goto fail; -    } -   -  free(fds); -  return 0; - fail: -  saved_errno = errno; -  free(fds); -  errno = saved_errno; -  return -1; -} - diff --git a/src/servers/master.h b/src/servers/master.h deleted file mode 100644 index d7ef6e5..0000000 --- a/src/servers/master.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * coopgammad -- Cooperative gamma server - * Copyright (C) 2016  Mattias Andrée (maandree@kth.se) - *  - * This program 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. - *  - * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef SERVERS_MASTER_H -#define SERVERS_MASTER_H - - -/** - * Disconnect all clients - */ -void disconnect_all(void); - -/** - * The program's main loop - *  - * @return  Zero on success, -1 on error - */ -int main_loop(void); - - -#endif -  | 
