~elementary-os/ubuntu-package-imports/mutter-bionic

« back to all changes in this revision

Viewing changes to src/backends/meta-monitor-manager-dummy.c

  • Committer: RabbitBot
  • Date: 2018-04-11 14:49:36 UTC
  • Revision ID: rabbitbot@elementary.io-20180411144936-hgymqa9d8d1xfpbh
Initial import, version 3.28.0-2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 
2
 
 
3
/*
 
4
 * Copyright (C) 2001, 2002 Havoc Pennington
 
5
 * Copyright (C) 2002, 2003 Red Hat Inc.
 
6
 * Some ICCCM manager selection code derived from fvwm2,
 
7
 * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
 
8
 * Copyright (C) 2003 Rob Adams
 
9
 * Copyright (C) 2004-2006 Elijah Newren
 
10
 * Copyright (C) 2013 Red Hat Inc.
 
11
 *
 
12
 * This program is free software; you can redistribute it and/or
 
13
 * modify it under the terms of the GNU General Public License as
 
14
 * published by the Free Software Foundation; either version 2 of the
 
15
 * License, or (at your option) any later version.
 
16
 *
 
17
 * This program is distributed in the hope that it will be useful, but
 
18
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
20
 * General Public License for more details.
 
21
 *
 
22
 * You should have received a copy of the GNU General Public License
 
23
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
 
 
28
#include "meta-monitor-manager-dummy.h"
 
29
 
 
30
#include <stdlib.h>
 
31
 
 
32
#include <meta/util.h>
 
33
#include "backends/meta-backend-private.h"
 
34
#include "backends/meta-crtc.h"
 
35
#include "backends/meta-monitor.h"
 
36
#include "backends/meta-monitor-config-manager.h"
 
37
#include "backends/meta-output.h"
 
38
 
 
39
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
 
40
 
 
41
#define MAX_MONITORS 5
 
42
#define MAX_OUTPUTS (MAX_MONITORS * 2)
 
43
#define MAX_CRTCS (MAX_MONITORS * 2)
 
44
#define MAX_MODES (MAX_MONITORS * 4)
 
45
 
 
46
struct _MetaMonitorManagerDummy
 
47
{
 
48
  MetaMonitorManager parent_instance;
 
49
 
 
50
  MetaGpu *gpu;
 
51
 
 
52
  gboolean is_transform_handled;
 
53
};
 
54
 
 
55
struct _MetaMonitorManagerDummyClass
 
56
{
 
57
  MetaMonitorManagerClass parent_class;
 
58
};
 
59
 
 
60
typedef struct _MetaOutputDummy
 
61
{
 
62
  float scale;
 
63
} MetaOutputDummy;
 
64
 
 
65
G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MONITOR_MANAGER);
 
66
 
 
67
struct _MetaGpuDummy
 
68
{
 
69
  MetaGpu parent;
 
70
};
 
71
 
 
72
G_DEFINE_TYPE (MetaGpuDummy, meta_gpu_dummy, META_TYPE_GPU)
 
73
 
 
74
static void
 
75
meta_output_dummy_notify_destroy (MetaOutput *output);
 
76
 
 
77
typedef struct _CrtcModeSpec
 
78
{
 
79
  int width;
 
80
  int height;
 
81
  float refresh_rate;
 
82
} CrtcModeSpec;
 
83
 
 
84
static MetaCrtcMode *
 
85
create_mode (CrtcModeSpec *spec,
 
86
             long          mode_id)
 
87
{
 
88
  MetaCrtcMode *mode;
 
89
 
 
90
  mode = g_object_new (META_TYPE_CRTC_MODE, NULL);
 
91
 
 
92
  mode->mode_id = mode_id;
 
93
  mode->width = spec->width;
 
94
  mode->height = spec->height;
 
95
  mode->refresh_rate = spec->refresh_rate;
 
96
 
 
97
  return mode;
 
98
}
 
99
 
 
100
static void
 
101
append_monitor (MetaMonitorManager *manager,
 
102
                GList             **modes,
 
103
                GList             **crtcs,
 
104
                GList             **outputs,
 
105
                float               scale)
 
106
{
 
107
  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager);
 
108
  MetaGpu *gpu = manager_dummy->gpu;
 
109
  CrtcModeSpec mode_specs[] = {
 
110
    {
 
111
      .width = 800,
 
112
      .height = 600,
 
113
      .refresh_rate = 60.0
 
114
    },
 
115
    {
 
116
      .width = 1024,
 
117
      .height = 768,
 
118
      .refresh_rate = 60.0
 
119
    }
 
120
  };
 
121
  GList *new_modes = NULL;
 
122
  MetaCrtc *crtc;
 
123
  MetaOutputDummy *output_dummy;
 
124
  MetaOutput *output;
 
125
  unsigned int i;
 
126
  unsigned int number;
 
127
  GList *l;
 
128
 
 
129
  for (i = 0; i < G_N_ELEMENTS (mode_specs); i++)
 
130
    {
 
131
      long mode_id;
 
132
      MetaCrtcMode *mode;
 
133
 
 
134
      mode_id = g_list_length (*modes) + i + 1;
 
135
      mode = create_mode (&mode_specs[i], mode_id);
 
136
 
 
137
      new_modes = g_list_append (new_modes, mode);
 
138
    }
 
139
  *modes = g_list_concat (*modes, new_modes);
 
140
 
 
141
  crtc = g_object_new (META_TYPE_CRTC, NULL);
 
142
  crtc->crtc_id = g_list_length (*crtcs) + 1;
 
143
  crtc->all_transforms = ALL_TRANSFORMS;
 
144
  *crtcs = g_list_append (*crtcs, crtc);
 
145
 
 
146
  output = g_object_new (META_TYPE_OUTPUT, NULL);
 
147
 
 
148
  output_dummy = g_new0 (MetaOutputDummy, 1);
 
149
  *output_dummy = (MetaOutputDummy) {
 
150
    .scale = scale
 
151
  };
 
152
 
 
153
  number = g_list_length (*outputs) + 1;
 
154
 
 
155
  output->gpu = gpu;
 
156
  output->winsys_id = number;
 
157
  output->name = g_strdup_printf ("LVDS%d", number);
 
158
  output->vendor = g_strdup ("MetaProducts Inc.");
 
159
  output->product = g_strdup ("MetaMonitor");
 
160
  output->serial = g_strdup_printf ("0xC0FFEE-%d", number);
 
161
  output->suggested_x = -1;
 
162
  output->suggested_y = -1;
 
163
  output->width_mm = 222;
 
164
  output->height_mm = 125;
 
165
  output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
 
166
  output->preferred_mode = g_list_last (*modes)->data;
 
167
  output->n_possible_clones = 0;
 
168
  output->backlight = -1;
 
169
  output->connector_type = META_CONNECTOR_TYPE_LVDS;
 
170
  output->driver_private = output_dummy;
 
171
  output->driver_notify =
 
172
    (GDestroyNotify) meta_output_dummy_notify_destroy;
 
173
 
 
174
  output->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs));
 
175
  for (l = new_modes, i = 0; l; l = l->next, i++)
 
176
    {
 
177
      MetaCrtcMode *mode = l->data;
 
178
 
 
179
      output->modes[i] = mode;
 
180
    }
 
181
  output->n_modes = G_N_ELEMENTS (mode_specs);
 
182
  output->possible_crtcs = g_new0 (MetaCrtc *, 1);
 
183
  output->possible_crtcs[0] = g_list_last (*crtcs)->data;
 
184
  output->n_possible_crtcs = 1;
 
185
 
 
186
  *outputs = g_list_append (*outputs, output);
 
187
}
 
188
 
 
189
static void
 
190
append_tiled_monitor (MetaMonitorManager *manager,
 
191
                      GList             **modes,
 
192
                      GList             **crtcs,
 
193
                      GList             **outputs,
 
194
                      int                 scale)
 
195
{
 
196
  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager);
 
197
  MetaGpu *gpu = manager_dummy->gpu;
 
198
  CrtcModeSpec mode_specs[] = {
 
199
    {
 
200
      .width = 800,
 
201
      .height = 600,
 
202
      .refresh_rate = 60.0
 
203
    },
 
204
    {
 
205
      .width = 512,
 
206
      .height = 768,
 
207
      .refresh_rate = 60.0
 
208
    }
 
209
  };
 
210
  unsigned int n_tiles = 2;
 
211
  GList *new_modes = NULL;
 
212
  GList *new_crtcs = NULL;
 
213
  MetaOutput *output;
 
214
  unsigned int i;
 
215
  uint32_t tile_group_id;
 
216
 
 
217
  for (i = 0; i < G_N_ELEMENTS (mode_specs); i++)
 
218
    {
 
219
      long mode_id;
 
220
      MetaCrtcMode *mode;
 
221
 
 
222
      mode_id = g_list_length (*modes) + i + 1;
 
223
      mode = create_mode (&mode_specs[i], mode_id);
 
224
 
 
225
      new_modes = g_list_append (new_modes, mode);
 
226
    }
 
227
  *modes = g_list_concat (*modes, new_modes);
 
228
 
 
229
  for (i = 0; i < n_tiles; i++)
 
230
    {
 
231
      MetaCrtc *crtc;
 
232
 
 
233
      crtc = g_object_new (META_TYPE_CRTC, NULL);
 
234
      crtc->gpu = gpu;
 
235
      crtc->crtc_id = g_list_length (*crtcs) + i + 1;
 
236
      crtc->all_transforms = ALL_TRANSFORMS;
 
237
      new_crtcs = g_list_append (new_crtcs, crtc);
 
238
    }
 
239
  *crtcs = g_list_concat (*crtcs, new_crtcs);
 
240
 
 
241
  tile_group_id = g_list_length (*outputs) + 1;
 
242
  for (i = 0; i < n_tiles; i++)
 
243
    {
 
244
      MetaOutputDummy *output_dummy;
 
245
      MetaCrtcMode *preferred_mode;
 
246
      unsigned int j;
 
247
      unsigned int number;
 
248
      GList *l;
 
249
 
 
250
      output_dummy = g_new0 (MetaOutputDummy, 1);
 
251
      *output_dummy = (MetaOutputDummy) {
 
252
        .scale = scale
 
253
      };
 
254
 
 
255
      /* Arbitrary ID unique for this output */
 
