11b5d61b8Smrg/*
21b5d61b8Smrg * Copyright (c) 2016, NVIDIA CORPORATION.
31b5d61b8Smrg *
41b5d61b8Smrg * Permission is hereby granted, free of charge, to any person obtaining a
51b5d61b8Smrg * copy of this software and/or associated documentation files (the
61b5d61b8Smrg * "Materials"), to deal in the Materials without restriction, including
71b5d61b8Smrg * without limitation the rights to use, copy, modify, merge, publish,
81b5d61b8Smrg * distribute, sublicense, and/or sell copies of the Materials, and to
91b5d61b8Smrg * permit persons to whom the Materials are furnished to do so, subject to
101b5d61b8Smrg * the following conditions:
111b5d61b8Smrg *
121b5d61b8Smrg * The above copyright notice and this permission notice shall be included
131b5d61b8Smrg * unaltered in all copies or substantial portions of the Materials.
141b5d61b8Smrg * Any additions, deletions, or changes to the original source files
151b5d61b8Smrg * must be clearly indicated in accompanying documentation.
161b5d61b8Smrg *
171b5d61b8Smrg * If only executable code is distributed, then the accompanying
181b5d61b8Smrg * documentation must state that "this software is based in part on the
191b5d61b8Smrg * work of the Khronos Group."
201b5d61b8Smrg *
211b5d61b8Smrg * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
221b5d61b8Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
231b5d61b8Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
241b5d61b8Smrg * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
251b5d61b8Smrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
261b5d61b8Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
271b5d61b8Smrg * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
281b5d61b8Smrg */
291b5d61b8Smrg
301b5d61b8Smrg#include "vndservervendor.h"
311b5d61b8Smrg
321b5d61b8Smrgstruct xorg_list GlxVendorList = { &GlxVendorList, &GlxVendorList };
331b5d61b8Smrg
341b5d61b8SmrgGlxServerVendor *GlxCreateVendor(const GlxServerImports *imports)
351b5d61b8Smrg{
361b5d61b8Smrg    GlxServerVendor *vendor = NULL;
371b5d61b8Smrg
381b5d61b8Smrg    if (imports == NULL) {
391b5d61b8Smrg        ErrorF("GLX: Vendor library did not provide an imports table\n");
401b5d61b8Smrg        return NULL;
411b5d61b8Smrg    }
421b5d61b8Smrg
431b5d61b8Smrg    if (imports->extensionCloseDown == NULL
441b5d61b8Smrg            || imports->handleRequest == NULL
451b5d61b8Smrg            || imports->getDispatchAddress == NULL
461b5d61b8Smrg            || imports->makeCurrent == NULL) {
471b5d61b8Smrg        ErrorF("GLX: Vendor library is missing required callback functions.\n");
481b5d61b8Smrg        return NULL;
491b5d61b8Smrg    }
501b5d61b8Smrg
511b5d61b8Smrg    vendor = (GlxServerVendor *) calloc(1, sizeof(GlxServerVendor));
521b5d61b8Smrg    if (vendor == NULL) {
531b5d61b8Smrg        ErrorF("GLX: Can't allocate vendor library.\n");
541b5d61b8Smrg        return NULL;
551b5d61b8Smrg    }
561b5d61b8Smrg    memcpy(&vendor->glxvc, imports, sizeof(GlxServerImports));
571b5d61b8Smrg
581b5d61b8Smrg    xorg_list_append(&vendor->entry, &GlxVendorList);
591b5d61b8Smrg    return vendor;
601b5d61b8Smrg}
611b5d61b8Smrg
621b5d61b8Smrgvoid GlxDestroyVendor(GlxServerVendor *vendor)
631b5d61b8Smrg{
641b5d61b8Smrg    if (vendor != NULL) {
651b5d61b8Smrg        xorg_list_del(&vendor->entry);
661b5d61b8Smrg        free(vendor);
671b5d61b8Smrg    }
681b5d61b8Smrg}
691b5d61b8Smrg
701b5d61b8Smrgvoid GlxVendorExtensionReset(const ExtensionEntry *extEntry)
711b5d61b8Smrg{
721b5d61b8Smrg    GlxServerVendor *vendor, *tempVendor;
731b5d61b8Smrg
741b5d61b8Smrg    // TODO: Do we allow the driver to destroy a vendor library handle from
751b5d61b8Smrg    // here?
761b5d61b8Smrg    xorg_list_for_each_entry_safe(vendor, tempVendor, &GlxVendorList, entry) {
771b5d61b8Smrg        if (vendor->glxvc.extensionCloseDown != NULL) {
781b5d61b8Smrg            vendor->glxvc.extensionCloseDown(extEntry);
791b5d61b8Smrg        }
801b5d61b8Smrg    }
811b5d61b8Smrg
821b5d61b8Smrg    // If the server is exiting instead of starting a new generation, then
831b5d61b8Smrg    // free the remaining GlxServerVendor structs.
841b5d61b8Smrg    //
851b5d61b8Smrg    // XXX this used to be conditional on xf86ServerIsExiting, but it's
861b5d61b8Smrg    // cleaner to just always create the vendor struct on every generation,
871b5d61b8Smrg    // if nothing else so all ddxes get the same behavior.
881b5d61b8Smrg    xorg_list_for_each_entry_safe(vendor, tempVendor, &GlxVendorList, entry) {
891b5d61b8Smrg        GlxDestroyVendor(vendor);
901b5d61b8Smrg    }
911b5d61b8Smrg}
92