55#include <sys/socket.h>
66#include <sys/wait.h>
77#include <unistd.h>
8+ #include <fnmatch.h>
89#include <wlr/types/wlr_cursor.h>
910#include <wlr/types/wlr_output_layout.h>
1011#include <wlr/types/wlr_output.h>
1516#include "log.h"
1617#include "util.h"
1718
18- int output_name_cmp (const void * item , const void * data ) {
19- const struct output_config * output = item ;
20- const char * name = data ;
21-
22- return strcmp (output -> name , name );
23- }
24-
2519void output_get_identifier (char * identifier , size_t len ,
2620 struct sway_output * output ) {
2721 struct wlr_output * wlr_output = output -> wlr_output ;
@@ -125,104 +119,8 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
125119 }
126120}
127121
128- static void merge_wildcard_on_all (struct output_config * wildcard ) {
129- for (int i = 0 ; i < config -> output_configs -> length ; i ++ ) {
130- struct output_config * oc = config -> output_configs -> items [i ];
131- if (strcmp (wildcard -> name , oc -> name ) != 0 ) {
132- sway_log (SWAY_DEBUG , "Merging output * config on %s" , oc -> name );
133- merge_output_config (oc , wildcard );
134- }
135- }
136- }
137-
138- static void merge_id_on_name (struct output_config * oc ) {
139- char * id_on_name = NULL ;
140- char id [128 ];
141- char * name = NULL ;
142- struct sway_output * output ;
143- wl_list_for_each (output , & root -> all_outputs , link ) {
144- name = output -> wlr_output -> name ;
145- output_get_identifier (id , sizeof (id ), output );
146- if (strcmp (name , oc -> name ) == 0 || strcmp (id , oc -> name ) == 0 ) {
147- size_t length = snprintf (NULL , 0 , "%s on %s" , id , name ) + 1 ;
148- id_on_name = malloc (length );
149- if (!id_on_name ) {
150- sway_log (SWAY_ERROR , "Failed to allocate id on name string" );
151- return ;
152- }
153- snprintf (id_on_name , length , "%s on %s" , id , name );
154- break ;
155- }
156- }
157-
158- if (!id_on_name ) {
159- return ;
160- }
161-
162- int i = list_seq_find (config -> output_configs , output_name_cmp , id_on_name );
163- if (i >= 0 ) {
164- sway_log (SWAY_DEBUG , "Merging on top of existing id on name config" );
165- merge_output_config (config -> output_configs -> items [i ], oc );
166- } else {
167- // If both a name and identifier config, exist generate an id on name
168- int ni = list_seq_find (config -> output_configs , output_name_cmp , name );
169- int ii = list_seq_find (config -> output_configs , output_name_cmp , id );
170- if ((ni >= 0 && ii >= 0 ) || (ni >= 0 && strcmp (oc -> name , id ) == 0 )
171- || (ii >= 0 && strcmp (oc -> name , name ) == 0 )) {
172- struct output_config * ion_oc = new_output_config (id_on_name );
173- if (ni >= 0 ) {
174- merge_output_config (ion_oc , config -> output_configs -> items [ni ]);
175- }
176- if (ii >= 0 ) {
177- merge_output_config (ion_oc , config -> output_configs -> items [ii ]);
178- }
179- merge_output_config (ion_oc , oc );
180- list_add (config -> output_configs , ion_oc );
181- sway_log (SWAY_DEBUG , "Generated id on name output config \"%s\""
182- " (enabled: %d) (%dx%d@%fHz position %d,%d scale %f "
183- "transform %d) (bg %s %s) (dpms %d) (max render time: %d)" ,
184- ion_oc -> name , ion_oc -> enabled , ion_oc -> width , ion_oc -> height ,
185- ion_oc -> refresh_rate , ion_oc -> x , ion_oc -> y , ion_oc -> scale ,
186- ion_oc -> transform , ion_oc -> background ,
187- ion_oc -> background_option , ion_oc -> dpms_state ,
188- ion_oc -> max_render_time );
189- }
190- }
191- free (id_on_name );
192- }
193-
194122struct output_config * store_output_config (struct output_config * oc ) {
195- bool wildcard = strcmp (oc -> name , "*" ) == 0 ;
196- if (wildcard ) {
197- merge_wildcard_on_all (oc );
198- } else {
199- merge_id_on_name (oc );
200- }
201-
202- int i = list_seq_find (config -> output_configs , output_name_cmp , oc -> name );
203- if (i >= 0 ) {
204- sway_log (SWAY_DEBUG , "Merging on top of existing output config" );
205- struct output_config * current = config -> output_configs -> items [i ];
206- merge_output_config (current , oc );
207- free_output_config (oc );
208- oc = current ;
209- } else if (!wildcard ) {
210- sway_log (SWAY_DEBUG , "Adding non-wildcard output config" );
211- i = list_seq_find (config -> output_configs , output_name_cmp , "*" );
212- if (i >= 0 ) {
213- sway_log (SWAY_DEBUG , "Merging on top of output * config" );
214- struct output_config * current = new_output_config (oc -> name );
215- merge_output_config (current , config -> output_configs -> items [i ]);
216- merge_output_config (current , oc );
217- free_output_config (oc );
218- oc = current ;
219- }
220- list_add (config -> output_configs , oc );
221- } else {
222- // New wildcard config. Just add it
223- sway_log (SWAY_DEBUG , "Adding output * config" );
224- list_add (config -> output_configs , oc );
225- }
123+ list_add (config -> output_configs , oc );
226124
227125 sway_log (SWAY_DEBUG , "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
228126 "position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (dpms %d) "
@@ -513,125 +411,43 @@ static void default_output_config(struct output_config *oc,
513411 oc -> max_render_time = 0 ;
514412}
515413
516- static struct output_config * get_output_config (char * identifier ,
517- struct sway_output * sway_output ) {
518- const char * name = sway_output -> wlr_output -> name ;
519-
520- struct output_config * oc_id_on_name = NULL ;
521- struct output_config * oc_name = NULL ;
522- struct output_config * oc_id = NULL ;
523-
524- size_t length = snprintf (NULL , 0 , "%s on %s" , identifier , name ) + 1 ;
525- char * id_on_name = malloc (length );
526- snprintf (id_on_name , length , "%s on %s" , identifier , name );
527- int i = list_seq_find (config -> output_configs , output_name_cmp , id_on_name );
528- if (i >= 0 ) {
529- oc_id_on_name = config -> output_configs -> items [i ];
530- } else {
531- i = list_seq_find (config -> output_configs , output_name_cmp , name );
532- if (i >= 0 ) {
533- oc_name = config -> output_configs -> items [i ];
534- }
414+ struct output_config * find_output_config (struct sway_output * sway_output ) {
415+ // Start with a default config for this output
416+ struct output_config * result = new_output_config ("merge" );
417+ default_output_config (result , sway_output -> wlr_output );
535418
536- i = list_seq_find (config -> output_configs , output_name_cmp , identifier );
537- if (i >= 0 ) {
538- oc_id = config -> output_configs -> items [i ];
419+ // Apply all matches in order
420+ char id [128 ];
421+ output_get_identifier (id , sizeof (id ), sway_output );
422+ char * name = sway_output -> wlr_output -> name ;
423+ for (int i = 0 ; i < config -> output_configs -> length ; ++ i ) {
424+ struct output_config * oc = config -> output_configs -> items [i ];
425+ if (!strcmp (oc -> name , "*" ) || !strcmp (oc -> name , name ) || !strcmp (oc -> name , id )) {
426+ merge_output_config (result , oc );
539427 }
540428 }
541429
542- struct output_config * result = new_output_config ("temp" );
543- if (config -> reloading ) {
544- default_output_config (result , sway_output -> wlr_output );
545- }
546- if (oc_id_on_name ) {
547- // Already have an identifier on name config, use that
548- free (result -> name );
549- result -> name = strdup (id_on_name );
550- merge_output_config (result , oc_id_on_name );
551- } else if (oc_name && oc_id ) {
552- // Generate a config named `<identifier> on <name>` which contains a
553- // merged copy of the identifier on name. This will make sure that both
554- // identifier and name configs are respected, with identifier getting
555- // priority
556- struct output_config * temp = new_output_config (id_on_name );
557- merge_output_config (temp , oc_name );
558- merge_output_config (temp , oc_id );
559- list_add (config -> output_configs , temp );
560-
561- free (result -> name );
562- result -> name = strdup (id_on_name );
563- merge_output_config (result , temp );
564-
565- sway_log (SWAY_DEBUG , "Generated output config \"%s\" (enabled: %d)"
566- " (%dx%d@%fHz position %d,%d scale %f transform %d) (bg %s %s)"
567- " (dpms %d) (max render time: %d)" , result -> name , result -> enabled ,
568- result -> width , result -> height , result -> refresh_rate ,
569- result -> x , result -> y , result -> scale , result -> transform ,
570- result -> background , result -> background_option , result -> dpms_state ,
571- result -> max_render_time );
572- } else if (oc_name ) {
573- // No identifier config, just return a copy of the name config
574- free (result -> name );
575- result -> name = strdup (name );
576- merge_output_config (result , oc_name );
577- } else if (oc_id ) {
578- // No name config, just return a copy of the identifier config
579- free (result -> name );
580- result -> name = strdup (identifier );
581- merge_output_config (result , oc_id );
582- } else {
583- i = list_seq_find (config -> output_configs , output_name_cmp , "*" );
584- if (i >= 0 ) {
585- // No name or identifier config, but there is a wildcard config
586- free (result -> name );
587- result -> name = strdup ("*" );
588- merge_output_config (result , config -> output_configs -> items [i ]);
589- } else if (!config -> reloading ) {
590- // No name, identifier, or wildcard config. Since we are not
591- // reloading with defaults, the output config will be empty, so
592- // just return NULL
593- free_output_config (result );
594- result = NULL ;
595- }
596- }
430+ struct output_config * oc = result ;
431+ sway_log (SWAY_DEBUG , "Found output config %s (enabled: %d) (%dx%d@%fHz "
432+ "position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (dpms %d) "
433+ "(max render time: %d)" ,
434+ oc -> name , oc -> enabled , oc -> width , oc -> height , oc -> refresh_rate ,
435+ oc -> x , oc -> y , oc -> scale , sway_wl_output_subpixel_to_string (oc -> subpixel ),
436+ oc -> transform , oc -> background , oc -> background_option , oc -> dpms_state ,
437+ oc -> max_render_time );
597438
598- free (id_on_name );
599439 return result ;
600440}
601441
602- struct output_config * find_output_config (struct sway_output * output ) {
603- char id [128 ];
604- output_get_identifier (id , sizeof (id ), output );
605- return get_output_config (id , output );
606- }
607-
608- void apply_output_config_to_outputs (struct output_config * oc ) {
442+ void apply_output_config_to_outputs (void ) {
609443 // Try to find the output container and apply configuration now. If
610444 // this is during startup then there will be no container and config
611445 // will be applied during normal "new output" event from wlroots.
612- bool wildcard = strcmp (oc -> name , "*" ) == 0 ;
613- char id [128 ];
614446 struct sway_output * sway_output , * tmp ;
615447 wl_list_for_each_safe (sway_output , tmp , & root -> all_outputs , link ) {
616- char * name = sway_output -> wlr_output -> name ;
617- output_get_identifier (id , sizeof (id ), sway_output );
618- if (wildcard || !strcmp (name , oc -> name ) || !strcmp (id , oc -> name )) {
619- struct output_config * current = get_output_config (id , sway_output );
620- if (!current ) {
621- // No stored output config matched, apply oc directly
622- sway_log (SWAY_DEBUG , "Applying oc directly" );
623- current = new_output_config (oc -> name );
624- merge_output_config (current , oc );
625- }
626- apply_output_config (current , sway_output );
627- free_output_config (current );
628-
629- if (!wildcard ) {
630- // Stop looking if the output config isn't applicable to all
631- // outputs
632- break ;
633- }
634- }
448+ struct output_config * oc = find_output_config (sway_output );
449+ apply_output_config (oc , sway_output );
450+ free_output_config (oc );
635451 }
636452
637453 struct sway_seat * seat ;
@@ -642,14 +458,7 @@ void apply_output_config_to_outputs(struct output_config *oc) {
642458}
643459
644460void reset_outputs (void ) {
645- struct output_config * oc = NULL ;
646- int i = list_seq_find (config -> output_configs , output_name_cmp , "*" );
647- if (i >= 0 ) {
648- oc = config -> output_configs -> items [i ];
649- } else {
650- oc = store_output_config (new_output_config ("*" ));
651- }
652- apply_output_config_to_outputs (oc );
461+ apply_output_config_to_outputs ();
653462}
654463
655464void free_output_config (struct output_config * oc ) {
0 commit comments