256
      number = g_list_length (*outputs) + 1;
 
257
 
 
258
      preferred_mode = g_list_last (*modes)->data;
 
259
 
 
260
      output = g_object_new (META_TYPE_OUTPUT, NULL);
 
261
 
 
262
      output->gpu = gpu;
 
263
      output->winsys_id = number;
 
264
      output->name = g_strdup_printf ("LVDS%d", number);
 
265
      output->vendor = g_strdup ("MetaProducts Inc.");
 
266
      output->product = g_strdup ("MetaMonitor");
 
267
      output->serial = g_strdup_printf ("0xC0FFEE-%d", number);
 
268
      output->suggested_x = -1;
 
269
      output->suggested_y = -1;
 
270
      output->width_mm = 222;
 
271
      output->height_mm = 125;
 
272
      output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
 
273
      output->preferred_mode = preferred_mode;
 
274
      output->n_possible_clones = 0;
 
275
      output->backlight = -1;
 
276
      output->connector_type = META_CONNECTOR_TYPE_LVDS;
 
277
      output->tile_info = (MetaTileInfo) {
 
278
        .group_id = tile_group_id,
 
279
        .max_h_tiles = n_tiles,
 
280
        .max_v_tiles = 1,
 
281
        .loc_h_tile = i,
 
282
        .loc_v_tile = 0,
 
283
        .tile_w = preferred_mode->width,
 
284
        .tile_h = preferred_mode->height
 
285
      },
 
286
      output->driver_private = output_dummy;
 
287
      output->driver_notify =
 
288
        (GDestroyNotify) meta_output_dummy_notify_destroy;
 
289
 
 
290
      output->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs));
 
291
      for (l = new_modes, j = 0; l; l = l->next, j++)
 
292
        {
 
293
          MetaCrtcMode *mode = l->data;
 
294
 
 
295
          output->modes[j] = mode;
 
296
        }
 
297
      output->n_modes = G_N_ELEMENTS (mode_specs);
 
298
 
 
299
      output->possible_crtcs = g_new0 (MetaCrtc *, n_tiles);
 
300
      for (l = new_crtcs, j = 0; l; l = l->next, j++)
 
301
        {
 
302
          MetaCrtc *crtc = l->data;
 
303
 
 
304
          output->possible_crtcs[j] = crtc;
 
305
        }
 
306
      output->n_possible_crtcs = n_tiles;
 
307
 
 
308
      *outputs = g_list_append (*outputs, output);
 
309
    }
 
310
}
 
311
 
 
312
static void
 
313
meta_output_dummy_notify_destroy (MetaOutput *output)
 
314
{
 
315
  g_clear_pointer (&output->driver_private, g_free);
 
316
}
 
317
 
 
318
static void
 
319
meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
 
320
{
 
321
  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager);
 
322
  MetaGpu *gpu = manager_dummy->gpu;
 
323
  unsigned int num_monitors = 1;
 
324
  float *monitor_scales = NULL;
 
325
  const char *num_monitors_str;
 
326
  const char *monitor_scales_str;
 
327
  const char *tiled_monitors_str;
 
328
  gboolean tiled_monitors;
 
329
  unsigned int i;
 
330
  GList *outputs;
 
331
  GList *crtcs;
 
332
  GList *modes;
 
333
 
 
334
  /* To control what monitor configuration is generated, there are two available
 
335
   * environmental variables that can be used:
 
336
   *
 
337
   * MUTTER_DEBUG_NUM_DUMMY_MONITORS
 
338
   *
 
339
   * Specifies the number of dummy monitors to include in the stage. Every
 
340
   * monitor is 1024x786 pixels and they are placed on a horizontal row.
 
341
   *
 
342
   * MUTTER_DEBUG_DUMMY_MONITOR_SCALES
 
343
   *
 
344
   * A comma separated list that specifies the scales of the dummy monitors.
 
345
   *
 
346
   * MUTTER_DEBUG_TILED_DUMMY_MONITORS
 
347
   *
 
348
   * If set to "1" the dummy monitors will emulate being tiled, i.e. each have a
 
349
   * unique tile group id, made up of multiple outputs and CRTCs.
 
350
   *
 
351
   * For example the following configuration results in two monitors, where the
 
352
   * first one has the monitor scale 1, and the other the monitor scale 2.
 
353
   *
 
354
   * MUTTER_DEBUG_NUM_DUMMY_MONITORS=2
 
355
   * MUTTER_DEBUG_DUMMY_MONITOR_SCALES=1,2
 
356
   * MUTTER_DEBUG_TILED_DUMMY_MONITORS=1
 
357
   */
 
358
  num_monitors_str = getenv ("MUTTER_DEBUG_NUM_DUMMY_MONITORS");
 
359
  if (num_monitors_str)
 
360
    {
 
361
      num_monitors = g_ascii_strtoll (num_monitors_str, NULL, 10);
 
362
      if (num_monitors <= 0)
 
363
        {
 
364
          meta_warning ("Invalid number of dummy monitors");
 
365
          num_monitors = 1;
 
366
        }
 
367
 
 
368
      if (num_monitors > MAX_MONITORS)
 
369
        {
 
370
          meta_warning ("Clamping monitor count to max (%d)",
 
371
                        MAX_MONITORS);
 
372
          num_monitors = MAX_MONITORS;
 
373
        }
 
374
    }
 
375
 
 
376
  monitor_scales = g_newa (typeof (*monitor_scales), num_monitors);
 
377
  for (i = 0; i < num_monitors; i++)
 
378
    monitor_scales[i] = 1.0;
 
379
 
 
380
  monitor_scales_str = getenv ("MUTTER_DEBUG_DUMMY_MONITOR_SCALES");
 
381
  if (monitor_scales_str)
 
382
    {
 
383
      gchar **scales_str_list;
 
384
 
 
385
      scales_str_list = g_strsplit (monitor_scales_str, ",", -1);
 
386
      if (g_strv_length (scales_str_list) != num_monitors)
 
387
        meta_warning ("Number of specified monitor scales differ from number "
 
388
                      "of monitors (defaults to 1).\n");
 
389
      for (i = 0; i < num_monitors && scales_str_list[i]; i++)
 
390
        {
 
391
          float scale = g_ascii_strtod (scales_str_list[i], NULL);
 
392
 
 
393
          monitor_scales[i] = scale;
 
394
        }
 
395
      g_strfreev (scales_str_list);
 
396
    }
 
397
 
 
398
  tiled_monitors_str = g_getenv ("MUTTER_DEBUG_TILED_DUMMY_MONITORS");
 
399
  tiled_monitors = g_strcmp0 (tiled_monitors_str, "1") == 0;
 
400
 
 
401
  modes = NULL;
 
402
  crtcs = NULL;
 
403
  outputs = NULL;
 
404
 
 
405
  for (i = 0; i < num_monitors; i++)
 
406
    {
 
407
      if (tiled_monitors)
 
408
        append_tiled_monitor (manager,
 
409
                              &modes, &crtcs, &outputs, monitor_scales[i]);
 
410
      else
 
411
        append_monitor (manager, &modes, &crtcs, &outputs, monitor_scales[i]);
 
412
    }
 
413
 
 
414
  meta_gpu_take_modes (gpu, modes);
 
415
  meta_gpu_take_crtcs (gpu, crtcs);
 
416
  meta_gpu_take_outputs (gpu, outputs);
 
417
}
 
418
 
 
419
static void
 
420
meta_monitor_manager_dummy_ensure_initial_config (MetaMonitorManager *manager)
 
421
{
 
422
  MetaMonitorsConfig *config;
 
423
 
 
424
  config = meta_monitor_manager_ensure_configured (manager);
 
425
 
 
426
  if (meta_is_stage_views_enabled ())
 
427
    meta_monitor_manager_update_logical_state (manager, config);
 
428
  else
 
429
    meta_monitor_manager_update_logical_state_derived (manager, NULL);
 
430
}
 
431
 
 
432
static void
 
433
apply_crtc_assignments (MetaMonitorManager *manager,
 
434
                        MetaCrtcInfo      **crtcs,
 
435
                        unsigned int        n_crtcs,
 
436
                        MetaOutputInfo    **outputs,
 
437
                        unsigned int        n_outputs)
 
438
{
 
439
  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager);
 
440
  GList *l;
 
441
  unsigned i;
 
442
 
 
443
  for (i = 0; i < n_crtcs; i++)
 
444
    {
 
445
      MetaCrtcInfo *crtc_info = crtcs[i];
 
446
      MetaCrtc *crtc = crtc_info->crtc;
 
447
      crtc->is_dirty = TRUE;
 
448
 
 
449
      if (crtc_info->mode == NULL)
 
450
        {
 
451
          crtc->rect.x = 0;
 
452
          crtc->rect.y = 0;
 
453
          crtc->rect.width = 0;
 
454
          crtc->rect.height = 0;
 
455
          crtc->current_mode = NULL;
 
456
        }
 
457
      else
 
458
        {
 
459
          MetaCrtcMode *mode;
 
460
          MetaOutput *output;
 
461
          unsigned int j;
 
462
          int width, height;
 
463
 
 
464
          mode = crtc_info->mode;
 
465
 
 
466
          if (meta_monitor_transform_is_rotated (crtc_info->transform))
 
467
            {
 
468
              width = mode->height;
 
469
              height = mode->width;
 
470
            }
 
471
          else
 
472
            {
 
473
              width = mode->width;
 
474
              height = mode->height;
 
475
            }
 
476
 
 
477
          crtc->rect.x = crtc_info->x;
 
478
          crtc->rect.y = crtc_info->y;
 
479
          crtc->rect.width = width;
 
480
          crtc->rect.height = height;
 
481
          crtc->current_mode = mode;
 
482
          crtc->transform = crtc_info->transform;
 
483
 
 
484
          for (j = 0; j < crtc_info->outputs->len; j++)
 
485
            {
 
486
              output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
 
487
 
 
488
              output->is_dirty = TRUE;
 
489
              output->crtc = crtc;
 
490
            }
 
491
        }
 
492
    }
 
493
 
 
494
  for (i = 0; i < n_outputs; i++)
 
495
    {
 
496
      MetaOutputInfo *output_info = outputs[i];
 
497
      MetaOutput *output = output_info->output;
 
498
 
 
499
      output->is_primary = output_info->is_primary;
 
500
      output->is_presentation = output_info->is_presentation;
 
501
    }
 
502
 
 
503
  /* Disable CRTCs not mentioned in the list */
 
504
  for (l = meta_gpu_get_crtcs (manager_dummy->gpu); l; l = l->next)
 
505
    {
 
506
      MetaCrtc *crtc = l->data;
 
507
 
 
508
      crtc->logical_monitor = NULL;
 
509
 
 
510
      if (crtc->is_dirty)
 
511
        {
 
512
          crtc->is_dirty = FALSE;
 
513
          continue;
 
514
        }
 
515
 
 
516
      crtc->rect.x = 0;
 
517
      crtc->rect.y = 0;
 
518
      crtc->rect.width = 0;
 
519
      crtc->rect.height = 0;
 
520
      crtc->current_mode = NULL;
 
521
    }
 
522
 
 
523
  /* Disable outputs not mentioned in the list */
 
524
  for (l = meta_gpu_get_outputs (manager_dummy->gpu); l; l = l->next)
 
525
    {
 
526
      MetaOutput *output = l->data;
 
527
 
 
528
      if (output->is_dirty)
 
529
        {
 
530
          output->is_dirty = FALSE;
 
531
          continue;
 
532
        }
 
533
 
 
534
      output->crtc = NULL;
 
535
      output->is_primary = FALSE;
 
536
    }
 
537
}
 
538
 
 
539
static void
 
540
update_screen_size (MetaMonitorManager *manager,
 
541
                    MetaMonitorsConfig *config)
 
542
{
 
543
  GList *l;
 
544
  int screen_width = 0;
 
545
  int screen_height = 0;
 
546
 
 
547
  for (l = config->logical_monitor_configs; l; l = l->next)
 
548
    {
 
549
      MetaLogicalMonitorConfig *logical_monitor_config = l->data;
 
550
      int right_edge;
 
551
      int bottom_edge;
 
552
 
 
553
      right_edge = (logical_monitor_config->layout.width +
 
554
                    logical_monitor_config->layout.x);
 
555
      if (right_edge > screen_width)
 
556
        screen_width = right_edge;
 
557
 
 
558
      bottom_edge = (logical_monitor_config->layout.height +
 
559
                     logical_monitor_config->layout.y);
 
560
      if (bottom_edge > screen_height)
 
561
        screen_height = bottom_edge;
 
562
    }
 
563
 
 
564
  manager->screen_width = screen_width;
 
565
  manager->screen_height = screen_height;
 
566
}
 
567
 
 
568
static gboolean
 
569
meta_monitor_manager_dummy_apply_monitors_config (MetaMonitorManager      *manager,
 
570
                                                  MetaMonitorsConfig      *config,
 
571
                                                  MetaMonitorsConfigMethod method,
 
572
                                                  GError                 **error)
 
573
{
 
574
  GPtrArray *crtc_infos;
 
575
  GPtrArray *output_infos;
 
576
 
 
577
  if (!config)
 
578
    {
 
579
      manager->screen_width = META_MONITOR_MANAGER_MIN_SCREEN_WIDTH;
 
580
      manager->screen_height = META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT;
 
581
 
 
582
      meta_monitor_manager_rebuild (manager, NULL);
 
583
      return TRUE;
 
584
    }
 
585
 
 
586
  if (!meta_monitor_config_manager_assign (manager, config,
 
587
                                           &crtc_infos, &output_infos,
 
588
                                           error))
 
589
    return FALSE;
 
590
 
 
591
  if (method == META_MONITORS_CONFIG_METHOD_VERIFY)
 
592
    {
 
593
      g_ptr_array_free (crtc_infos, TRUE);
 
594
      g_ptr_array_free (output_infos, TRUE);
 
595
      return TRUE;
 
596
    }
 
597
 
 
598
  apply_crtc_assignments (manager,
 
599
                          (MetaCrtcInfo **) crtc_infos->pdata,
 
600
                          crtc_infos->len,
 
601
                          (MetaOutputInfo **) output_infos->pdata,
 
602
                          output_infos->len);
 
603
 
 
604
  g_ptr_array_free (crtc_infos, TRUE);
 
605
  g_ptr_array_free (output_infos, TRUE);
 
606
 
 
607
  update_screen_size (manager, config);
 
608
  meta_monitor_manager_rebuild (manager, config);
 
609
 
 
610
  return TRUE;
 
611
}
 
612
 
 
613
static gboolean
 
614
meta_monitor_manager_dummy_is_transform_handled (MetaMonitorManager  *manager,
 
615
                                                 MetaCrtc            *crtc,
 
616
                                                 MetaMonitorTransform transform)
 
617
{
 
618
  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager);
 
619
 
 
620
  return manager_dummy->is_transform_handled;
 
621
}
 
622
 
 
623
static float
 
624
meta_monitor_manager_dummy_calculate_monitor_mode_scale (MetaMonitorManager *manager,
 
625
                                                         MetaMonitor        *monitor,
 
626
                                                         MetaMonitorMode    *monitor_mode)
 
627
{
 
628
  MetaOutput *output;
 
629
  MetaOutputDummy *output_dummy;
 
630
 
 
631
  output = meta_monitor_get_main_output (monitor);
 
632
  output_dummy = output->driver_private;
 
633
 
 
634
  return output_dummy->scale;
 
635
}
 
636
 
 
637
static float *
 
638
meta_monitor_manager_dummy_calculate_supported_scales (MetaMonitorManager          *manager,
 
639
                                                       MetaLogicalMonitorLayoutMode layout_mode,
 
640
                                                       MetaMonitor                 *monitor,
 
641
                                                       MetaMonitorMode             *monitor_mode,
 
642
                                                       int                         *n_supported_scales)
 
643
{
 
644
  MetaMonitorScalesConstraint constraints =
 
645
    META_MONITOR_SCALES_CONSTRAINT_NONE;
 
646
 
 
647
  switch (layout_mode)
 
648
    {
 
649
    case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
 
650
      break;
 
651
    case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
 
652
      constraints |= META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
 
653
      break;
 
654
    }
 
655
 
 
656
  return meta_monitor_calculate_supported_scales (monitor, monitor_mode,
 
657
                                                  constraints,
 
658
                                                  n_supported_scales);
 
659
}
 
660
 
 
661
static gboolean
 
662
is_monitor_framebuffers_scaled (void)
 
663
{
 
664
  MetaBackend *backend = meta_get_backend ();
 
665
  MetaSettings *settings = meta_backend_get_settings (backend);
 
666
 
 
667
  return meta_settings_is_experimental_feature_enabled (
 
668
    settings,
 
669
    META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
 
670
}
 
671
 
 
672
static MetaMonitorManagerCapability
 
673
meta_monitor_manager_dummy_get_capabilities (MetaMonitorManager *manager)
 
674
{
 
675
  MetaBackend *backend = meta_get_backend ();
 
676
  MetaSettings *settings = meta_backend_get_settings (backend);
 
677
  MetaMonitorManagerCapability capabilities =
 
678
    META_MONITOR_MANAGER_CAPABILITY_NONE;
 
679
 
 
680
  capabilities |= META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
 
681
 
 
682
  if (meta_settings_is_experimental_feature_enabled (
 
683
        settings,
 
684
        META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
 
685
    capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;
 
686
 
 
687
  return capabilities;
 
688
}
 
689
 
 
690
static gboolean
 
691
meta_monitor_manager_dummy_get_max_screen_size (MetaMonitorManager *manager,
 
692
                                                int                *max_width,
 
693
                                                int                *max_height)
 
694
{
 
695
  if (meta_is_stage_views_enabled ())
 
696
    return FALSE;
 
697
 
 
698
  *max_width = 65535;
 
699
  *max_height = 65535;
 
700
 
 
701
  return TRUE;
 
702
}
 
703
 
 
704
static MetaLogicalMonitorLayoutMode
 
705
meta_monitor_manager_dummy_get_default_layout_mode (MetaMonitorManager *manager)
 
706
{
 
707
  if (!meta_is_stage_views_enabled ())
 
708
    return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
 
709
 
 
710
  if (is_monitor_framebuffers_scaled ())
 
711
    return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
 
712
  else
 
713
    return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
 
714
}
 
715
 
 
716
static void
 
717
meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
 
718
{
 
719
  MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
 
720
 
 
721
  manager_class->ensure_initial_config = meta_monitor_manager_dummy_ensure_initial_config;
 
722
  manager_class->apply_monitors_config = meta_monitor_manager_dummy_apply_monitors_config;
 
723
  manager_class->is_transform_handled = meta_monitor_manager_dummy_is_transform_handled;
 
724
  manager_class->calculate_monitor_mode_scale = meta_monitor_manager_dummy_calculate_monitor_mode_scale;
 
725
  manager_class->calculate_supported_scales = meta_monitor_manager_dummy_calculate_supported_scales;
 
726
  manager_class->get_capabilities = meta_monitor_manager_dummy_get_capabilities;
 
727
  manager_class->get_max_screen_size = meta_monitor_manager_dummy_get_max_screen_size;
 
728
  manager_class->get_default_layout_mode = meta_monitor_manager_dummy_get_default_layout_mode;
 
729
}
 
730
 
 
731
static void
 
732
meta_monitor_manager_dummy_init (MetaMonitorManagerDummy *manager_dummy)
 
733
{
 
734
  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_dummy);
 
735
  const char *nested_offscreen_transform;
 
736
 
 
737
  nested_offscreen_transform =
 
738
    g_getenv ("MUTTER_DEBUG_NESTED_OFFSCREEN_TRANSFORM");
 
739
  if (g_strcmp0 (nested_offscreen_transform, "1") == 0)
 
740
    manager_dummy->is_transform_handled = FALSE;
 
741
  else
 
742
    manager_dummy->is_transform_handled = TRUE;
 
743
 
 
744
  manager_dummy->gpu = g_object_new (META_TYPE_GPU_DUMMY,
 
745
                                     "monitor-manager", manager,
 
746
                                     NULL);
 
747
  meta_monitor_manager_add_gpu (manager, manager_dummy->gpu);
 
748
}
 
749
 
 
750
static gboolean
 
751
meta_gpu_dummy_read_current (MetaGpu  *gpu,
 
752
                             GError  **error)
 
753
{
 
754
  MetaMonitorManager *manager = meta_gpu_get_monitor_manager (gpu);
 
755
 
 
756
  meta_monitor_manager_dummy_read_current (manager);
 
757
 
 
758
  return TRUE;
 
759
}
 
760
 
 
761
static void
 
762
meta_gpu_dummy_init (MetaGpuDummy *gpu_dummy)
 
763
{
 
764
}
 
765
 
 
766
static void
 
767
meta_gpu_dummy_class_init (MetaGpuDummyClass *klass)
 
768
{
 
769
  MetaGpuClass *gpu_class = META_GPU_CLASS (klass);
 
770
 
 
771
  gpu_class->read_current = meta_gpu_dummy_read_current;
 
772
}